diff --git a/Applications/CMakeLists.txt b/Applications/CMakeLists.txt index cf092c2999..88e2c69c17 100644 --- a/Applications/CMakeLists.txt +++ b/Applications/CMakeLists.txt @@ -1,27 +1,27 @@ set(MITK_CPACK_PACKAGE_EXECUTABLES "" CACHE INTERNAL "Collecting windows shortcuts to executables" FORCE) set(MITK_DIR ${PROJECT_BINARY_DIR}) set(MITK_EXPORTS_FILE_INCLUDED 1) -if(MITK_USE_QT AND QT4_FOUND) +if(MITK_USE_QT) if(MITK_USE_CTK) add_subdirectory(PluginGenerator) endif() - + if(MITK_USE_BLUEBERRY) - + foreach(mitk_app ${MITK_APPS}) # extract target_dir and option_name string(REPLACE "^^" "\\;" target_info ${mitk_app}) set(target_info_list ${target_info}) list(GET target_info_list 0 target_dir) list(GET target_info_list 1 option_name) # check if the application is enabled if(${option_name} OR MITK_BUILD_ALL_APPS) add_subdirectory(${target_dir}) endif() endforeach() - + endif() endif() diff --git a/Applications/CoreApp/CMakeLists.txt b/Applications/CoreApp/CMakeLists.txt index 7cc6731c54..b517434c0d 100644 --- a/Applications/CoreApp/CMakeLists.txt +++ b/Applications/CoreApp/CMakeLists.txt @@ -1,35 +1,35 @@ project(CoreApp) set(_app_options) if(MITK_SHOW_CONSOLE_WINDOW) list(APPEND _app_options SHOW_CONSOLE) endif() # Create a cache entry for the provisioning file which is used to export # the file name in the MITKConfig.cmake file. This will keep external projects # which rely on this file happy. set(MITK_COREAPP_PROVISIONING_FILE "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/MitkCoreApp.provisioning" CACHE INTERNAL "CoreApp provisioning file" FORCE) set(_plugins org.blueberry.compat org.mitk.gui.qt.coreapplication org.mitk.gui.qt.stdmultiwidgeteditor ) # Plug-ins listed below will not be # - added as a build-time dependency to the executable # - listed in the provisioning file for the executable # - installed if they are external plug-ins set(_exclude_plugins ) FunctionCreateBlueBerryApplication( NAME MitkCoreApp DESCRIPTION "MITK - CoreApp Application" PLUGINS ${_plugins} ${_app_options} ) -mitk_use_modules(TARGET MitkCoreApp PACKAGES Qt4|QtGui) +mitk_use_modules(TARGET MitkCoreApp PACKAGES Qt4|QtGui Qt5|Widgets) # subproject support add_dependencies(MITK-CoreUI MitkCoreApp) diff --git a/Applications/PluginGenerator/CMakeLists.txt b/Applications/PluginGenerator/CMakeLists.txt index c47bb30588..1684f097e8 100644 --- a/Applications/PluginGenerator/CMakeLists.txt +++ b/Applications/PluginGenerator/CMakeLists.txt @@ -1,77 +1,92 @@ -cmake_minimum_required(VERSION 2.8.9) +if (${CMAKE_SOURCE_DIR} EQUAL ${PROJECT_SOURCE_DIR}) + cmake_minimum_required(VERSION 2.8.9) +endif() project(MitkPluginGenerator) set(VERSION_MAJOR 1) set(VERSION_MINOR 5) set(VERSION_PATCH 0) set(VERSION_STRING "${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}") if(CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME) set(standalone_build 1) else() set(standalone_build 0) endif() #----------------------------------------------------------------------------- # Prerequisites #----------------------------------------------------------------------------- set(QT_DONT_USE_QTGUI 1) set(QT_USE_QTNETWORK 1) -find_package(Qt 4.7 REQUIRED) - -include(${QT_USE_FILE}) +if(MITK_USE_Qt4) + find_package(Qt 4.7 REQUIRED) + include(${QT_USE_FILE}) +else() + find_package(Qt5Network REQUIRED) +endif() configure_file("${CMAKE_CURRENT_SOURCE_DIR}/PluginGeneratorConfig.h.in" "${CMAKE_CURRENT_BINARY_DIR}/PluginGeneratorConfig.h" @ONLY) include_directories("${CMAKE_CURRENT_BINARY_DIR}") #----------------------------------------------------------------------------- # Executable #----------------------------------------------------------------------------- set(src_files PluginGenerator.cpp ctkCommandLineParser.cpp ) -qt4_wrap_cpp(src_files ctkCommandLineParser.h OPTIONS -DBOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) -qt4_add_resources(src_files plugin_template.qrc project_template.qrc) +if(MITK_USE_Qt4) + qt4_wrap_cpp(src_files ctkCommandLineParser.h OPTIONS -DBOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) + qt4_add_resources(src_files plugin_template.qrc project_template.qrc) +else() + qt5_wrap_cpp(src_files ctkCommandLineParser.h OPTIONS -DBOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) + qt5_add_resources(src_files plugin_template.qrc project_template.qrc) +endif() set(exec_target ${PROJECT_NAME}) add_executable(${exec_target} ${src_files}) -target_link_libraries(${exec_target} ${QT_LIBRARIES}) + +if(MITK_USE_Qt4) + target_link_libraries(${exec_target} ${QT_LIBRARIES}) +else() + target_link_libraries(${exec_target} Qt5::Network) +endif() if(NOT standalone_build) # subproject support add_dependencies(MITK-CoreUI ${exec_target}) endif() #----------------------------------------------------------------------------- # Win32 Convenience #----------------------------------------------------------------------------- if(WIN32 AND NOT standalone_build) file(TO_NATIVE_PATH "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${CMAKE_CFG_INTDIR}" native_runtime_dir) add_custom_target(NewPlugin start "MITK PluginGenerator" /D "${native_runtime_dir}" cmd /K ${exec_target}.exe -h DEPENDS ${exec_target}) endif() #----------------------------------------------------------------------------- # Testing #----------------------------------------------------------------------------- if(NOT standalone_build) # Test the plugin generator include(mitkTestPluginGenerator) endif() #----------------------------------------------------------------------------- # Packaging support #----------------------------------------------------------------------------- if(standalone_build) include(SetupPackaging.cmake) endif() diff --git a/Applications/PluginGenerator/PluginTemplate/src/internal/mitkPluginActivator.cpp b/Applications/PluginGenerator/PluginTemplate/src/internal/mitkPluginActivator.cpp index 359d7be966..3cb1b61642 100644 --- a/Applications/PluginGenerator/PluginTemplate/src/internal/mitkPluginActivator.cpp +++ b/Applications/PluginGenerator/PluginTemplate/src/internal/mitkPluginActivator.cpp @@ -1,23 +1,25 @@ $(license) #include "$(activator-file-name).h" #include #include "$(view-file-name).h" namespace mitk { void $(activator-class-name)::start(ctkPluginContext* context) { BERRY_REGISTER_EXTENSION_CLASS($(view-class-name), context) } void $(activator-class-name)::stop(ctkPluginContext* context) { Q_UNUSED(context) } } -Q_EXPORT_PLUGIN2($(plugin-target), mitk::$(activator-class-name)) +#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) + Q_EXPORT_PLUGIN2($(plugin-target), mitk::$(activator-class-name)) +#endif diff --git a/Applications/PluginGenerator/PluginTemplate/src/internal/mitkPluginActivator.h b/Applications/PluginGenerator/PluginTemplate/src/internal/mitkPluginActivator.h index 2c672945eb..589d471ae3 100644 --- a/Applications/PluginGenerator/PluginTemplate/src/internal/mitkPluginActivator.h +++ b/Applications/PluginGenerator/PluginTemplate/src/internal/mitkPluginActivator.h @@ -1,25 +1,28 @@ $(license) #ifndef $(activator-file-name)_h #define $(activator-file-name)_h #include namespace mitk { class $(activator-class-name) : public QObject, public ctkPluginActivator { Q_OBJECT +#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) + Q_PLUGIN_METADATA(IID "$(plugin-target)") +#endif Q_INTERFACES(ctkPluginActivator) public: void start(ctkPluginContext* context); void stop(ctkPluginContext* context); }; // $(activator-class-name) } #endif // $(activator-file-name)_h diff --git a/Applications/PluginGenerator/ProjectTemplate/CMakeExternals/MITK.cmake b/Applications/PluginGenerator/ProjectTemplate/CMakeExternals/MITK.cmake index 960505af33..c0cacdae5e 100644 --- a/Applications/PluginGenerator/ProjectTemplate/CMakeExternals/MITK.cmake +++ b/Applications/PluginGenerator/ProjectTemplate/CMakeExternals/MITK.cmake @@ -1,217 +1,217 @@ #----------------------------------------------------------------------------- # 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_Boost "Use the Boost library in MITK" OFF) option(MITK_USE_OpenCV "Use Intel's OpenCV library" OFF) option(MITK_USE_SOFA "Use Simulation Open Framework Architecture" 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_Boost MITK_USE_OpenCV MITK_USE_SOFA MITK_USE_Python ) if(MITK_USE_QT) # Look for Qt at the superbuild level, to catch missing Qt libs early find_package(Qt4 4.7 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 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() if(MITK_USE_Boost) 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() 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/2014-03" CACHE STRING "The git tag/hash to be used when cloning from MITK_GIT_REPOSITORY") + set(MITK_GIT_TAG "releases/master" 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_QT AND QT_QMAKE_EXECUTABLE) list(APPEND additional_mitk_cmakevars "-DQT_QMAKE_EXECUTABLE:FILEPATH=${QT_QMAKE_EXECUTABLE}") 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} 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}) set(my_qmake_executable ${QT_QMAKE_EXECUTABLE}) 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(my_qmake_executable AND 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() diff --git a/Applications/PluginGenerator/ProjectTemplate/CMakeLists.txt b/Applications/PluginGenerator/ProjectTemplate/CMakeLists.txt index dc3e8c7c1b..0e20c1e221 100644 --- a/Applications/PluginGenerator/ProjectTemplate/CMakeLists.txt +++ b/Applications/PluginGenerator/ProjectTemplate/CMakeLists.txt @@ -1,365 +1,367 @@ cmake_minimum_required(VERSION 2.8.8) # Change project and application name to your own set(MY_PROJECT_NAME $(project-name)) set(MY_APP_NAME $(project-app-name)) #----------------------------------------------------------------------------- # Set a default build type if none was specified #----------------------------------------------------------------------------- if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) message(STATUS "Setting build type to 'Debug' as none was specified.") set(CMAKE_BUILD_TYPE Debug CACHE STRING "Choose the type of build." FORCE) # Set the possible values of build type for cmake-gui set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release" "MinSizeRel" "RelWithDebInfo") endif() #----------------------------------------------------------------------------- # Superbuild Option - Enabled by default #----------------------------------------------------------------------------- option(${MY_PROJECT_NAME}_USE_SUPERBUILD "Build ${MY_PROJECT_NAME} and the projects it depends on via SuperBuild.cmake." ON) if(${MY_PROJECT_NAME}_USE_SUPERBUILD) project(${MY_PROJECT_NAME}-superbuild) set(${MY_PROJECT_NAME}_SOURCE_DIR ${PROJECT_SOURCE_DIR}) set(${MY_PROJECT_NAME}_BINARY_DIR ${PROJECT_BINARY_DIR}) else() project(${MY_PROJECT_NAME}) endif() #----------------------------------------------------------------------------- # See http://cmake.org/cmake/help/cmake-2-8-docs.html#section_Policies for details #----------------------------------------------------------------------------- set(project_policies CMP0001 # NEW: CMAKE_BACKWARDS_COMPATIBILITY should no longer be used. CMP0002 # NEW: Logical target names must be globally unique. CMP0003 # NEW: Libraries linked via full path no longer produce linker search paths. CMP0004 # NEW: Libraries linked may NOT have leading or trailing whitespace. CMP0005 # NEW: Preprocessor definition values are now escaped automatically. CMP0006 # NEW: Installing MACOSX_BUNDLE targets requires a BUNDLE DESTINATION. CMP0007 # NEW: List command no longer ignores empty elements. CMP0008 # NEW: Libraries linked by full-path must have a valid library file name. CMP0009 # NEW: FILE GLOB_RECURSE calls should not follow symlinks by default. CMP0010 # NEW: Bad variable reference syntax is an error. CMP0011 # NEW: Included scripts do automatic cmake_policy PUSH and POP. CMP0012 # NEW: if() recognizes numbers and boolean constants. CMP0013 # NEW: Duplicate binary directories are not allowed. CMP0014 # NEW: Input directories must have CMakeLists.txt + CMP0020 # NEW: Automatically link Qt executables to qtmain target on Windows. + CMP0028 # NEW: Double colon in target name means ALIAS or IMPORTED target. ) foreach(policy ${project_policies}) if(POLICY ${policy}) cmake_policy(SET ${policy} NEW) endif() endforeach() #----------------------------------------------------------------------------- # Update CMake module path #------------------------------------------------------------------------------ set(CMAKE_MODULE_PATH ${${MY_PROJECT_NAME}_SOURCE_DIR}/CMake ${CMAKE_MODULE_PATH} ) #----------------------------------------------------------------------------- # CMake Function(s) and Macro(s) #----------------------------------------------------------------------------- include(MacroEmptyExternalProject) #----------------------------------------------------------------------------- # Output directories. #----------------------------------------------------------------------------- foreach(type LIBRARY RUNTIME ARCHIVE) set(output_dir ${${MY_PROJECT_NAME}_BINARY_DIR}/bin) set(CMAKE_${type}_OUTPUT_DIRECTORY ${output_dir} CACHE INTERNAL "Single output directory for building all libraries.") mark_as_advanced(CMAKE_${type}_OUTPUT_DIRECTORY) endforeach() #----------------------------------------------------------------------------- # Additional Options (also shown during superbuild) #----------------------------------------------------------------------------- option(BUILD_SHARED_LIBS "Build ${MY_PROJECT_NAME} with shared libraries" ON) option(WITH_COVERAGE "Enable/Disable coverage" OFF) option(BUILD_TESTING "Test the project" ON) option(${MY_PROJECT_NAME}_BUILD_ALL_PLUGINS "Build all ${MY_PROJECT_NAME} plugins" OFF) mark_as_advanced(${MY_PROJECT_NAME}_INSTALL_RPATH_RELATIVE ${MY_PROJECT_NAME}_BUILD_ALL_PLUGINS ) #----------------------------------------------------------------------------- # Superbuild script #----------------------------------------------------------------------------- if(${MY_PROJECT_NAME}_USE_SUPERBUILD) include("${CMAKE_CURRENT_SOURCE_DIR}/SuperBuild.cmake") return() endif() #***************************************************************************** #**************************** END OF SUPERBUILD **************************** #***************************************************************************** #----------------------------------------------------------------------------- # Prerequesites #----------------------------------------------------------------------------- set(${PROJECT_NAME}_MODULES_PACKAGE_DEPENDS_DIR "${PROJECT_SOURCE_DIR}/CMake/PackageDepends") set(MODULES_PACKAGE_DEPENDS_DIRS ${${PROJECT_NAME}_MODULES_PACKAGE_DEPENDS_DIR}) -find_package(MITK 2014.03.99 REQUIRED) +find_package(MITK 2014.10.99 REQUIRED) if(COMMAND mitkFunctionCheckMitkCompatibility) mitkFunctionCheckMitkCompatibility(VERSIONS MITK_VERSION_PLUGIN_SYSTEM 1 REQUIRED) else() message(SEND_ERROR "Your MITK version is too old. Please use Git hash b86bf28 or newer") endif() link_directories(${MITK_LINK_DIRECTORIES}) #----------------------------------------------------------------------------- # CMake Function(s) and Macro(s) #----------------------------------------------------------------------------- set(CMAKE_MODULE_PATH ${MITK_SOURCE_DIR}/CMake ${CMAKE_MODULE_PATH} ) include(mitkFunctionCheckCompilerFlags) include(mitkFunctionGetGccVersion) include(mitkFunctionGetVersion) #----------------------------------------------------------------------------- # Set project specific options and variables (NOT available during superbuild) #----------------------------------------------------------------------------- set(${PROJECT_NAME}_VERSION_MAJOR "0") set(${PROJECT_NAME}_VERSION_MINOR "1") set(${PROJECT_NAME}_VERSION_PATCH "1") set(${PROJECT_NAME}_VERSION_STRING "${${PROJECT_NAME}_VERSION_MAJOR}.${${PROJECT_NAME}_VERSION_MINOR}.${${PROJECT_NAME}_VERSION_PATCH}") # Ask the user if a console window should be shown with the applications option(${PROJECT_NAME}_SHOW_CONSOLE_WINDOW "Use this to enable or disable the console window when starting GUI Applications" ON) mark_as_advanced(${PROJECT_NAME}_SHOW_CONSOLE_WINDOW) if(NOT UNIX AND NOT MINGW) set(MITK_WIN32_FORCE_STATIC "STATIC") endif() #----------------------------------------------------------------------------- # Get project version info #----------------------------------------------------------------------------- mitkFunctionGetVersion(${PROJECT_SOURCE_DIR} ${PROJECT_NAME}) #----------------------------------------------------------------------------- # Installation preparation # # These should be set before any MITK install macros are used #----------------------------------------------------------------------------- # on Mac OSX all CTK plugins get copied into every # application bundle (.app directory) specified here set(MACOSX_BUNDLE_NAMES) if(APPLE) list(APPEND MACOSX_BUNDLE_NAMES ${MY_APP_NAME}) endif(APPLE) #----------------------------------------------------------------------------- # Set symbol visibility Flags #----------------------------------------------------------------------------- # MinGW does not export all symbols automatically, so no need to set flags if(CMAKE_COMPILER_IS_GNUCXX AND NOT MINGW) # The MITK module build system does not yet support default hidden visibility set(VISIBILITY_CXX_FLAGS ) # "-fvisibility=hidden -fvisibility-inlines-hidden") endif() #----------------------------------------------------------------------------- # Set coverage Flags #----------------------------------------------------------------------------- if(WITH_COVERAGE) if(CMAKE_COMPILER_IS_GNUCXX) set(coverage_flags "-g -fprofile-arcs -ftest-coverage -O0 -DNDEBUG") set(COVERAGE_CXX_FLAGS ${coverage_flags}) set(COVERAGE_C_FLAGS ${coverage_flags}) endif() endif() #----------------------------------------------------------------------------- # Project C/CXX Flags #----------------------------------------------------------------------------- set(${PROJECT_NAME}_C_FLAGS "${MITK_C_FLAGS} ${COVERAGE_C_FLAGS}") set(${PROJECT_NAME}_C_FLAGS_DEBUG ${MITK_C_FLAGS_DEBUG}) set(${PROJECT_NAME}_C_FLAGS_RELEASE ${MITK_C_FLAGS_RELEASE}) set(${PROJECT_NAME}_CXX_FLAGS "${MITK_CXX_FLAGS} ${VISIBILITY_CXX_FLAGS} ${COVERAGE_CXX_FLAGS}") set(${PROJECT_NAME}_CXX_FLAGS_DEBUG ${MITK_CXX_FLAGS_DEBUG}) set(${PROJECT_NAME}_CXX_FLAGS_RELEASE ${MITK_CXX_FLAGS_RELEASE}) set(${PROJECT_NAME}_EXE_LINKER_FLAGS ${MITK_EXE_LINKER_FLAGS}) set(${PROJECT_NAME}_SHARED_LINKER_FLAGS ${MITK_SHARED_LINKER_FLAGS}) set(${PROJECT_NAME}_MODULE_LINKER_FLAGS ${MITK_MODULE_LINKER_FLAGS}) #----------------------------------------------------------------------------- # Set C/CXX Flags #----------------------------------------------------------------------------- set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${${PROJECT_NAME}_C_FLAGS}") set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} ${${PROJECT_NAME}_C_FLAGS_DEBUG}") set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} ${${PROJECT_NAME}_C_FLAGS_RELEASE}") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${${PROJECT_NAME}_CXX_FLAGS}") set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} ${${PROJECT_NAME}_CXX_FLAGS_DEBUG}") set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} ${${PROJECT_NAME}_CXX_FLAGS_RELEASE}") set(CMAKE_EXE_LINKER_FLAGS ${${PROJECT_NAME}_EXE_LINKER_FLAGS}) set(CMAKE_SHARED_LINKER_FLAGS ${${PROJECT_NAME}_SHARED_LINKER_FLAGS}) set(CMAKE_MODULE_LINKER_FLAGS ${${PROJECT_NAME}_MODULE_LINKER_FLAGS}) #----------------------------------------------------------------------------- # Testing #----------------------------------------------------------------------------- if(BUILD_TESTING) enable_testing() include(CTest) mark_as_advanced(TCL_TCLSH DART_ROOT) # Setup file for setting custom ctest vars configure_file( CMake/CTestCustom.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/CTestCustom.cmake @ONLY ) # Configuration for the CMake-generated test driver set(CMAKE_TESTDRIVER_EXTRA_INCLUDES "#include ") set(CMAKE_TESTDRIVER_BEFORE_TESTMAIN " try {") set(CMAKE_TESTDRIVER_AFTER_TESTMAIN " } catch( std::exception & excp ) { fprintf(stderr,\"%s\\n\",excp.what()); return EXIT_FAILURE; } catch( ... ) { printf(\"Exception caught in the test driver\\n\"); return EXIT_FAILURE; } ") endif() #----------------------------------------------------------------------------- # ${MY_PROJECT_NAME}_SUPERBUILD_BINARY_DIR #----------------------------------------------------------------------------- # If ${MY_PROJECT_NAME}_SUPERBUILD_BINARY_DIR isn't defined, it means this project is # *NOT* build using Superbuild. In that specific case, ${MY_PROJECT_NAME}_SUPERBUILD_BINARY_DIR # should default to PROJECT_BINARY_DIR if(NOT DEFINED ${PROJECT_NAME}_SUPERBUILD_BINARY_DIR) set(${PROJECT_NAME}_SUPERBUILD_BINARY_DIR ${PROJECT_BINARY_DIR}) endif() #----------------------------------------------------------------------------- # Qt support #----------------------------------------------------------------------------- if(MITK_USE_QT) set(QT_QMAKE_EXECUTABLE ${MITK_QMAKE_EXECUTABLE}) endif() #----------------------------------------------------------------------------- # MITK modules #----------------------------------------------------------------------------- # This project's directory holding module config files #set(${PROJECT_NAME}_MODULES_CONF_DIR "${PROJECT_BINARY_DIR}/${MODULES_CONF_DIRNAME}") # Append this projects's module config directory to the global list # (This is used to get include directories for the Exports.h files right) #list(APPEND MODULES_CONF_DIRS ${${PROJECT_NAME}_MODULES_CONF_DIR}) # Clean the modulesConf directory. This ensures that modules are sorted # according to their dependencies in the Modules/CMakeLists.txt file #file(GLOB _modules_conf_files ${${PROJECT_NAME}_MODULES_CONF_DIR}/*.cmake) #if(_modules_conf_files) # file(REMOVE ${_modules_conf_files}) #endif() #add_subdirectory(Modules) #----------------------------------------------------------------------------- # CTK plugins #----------------------------------------------------------------------------- # The CMake code in this section *must* be in the top-level CMakeLists.txt file macro(GetMyTargetLibraries all_target_libraries varname) set(re_ctkplugin "^$(project-plugin-base)_[a-zA-Z0-9_]+$") set(_tmp_list) list(APPEND _tmp_list ${all_target_libraries}) ctkMacroListFilter(_tmp_list re_ctkplugin OUTPUT_VARIABLE ${varname}) endmacro() include(${CMAKE_CURRENT_SOURCE_DIR}/Plugins/Plugins.cmake) ctkMacroSetupPlugins(${PROJECT_PLUGINS} BUILD_OPTION_PREFIX ${MY_PROJECT_NAME}_ BUILD_ALL ${${MY_PROJECT_NAME}_BUILD_ALL_PLUGINS}) #----------------------------------------------------------------------------- # Add subdirectories #----------------------------------------------------------------------------- add_subdirectory(Apps/$(project-app-name)) #----------------------------------------------------------------------------- # Installation #----------------------------------------------------------------------------- # set MITK cpack variables include(mitkSetupCPack) # Customize CPack variables for this project include(CPackSetup) list(APPEND CPACK_CREATE_DESKTOP_LINKS "${MY_APP_NAME}") configure_file(${MITK_SOURCE_DIR}/MITKCPackOptions.cmake.in ${PROJECT_BINARY_DIR}/${PROJECT_NAME}CPackOptions.cmake @ONLY) set(CPACK_PROJECT_CONFIG_FILE "${PROJECT_BINARY_DIR}/${PROJECT_NAME}CPackOptions.cmake") # include CPack model once all variables are set include(CPack) # Additional installation rules include(mitkInstallRules) #----------------------------------------------------------------------------- # Last configuration steps #----------------------------------------------------------------------------- # If we are under Windows, create two batch files which correctly # set up the environment for the application and for Visual Studio if(WIN32) include(mitkFunctionCreateWindowsBatchScript) set(VS_SOLUTION_FILE "${PROJECT_BINARY_DIR}/${PROJECT_NAME}.sln") foreach(VS_BUILD_TYPE debug release) mitkFunctionCreateWindowsBatchScript("${PROJECT_SOURCE_DIR}/CMake/StartVS.bat.in" ${PROJECT_BINARY_DIR}/StartVS_${VS_BUILD_TYPE}.bat ${VS_BUILD_TYPE}) endforeach() endif(WIN32) diff --git a/Applications/Workbench/MitkWorkbench.cpp b/Applications/Workbench/MitkWorkbench.cpp index 9bee617438..6f22216146 100644 --- a/Applications/Workbench/MitkWorkbench.cpp +++ b/Applications/Workbench/MitkWorkbench.cpp @@ -1,215 +1,219 @@ /*=================================================================== 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 #include #include #include #include #include #include #include #include #include #include #include #include class QtSafeApplication : public QtSingleApplication { public: QtSafeApplication(int& argc, char** argv) : QtSingleApplication(argc, argv) {} /** * Reimplement notify to catch unhandled exceptions and open an error message. * * @param receiver * @param event * @return */ bool notify(QObject* receiver, QEvent* event) { QString msg; try { return QApplication::notify(receiver, event); } catch (mitk::Exception& e) { msg = QString("MITK Exception:\n\n") + QString("Description: ") + QString(e.GetDescription()) + QString("\n\n") + QString("Filename: ") + QString(e.GetFile()) + QString("\n\n") + QString("Line: ") + QString::number(e.GetLine()); } catch (Poco::Exception& e) { msg = QString::fromStdString(e.displayText()); } catch (std::exception& e) { msg = e.what(); } catch (...) { msg = "Unknown exception"; } MITK_ERROR << "An error occurred: " << msg.toStdString(); QMessageBox msgBox; msgBox.setText("An error occurred. You should save all data and quit the program to prevent possible data loss."); msgBox.setDetailedText(msg); msgBox.setIcon(QMessageBox::Critical); msgBox.addButton(trUtf8("Exit immediately"), QMessageBox::YesRole); msgBox.addButton(trUtf8("Ignore"), QMessageBox::NoRole); int ret = msgBox.exec(); switch(ret) { case 0: MITK_ERROR << "The program was closed."; this->closeAllWindows(); break; case 1: MITK_ERROR << "The error was ignored by the user. The program may be in a corrupt state and don't behave like expected!"; break; } return false; } }; int main(int argc, char** argv) { // Create a QApplication instance first QtSafeApplication qSafeApp(argc, argv); qSafeApp.setApplicationName("MITK Workbench"); qSafeApp.setOrganizationName("DKFZ"); // This function checks if an instance is already running // and either sends a message to it (containing the command // line arguments) or checks if a new instance was forced by // providing the BlueBerry.newInstance command line argument. // In the latter case, a path to a temporary directory for // the new application's storage directory is returned. QString storageDir = handleNewAppInstance(&qSafeApp, argc, argv, "BlueBerry.newInstance"); if (storageDir.isEmpty()) { // This is a new instance and no other instance is already running. We specify // the storage directory here (this is the same code as in berryInternalPlatform.cpp // so that we can re-use the location for the persistent data location of the // the CppMicroServices library. // Append a hash value of the absolute path of the executable to the data location. // This allows to start the same application from different build or install trees. +#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) + storageDir = QStandardPaths::writableLocation(QStandardPaths::DataLocation) + '_'; +#else storageDir = QDesktopServices::storageLocation(QDesktopServices::DataLocation) + '_'; +#endif storageDir += QString::number(qHash(QCoreApplication::applicationDirPath())) + QDir::separator(); } us::ModuleSettings::SetStoragePath((storageDir + QString("us") + QDir::separator()).toStdString()); // These paths replace the .ini file and are tailored for installation // packages created with CPack. If a .ini file is presented, it will // overwrite the settings in MapConfiguration Poco::Path basePath(argv[0]); basePath.setFileName(""); Poco::Path provFile(basePath); provFile.setFileName("MitkWorkbench.provisioning"); Poco::Path extPath(basePath); extPath.pushDirectory("ExtBundles"); std::string pluginDirs = extPath.toString(); Poco::Util::MapConfiguration* extConfig(new Poco::Util::MapConfiguration()); if (!storageDir.isEmpty()) { extConfig->setString(berry::Platform::ARG_STORAGE_DIR, storageDir.toStdString()); } extConfig->setString(berry::Platform::ARG_PLUGIN_DIRS, pluginDirs); extConfig->setString(berry::Platform::ARG_PROVISIONING, provFile.toString()); extConfig->setString(berry::Platform::ARG_APPLICATION, "org.mitk.qt.extapplication"); QStringList preloadLibs; // Preload the org.mitk.gui.qt.ext plug-in (and hence also QmitkExt) to speed // up a clean-cache start. This also works around bugs in older gcc and glibc implementations, // which have difficulties with multiple dynamic opening and closing of shared libraries with // many global static initializers. It also helps if dependent libraries have weird static // initialization methods and/or missing de-initialization code. preloadLibs << "liborg_mitk_gui_qt_ext"; QMap preloadLibVersion; #ifdef Q_OS_MAC const QString libSuffix = ".dylib"; #elif defined(Q_OS_UNIX) const QString libSuffix = ".so"; #elif defined(Q_OS_WIN) const QString libSuffix = ".dll"; #else const QString libSuffix; #endif for (QStringList::Iterator preloadLibIter = preloadLibs.begin(), iterEnd = preloadLibs.end(); preloadLibIter != iterEnd; ++preloadLibIter) { QString& preloadLib = *preloadLibIter; // In case the application is started from an install directory QString tempLibraryPath = QCoreApplication::applicationDirPath() + "/plugins/" + preloadLib + libSuffix; QFile preloadLibrary (tempLibraryPath); #ifdef Q_OS_MAC if (!preloadLibrary.exists()) { // In case the application is started from a build tree QString relPath = "/../../../plugins/" + preloadLib + libSuffix; tempLibraryPath = QCoreApplication::applicationDirPath() + relPath; preloadLibrary.setFileName(tempLibraryPath); } #endif if(preloadLibrary.exists()) { preloadLib = tempLibraryPath; } // Else fall back to the QLibrary search logic } QString preloadConfig; Q_FOREACH(const QString& preloadLib, preloadLibs) { preloadConfig += preloadLib + preloadLibVersion[preloadLib] + ","; } preloadConfig.chop(1); extConfig->setString(berry::Platform::ARG_PRELOAD_LIBRARY, preloadConfig.toStdString()); // Seed the random number generator, once at startup. QTime time = QTime::currentTime(); qsrand((uint)time.msec()); // Run the workbench. return berry::Starter::Run(argc, argv, extConfig); } diff --git a/BlueBerry/Bundles/org.blueberry.compat/berryPluginActivator.cpp b/BlueBerry/Bundles/org.blueberry.compat/berryPluginActivator.cpp index 2dbbcf72f6..c80399145b 100644 --- a/BlueBerry/Bundles/org.blueberry.compat/berryPluginActivator.cpp +++ b/BlueBerry/Bundles/org.blueberry.compat/berryPluginActivator.cpp @@ -1,70 +1,70 @@ /*=================================================================== BlueBerry Platform 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 "berryPluginActivator_p.h" #include "berryCTKPluginListener_p.h" #include #include namespace berry { org_blueberry_compat_Activator::org_blueberry_compat_Activator() : pluginListener(0) { } org_blueberry_compat_Activator::~org_blueberry_compat_Activator() { delete pluginListener; } void org_blueberry_compat_Activator::start(ctkPluginContext* context) { ctkServiceReference xpRef = context->getServiceReference(); Q_ASSERT(xpRef); IExtensionPointService::Pointer xpService(context->getService(xpRef)); Q_ASSERT(xpService); delete pluginListener; // register a listener to catch new plugin installations/resolutions. pluginListener = new CTKPluginListener(xpService); context->connectPluginListener(pluginListener, SLOT(pluginChanged(ctkPluginEvent)), Qt::DirectConnection); // populate the registry with all the currently installed plugins. // There is a small window here while processPlugins is being // called where the pluginListener may receive a ctkPluginEvent // to add/remove a plugin from the registry. This is ok since // the registry is a synchronized object and will not add the // same bundle twice. pluginListener->processPlugins(context->getPlugins()); } void org_blueberry_compat_Activator::stop(ctkPluginContext* context) { Q_UNUSED(context) } } -Q_EXPORT_PLUGIN2(org_blueberry_compat, berry::org_blueberry_compat_Activator) - - +#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) + Q_EXPORT_PLUGIN2(org_blueberry_compat, berry::org_blueberry_compat_Activator) +#endif diff --git a/BlueBerry/Bundles/org.blueberry.compat/berryPluginActivator_p.h b/BlueBerry/Bundles/org.blueberry.compat/berryPluginActivator_p.h index 9ace285ab1..c0cbcc86bc 100644 --- a/BlueBerry/Bundles/org.blueberry.compat/berryPluginActivator_p.h +++ b/BlueBerry/Bundles/org.blueberry.compat/berryPluginActivator_p.h @@ -1,51 +1,54 @@ /*=================================================================== BlueBerry Platform 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 BERRYCOMPATIBILITYACTIVATOR_P_H #define BERRYCOMPATIBILITYACTIVATOR_P_H #include namespace berry { class CTKPluginListener; class org_blueberry_compat_Activator : public QObject, public ctkPluginActivator { Q_OBJECT +#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) + Q_PLUGIN_METADATA(IID "org_blueberry_compat") +#endif Q_INTERFACES(ctkPluginActivator) public: org_blueberry_compat_Activator(); ~org_blueberry_compat_Activator(); void start(ctkPluginContext* context); void stop(ctkPluginContext* context); private: CTKPluginListener* pluginListener; }; // org_blueberry_compat_Activator typedef org_blueberry_compat_Activator PluginActivator; } #endif // BERRYCOMPATIBILITYACTIVATOR_P_H diff --git a/BlueBerry/Bundles/org.blueberry.core.commands/src/internal/berryPluginActivator.cpp b/BlueBerry/Bundles/org.blueberry.core.commands/src/internal/berryPluginActivator.cpp index 0f96034921..96d36e2dfb 100644 --- a/BlueBerry/Bundles/org.blueberry.core.commands/src/internal/berryPluginActivator.cpp +++ b/BlueBerry/Bundles/org.blueberry.core.commands/src/internal/berryPluginActivator.cpp @@ -1,40 +1,42 @@ /*=================================================================== BlueBerry Platform 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 "berryPluginActivator.h" #include namespace berry { org_blueberry_core_commands_Activator::org_blueberry_core_commands_Activator() { } void org_blueberry_core_commands_Activator::start(ctkPluginContext* context) { Q_UNUSED(context) } void org_blueberry_core_commands_Activator::stop(ctkPluginContext* context) { Q_UNUSED(context) } } -Q_EXPORT_PLUGIN2(org_blueberry_core_commands, berry::org_blueberry_core_commands_Activator) +#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) + Q_EXPORT_PLUGIN2(org_blueberry_core_commands, berry::org_blueberry_core_commands_Activator) +#endif diff --git a/BlueBerry/Bundles/org.blueberry.core.commands/src/internal/berryPluginActivator.h b/BlueBerry/Bundles/org.blueberry.core.commands/src/internal/berryPluginActivator.h index 5eab31b1ee..4ef296411d 100644 --- a/BlueBerry/Bundles/org.blueberry.core.commands/src/internal/berryPluginActivator.h +++ b/BlueBerry/Bundles/org.blueberry.core.commands/src/internal/berryPluginActivator.h @@ -1,42 +1,45 @@ /*=================================================================== BlueBerry Platform 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 BERRYPLUGINACTIVATOR_H #define BERRYPLUGINACTIVATOR_H #include namespace berry { class org_blueberry_core_commands_Activator : public QObject, public ctkPluginActivator { Q_OBJECT +#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) + Q_PLUGIN_METADATA(IID "org_blueberry_core_commands") +#endif Q_INTERFACES(ctkPluginActivator) public: org_blueberry_core_commands_Activator(); void start(ctkPluginContext* context); void stop(ctkPluginContext* context); }; typedef org_blueberry_core_commands_Activator PluginActivator; } #endif // BERRYPLUGINACTIVATOR_H diff --git a/BlueBerry/Bundles/org.blueberry.core.expressions/src/internal/berryPluginActivator.cpp b/BlueBerry/Bundles/org.blueberry.core.expressions/src/internal/berryPluginActivator.cpp index d6926b50cc..8200b5023a 100644 --- a/BlueBerry/Bundles/org.blueberry.core.expressions/src/internal/berryPluginActivator.cpp +++ b/BlueBerry/Bundles/org.blueberry.core.expressions/src/internal/berryPluginActivator.cpp @@ -1,40 +1,42 @@ /*=================================================================== BlueBerry Platform 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 "berryPluginActivator.h" #include namespace berry { org_blueberry_core_expressions_Activator::org_blueberry_core_expressions_Activator() { } void org_blueberry_core_expressions_Activator::start(ctkPluginContext* context) { Q_UNUSED(context) } void org_blueberry_core_expressions_Activator::stop(ctkPluginContext* context) { Q_UNUSED(context) } } -Q_EXPORT_PLUGIN2(org_blueberry_core_expressions, berry::org_blueberry_core_expressions_Activator) +#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) + Q_EXPORT_PLUGIN2(org_blueberry_core_expressions, berry::org_blueberry_core_expressions_Activator) +#endif diff --git a/BlueBerry/Bundles/org.blueberry.core.expressions/src/internal/berryPluginActivator.h b/BlueBerry/Bundles/org.blueberry.core.expressions/src/internal/berryPluginActivator.h index 6c31455fe5..666e66f040 100644 --- a/BlueBerry/Bundles/org.blueberry.core.expressions/src/internal/berryPluginActivator.h +++ b/BlueBerry/Bundles/org.blueberry.core.expressions/src/internal/berryPluginActivator.h @@ -1,42 +1,45 @@ /*=================================================================== BlueBerry Platform 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 BERRYPLUGINACTIVATOR_H #define BERRYPLUGINACTIVATOR_H #include namespace berry { class org_blueberry_core_expressions_Activator : public QObject, public ctkPluginActivator { Q_OBJECT +#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) + Q_PLUGIN_METADATA(IID "org_blueberry_core_expressions") +#endif Q_INTERFACES(ctkPluginActivator) public: org_blueberry_core_expressions_Activator(); void start(ctkPluginContext* context); void stop(ctkPluginContext* context); }; typedef org_blueberry_core_expressions_Activator PluginActivator; } #endif // BERRYPLUGINACTIVATOR_H diff --git a/BlueBerry/Bundles/org.blueberry.core.jobs/src/internal/berryPluginActivator.cpp b/BlueBerry/Bundles/org.blueberry.core.jobs/src/internal/berryPluginActivator.cpp index e56387a238..d731d79046 100644 --- a/BlueBerry/Bundles/org.blueberry.core.jobs/src/internal/berryPluginActivator.cpp +++ b/BlueBerry/Bundles/org.blueberry.core.jobs/src/internal/berryPluginActivator.cpp @@ -1,40 +1,42 @@ /*=================================================================== BlueBerry Platform 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 "berryPluginActivator.h" #include namespace berry { org_blueberry_core_jobs_Activator::org_blueberry_core_jobs_Activator() { } void org_blueberry_core_jobs_Activator::start(ctkPluginContext* context) { Q_UNUSED(context) } void org_blueberry_core_jobs_Activator::stop(ctkPluginContext* context) { Q_UNUSED(context) } } -Q_EXPORT_PLUGIN2(org_blueberry_core_jobs, berry::org_blueberry_core_jobs_Activator) +#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) + Q_EXPORT_PLUGIN2(org_blueberry_core_jobs, berry::org_blueberry_core_jobs_Activator) +#endif diff --git a/BlueBerry/Bundles/org.blueberry.core.jobs/src/internal/berryPluginActivator.h b/BlueBerry/Bundles/org.blueberry.core.jobs/src/internal/berryPluginActivator.h index 160fea1318..7cbaf0af92 100644 --- a/BlueBerry/Bundles/org.blueberry.core.jobs/src/internal/berryPluginActivator.h +++ b/BlueBerry/Bundles/org.blueberry.core.jobs/src/internal/berryPluginActivator.h @@ -1,42 +1,45 @@ /*=================================================================== BlueBerry Platform 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 BERRYPLUGINACTIVATOR_H #define BERRYPLUGINACTIVATOR_H #include namespace berry { class org_blueberry_core_jobs_Activator : public QObject, public ctkPluginActivator { Q_OBJECT +#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) + Q_PLUGIN_METADATA(IID "org_blueberry_core_jobs") +#endif Q_INTERFACES(ctkPluginActivator) public: org_blueberry_core_jobs_Activator(); void start(ctkPluginContext* context); void stop(ctkPluginContext* context); }; typedef org_blueberry_core_jobs_Activator PluginActivator; } #endif // BERRYPLUGINACTIVATOR_H diff --git a/BlueBerry/Bundles/org.blueberry.core.runtime/src/internal/berryPluginActivator.cpp b/BlueBerry/Bundles/org.blueberry.core.runtime/src/internal/berryPluginActivator.cpp index ddb71e1657..fb819bb921 100644 --- a/BlueBerry/Bundles/org.blueberry.core.runtime/src/internal/berryPluginActivator.cpp +++ b/BlueBerry/Bundles/org.blueberry.core.runtime/src/internal/berryPluginActivator.cpp @@ -1,44 +1,46 @@ /*=================================================================== BlueBerry Platform 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 "berryPluginActivator.h" #include namespace berry { org_blueberry_core_runtime_Activator::org_blueberry_core_runtime_Activator() { } void org_blueberry_core_runtime_Activator::start(ctkPluginContext* context) { m_PreferencesService = new PreferencesService(context->getDataFile("").absolutePath().toStdString()); m_PrefServiceReg = context->registerService(m_PreferencesService.GetPointer()); } void org_blueberry_core_runtime_Activator::stop(ctkPluginContext* context) { m_PrefServiceReg.unregister(); m_PreferencesService->ShutDown(); m_PreferencesService = 0; m_PrefServiceReg = 0; } } -Q_EXPORT_PLUGIN2(org_blueberry_core_runtime, berry::org_blueberry_core_runtime_Activator) +#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) + Q_EXPORT_PLUGIN2(org_blueberry_core_runtime, berry::org_blueberry_core_runtime_Activator) +#endif diff --git a/BlueBerry/Bundles/org.blueberry.core.runtime/src/internal/berryPluginActivator.h b/BlueBerry/Bundles/org.blueberry.core.runtime/src/internal/berryPluginActivator.h index 44bb23387a..8b15124263 100644 --- a/BlueBerry/Bundles/org.blueberry.core.runtime/src/internal/berryPluginActivator.h +++ b/BlueBerry/Bundles/org.blueberry.core.runtime/src/internal/berryPluginActivator.h @@ -1,50 +1,53 @@ /*=================================================================== BlueBerry Platform 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 BERRYPLUGINACTIVATOR_H #define BERRYPLUGINACTIVATOR_H #include #include #include "berryPreferencesService.h" namespace berry { class org_blueberry_core_runtime_Activator : public QObject, public ctkPluginActivator { Q_OBJECT +#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) + Q_PLUGIN_METADATA(IID "org_blueberry_core_runtime") +#endif Q_INTERFACES(ctkPluginActivator) public: org_blueberry_core_runtime_Activator(); void start(ctkPluginContext* context); void stop(ctkPluginContext* context); private: PreferencesService::Pointer m_PreferencesService; ctkServiceRegistration m_PrefServiceReg; }; typedef org_blueberry_core_runtime_Activator PluginActivator; } #endif // BERRYPLUGINACTIVATOR_H diff --git a/BlueBerry/Bundles/org.blueberry.osgi/CMakeLists.txt b/BlueBerry/Bundles/org.blueberry.osgi/CMakeLists.txt index cd259682dc..84895ecaed 100644 --- a/BlueBerry/Bundles/org.blueberry.osgi/CMakeLists.txt +++ b/BlueBerry/Bundles/org.blueberry.osgi/CMakeLists.txt @@ -1,37 +1,44 @@ project(org_blueberry_osgi) MACRO_CREATE_CTK_PLUGIN( EXPORT_DIRECTIVE BERRY_OSGI EXPORTED_INCLUDE_SUFFIXES src src/application src/event src/service ) +if(MITK_USE_Qt5) + qt5_use_modules(${PLUGIN_TARGET} Concurrent Gui Sql) +endif() add_executable(${OSGI_APP} MACOSX_BUNDLE "src/application/berryMain.cpp") target_link_libraries(${OSGI_APP} ${PROJECT_NAME} mbilog) if(_ctk_test_plugins) add_dependencies(${OSGI_APP} ${_ctk_test_plugins}) add_dependencies(BlueBerry ${OSGI_APP}) set_property(TARGET ${OSGI_APP} APPEND PROPERTY LABELS BlueBerry) endif() configure_file(src/application/solstice.ini ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${OSGI_APP}.ini) add_executable(${OSGI_UI_APP} MACOSX_BUNDLE "src/application/berryMainUI.cpp") +if(MITK_USE_Qt5) + qt5_use_modules(${OSGI_UI_APP} Widgets) +endif() + target_link_libraries(${OSGI_UI_APP} ${PROJECT_NAME} mbilog) if(_ctk_test_plugins) add_dependencies(${OSGI_UI_APP} ${_ctk_test_plugins}) add_dependencies(BlueBerry ${OSGI_UI_APP}) set_property(TARGET ${OSGI_UI_APP} APPEND PROPERTY LABELS BlueBerry) endif() configure_file(src/application/solstice.ini ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${OSGI_UI_APP}.ini) set(BLUEBERRY_PLUGIN_CACHE_DIR "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/plugin_cache") configure_file("${CMAKE_CURRENT_SOURCE_DIR}/src/berryConfig.h.in" "${CMAKE_CURRENT_BINARY_DIR}/berryConfig.h" @ONLY) diff --git a/BlueBerry/Bundles/org.blueberry.osgi/src/berryMacros.h b/BlueBerry/Bundles/org.blueberry.osgi/src/berryMacros.h index 9c8581cec7..1c95e2cff2 100644 --- a/BlueBerry/Bundles/org.blueberry.osgi/src/berryMacros.h +++ b/BlueBerry/Bundles/org.blueberry.osgi/src/berryMacros.h @@ -1,119 +1,119 @@ /*=================================================================== BlueBerry Platform 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 __BERRY_MACROS_H__ #define __BERRY_MACROS_H__ #include "berryWeakPointer.h" #include "berryExtensionType.h" #define berryNameMacro(className) \ virtual const char* GetClassName() const \ { return #className; }\ static const char* GetStaticClassName() \ { return #className; }\ #define berryManifestMacro(className, namespaze) \ static const char* GetManifestName() \ { return #namespaze #className; } \ #define berryObjectMacro(className) \ typedef className Self; \ typedef berry::SmartPointer Pointer; \ typedef berry::SmartPointer ConstPointer; \ typedef berry::WeakPointer WeakPtr; \ typedef berry::WeakPointer ConstWeakPtr; \ berryNameMacro(className); \ #define berryInterfaceMacro(className, namespaze) \ public: \ berryObjectMacro(className); \ berryManifestMacro(className, namespaze); \ #define berrySimpleInterfaceMacro(className, namespaze) \ protected: className() {} \ public: \ berryNameMacro(className); \ berryManifestMacro(className, namespaze); \ #define berryNewMacro(x) \ static Pointer New(void) \ { \ Pointer smartPtr(new x); \ return smartPtr; \ } \ #define berryNewMacro1Param(x, type1) \ static Pointer New(type1 param1) \ { \ Pointer smartPtr(new x(param1)); \ return smartPtr; \ } \ #define berryNewMacro2Param(x, type1, type2) \ static Pointer New(type1 param1, type2 param2) \ { \ Pointer smartPtr(new x(param1, param2)); \ return smartPtr; \ } \ #define berryNewMacro3Param(x, type1, type2, type3) \ static Pointer New(type1 param1, type2 param2, type3 param3) \ { \ Pointer smartPtr (new x(param1, param2, param3)); \ return smartPtr; \ } \ #ifndef BERRY_NO_TYPESAFE_FLAGS #include "berryFlags.h" #define BERRY_DECLARE_FLAGS(_Flags, _Enum)\ typedef berry::Flags<_Enum> _Flags; #if defined _MSC_VER && _MSC_VER < 1300 # define BERRY_DECLARE_INCOMPATIBLE_FLAGS(_Flags) #else # define BERRY_DECLARE_INCOMPATIBLE_FLAGS(_Flags) \ inline berry::IncompatibleFlag operator|(_Flags::enum_type f1, int f2) \ { return berry::IncompatibleFlag(int(f1) | f2); } #endif #define BERRY_DECLARE_OPERATORS_FOR_FLAGS(_Flags) \ inline berry::Flags<_Flags::enum_type> operator|(_Flags::enum_type f1, _Flags::enum_type f2) \ { return berry::Flags<_Flags::enum_type>(f1) | f2; } \ inline berry::Flags<_Flags::enum_type> operator|(_Flags::enum_type f1, berry::Flags<_Flags::enum_type> f2) \ { return f2 | f1; } BERRY_DECLARE_INCOMPATIBLE_FLAGS(_Flags) #else /* BERRY_NO_TYPESAFE_FLAGS */ #define BERRY_DECLARE_FLAGS(_Flags, _Enum)\ typedef uint _Flags; #define BERRY_DECLARE_OPERATORS_FOR_FLAGS(_Flags) #endif /* BERRY_NO_TYPESAFE_FLAGS */ #define BERRY_REGISTER_EXTENSION_CLASS(_ClassType, _PluginContext)\ {\ QString typeName = _PluginContext->getPlugin()->getSymbolicName();\ typeName = (typeName + "_") + _ClassType::staticMetaObject.className();\ - ::berry::registerExtensionType<_ClassType>(typeName.toAscii().data());\ + ::berry::registerExtensionType<_ClassType>(typeName.toLatin1().data());\ } #endif /*__BERRY_MACROS_H__*/ diff --git a/BlueBerry/Bundles/org.blueberry.osgi/src/internal/berryCTKPluginActivator.cpp b/BlueBerry/Bundles/org.blueberry.osgi/src/internal/berryCTKPluginActivator.cpp index 7bae0fca60..3a1a4d8a91 100755 --- a/BlueBerry/Bundles/org.blueberry.osgi/src/internal/berryCTKPluginActivator.cpp +++ b/BlueBerry/Bundles/org.blueberry.osgi/src/internal/berryCTKPluginActivator.cpp @@ -1,65 +1,67 @@ /*=================================================================== BlueBerry Platform 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 "berryCTKPluginActivator.h" #include "berrySystemBundle.h" #include "berryInternalPlatform.h" #include #include #include #include namespace berry { ctkPluginContext* org_blueberry_osgi_Activator::context = 0; void org_blueberry_osgi_Activator::start(ctkPluginContext* context) { this->context = context; SystemBundle::Pointer systemBundle = InternalPlatform::GetInstance()->GetBundle("system.bundle").Cast(); ExtensionPointService::Pointer service(new ExtensionPointService(&systemBundle->GetBundleLoader())); // register the service in the legacy BlueBerry service registry Platform::GetServiceRegistry().RegisterService(IExtensionPointService::SERVICE_ID, service); // register the service in the CTK service registry context->registerService(service.GetPointer()); } void org_blueberry_osgi_Activator::stop(ctkPluginContext* context) { Q_UNUSED(context) Platform::GetServiceRegistry().UnRegisterService(IExtensionPointService::SERVICE_ID); this->context = 0; // TODO stop framework } ctkPluginContext* org_blueberry_osgi_Activator::getPluginContext() { return context; } } -Q_EXPORT_PLUGIN2(org_blueberry_osgi, berry::org_blueberry_osgi_Activator) +#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) + Q_EXPORT_PLUGIN2(org_blueberry_osgi, berry::org_blueberry_osgi_Activator) +#endif diff --git a/BlueBerry/Bundles/org.blueberry.osgi/src/internal/berryCTKPluginActivator.h b/BlueBerry/Bundles/org.blueberry.osgi/src/internal/berryCTKPluginActivator.h index 9ff6d85df4..6022953670 100755 --- a/BlueBerry/Bundles/org.blueberry.osgi/src/internal/berryCTKPluginActivator.h +++ b/BlueBerry/Bundles/org.blueberry.osgi/src/internal/berryCTKPluginActivator.h @@ -1,51 +1,54 @@ /*=================================================================== BlueBerry Platform 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 BERRYCTKPLUGINACTIVATOR_H #define BERRYCTKPLUGINACTIVATOR_H #include #include #include namespace berry { // We need to export this activator, because it is referenced // in the templated method berry::ServiceRegistry::GetServiceById<>(...) class BERRY_OSGI org_blueberry_osgi_Activator : public QObject, public ctkPluginActivator { Q_OBJECT +#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) + Q_PLUGIN_METADATA(IID "org_blueberry_osgi") +#endif Q_INTERFACES(ctkPluginActivator) public: void start(ctkPluginContext* context); void stop(ctkPluginContext* context); static ctkPluginContext* getPluginContext(); private: static ctkPluginContext* context; }; typedef org_blueberry_osgi_Activator CTKPluginActivator; } #endif // BERRYCTKPLUGINACTIVATOR_H diff --git a/BlueBerry/Bundles/org.blueberry.osgi/src/internal/berryInternalPlatform.cpp b/BlueBerry/Bundles/org.blueberry.osgi/src/internal/berryInternalPlatform.cpp index 68485da61c..798f1ba1e1 100644 --- a/BlueBerry/Bundles/org.blueberry.osgi/src/internal/berryInternalPlatform.cpp +++ b/BlueBerry/Bundles/org.blueberry.osgi/src/internal/berryInternalPlatform.cpp @@ -1,626 +1,630 @@ /*=================================================================== BlueBerry Platform 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 "berryInternalPlatform.h" #include "berryLog.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "berryPlatform.h" #include "berryPlatformException.h" #include "berryDebugUtil.h" #include "event/berryPlatformEvents.h" #include "berryPlatformLogChannel.h" #include "berryIBundle.h" #include "berryCodeCache.h" #include "berryBundleLoader.h" #include "berrySystemBundle.h" #include "berryBundleDirectory.h" #include "berryProvisioningInfo.h" #include #include #include namespace berry { Poco::Mutex InternalPlatform::m_Mutex; InternalPlatform::InternalPlatform() : m_Initialized(false), m_Running(false), m_ConsoleLog(false), m_ServiceRegistry(0), m_CodeCache(0), m_BundleLoader(0), m_SystemBundle(0), m_PlatformLogger(0), m_ctkPluginFrameworkFactory(0), m_EventStarted(PlatformEvent::EV_PLATFORM_STARTED) { } InternalPlatform::~InternalPlatform() { } InternalPlatform* InternalPlatform::GetInstance() { Poco::Mutex::ScopedLock lock(m_Mutex); static InternalPlatform instance; return &instance; } bool InternalPlatform::ConsoleLog() const { return m_ConsoleLog; } ctkPluginContext* InternalPlatform::GetCTKPluginFrameworkContext() const { if (m_ctkPluginFrameworkFactory) { return m_ctkPluginFrameworkFactory->getFramework()->getPluginContext(); } return 0; } ServiceRegistry& InternalPlatform::GetServiceRegistry() { AssertInitialized(); return *m_ServiceRegistry; } void InternalPlatform::Initialize(int& argc, char** argv, Poco::Util::AbstractConfiguration* config) { // initialization Poco::Mutex::ScopedLock lock(m_Mutex); m_Argc = &argc; m_Argv = argv; try { this->init(argc, argv); } catch (const Poco::Util::UnknownOptionException& e) { BERRY_WARN << e.displayText(); } this->loadConfiguration(); if (config) { this->config().add(config, 50, false); } m_ServiceRegistry = new ServiceRegistry(); m_ConsoleLog = this->GetConfiguration().hasProperty(Platform::ARG_CONSOLELOG); m_ConfigPath.assign(this->GetConfiguration().getString("application.configDir")); m_InstancePath.assign(this->GetConfiguration().getString("application.dir")); try { m_InstallPath.assign(this->GetConfiguration().getString(Platform::ARG_HOME)); } catch (Poco::NotFoundException& ) { m_InstallPath.assign(m_InstancePath); } if (this->GetConfiguration().hasProperty(Platform::ARG_STORAGE_DIR)) { std::string dataLocation = this->GetConfiguration().getString(Platform::ARG_STORAGE_DIR, ""); if (dataLocation.at(dataLocation.size()-1) != '/') { dataLocation += '/'; } m_UserPath.assign(dataLocation); } else { // Append a hash value of the absolute path of the executable to the data location. // This allows to start the same application from different build or install trees. +#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) + QString dataLocation = QStandardPaths::writableLocation(QStandardPaths::DataLocation) + '_'; +#else QString dataLocation = QDesktopServices::storageLocation(QDesktopServices::DataLocation) + '_'; +#endif dataLocation += QString::number(qHash(QCoreApplication::applicationDirPath())) + "/"; m_UserPath.assign(dataLocation.toStdString()); } BERRY_INFO(m_ConsoleLog) << "Framework storage dir: " << m_UserPath.toString(); Poco::File userFile(m_UserPath); try { userFile.createDirectories(); userFile.canWrite(); } catch(const Poco::IOException& e) { BERRY_WARN << e.displayText(); m_UserPath.assign(Poco::Path::temp()); m_UserPath.pushDirectory("." + this->commandName()); userFile = m_UserPath; } // Initialize the CTK Plugin Framework ctkProperties fwProps; fwProps.insert(ctkPluginConstants::FRAMEWORK_STORAGE, QString::fromStdString(userFile.path())); if (this->GetConfiguration().hasProperty(Platform::ARG_CLEAN)) { fwProps.insert(ctkPluginConstants::FRAMEWORK_STORAGE_CLEAN, ctkPluginConstants::FRAMEWORK_STORAGE_CLEAN_ONFIRSTINIT); } if (this->GetConfiguration().hasProperty(Platform::ARG_CONSOLELOG)) { fwProps.insert("org.commontk.pluginfw.debug.framework", true); fwProps.insert("org.commontk.pluginfw.debug.errors", true); fwProps.insert("org.commontk.pluginfw.debug.pluginfw", true); fwProps.insert("org.commontk.pluginfw.debug.lazy_activation", true); fwProps.insert("org.commontk.pluginfw.debug.resolve", true); } if (this->GetConfiguration().hasProperty(Platform::ARG_PRELOAD_LIBRARY)) { QString preloadLibs = QString::fromStdString(this->GetConfiguration().getString(Platform::ARG_PRELOAD_LIBRARY)); fwProps.insert(ctkPluginConstants::FRAMEWORK_PRELOAD_LIBRARIES, preloadLibs.split(',', QString::SkipEmptyParts)); } m_ctkPluginFrameworkFactory = new ctkPluginFrameworkFactory(fwProps); QSharedPointer pfw = m_ctkPluginFrameworkFactory->getFramework(); ctkPluginContext* pfwContext = NULL; std::string provisioningFile = this->GetConfiguration().getString(Platform::ARG_PROVISIONING); if (!provisioningFile.empty()) { BERRY_INFO(m_ConsoleLog) << "Using provisioning file: " << provisioningFile; // FIXME: This is a quick-fix for Bug 16224 - Umlaut and other special characters in install/binary path // Assumption : linux provides utf8, windows provides ascii encoded argv lists #ifdef Q_OS_WIN ProvisioningInfo provInfo(QString::fromStdString(provisioningFile.c_str())); #else ProvisioningInfo provInfo(QString::fromUtf8(provisioningFile.c_str())); #endif // it can still happen, that the encoding is not compatible with the fromUtf8 function ( i.e. when manipulating the LANG variable // in such case, the QStringList in provInfo is empty which we can easily check for if( provInfo.getPluginDirs().empty() ) { BERRY_ERROR << "Cannot search for provisioning file, the retrieved directory list is empty.\n" << "This can occur if there are some special (non-ascii) characters in the install path."; throw berry::PlatformException("No provisioning file specified. Terminating..."); } foreach(QString pluginPath, provInfo.getPluginDirs()) { ctkPluginFrameworkLauncher::addSearchPath(pluginPath); } pfw->init(); pfwContext = pfw->getPluginContext(); bool forcePluginOverwrite = this->GetConfiguration().hasOption(Platform::ARG_FORCE_PLUGIN_INSTALL); QList pluginsToStart = provInfo.getPluginsToStart(); foreach(QUrl pluginUrl, provInfo.getPluginsToInstall()) { if (forcePluginOverwrite) { uninstallPugin(pluginUrl, pfwContext); } try { BERRY_INFO(m_ConsoleLog) << "Installing CTK plug-in from: " << pluginUrl.toString().toStdString(); QSharedPointer plugin = pfwContext->installPlugin(pluginUrl); if (pluginsToStart.contains(pluginUrl)) { m_CTKPluginsToStart << plugin->getPluginId(); } } catch (const ctkPluginException& e) { QString errorMsg; QDebug dbg(&errorMsg); dbg << e.printStackTrace(); BERRY_ERROR << qPrintable(errorMsg); } } } else { pfw->init(); pfwContext = pfw->getPluginContext(); BERRY_INFO << "No provisioning file set."; } m_BaseStatePath = m_UserPath; m_BaseStatePath.pushDirectory("bb-metadata"); m_BaseStatePath.pushDirectory("bb-plugins"); Poco::Path logPath(m_UserPath); logPath.setFileName(this->commandName() + ".log"); m_PlatformLogChannel = new PlatformLogChannel(logPath.toString()); m_PlatformLogger = &Poco::Logger::create("PlatformLogger", m_PlatformLogChannel, Poco::Message::PRIO_TRACE); try { m_CodeCache = new CodeCache(this->GetConfiguration().getString(Platform::ARG_PLUGIN_CACHE)); } catch (Poco::NotFoundException&) { Poco::Path cachePath(m_UserPath); cachePath.pushDirectory("bb-plugin_cache"); m_CodeCache = new CodeCache(cachePath.toString()); } m_BundleLoader = new BundleLoader(m_CodeCache, *m_PlatformLogger); // tell the BundleLoader about the installed CTK plug-ins QStringList installedCTKPlugins; foreach(QSharedPointer plugin, pfwContext->getPlugins()) { installedCTKPlugins << plugin->getSymbolicName(); } m_BundleLoader->SetCTKPlugins(installedCTKPlugins); m_Initialized = true; // Clear the CodeCache if (this->GetConfiguration().hasProperty(Platform::ARG_CLEAN)) m_CodeCache->Clear(); try { // assemble a list of base plugin-directories (which contain // the real plugins as directories) std::vector pluginBaseDirs; Poco::StringTokenizer tokenizer(this->GetConfiguration().getString(Platform::ARG_PLUGIN_DIRS, ""), ";", Poco::StringTokenizer::TOK_IGNORE_EMPTY | Poco::StringTokenizer::TOK_TRIM); for (Poco::StringTokenizer::Iterator token = tokenizer.begin(); token != tokenizer.end(); ++token) { pluginBaseDirs.push_back(*token); } std::vector pluginPaths; for (std::vector::iterator pluginBaseDir = pluginBaseDirs.begin(); pluginBaseDir != pluginBaseDirs.end(); ++pluginBaseDir) { BERRY_INFO(m_ConsoleLog) << "Plugin base directory: " << *pluginBaseDir; Poco::File pluginDir(*pluginBaseDir); if (!pluginDir.exists() || !pluginDir.isDirectory()) { BERRY_WARN(m_ConsoleLog) << *pluginBaseDir << " is not a direcotry or does not exist. SKIPPED.\n"; continue; } std::vector pluginList; pluginDir.list(pluginList); std::vector::iterator iter; for (iter = pluginList.begin(); iter != pluginList.end(); iter++) { Poco::Path pluginPath = Poco::Path::forDirectory(*pluginBaseDir); pluginPath.pushDirectory(*iter); Poco::File file(pluginPath); if (file.exists() && file.isDirectory()) { pluginPaths.push_back(pluginPath); } } } std::vector::iterator pathIter; for (pathIter = pluginPaths.begin(); pathIter != pluginPaths.end(); pathIter++) { try { Bundle::Pointer bundle = m_BundleLoader->LoadBundle(*pathIter); if (bundle) { BERRY_INFO(m_ConsoleLog) << "Bundle state (" << pathIter->toString() << "): " << bundle->GetStateString() << std::endl; } } catch (const BundleStateException& exc) { BERRY_WARN << exc.displayText() << std::endl; } } // resolve plugins m_BundleLoader->ResolveAllBundles(); } catch (Poco::Exception& exc) { this->logger().log(exc); } #ifdef BLUEBERRY_DEBUG_SMARTPOINTER DebugUtil::RestoreState(); #endif } void InternalPlatform::uninstallPugin(const QUrl& pluginUrl, ctkPluginContext* pfwContext) { QFileInfo libInfo(pluginUrl.toLocalFile()); QString libName = libInfo.baseName(); if (libName.startsWith("lib")) { libName = libName.mid(3); } QString symbolicName = libName.replace('_', '.'); foreach(QSharedPointer plugin, pfwContext->getPlugins()) { if (plugin->getSymbolicName() == symbolicName && plugin->getLocation() != pluginUrl.toString()) { BERRY_WARN << "A plug-in with the symbolic name " << symbolicName.toStdString() << " but different location is already installed. Trying to uninstall " << plugin->getLocation().toStdString(); plugin->uninstall(); return; } } } void InternalPlatform::Launch() { AssertInitialized(); if (m_Running) return; m_Running = true; this->run(); } void InternalPlatform::Shutdown() { QSharedPointer ctkPluginFW; { Poco::Mutex::ScopedLock lock(m_Mutex); AssertInitialized(); DebugUtil::SaveState(); ctkPluginFW = m_ctkPluginFrameworkFactory->getFramework(); m_Initialized = false; } ctkPluginFW->stop(); this->uninitialize(); // wait 10 seconds for the CTK plugin framework to stop ctkPluginFW->waitForStop(10000); { Poco::Mutex::ScopedLock lock(m_Mutex); delete m_ServiceRegistry; delete m_BundleLoader; delete m_CodeCache; } } void InternalPlatform::AssertInitialized() { if (!m_Initialized) throw Poco::SystemException("The Platform has not been initialized yet!"); } IExtensionPointService::Pointer InternalPlatform::GetExtensionPointService() { Poco::Mutex::ScopedLock lock(m_Mutex); this->AssertInitialized(); return m_ServiceRegistry->GetServiceById(IExtensionPointService::SERVICE_ID); } const Poco::Path& InternalPlatform::GetConfigurationPath() { return m_ConfigPath; } const Poco::Path& InternalPlatform::GetInstallPath() { return m_InstallPath; } const Poco::Path& InternalPlatform::GetInstancePath() { return m_InstancePath; } bool InternalPlatform::GetStatePath(Poco::Path& statePath, IBundle::Pointer bundle, bool create) { statePath = m_BaseStatePath; statePath.pushDirectory(bundle->GetSymbolicName()); try { Poco::File stateFile(statePath); if (!stateFile.exists() && create) stateFile.createDirectories(); } catch (Poco::FileException&) { return false; } return true; } PlatformEvents& InternalPlatform::GetEvents() { return m_Events; } const Poco::Path& InternalPlatform::GetUserPath() { return m_UserPath; } bool InternalPlatform::IsRunning() const { Poco::Mutex::ScopedLock lock(m_Mutex); return (m_Initialized && m_Running); } IBundle::Pointer InternalPlatform::GetBundle(const std::string& id) { Poco::Mutex::ScopedLock lock(m_Mutex); AssertInitialized(); return m_BundleLoader->FindBundle(id); } std::vector InternalPlatform::GetBundles() const { return m_BundleLoader->GetBundles(); } Poco::Logger* InternalPlatform::GetLogger() { return m_PlatformLogger; } Poco::Util::LayeredConfiguration& InternalPlatform::GetConfiguration() const { return this->config(); } std::vector InternalPlatform::GetApplicationArgs() const { return m_FilteredArgs; } int& InternalPlatform::GetRawApplicationArgs(char**& argv) { argv = m_Argv; return *m_Argc; } void InternalPlatform::defineOptions(Poco::Util::OptionSet& options) { Poco::Util::Option helpOption("help", "h", "print this help text"); helpOption.callback(Poco::Util::OptionCallback(this, &InternalPlatform::PrintHelp)); options.addOption(helpOption); Poco::Util::Option newInstanceOption(Platform::ARG_NEWINSTANCE, "", "forces a new instance of this application"); newInstanceOption.binding(Platform::ARG_NEWINSTANCE); options.addOption(newInstanceOption); Poco::Util::Option cleanOption(Platform::ARG_CLEAN, "", "cleans the plugin cache"); cleanOption.binding(Platform::ARG_CLEAN); options.addOption(cleanOption); Poco::Util::Option appOption(Platform::ARG_APPLICATION, "", "the id of the application extension to be executed"); appOption.argument("").binding(Platform::ARG_APPLICATION); options.addOption(appOption); Poco::Util::Option storageDirOption(Platform::ARG_STORAGE_DIR, "", "the location for storing persistent application data"); storageDirOption.argument("").binding(Platform::ARG_STORAGE_DIR); options.addOption(storageDirOption); Poco::Util::Option consoleLogOption(Platform::ARG_CONSOLELOG, "", "log messages to the console"); consoleLogOption.binding(Platform::ARG_CONSOLELOG); options.addOption(consoleLogOption); Poco::Util::Option forcePluginOption(Platform::ARG_FORCE_PLUGIN_INSTALL, "", "force installing plug-ins with same symbolic name"); forcePluginOption.binding(Platform::ARG_FORCE_PLUGIN_INSTALL); options.addOption(forcePluginOption); Poco::Util::Option preloadLibsOption(Platform::ARG_PRELOAD_LIBRARY, "", "preload a library"); preloadLibsOption.argument("").repeatable(true).callback(Poco::Util::OptionCallback(this, &InternalPlatform::handlePreloadLibraryOption)); options.addOption(preloadLibsOption); Poco::Util::Option testPluginOption(Platform::ARG_TESTPLUGIN, "", "the plug-in to be tested"); testPluginOption.argument("").binding(Platform::ARG_TESTPLUGIN); options.addOption(testPluginOption); Poco::Util::Option testAppOption(Platform::ARG_TESTAPPLICATION, "", "the application to be tested"); testAppOption.argument("").binding(Platform::ARG_TESTAPPLICATION); options.addOption(testAppOption); Poco::Util::Option xargsOption(Platform::ARG_XARGS, "", "Extended argument list"); xargsOption.argument("").binding(Platform::ARG_XARGS); options.addOption(xargsOption); Poco::Util::Application::defineOptions(options); } void InternalPlatform::handlePreloadLibraryOption(const std::string& name, const std::string& value) { std::string oldVal; if (this->config().hasProperty(Platform::ARG_PRELOAD_LIBRARY)) { oldVal = this->config().getString(Platform::ARG_PRELOAD_LIBRARY); } this->config().setString(Platform::ARG_PRELOAD_LIBRARY, oldVal + "," + value); } int InternalPlatform::main(const std::vector& args) { m_FilteredArgs = args; //m_FilteredArgs.insert(m_FilteredArgs.begin(), this->config().getString("application.argv[0]")); ctkPluginContext* context = GetCTKPluginFrameworkContext(); QFileInfo storageDir = context->getDataFile(""); BundleDirectory::Pointer bundleStorage(new BundleDirectory(Poco::Path(storageDir.absolutePath().toStdString()))); SystemBundle::Pointer systemBundle(new SystemBundle(*m_BundleLoader, bundleStorage)); if (systemBundle == 0) throw PlatformException("Could not find the system bundle"); m_BundleLoader->m_SystemBundle = systemBundle; m_BundleLoader->LoadBundle(systemBundle); m_ctkPluginFrameworkFactory->getFramework()->start(); foreach(long pluginId, m_CTKPluginsToStart) { BERRY_INFO(m_ConsoleLog) << "Starting CTK plug-in: " << context->getPlugin(pluginId)->getSymbolicName().toStdString() << " [" << pluginId << "]"; // do not change the autostart setting of this plugin context->getPlugin(pluginId)->start(ctkPlugin::START_TRANSIENT | ctkPlugin::START_ACTIVATION_POLICY); } m_BundleLoader->StartSystemBundle(systemBundle); systemBundle->Resume(); return EXIT_OK; } void InternalPlatform::PrintHelp(const std::string&, const std::string&) { Poco::Util::HelpFormatter help(this->options()); help.setAutoIndent(); help.setCommand(this->commandName()); help.format(std::cout); exit(EXIT_OK); } } diff --git a/BlueBerry/Bundles/org.blueberry.osgi/src/service/berryIConfigurationElement.h b/BlueBerry/Bundles/org.blueberry.osgi/src/service/berryIConfigurationElement.h index c2802bb2e6..c05428584e 100644 --- a/BlueBerry/Bundles/org.blueberry.osgi/src/service/berryIConfigurationElement.h +++ b/BlueBerry/Bundles/org.blueberry.osgi/src/service/berryIConfigurationElement.h @@ -1,156 +1,156 @@ /*=================================================================== BlueBerry Platform 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 BERRYIEXTENSIONELEMENT_H_ #define BERRYIEXTENSIONELEMENT_H_ #include "berryLog.h" #include #include "berryBundleLoader.h" #include "berryPlatformException.h" #include "berryExtensionType.h" #include "berryIExecutableExtension.h" #include "berryIExtension.h" #include #include namespace berry { struct IExtension; struct BERRY_OSGI IConfigurationElement : public Object { berryObjectMacro(IConfigurationElement); public: typedef std::vector vector; template C* CreateExecutableExtension(const std::string& propertyName, const std::string& manifestName) { std::string className; if (this->GetAttribute(propertyName, className)) { try { C* cl = m_ClassLoader->LoadClass(m_Contributor, className, manifestName); // check if we have extension adapter and initialize if (dynamic_cast(cl) != 0) { // make the call even if the initialization string is null dynamic_cast(cl)->SetInitializationData(Pointer(this), propertyName, Object::Pointer(0)); } if (cl == 0) { BERRY_WARN << "Could not load executable extension " << className << " from " << GetContributor(); } return cl; } catch (Poco::Exception& e) { BERRY_ERROR << "Error loading class: " << e.displayText() << std::endl; throw e; } } throw CoreException("Missing attribute", propertyName); } template C* CreateExecutableExtension(const std::string& propertyName) { std::string className; if (this->GetAttribute(propertyName, className)) { std::string contributor = this->GetContributor(); QSharedPointer plugin = Platform::GetCTKPlugin(QString::fromStdString(contributor)); if (!plugin.isNull()) { // immediately start the plugin but do not change the plugins autostart setting plugin->start(ctkPlugin::START_TRANSIENT); QString typeName = plugin->getSymbolicName() + "_" + QString::fromStdString(className); - int extensionTypeId = ExtensionType::type(typeName.toAscii().data()); + int extensionTypeId = ExtensionType::type(typeName.toLatin1().data()); if (extensionTypeId == 0) { BERRY_WARN << "The class " << className << " was not registered as an Extension Type using BERRY_REGISTER_EXTENSION_CLASS(type, pluginContext) or you forgot to run Qt's moc on the header file. " "Legacy BlueBerry bundles should use CreateExecutableExtension(propertyName, C::GetManifestName()) instead."; } else { QObject* obj = ExtensionType::construct(extensionTypeId); // check if we have extension adapter and initialize if (IExecutableExtension* execExt = qobject_cast(obj)) { // make the call even if the initialization string is null execExt->SetInitializationData(Pointer(this), propertyName, Object::Pointer(0)); } C* interface = qobject_cast(obj); if (interface == 0) { BERRY_WARN << "The QObject subclass " << className << " does not seem to implement the required interface class, or you forgot the Q_INTERFACES macro."; } return interface; } } else { BERRY_WARN << "Trying to create an executable extension (from " << this->GetDeclaringExtension()->GetExtensionPointIdentifier() << " in " << contributor << ") from a non-CTK plug-in. " "Use the CreateExecutableExtension(propertyName, manifestName) method instead."; } } return 0; } virtual bool GetAttribute(const std::string& name, std::string& value) const = 0; virtual bool GetBoolAttribute(const std::string& name, bool& value) const = 0; virtual const std::vector GetChildren() const = 0; virtual const std::vector GetChildren(const std::string& name) const = 0; virtual std::string GetValue() const = 0; virtual std::string GetName() const = 0; virtual const IConfigurationElement* GetParent() const = 0; virtual const std::string& GetContributor() const = 0; virtual const IExtension* GetDeclaringExtension() const = 0; virtual ~IConfigurationElement() {}; protected: BundleLoader* m_ClassLoader; std::string m_Contributor; }; } // namespace berry #endif /*BERRYIEXTENSIONELEMENT_H_*/ diff --git a/BlueBerry/Bundles/org.blueberry.solstice.common/src/internal/berryPluginActivator.cpp b/BlueBerry/Bundles/org.blueberry.solstice.common/src/internal/berryPluginActivator.cpp index adca73e141..111d643109 100644 --- a/BlueBerry/Bundles/org.blueberry.solstice.common/src/internal/berryPluginActivator.cpp +++ b/BlueBerry/Bundles/org.blueberry.solstice.common/src/internal/berryPluginActivator.cpp @@ -1,40 +1,42 @@ /*=================================================================== BlueBerry Platform 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 "berryPluginActivator.h" #include namespace berry { org_blueberry_solstice_common_Activator::org_blueberry_solstice_common_Activator() { } void org_blueberry_solstice_common_Activator::start(ctkPluginContext* context) { Q_UNUSED(context) } void org_blueberry_solstice_common_Activator::stop(ctkPluginContext* context) { Q_UNUSED(context) } } -Q_EXPORT_PLUGIN2(org_blueberry_solstice_common, berry::org_blueberry_solstice_common_Activator) +#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) + Q_EXPORT_PLUGIN2(org_blueberry_solstice_common, berry::org_blueberry_solstice_common_Activator) +#endif diff --git a/BlueBerry/Bundles/org.blueberry.solstice.common/src/internal/berryPluginActivator.h b/BlueBerry/Bundles/org.blueberry.solstice.common/src/internal/berryPluginActivator.h index 196aaded06..c35fa53e29 100644 --- a/BlueBerry/Bundles/org.blueberry.solstice.common/src/internal/berryPluginActivator.h +++ b/BlueBerry/Bundles/org.blueberry.solstice.common/src/internal/berryPluginActivator.h @@ -1,42 +1,45 @@ /*=================================================================== BlueBerry Platform 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 BERRYPLUGINACTIVATOR_H #define BERRYPLUGINACTIVATOR_H #include namespace berry { class org_blueberry_solstice_common_Activator : public QObject, public ctkPluginActivator { Q_OBJECT +#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) + Q_PLUGIN_METADATA(IID "org_blueberry_solstice_common") +#endif Q_INTERFACES(ctkPluginActivator) public: org_blueberry_solstice_common_Activator(); void start(ctkPluginContext* context); void stop(ctkPluginContext* context); }; typedef org_blueberry_solstice_common_Activator PluginActivator; } #endif // BERRYPLUGINACTIVATOR_H diff --git a/BlueBerry/Bundles/org.blueberry.test/src/internal/berryPluginActivator.cpp b/BlueBerry/Bundles/org.blueberry.test/src/internal/berryPluginActivator.cpp index 085950143e..f6d0a19b0f 100644 --- a/BlueBerry/Bundles/org.blueberry.test/src/internal/berryPluginActivator.cpp +++ b/BlueBerry/Bundles/org.blueberry.test/src/internal/berryPluginActivator.cpp @@ -1,43 +1,45 @@ /*=================================================================== BlueBerry Platform 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 "berryPluginActivator.h" #include "berryCoreTestApplication.h" #include namespace berry { org_blueberry_test_Activator::org_blueberry_test_Activator() { } void org_blueberry_test_Activator::start(ctkPluginContext* context) { BERRY_REGISTER_EXTENSION_CLASS(CoreTestApplication, context) } void org_blueberry_test_Activator::stop(ctkPluginContext* context) { Q_UNUSED(context) } } -Q_EXPORT_PLUGIN2(org_blueberry_test, berry::org_blueberry_test_Activator) +#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) + Q_EXPORT_PLUGIN2(org_blueberry_test, berry::org_blueberry_test_Activator) +#endif diff --git a/BlueBerry/Bundles/org.blueberry.test/src/internal/berryPluginActivator.h b/BlueBerry/Bundles/org.blueberry.test/src/internal/berryPluginActivator.h index 1520a8d1c6..a01f96544e 100644 --- a/BlueBerry/Bundles/org.blueberry.test/src/internal/berryPluginActivator.h +++ b/BlueBerry/Bundles/org.blueberry.test/src/internal/berryPluginActivator.h @@ -1,42 +1,45 @@ /*=================================================================== BlueBerry Platform 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 BERRYPLUGINACTIVATOR_H #define BERRYPLUGINACTIVATOR_H #include namespace berry { class org_blueberry_test_Activator : public QObject, public ctkPluginActivator { Q_OBJECT +#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) + Q_PLUGIN_METADATA(IID "org_blueberry_test") +#endif Q_INTERFACES(ctkPluginActivator) public: org_blueberry_test_Activator(); void start(ctkPluginContext* context); void stop(ctkPluginContext* context); }; typedef org_blueberry_test_Activator PluginActivator; } #endif // BERRYPLUGINACTIVATOR_H diff --git a/BlueBerry/Bundles/org.blueberry.ui.qt.help/CMakeLists.txt b/BlueBerry/Bundles/org.blueberry.ui.qt.help/CMakeLists.txt index c410566d05..ab3b99d97b 100644 --- a/BlueBerry/Bundles/org.blueberry.ui.qt.help/CMakeLists.txt +++ b/BlueBerry/Bundles/org.blueberry.ui.qt.help/CMakeLists.txt @@ -1,13 +1,17 @@ project(org_blueberry_ui_qt_help) set(QT_USE_QTHELP 1) set(QT_USE_QTWEBKIT 1) set(QT_USE_QTNETWORK 1) MACRO_CREATE_CTK_PLUGIN( EXPORT_DIRECTIVE org_blueberry_ui_qt_help_EXPORT EXPORTED_INCLUDE_SUFFIXES src ) +if(MITK_USE_Qt5) + qt5_use_modules(${PLUGIN_TARGET} Help OpenGL PrintSupport WebKitWidgets Xml) +endif() + target_link_libraries(${PROJECT_NAME} ${QT_QTHELP_LIBRARY} ${QT_QTWEBKIT_LIBRARY} ${QT_QTNETWORK_LIBRARY}) diff --git a/BlueBerry/Bundles/org.blueberry.ui.qt.help/src/internal/berryHelpPluginActivator.cpp b/BlueBerry/Bundles/org.blueberry.ui.qt.help/src/internal/berryHelpPluginActivator.cpp index 31f28bf0cb..ea14811264 100644 --- a/BlueBerry/Bundles/org.blueberry.ui.qt.help/src/internal/berryHelpPluginActivator.cpp +++ b/BlueBerry/Bundles/org.blueberry.ui.qt.help/src/internal/berryHelpPluginActivator.cpp @@ -1,470 +1,472 @@ /*=================================================================== BlueBerry Platform 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 "berryHelpPluginActivator.h" #include "berryHelpContentView.h" #include "berryHelpIndexView.h" #include "berryHelpSearchView.h" #include "berryHelpEditor.h" #include "berryHelpEditorInput.h" #include "berryHelpPerspective.h" #include "berryQHelpEngineConfiguration.h" #include "berryQHelpEngineWrapper.h" #include #include #include #include #include namespace berry { class HelpPerspectiveListener : public IPerspectiveListener { public: Events::Types GetPerspectiveEventTypes() const; void PerspectiveOpened(SmartPointer page, IPerspectiveDescriptor::Pointer perspective); void PerspectiveChanged(SmartPointer page, IPerspectiveDescriptor::Pointer perspective, const std::string &changeId); }; class HelpWindowListener : public IWindowListener { public: HelpWindowListener(); ~HelpWindowListener(); void WindowClosed(IWorkbenchWindow::Pointer window); void WindowOpened(IWorkbenchWindow::Pointer window); private: // We use the same perspective listener for every window IPerspectiveListener::Pointer perspListener; }; HelpPluginActivator* HelpPluginActivator::instance = 0; HelpPluginActivator::HelpPluginActivator() : pluginListener(0) { this->instance = this; } HelpPluginActivator::~HelpPluginActivator() { instance = 0; } void HelpPluginActivator::start(ctkPluginContext* context) { BERRY_REGISTER_EXTENSION_CLASS(berry::HelpContentView, context) BERRY_REGISTER_EXTENSION_CLASS(berry::HelpIndexView, context) BERRY_REGISTER_EXTENSION_CLASS(berry::HelpSearchView, context) BERRY_REGISTER_EXTENSION_CLASS(berry::HelpEditor, context) BERRY_REGISTER_EXTENSION_CLASS(berry::HelpPerspective, context) QFileInfo qhcInfo = context->getDataFile("qthelpcollection.qhc"); helpEngine.reset(new QHelpEngineWrapper(qhcInfo.absoluteFilePath())); if (!helpEngine->setupData()) { BERRY_ERROR << "QHelpEngine set-up failed: " << helpEngine->error().toStdString(); return; } helpEngineConfiguration.reset(new QHelpEngineConfiguration(context, *helpEngine.data())); delete pluginListener; pluginListener = new QCHPluginListener(context, helpEngine.data()); context->connectPluginListener(pluginListener, SLOT(pluginChanged(ctkPluginEvent))); // register all QCH files from all the currently installed plugins pluginListener->processPlugins(); helpEngine->initialDocSetupDone(); // Register a wnd listener which registers a perspective listener for each // new window. The perspective listener opens the help home page in the window // if no other help page is opened yet. wndListener = IWindowListener::Pointer(new HelpWindowListener()); PlatformUI::GetWorkbench()->AddWindowListener(wndListener); // Register an event handler for CONTEXTHELP_REQUESTED events helpContextHandler.reset(new HelpContextHandler); ctkDictionary helpHandlerProps; helpHandlerProps.insert(ctkEventConstants::EVENT_TOPIC, "org/blueberry/ui/help/CONTEXTHELP_REQUESTED"); context->registerService(helpContextHandler.data(), helpHandlerProps); } void HelpPluginActivator::stop(ctkPluginContext* /*context*/) { delete pluginListener; pluginListener = 0; if (PlatformUI::IsWorkbenchRunning()) { PlatformUI::GetWorkbench()->RemoveWindowListener(wndListener); } wndListener = 0; } HelpPluginActivator *HelpPluginActivator::getInstance() { return instance; } QHelpEngineWrapper& HelpPluginActivator::getQHelpEngine() { return *helpEngine; } void HelpPluginActivator::linkActivated(IWorkbenchPage::Pointer page, const QUrl &link) { IEditorInput::Pointer input(new HelpEditorInput(link)); // see if an editor with the same input is already open IEditorPart::Pointer reuseEditor = page->FindEditor(input); if (reuseEditor) { // just activate it page->Activate(reuseEditor); } else { // reuse the currently active editor, if it is a HelpEditor reuseEditor = page->GetActiveEditor(); if (reuseEditor.IsNotNull() && page->GetReference(reuseEditor)->GetId() == HelpEditor::EDITOR_ID) { page->ReuseEditor(reuseEditor.Cast(), input); page->Activate(reuseEditor); } else { // get the last used HelpEditor instance std::vector editors = page->FindEditors(IEditorInput::Pointer(0), HelpEditor::EDITOR_ID, IWorkbenchPage::MATCH_ID); if (editors.empty()) { // no HelpEditor is currently open, create a new one page->OpenEditor(input, HelpEditor::EDITOR_ID); } else { // reuse an existing editor reuseEditor = editors.front()->GetEditor(false); page->ReuseEditor(reuseEditor.Cast(), input); page->Activate(reuseEditor); } } } } QCHPluginListener::QCHPluginListener(ctkPluginContext* context, QHelpEngine* helpEngine) : delayRegistration(true), context(context), helpEngine(helpEngine) {} void QCHPluginListener::processPlugins() { QMutexLocker lock(&mutex); processPlugins_unlocked(); } void QCHPluginListener::pluginChanged(const ctkPluginEvent& event) { QMutexLocker lock(&mutex); if (delayRegistration) { this->processPlugins_unlocked(); return; } /* Only should listen for RESOLVED and UNRESOLVED events. * * When a plugin is updated the Framework will publish an UNRESOLVED and * then a RESOLVED event which should cause the plugin to be removed * and then added back into the registry. * * When a plugin is uninstalled the Framework should publish an UNRESOLVED * event and then an UNINSTALLED event so the plugin will have been removed * by the UNRESOLVED event before the UNINSTALLED event is published. */ QSharedPointer plugin = event.getPlugin(); switch (event.getType()) { case ctkPluginEvent::RESOLVED : addPlugin(plugin); break; case ctkPluginEvent::UNRESOLVED : removePlugin(plugin); break; } } void QCHPluginListener::processPlugins_unlocked() { if (!delayRegistration) return; foreach (QSharedPointer plugin, context->getPlugins()) { if (isPluginResolved(plugin)) addPlugin(plugin); else removePlugin(plugin); } delayRegistration = false; } bool QCHPluginListener::isPluginResolved(QSharedPointer plugin) { return (plugin->getState() & (ctkPlugin::RESOLVED | ctkPlugin::ACTIVE | ctkPlugin::STARTING | ctkPlugin::STOPPING)) != 0; } void QCHPluginListener::removePlugin(QSharedPointer plugin) { // bail out if system plugin if (plugin->getPluginId() == 0) return; QFileInfo qchDirInfo = context->getDataFile("qch_files/" + QString::number(plugin->getPluginId())); if (qchDirInfo.exists()) { QDir qchDir(qchDirInfo.absoluteFilePath()); QStringList qchEntries = qchDir.entryList(QStringList("*.qch")); QStringList qchFiles; foreach(QString qchEntry, qchEntries) { qchFiles << qchDir.absoluteFilePath(qchEntry); } // unregister the cached qch files foreach(QString qchFile, qchFiles) { QString namespaceName = QHelpEngineCore::namespaceName(qchFile); if (namespaceName.isEmpty()) { BERRY_ERROR << "Could not get the namespace for qch file " << qchFile.toStdString(); continue; } else { if (!helpEngine->unregisterDocumentation(namespaceName)) { BERRY_ERROR << "Unregistering qch namespace " << namespaceName.toStdString() << " failed: " << helpEngine->error().toStdString(); } } } // clean the directory foreach(QString qchEntry, qchEntries) { qchDir.remove(qchEntry); } } } void QCHPluginListener::addPlugin(QSharedPointer plugin) { // bail out if system plugin if (plugin->getPluginId() == 0) return; QFileInfo qchDirInfo = context->getDataFile("qch_files/" + QString::number(plugin->getPluginId())); QUrl location(plugin->getLocation()); QFileInfo pluginFileInfo(location.toLocalFile()); if (!qchDirInfo.exists() || qchDirInfo.lastModified() < pluginFileInfo.lastModified()) { removePlugin(plugin); if (!qchDirInfo.exists()) { QDir().mkpath(qchDirInfo.absoluteFilePath()); } QStringList localQCHFiles; QStringList resourceList = plugin->findResources("/", "*.qch", true); foreach(QString resource, resourceList) { QByteArray content = plugin->getResource(resource); QFile localFile(qchDirInfo.absoluteFilePath() + "/" + resource.section('/', -1)); localFile.open(QIODevice::WriteOnly); localFile.write(content); localFile.close(); if (localFile.error() != QFile::NoError) { BERRY_WARN << "Error writing " << localFile.fileName().toStdString() << ": " << localFile.errorString().toStdString(); } else { localQCHFiles << localFile.fileName(); } } foreach(QString qchFile, localQCHFiles) { if (!helpEngine->registerDocumentation(qchFile)) { BERRY_ERROR << "Registering qch file " << qchFile.toStdString() << " failed: " << helpEngine->error().toStdString(); } } } } IPerspectiveListener::Events::Types HelpPerspectiveListener::GetPerspectiveEventTypes() const { return Events::OPENED | Events::CHANGED; } void HelpPerspectiveListener::PerspectiveOpened(SmartPointer page, IPerspectiveDescriptor::Pointer perspective) { // if no help editor is opened, open one showing the home page if (perspective->GetId() == HelpPerspective::ID && page->FindEditors(IEditorInput::Pointer(0), HelpEditor::EDITOR_ID, IWorkbenchPage::MATCH_ID).empty()) { IEditorInput::Pointer input(new HelpEditorInput()); page->OpenEditor(input, HelpEditor::EDITOR_ID); } } void HelpPerspectiveListener::PerspectiveChanged(SmartPointer page, IPerspectiveDescriptor::Pointer perspective, const std::string &changeId) { if (perspective->GetId() == HelpPerspective::ID && changeId == IWorkbenchPage::CHANGE_RESET) { PerspectiveOpened(page, perspective); } } HelpWindowListener::HelpWindowListener() : perspListener(new HelpPerspectiveListener()) { // Register perspective listener for already opened windows typedef std::vector WndVec; WndVec windows = PlatformUI::GetWorkbench()->GetWorkbenchWindows(); for (WndVec::iterator i = windows.begin(); i != windows.end(); ++i) { (*i)->AddPerspectiveListener(perspListener); } } HelpWindowListener::~HelpWindowListener() { typedef std::vector WndVec; WndVec windows = PlatformUI::GetWorkbench()->GetWorkbenchWindows(); for (WndVec::iterator i = windows.begin(); i != windows.end(); ++i) { (*i)->RemovePerspectiveListener(perspListener); } } void HelpWindowListener::WindowClosed(IWorkbenchWindow::Pointer window) { window->RemovePerspectiveListener(perspListener); } void HelpWindowListener::WindowOpened(IWorkbenchWindow::Pointer window) { window->AddPerspectiveListener(perspListener); } void HelpContextHandler::handleEvent(const ctkEvent &event) { struct _runner : public Poco::Runnable { _runner(const ctkEvent& ev) : ev(ev) {} void run() { QUrl helpUrl; if (ev.containsProperty("url")) { helpUrl = QUrl(ev.getProperty("url").toString()); } else { helpUrl = contextUrl(); } HelpPluginActivator::linkActivated(PlatformUI::GetWorkbench()->GetActiveWorkbenchWindow()->GetActivePage(), helpUrl); delete this; } QUrl contextUrl() const { berry::IWorkbench* currentWorkbench = berry::PlatformUI::GetWorkbench(); if (currentWorkbench) { berry::IWorkbenchWindow::Pointer currentWorkbenchWindow = currentWorkbench->GetActiveWorkbenchWindow(); if (currentWorkbenchWindow) { berry::IWorkbenchPage::Pointer currentPage = currentWorkbenchWindow->GetActivePage(); if (currentPage) { berry::IWorkbenchPart::Pointer currentPart = currentPage->GetActivePart(); if (currentPart) { QString pluginID = QString::fromStdString(currentPart->GetSite()->GetPluginId()); QString viewID = QString::fromStdString(currentPart->GetSite()->GetId()); QString loc = "qthelp://" + pluginID + "/bundle/%1.html"; QHelpEngineWrapper& helpEngine = HelpPluginActivator::getInstance()->getQHelpEngine(); // Get view help page if available QUrl contextUrl(loc.arg(viewID.replace(".", "_"))); QUrl url = helpEngine.findFile(contextUrl); if (url.isValid()) return url; else { BERRY_INFO << "Context help url invalid: " << contextUrl.toString().toStdString(); } // If no view help exists get plugin help if available QUrl pluginContextUrl(loc.arg(pluginID.replace(".", "_"))); url = helpEngine.findFile(pluginContextUrl); if (url.isValid()) return url; // Try to get the index.html file of the plug-in contributing the // currently active part. QUrl pluginIndexUrl(loc.arg("index")); url = helpEngine.findFile(pluginIndexUrl); if (url != pluginIndexUrl) { // Use the default page instead of another index.html // (merged via the virtual folder property). url = QUrl(); } return url; } } } } return QUrl(); } ctkEvent ev; }; // sync with GUI thread Display::GetDefault()->AsyncExec(new _runner(event)); } } -Q_EXPORT_PLUGIN2(org_blueberry_ui_qt_help, berry::HelpPluginActivator) +#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) + Q_EXPORT_PLUGIN2(org_blueberry_ui_qt_help, berry::HelpPluginActivator) +#endif diff --git a/BlueBerry/Bundles/org.blueberry.ui.qt.help/src/internal/berryHelpPluginActivator.h b/BlueBerry/Bundles/org.blueberry.ui.qt.help/src/internal/berryHelpPluginActivator.h index c982abd6c8..157018f622 100644 --- a/BlueBerry/Bundles/org.blueberry.ui.qt.help/src/internal/berryHelpPluginActivator.h +++ b/BlueBerry/Bundles/org.blueberry.ui.qt.help/src/internal/berryHelpPluginActivator.h @@ -1,117 +1,120 @@ /*=================================================================== BlueBerry Platform 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 BERRYLOGPLUGIN_H_ #define BERRYLOGPLUGIN_H_ #include #include #include #include #include #include #include class QHelpEngine; namespace berry { class QHelpEngineConfiguration; class QHelpEngineWrapper; class QCHPluginListener; class HelpContextHandler : public QObject, public ctkEventHandler { Q_OBJECT +#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) + Q_PLUGIN_METADATA(IID "org_blueberry_ui_qt_help") +#endif Q_INTERFACES(ctkEventHandler) public: void handleEvent(const ctkEvent& event); }; class HelpPluginActivator : public QObject, public ctkPluginActivator { Q_OBJECT Q_INTERFACES(ctkPluginActivator) public: HelpPluginActivator(); ~HelpPluginActivator(); void start(ctkPluginContext* context); void stop(ctkPluginContext* context); static HelpPluginActivator* getInstance(); static void linkActivated(IWorkbenchPage::Pointer page, const QUrl &link); QHelpEngineWrapper& getQHelpEngine(); private: Q_DISABLE_COPY(HelpPluginActivator) static HelpPluginActivator* instance; QScopedPointer helpEngine; QScopedPointer helpEngineConfiguration; QScopedPointer helpContextHandler; QCHPluginListener* pluginListener; IWindowListener::Pointer wndListener; }; /** * A listener for CTK plugin events. When plugins come and go we look to see * if there are any qch files and update the QHelpEngine accordingly. */ class QCHPluginListener : public QObject { Q_OBJECT public: QCHPluginListener(ctkPluginContext* context, QHelpEngine* helpEngine); void processPlugins(); public Q_SLOTS: void pluginChanged(const ctkPluginEvent& event); private: void processPlugins_unlocked(); bool isPluginResolved(QSharedPointer plugin); void removePlugin(QSharedPointer plugin); void addPlugin(QSharedPointer plugin); QMutex mutex; bool delayRegistration; ctkPluginContext* context; QHelpEngine* helpEngine; }; } #endif /*BERRYLOGPLUGIN_H_*/ diff --git a/BlueBerry/Bundles/org.blueberry.ui.qt.help/src/internal/berryHelpSearchView.cpp b/BlueBerry/Bundles/org.blueberry.ui.qt.help/src/internal/berryHelpSearchView.cpp index 6463978ab9..8747f673ae 100644 --- a/BlueBerry/Bundles/org.blueberry.ui.qt.help/src/internal/berryHelpSearchView.cpp +++ b/BlueBerry/Bundles/org.blueberry.ui.qt.help/src/internal/berryHelpSearchView.cpp @@ -1,242 +1,243 @@ /*=================================================================== BlueBerry Platform 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. ===================================================================*/ #ifdef __MINGW32__ // We need to inlclude winbase.h here in order to declare // atomic intrinsics like InterlockedIncrement correctly. // Otherwhise, they would be declared wrong within qatomic_windows.h . #include #endif #include "berryHelpSearchView.h" #include "berryHelpPluginActivator.h" #include "berryQHelpEngineWrapper.h" #include "berryHelpEditorInput.h" #include "berryHelpEditor.h" #include #include #include #include +#include #include #include #include #include #include namespace berry { HelpSearchView::HelpSearchView() : m_ZoomCount(0) , m_Parent(0) , m_SearchEngine(HelpPluginActivator::getInstance()->getQHelpEngine().searchEngine()) , m_ResultWidget(0) , m_QueryWidget(0) { } HelpSearchView::~HelpSearchView() { // prevent deletion of the widget m_ResultWidget->setParent(0); } void HelpSearchView::CreateQtPartControl(QWidget* parent) { if (m_ResultWidget == 0) { m_Parent = parent; QVBoxLayout* vLayout = new QVBoxLayout(parent); // This will be lead to strange behavior when using multiple instances of this view // because the QHelpSearchResultWidget instance is shared. The new view will // reparent the widget. m_ResultWidget = m_SearchEngine->resultWidget(); m_QueryWidget = new QHelpSearchQueryWidget(); vLayout->addWidget(m_QueryWidget); vLayout->addWidget(m_ResultWidget); connect(m_QueryWidget, SIGNAL(search()), this, SLOT(search())); connect(m_ResultWidget, SIGNAL(requestShowLink(QUrl)), this, SLOT(requestShowLink(QUrl))); connect(m_SearchEngine, SIGNAL(searchingStarted()), this, SLOT(searchingStarted())); connect(m_SearchEngine, SIGNAL(searchingFinished(int)), this, SLOT(searchingFinished(int))); - QTextBrowser* browser = qFindChild(m_ResultWidget); + QTextBrowser* browser = m_ResultWidget->findChild(); if (browser) // Will be null if QtHelp was configured not to use CLucene. { browser->viewport()->installEventFilter(this); browser->setContextMenuPolicy(Qt::CustomContextMenu); connect(browser, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(showContextMenu(QPoint))); } } } void HelpSearchView::SetFocus() { if (!(m_ResultWidget->hasFocus())) { m_QueryWidget->setFocus(); } } void HelpSearchView::zoomIn() { - QTextBrowser* browser = qFindChild(m_ResultWidget); + QTextBrowser* browser = m_ResultWidget->findChild(); if (browser && m_ZoomCount != 10) { m_ZoomCount++; browser->zoomIn(); } } void HelpSearchView::zoomOut() { - QTextBrowser* browser = qFindChild(m_ResultWidget); + QTextBrowser* browser = m_ResultWidget->findChild(); if (browser && m_ZoomCount != -5) { m_ZoomCount--; browser->zoomOut(); } } void HelpSearchView::resetZoom() { if (m_ZoomCount == 0) return; - QTextBrowser* browser = qFindChild(m_ResultWidget); + QTextBrowser* browser = m_ResultWidget->findChild(); if (browser) { browser->zoomOut(m_ZoomCount); m_ZoomCount = 0; } } void HelpSearchView::search() const { QList query = m_QueryWidget->query(); m_SearchEngine->search(query); } void HelpSearchView::searchingStarted() { m_Parent->setCursor(QCursor(Qt::WaitCursor)); } void HelpSearchView::searchingFinished(int hits) { Q_UNUSED(hits) m_Parent->unsetCursor(); //qApp->restoreOverrideCursor(); } void HelpSearchView::requestShowLink(const QUrl &link) { HelpPluginActivator::linkActivated(this->GetSite()->GetPage(), link); } bool HelpSearchView::eventFilter(QObject* o, QEvent *e) { - QTextBrowser* browser = qFindChild(m_ResultWidget); + QTextBrowser* browser = m_ResultWidget->findChild(); if (browser && o == browser->viewport() && e->type() == QEvent::MouseButtonRelease) { QMouseEvent* me = static_cast(e); QUrl link = m_ResultWidget->linkAt(me->pos()); if (!link.isEmpty() || link.isValid()) { bool controlPressed = me->modifiers() & Qt::ControlModifier; if((me->button() == Qt::LeftButton && controlPressed) || (me->button() == Qt::MidButton)) { IEditorInput::Pointer input(new HelpEditorInput(link)); this->GetSite()->GetPage()->OpenEditor(input, HelpEditor::EDITOR_ID); } } } return QObject::eventFilter(o,e); } void HelpSearchView::showContextMenu(const QPoint& point) { QMenu menu; - QTextBrowser* browser = qFindChild(m_ResultWidget); + QTextBrowser* browser = m_ResultWidget->findChild(); if (!browser) return; // QPoint point = browser->mapFromGlobal(pos); // if (!browser->rect().contains(point, true)) // return; QUrl link = browser->anchorAt(point); QKeySequence keySeq(QKeySequence::Copy); QAction *copyAction = menu.addAction(tr("&Copy") + QLatin1String("\t") + keySeq.toString(QKeySequence::NativeText)); copyAction->setEnabled(QTextCursor(browser->textCursor()).hasSelection()); QAction *copyAnchorAction = menu.addAction(tr("Copy &Link Location")); copyAnchorAction->setEnabled(!link.isEmpty() && link.isValid()); keySeq = QKeySequence(Qt::CTRL); QAction *newTabAction = menu.addAction(tr("Open Link in New Tab") + QLatin1String("\t") + keySeq.toString(QKeySequence::NativeText) + QLatin1String("LMB")); newTabAction->setEnabled(!link.isEmpty() && link.isValid()); menu.addSeparator(); keySeq = QKeySequence::SelectAll; QAction *selectAllAction = menu.addAction(tr("Select All") + QLatin1String("\t") + keySeq.toString(QKeySequence::NativeText)); QAction *usedAction = menu.exec(browser->mapToGlobal(point)); if (usedAction == copyAction) { QTextCursor cursor = browser->textCursor(); if (!cursor.isNull() && cursor.hasSelection()) { QString selectedText = cursor.selectedText(); QMimeData *data = new QMimeData(); data->setText(selectedText); QApplication::clipboard()->setMimeData(data); } } else if (usedAction == copyAnchorAction) { QApplication::clipboard()->setText(link.toString()); } else if (usedAction == newTabAction) { IEditorInput::Pointer input(new HelpEditorInput(link)); this->GetSite()->GetPage()->OpenEditor(input, HelpEditor::EDITOR_ID); } else if (usedAction == selectAllAction) { browser->selectAll(); } } } diff --git a/BlueBerry/Bundles/org.blueberry.ui.qt.log/CMakeLists.txt b/BlueBerry/Bundles/org.blueberry.ui.qt.log/CMakeLists.txt index 5abf908b70..5a93b737c6 100644 --- a/BlueBerry/Bundles/org.blueberry.ui.qt.log/CMakeLists.txt +++ b/BlueBerry/Bundles/org.blueberry.ui.qt.log/CMakeLists.txt @@ -1,7 +1,10 @@ project(org_blueberry_ui_qt_log) MACRO_CREATE_CTK_PLUGIN( EXPORT_DIRECTIVE org_blueberry_ui_qt_log_EXPORT EXPORTED_INCLUDE_SUFFIXES src ) +if(MITK_USE_Qt5) + qt5_use_modules(${PLUGIN_TARGET} Widgets) +endif() diff --git a/BlueBerry/Bundles/org.blueberry.ui.qt.log/src/internal/berryLogView.h b/BlueBerry/Bundles/org.blueberry.ui.qt.log/src/internal/berryLogView.h index 04d276d975..4d08e09390 100644 --- a/BlueBerry/Bundles/org.blueberry.ui.qt.log/src/internal/berryLogView.h +++ b/BlueBerry/Bundles/org.blueberry.ui.qt.log/src/internal/berryLogView.h @@ -1,45 +1,45 @@ /*=================================================================== BlueBerry Platform 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 BERRYLOGVIEW_H_ #define BERRYLOGVIEW_H_ -#include +#include #include "berryQtViewPart.h" namespace berry { class LogView : public QtViewPart { Q_OBJECT public: LogView(); LogView(const LogView& other); void SetFocus(); protected: void CreateQtPartControl(QWidget* parent); }; } // namespace berry #endif /*BERRYLOGVIEW_H_*/ diff --git a/BlueBerry/Bundles/org.blueberry.ui.qt.log/src/internal/berryQtLogPlugin.cpp b/BlueBerry/Bundles/org.blueberry.ui.qt.log/src/internal/berryQtLogPlugin.cpp index df916bcfd5..cfcf09dc36 100644 --- a/BlueBerry/Bundles/org.blueberry.ui.qt.log/src/internal/berryQtLogPlugin.cpp +++ b/BlueBerry/Bundles/org.blueberry.ui.qt.log/src/internal/berryQtLogPlugin.cpp @@ -1,60 +1,62 @@ /*=================================================================== BlueBerry Platform 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 "berryQtLogPlugin.h" #include "berryLogView.h" #include namespace berry { QtLogPlugin* QtLogPlugin::instance = 0; QtLogPlugin::QtLogPlugin() { instance = this; } void QtLogPlugin::start(ctkPluginContext* context) { BERRY_REGISTER_EXTENSION_CLASS(berry::LogView, context) m_LogModel = new QtPlatformLogModel(); } void QtLogPlugin::stop(ctkPluginContext* /*context*/) { delete m_LogModel; } QtLogPlugin* QtLogPlugin::GetInstance() { return instance; } QtPlatformLogModel* QtLogPlugin::GetLogModel() { return m_LogModel; } } -Q_EXPORT_PLUGIN2(org_blueberry_ui_qt_log, berry::QtLogPlugin) +#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) + Q_EXPORT_PLUGIN2(org_blueberry_ui_qt_log, berry::QtLogPlugin) +#endif diff --git a/BlueBerry/Bundles/org.blueberry.ui.qt.log/src/internal/berryQtLogPlugin.h b/BlueBerry/Bundles/org.blueberry.ui.qt.log/src/internal/berryQtLogPlugin.h index 67cefc554f..3e5013dd1a 100644 --- a/BlueBerry/Bundles/org.blueberry.ui.qt.log/src/internal/berryQtLogPlugin.h +++ b/BlueBerry/Bundles/org.blueberry.ui.qt.log/src/internal/berryQtLogPlugin.h @@ -1,51 +1,54 @@ /*=================================================================== BlueBerry Platform 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 BERRYLOGPLUGIN_H_ #define BERRYLOGPLUGIN_H_ #include #include "berryQtPlatformLogModel.h" namespace berry { class QtLogPlugin : public QObject, public ctkPluginActivator { Q_OBJECT +#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) + Q_PLUGIN_METADATA(IID "org_blueberry_ui_qt_log") +#endif Q_INTERFACES(ctkPluginActivator) public: QtLogPlugin(); void start(ctkPluginContext* context); void stop(ctkPluginContext* context); static QtLogPlugin* GetInstance(); QtPlatformLogModel* GetLogModel(); private: static QtLogPlugin* instance; QtPlatformLogModel* m_LogModel; }; } #endif /*BERRYLOGPLUGIN_H_*/ diff --git a/BlueBerry/Bundles/org.blueberry.ui.qt.log/src/internal/berryQtLogView.h b/BlueBerry/Bundles/org.blueberry.ui.qt.log/src/internal/berryQtLogView.h index 555c7e19f4..864f6eb305 100644 --- a/BlueBerry/Bundles/org.blueberry.ui.qt.log/src/internal/berryQtLogView.h +++ b/BlueBerry/Bundles/org.blueberry.ui.qt.log/src/internal/berryQtLogView.h @@ -1,56 +1,56 @@ /*=================================================================== BlueBerry Platform 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 BERRYQTLOGVIEW_H #define BERRYQTLOGVIEW_H -#include +#include #include #include "ui_berryQtLogView.h" #include "berryQtPlatformLogModel.h" namespace berry { class QtLogView : public QWidget { Q_OBJECT public: QtLogView(QWidget *parent = 0); ~QtLogView(); QtPlatformLogModel *model; QSortFilterProxyModel *filterModel; private: Ui::QtLogViewClass ui; void showEvent ( QShowEvent * event ); protected slots: void slotFilterChange( const QString& ); void slotRowAdded( const QModelIndex & , int , int ); void slotScrollDown( ); void on_ShowAdvancedFields_clicked( bool checked = false ); void on_ShowCategory_clicked( bool checked = false ); void on_SaveToClipboard_clicked(); }; } #endif // BERRYQTLOGVIEW_H diff --git a/BlueBerry/Bundles/org.blueberry.ui.qt.log/src/internal/berryQtPlatformLogModel.cpp b/BlueBerry/Bundles/org.blueberry.ui.qt.log/src/internal/berryQtPlatformLogModel.cpp index 80ee8b8f98..ec373da9d7 100644 --- a/BlueBerry/Bundles/org.blueberry.ui.qt.log/src/internal/berryQtPlatformLogModel.cpp +++ b/BlueBerry/Bundles/org.blueberry.ui.qt.log/src/internal/berryQtPlatformLogModel.cpp @@ -1,329 +1,330 @@ /*=================================================================== BlueBerry Platform 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. ===================================================================*/ #ifdef __MINGW32__ // We need to inlclude winbase.h here in order to declare // atomic intrinsics like InterlockedIncrement correctly. // Otherwhise, they would be declared wrong within qatomic_windows.h . #include #endif #include "berryQtPlatformLogModel.h" #include "berryPlatform.h" #include "event/berryPlatformEvents.h" #include #include #include #include #include #include "berryLog.h" #include #include #include namespace berry { const QString QtPlatformLogModel::Error = QString("Error"); const QString QtPlatformLogModel::Warn = QString("Warning"); const QString QtPlatformLogModel::Fatal = QString("Fatal"); const QString QtPlatformLogModel::Info = QString("Info"); const QString QtPlatformLogModel::Debug = QString("Debug"); void QtPlatformLogModel::slotFlushLogEntries() { m_Mutex.lock(); std::list *tmp=m_Active; m_Active=m_Pending; m_Pending=tmp; m_Mutex.unlock(); int num = static_cast(m_Pending->size()); if (num > 0) { int row = static_cast(m_Entries.size()); this->beginInsertRows(QModelIndex(), row, row+num-1); do { m_Entries.push_back(m_Pending->front()); m_Pending->pop_front(); } while(--num); this->endInsertRows(); } } void QtPlatformLogModel::addLogEntry(const mbilog::LogMessage &msg) { m_Mutex.lock(); //mbilog::BackendCout::FormatSmart(msg); FormatSmart is not static any more. So commented out this statement. Todo: fix m_Active->push_back(ExtendedLogMessage(msg)); m_Mutex.unlock(); emit signalFlushLogEntries(); } void QtPlatformLogModel::SetShowAdvancedFiels( bool showAdvancedFiels ) { if( m_ShowAdvancedFiels != showAdvancedFiels ) { m_ShowAdvancedFiels = showAdvancedFiels; - this->reset(); - + this->beginResetModel(); + this->endResetModel(); } } void QtPlatformLogModel::SetShowCategory( bool showCategory ) { if( m_ShowCategory != showCategory ) { m_ShowCategory = showCategory; - this->reset(); + this->beginResetModel(); + this->endResetModel(); } } void QtPlatformLogModel::addLogEntry(const PlatformEvent& event) { const Poco::Message& entry = Poco::RefAnyCast(*event.GetData()); mbilog::LogMessage msg(mbilog::Info,"n/a",-1,"n/a"); msg.message += entry.getText(); msg.category = "BlueBerry."+entry.getSource(); msg.moduleName = "n/a"; addLogEntry(msg); } QtPlatformLogModel::QtPlatformLogModel(QObject* parent) : QAbstractTableModel(parent), m_ShowAdvancedFiels(false), m_ShowCategory(true) { m_Active=new std::list; m_Pending=new std::list; connect(this, SIGNAL(signalFlushLogEntries()), this, SLOT( slotFlushLogEntries() ), Qt::QueuedConnection ); Platform::GetEvents().logged += PlatformEventDelegate(this, &QtPlatformLogModel::addLogEntry); myBackend = new QtLogBackend(this); } QtPlatformLogModel::~QtPlatformLogModel() { disconnect(this, SIGNAL(signalFlushLogEntries()), this, SLOT( slotFlushLogEntries() )); // dont delete and unregister backend, only deactivate it to avoid thread syncronization issues cause mbilog::UnregisterBackend is not threadsafe // will be fixed. // delete myBackend; // delete m_Active; // delete m_Pending; m_Mutex.lock(); myBackend->Deactivate(); m_Mutex.unlock(); } // QT Binding int QtPlatformLogModel::rowCount(const QModelIndex&) const { return static_cast(m_Entries.size()); } int QtPlatformLogModel::columnCount(const QModelIndex&) const { int returnValue = 2; if( m_ShowAdvancedFiels ) returnValue += 7; if( m_ShowCategory ) returnValue += 1; return returnValue; } /* struct LogEntry { LogEntry(const std::string& msg, const std::string& src, std::time_t t) : message(msg.c_str()), moduleName(src.c_str()),time(std::clock()) { } QString message; clock_t time; QString level; QString filePath; QString lineNumber; QString moduleName; QString category; QString function; LogEntry(const mbilog::LogMessage &msg) { message = msg.message.c_str(); filePath = msg.filePath; std::stringstream out; out << msg.lineNumber; lineNumber = out.str().c_str(); moduleName = msg.moduleName; category = msg.category.c_str(); function = msg.functionName; time=std::clock(); } }; */ QVariant QtPlatformLogModel::data(const QModelIndex& index, int role) const { const ExtendedLogMessage *msg = &m_Entries[index.row()]; if (role == Qt::DisplayRole) { switch (index.column()) { case 0: if (m_ShowAdvancedFiels) return msg->getTime(); else return msg->getLevel(); case 1: if (m_ShowAdvancedFiels) return msg->getLevel(); else return msg->getMessage(); case 2: if (m_ShowAdvancedFiels) return msg->getMessage(); else return msg->getCategory(); case 3: if (m_ShowAdvancedFiels && m_ShowCategory) return msg->getCategory(); else if (m_ShowAdvancedFiels && !m_ShowCategory) return msg->getModuleName(); else break; case 4: if (m_ShowAdvancedFiels && m_ShowCategory) return msg->getModuleName(); else if (m_ShowAdvancedFiels && !m_ShowCategory) return msg->getFunctionName(); else break; case 5: if (m_ShowAdvancedFiels && m_ShowCategory) return msg->getFunctionName(); else if (m_ShowAdvancedFiels && !m_ShowCategory) return msg->getPath(); else break; case 6: if (m_ShowAdvancedFiels && m_ShowCategory) return msg->getPath(); else if (m_ShowAdvancedFiels && !m_ShowCategory) return msg->getLine(); else break; case 7: if (m_ShowAdvancedFiels && m_ShowCategory) return msg->getLine(); else break; } } else if( role == Qt::DecorationRole ) { if ( (m_ShowAdvancedFiels && index.column()==1) || (!m_ShowAdvancedFiels && index.column()==0) ) { QString file ( ":/org_blueberry_ui_qt_log/information.png" ); if( msg->message.level == mbilog::Error ) file = ":/org_blueberry_ui_qt_log/error.png"; else if( msg->message.level == mbilog::Warn ) file = ":/org_blueberry_ui_qt_log/warning.png"; else if( msg->message.level == mbilog::Debug ) file = ":/org_blueberry_ui_qt_log/debug.png"; else if( msg->message.level == mbilog::Fatal ) file = ":/org_blueberry_ui_qt_log/fatal.png"; QIcon icon(file); return QVariant(icon); } } return QVariant(); } QVariant QtPlatformLogModel::headerData(int section, Qt::Orientation orientation, int role) const { if (role == Qt::DisplayRole && orientation == Qt::Horizontal) { if( m_ShowAdvancedFiels && m_ShowCategory ) { switch (section) { case 0: return QVariant(" Time "); case 1: return QVariant(" Level "); case 2: return QVariant(" Message "); case 3: return QVariant(" Category "); case 4: return QVariant(" Module "); case 5: return QVariant(" Function "); case 6: return QVariant(" File "); case 7: return QVariant(" Line "); } } else if (m_ShowAdvancedFiels && !m_ShowCategory) { switch (section) { case 0: return QVariant(" Time "); case 1: return QVariant(" Level "); case 2: return QVariant(" Message "); case 3: return QVariant(" Module "); case 4: return QVariant(" Function "); case 5: return QVariant(" File "); case 6: return QVariant(" Line "); } } else //!m_ShowAdvancedFiels, m_ShowCategory is not handled seperately because it only activates case 2 { switch (section) { case 0: return QVariant(" Level "); case 1: return QVariant(" Message "); case 2: return QVariant(" Category "); } } } return QVariant(); } QVariant QtPlatformLogModel::ExtendedLogMessage::getTime() const { std::stringstream ss; std::locale C("C"); ss.imbue(C); ss << std::setw(7) << std::setprecision(3) << std::fixed << ((double)this->time)/CLOCKS_PER_SEC; return QVariant(QString(ss.str().c_str())); } QString QtPlatformLogModel::GetDataAsString() { QString returnValue(""); for (int message=0; messagerowCount(QModelIndex()); message++) { for (int column=0; columncolumnCount(QModelIndex()); column++) { returnValue += " " + this->data(this->index(message,column),Qt::DisplayRole).toString(); } returnValue += "\n"; } return returnValue; } } diff --git a/BlueBerry/Bundles/org.blueberry.ui.qt.objectinspector/src/internal/berryPluginActivator.cpp b/BlueBerry/Bundles/org.blueberry.ui.qt.objectinspector/src/internal/berryPluginActivator.cpp index 3deccddb55..79c6982d98 100644 --- a/BlueBerry/Bundles/org.blueberry.ui.qt.objectinspector/src/internal/berryPluginActivator.cpp +++ b/BlueBerry/Bundles/org.blueberry.ui.qt.objectinspector/src/internal/berryPluginActivator.cpp @@ -1,40 +1,40 @@ /*=================================================================== BlueBerry Platform 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 "berryPluginActivator.h" #include "berryObjectBrowserView.h" #include namespace berry { void org_blueberry_ui_qt_objectinspector_Activator::start(ctkPluginContext* context) { BERRY_REGISTER_EXTENSION_CLASS(berry::ObjectBrowserView, context) } void org_blueberry_ui_qt_objectinspector_Activator::stop(ctkPluginContext* context) { Q_UNUSED(context) } } -Q_EXPORT_PLUGIN2(org_blueberry_ui_qt_objectinspector, berry::org_blueberry_ui_qt_objectinspector_Activator) - - +#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) + Q_EXPORT_PLUGIN2(org_blueberry_ui_qt_objectinspector, berry::org_blueberry_ui_qt_objectinspector_Activator) +#endif diff --git a/BlueBerry/Bundles/org.blueberry.ui.qt.objectinspector/src/internal/berryPluginActivator.h b/BlueBerry/Bundles/org.blueberry.ui.qt.objectinspector/src/internal/berryPluginActivator.h index 0840e767d1..6126f0910e 100644 --- a/BlueBerry/Bundles/org.blueberry.ui.qt.objectinspector/src/internal/berryPluginActivator.h +++ b/BlueBerry/Bundles/org.blueberry.ui.qt.objectinspector/src/internal/berryPluginActivator.h @@ -1,42 +1,45 @@ /*=================================================================== BlueBerry Platform 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 BERRYOBJECTINSPECTORACTIVATOR_H #define BERRYOBJECTINSPECTORACTIVATOR_H #include namespace berry { class org_blueberry_ui_qt_objectinspector_Activator : public QObject, public ctkPluginActivator { Q_OBJECT +#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) + Q_PLUGIN_METADATA(IID "org_blueberry_ui_qt_objectinspector") +#endif Q_INTERFACES(ctkPluginActivator) public: void start(ctkPluginContext* context); void stop(ctkPluginContext* context); }; typedef org_blueberry_ui_qt_objectinspector_Activator PluginActivator; } #endif // BERRYOBJECTINSPECTORACTIVATOR_H diff --git a/BlueBerry/Bundles/org.blueberry.ui.qt.objectinspector/src/internal/berryQtObjectTableModel.cpp b/BlueBerry/Bundles/org.blueberry.ui.qt.objectinspector/src/internal/berryQtObjectTableModel.cpp index df920d5fa8..9a931e3c32 100644 --- a/BlueBerry/Bundles/org.blueberry.ui.qt.objectinspector/src/internal/berryQtObjectTableModel.cpp +++ b/BlueBerry/Bundles/org.blueberry.ui.qt.objectinspector/src/internal/berryQtObjectTableModel.cpp @@ -1,588 +1,589 @@ /*=================================================================== BlueBerry Platform 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 "berryQtObjectTableModel.h" #include #include #include #include #include #include namespace berry { class DebugObjectListener: public IDebugObjectListener { public: DebugObjectListener(QtObjectTableModel* model) : model(model) { } Events::Types GetEventTypes() const { return Events::ALL; } void ObjectCreated(const Object* obj) { model->ObjectCreated(obj); } void ObjectDestroyed(const Object* obj) { model->ObjectDestroyed(obj); } void ObjectTracingChanged(unsigned int /*traceId*/, bool /*enabled = true*/, const Object* /*obj*/ = 0) { } void SmartPointerCreated(unsigned int id, const Object* obj) { model->SmartPointerCreated(id, obj); } void SmartPointerDestroyed(unsigned int id, const Object* obj) { model->SmartPointerDestroyed(id, obj); } private: QtObjectTableModel* model; }; QtObjectTableModel::QtObjectTableModel(QObject* parent) : QAbstractItemModel(parent), objectListener(new DebugObjectListener(this)) { std::vector objects; DebugUtil::GetRegisteredObjects(objects); for (std::vector::const_iterator i = objects.begin(); i != objects.end(); ++i) { const char* name = (*i)->GetClassName(); ObjectItem* classItem = 0; QListIterator iter(indexData); bool classFound = false; while (iter.hasNext()) { classItem = iter.next(); if (std::strcmp(classItem->className, name) == 0) { classFound = true; break; } } ObjectItem* instanceItem = new ObjectItem(*i, 0); // get smartpointer ids std::list spIds(DebugUtil::GetSmartPointerIDs(*i)); for (std::list::const_iterator spIdIter = spIds.begin(); spIdIter != spIds.end(); ++spIdIter) { ObjectItem* spItem = new ObjectItem((unsigned int) (*spIdIter), instanceItem); instanceItem->children.push_back(spItem); } if (classFound) { instanceItem->parent = classItem; classItem->children.push_back(instanceItem); } else { classItem = new ObjectItem(name); indexData.push_back(classItem); instanceItem->parent = classItem; classItem->children.push_back(instanceItem); } } QTimer* timer = new QTimer(this); connect(timer, SIGNAL(timeout()), this, SLOT(UpdatePendingData())); timer->start(500); DebugUtil::AddObjectListener(objectListener); } QtObjectTableModel::~QtObjectTableModel() { DebugUtil::RemoveObjectListener(objectListener); } QModelIndex QtObjectTableModel::index(int row, int column, const QModelIndex& parent) const { if (parent.isValid()) { if (parent.parent().isValid()) { ObjectItem* data = static_cast (parent.internalPointer()); poco_assert(data->type == ObjectItem::INSTANCE) ; return createIndex(row, column, data->children[row]); } else { ObjectItem* data = static_cast(parent.internalPointer()); poco_assert(data->type == ObjectItem::CLASS); return createIndex(row, column, data->children[row]); } } else return createIndex(row, column, indexData[row]); } QModelIndex QtObjectTableModel::parent(const QModelIndex& index) const { ObjectItem* data = static_cast(index.internalPointer()); if (data->parent) { return createIndex(data->parent->children.indexOf(data), 0, data->parent); } else { return QModelIndex(); } } int QtObjectTableModel::rowCount(const QModelIndex& parent) const { if (parent.isValid()) { if (parent.parent().isValid()) { if (parent.parent().parent().isValid()) // smart pointer parent return 0; // instance parent ObjectItem* data = static_cast(parent.internalPointer()); poco_assert(data->type == ObjectItem::INSTANCE); return data->children.size(); } else { // class parent ObjectItem* data = static_cast(parent.internalPointer()); poco_assert(data->type == ObjectItem::CLASS); return data->children.size(); } } else { // root return indexData.size(); } } int QtObjectTableModel::columnCount(const QModelIndex&) const { return 2; } QVariant QtObjectTableModel::data(const QModelIndex& index, int role) const { if (role == Qt::DisplayRole) { if (index.column() == 0) { if (index.parent().isValid()) { QModelIndex parentIndex = index.parent(); if (parentIndex.parent().isValid()) { ObjectItem* data = static_cast(index.internalPointer()); poco_assert(data->type == ObjectItem::SMARTPOINTER); return QVariant(QString("SmartPointer (id: ") + QString::number(data->spId) + QString(")")); } else { ObjectItem* data = static_cast(index.internalPointer()); poco_assert(data->type == ObjectItem::INSTANCE); #ifdef BLUEBERRY_DEBUG_SMARTPOINTER QString text = QString::number(data->obj->GetTraceId()); #else QString text; #endif text += QString(" (References: ") + QString::number(data->obj->GetReferenceCount()) + QString(")"); return QVariant(text); } } else { ObjectItem* data = static_cast(index.internalPointer()); poco_assert(data->type == ObjectItem::CLASS); return QVariant(QString(data->className) + " (" + QString::number(data->children.size()) + ")"); } } } else if (role == Qt::CheckStateRole && index.column() == 1) { ObjectItem* data = static_cast(index.internalPointer()); if (data->type == ObjectItem::INSTANCE) { QVariant var = (DebugUtil::IsTraced(data->obj) ? Qt::Checked : Qt::Unchecked); return var; } else if (data->type == ObjectItem::CLASS) { QVariant var = (DebugUtil::IsTraced(data->className) ? Qt::Checked : Qt::Unchecked); return var; } } else if (role == Qt::DecorationRole && index.column() == 0) { ObjectItem* data = static_cast(index.internalPointer()); if (data->type == ObjectItem::INSTANCE) { QVariant var; #ifdef BLUEBERRY_DEBUG_SMARTPOINTER if (DebugUtil::GetBreakpointManager()->BreakAtObject(data->obj->GetTraceId())) #else if(false) #endif { var = QIcon(":/objectinspector/break-enabled.png"); } return var; } else if (data->type == ObjectItem::SMARTPOINTER) { QVariant var; if (DebugUtil::GetBreakpointManager()->BreakAtSmartpointer(data->spId)) { var = QIcon(":/objectinspector/break-enabled.png"); } return var; } } else if (role == Qt::UserRole) { return QVariant::fromValue(index.internalPointer()); } return QVariant(); } QVariant QtObjectTableModel::headerData(int section, Qt::Orientation orientation, int role) const { if (role == Qt::DisplayRole && orientation == Qt::Horizontal) { switch (section) { case 0: { int count = 0; QListIterator iter(indexData); while (iter.hasNext()) { count += iter.next()->children.size(); } return QVariant(QString("Instances (") + QString::number(count) + ")"); } case 1: { return QVariant(QString("Trace")); } } } return QVariant(); } Qt::ItemFlags QtObjectTableModel::flags(const QModelIndex& index) const { Qt::ItemFlags flags = QAbstractItemModel::flags(index); ObjectItem* item = static_cast (index.internalPointer()); if ((item->type == ObjectItem::INSTANCE || item->type == ObjectItem::CLASS) && index.column() == 1) flags |= Qt::ItemIsUserCheckable; return flags; } bool QtObjectTableModel::setData(const QModelIndex &index, const QVariant &value, int role) { if (index.isValid() && index.column() == 1 && role == Qt::CheckStateRole) { ObjectItem* item = static_cast (index.internalPointer()); if (value.toInt() == Qt::Checked) { if (item->type == ObjectItem::INSTANCE) DebugUtil::TraceObject(item->obj); else if (item->type == ObjectItem::CLASS) DebugUtil::TraceClass(item->className); } else { if (item->type == ObjectItem::INSTANCE) DebugUtil::StopTracing(item->obj); else if (item->type == ObjectItem::CLASS) DebugUtil::StopTracing(item->className); } emit dataChanged(index, index); return true; } return false; } void QtObjectTableModel::ResetData() { indexData.clear(); DebugUtil::ResetObjectSummary(); - QAbstractItemModel::reset(); + QAbstractItemModel::beginResetModel(); + QAbstractItemModel::endResetModel(); } void QtObjectTableModel::ObjectCreated(const Object* obj) { // This method is called inside the berry::Object // constructor, hence we cannot reliably call the virtual // method berry::Object::GetClassName() to put the new // object under the right "class" parent. So add it to // a list of pending objects. ObjectItem* item = new ObjectItem(obj, 0); pendingData.push_back(item); } void QtObjectTableModel::UpdatePendingData() { if (pendingData.empty()) return; QListIterator instanceIter(pendingData); while (instanceIter.hasNext()) { ObjectItem* instanceItem = instanceIter.next(); ObjectItem* classItem = 0; ObjectItem classSearchItem(instanceItem->obj->GetClassName()); int classIndex = 0; classItem = FindObjectItem(classSearchItem, classIndex); if (!classItem) { classItem = new ObjectItem(instanceItem->obj->GetClassName()); classItem->children.push_back(instanceItem); instanceItem->parent = classItem; classIndex = rowCount(QModelIndex()); beginInsertRows(QModelIndex(), classIndex, classIndex); indexData.push_back(classItem); endInsertRows(); } else { instanceItem->parent = classItem; QModelIndex classModelIndex = createIndex(classIndex, 0, classItem); int rowIndex = rowCount(classModelIndex); beginInsertRows(classModelIndex, rowIndex, rowIndex); classItem->children.push_back(instanceItem); endInsertRows(); } } pendingData.clear(); } void QtObjectTableModel::ObjectDestroyed(const Object* obj) { ObjectItem searchItem(obj, 0); int index = 0; ObjectItem* item = FindObjectItem(searchItem, index); if (!item) { QMutableListIterator pendingIter(pendingData); while (pendingIter.hasNext()) { ObjectItem* pendingItem = pendingIter.next(); if (pendingItem->obj == obj) { pendingIter.remove(); delete pendingItem; break; } } return; } int parentIndex = indexData.indexOf(item->parent); beginRemoveRows(createIndex(parentIndex, 0, item->parent), index, index); item->parent->children.removeAt(index); endRemoveRows(); if (item->parent->children.empty()) { beginRemoveRows(QModelIndex(), parentIndex, parentIndex); indexData.removeAt(parentIndex); endRemoveRows(); delete item->parent; } else { delete item; } } void QtObjectTableModel::SmartPointerCreated(unsigned int id, const Object* obj) { ObjectItem searchInstance(obj, 0); int instanceIndex = 0; ObjectItem* instanceItem = FindObjectItem(searchInstance, instanceIndex); if (!instanceItem) { QListIterator pendingIter(pendingData); while (pendingIter.hasNext()) { ObjectItem* pendingItem = pendingIter.next(); if (pendingItem->obj == obj) { pendingItem->children.push_back(new ObjectItem(id, pendingItem)); break; } } return; } int itemIndex = instanceItem->children.size(); beginInsertRows(createIndex(instanceIndex, 0, instanceItem), itemIndex, itemIndex); instanceItem->children.push_back(new ObjectItem(id, instanceItem)); endInsertRows(); } void QtObjectTableModel::SmartPointerDestroyed(unsigned int id, const Object* obj) { ObjectItem searchSP(id, 0); int spIndex = 0; ObjectItem* spItem = FindObjectItem(searchSP, spIndex); if (!spItem) { QListIterator pendingIter(pendingData); while (pendingIter.hasNext()) { ObjectItem* pendingItem = pendingIter.next(); if (pendingItem->obj == obj) { QMutableListIterator spIter(pendingItem->children); while (spIter.hasNext()) { spItem = spIter.next(); if (spItem->spId == id) { spIter.remove(); delete spItem; return; } } break; } } return; } int parentIndex = 0; ObjectItem searchInstance(obj, 0); ObjectItem* instanceItem = FindObjectItem(searchInstance, parentIndex); beginRemoveRows(createIndex(parentIndex, 0, instanceItem), spIndex, spIndex); instanceItem->children.removeAt(spIndex); delete spItem; endRemoveRows(); } ObjectItem* QtObjectTableModel::FindObjectItem( const ObjectItem& item, int& index) { switch (item.type) { case ObjectItem::CLASS: { QListIterator i(indexData); index = 0; while (i.hasNext()) { ObjectItem* next = i.next(); if (std::strcmp(next->className, item.className) == 0) return next; ++index; } return 0; } case ObjectItem::INSTANCE: { QListIterator i(indexData); while (i.hasNext()) { ObjectItem* next = i.next(); index = 0; QListIterator childIter(next->children); while (childIter.hasNext()) { ObjectItem* child = childIter.next(); if (child->obj == item.obj) return child; ++index; } } return 0; } case ObjectItem::SMARTPOINTER: { QListIterator classIter(indexData); while (classIter.hasNext()) { ObjectItem* nextClass = classIter.next(); QListIterator instanceIter(nextClass->children); while (instanceIter.hasNext()) { ObjectItem* nextInstance = instanceIter.next(); index = 0; QListIterator spIter(nextInstance->children); while (spIter.hasNext()) { ObjectItem* nextSp = spIter.next(); if (nextSp->spId == item.spId) return nextSp; ++index; } } } return 0; } } return 0; } } diff --git a/BlueBerry/Bundles/org.blueberry.ui.qt/CMakeLists.txt b/BlueBerry/Bundles/org.blueberry.ui.qt/CMakeLists.txt index dc02c6ff78..f295636662 100644 --- a/BlueBerry/Bundles/org.blueberry.ui.qt/CMakeLists.txt +++ b/BlueBerry/Bundles/org.blueberry.ui.qt/CMakeLists.txt @@ -1,5 +1,8 @@ project(org_blueberry_ui_qt) MACRO_CREATE_CTK_PLUGIN(EXPORT_DIRECTIVE BERRY_UI_QT EXPORTED_INCLUDE_SUFFIXES src src/application) +if(MITK_USE_Qt5) + qt5_use_modules(${PLUGIN_TARGET} Widgets) +endif() diff --git a/BlueBerry/Bundles/org.blueberry.ui.qt/src/application/berryQtWorkbenchAdvisor.cpp b/BlueBerry/Bundles/org.blueberry.ui.qt/src/application/berryQtWorkbenchAdvisor.cpp index cbc0062635..4916ca0cb7 100755 --- a/BlueBerry/Bundles/org.blueberry.ui.qt/src/application/berryQtWorkbenchAdvisor.cpp +++ b/BlueBerry/Bundles/org.blueberry.ui.qt/src/application/berryQtWorkbenchAdvisor.cpp @@ -1,59 +1,61 @@ /*=================================================================== BlueBerry Platform 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 "berryQtWorkbenchAdvisor.h" #include "internal/berryQtGlobalEventFilter.h" #include "berryQtPreferences.h" #include #include #include #include #include #include #include #include #include namespace berry { void QtWorkbenchAdvisor::Initialize(IWorkbenchConfigurer::Pointer configurer) { WorkbenchAdvisor::Initialize(configurer); IPreferencesService::Pointer prefService = Platform::GetServiceRegistry().GetServiceById( IPreferencesService::ID); IPreferences::Pointer prefs = prefService->GetSystemPreferences()->Node(QtPreferences::QT_STYLES_NODE); QString styleName = QString::fromStdString(prefs->Get(QtPreferences::QT_STYLE_NAME, "")); IQtStyleManager::Pointer styleManager = Platform::GetServiceRegistry().GetServiceById(IQtStyleManager::ID); styleManager->SetStyle(styleName); QObject* eventFilter = new QtGlobalEventFilter(qApp); qApp->installEventFilter(eventFilter); +#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) // character strings should be interpreted as UTF-8 encoded strings // e.g. plugin.xml files are UTF-8 encoded QTextCodec* utf8Codec = QTextCodec::codecForName("UTF-8"); QTextCodec::setCodecForCStrings(utf8Codec); QTextCodec::setCodecForTr(utf8Codec); +#endif } } diff --git a/BlueBerry/Bundles/org.blueberry.ui.qt/src/internal/berryQtPluginActivator.cpp b/BlueBerry/Bundles/org.blueberry.ui.qt/src/internal/berryQtPluginActivator.cpp index d69fdd9321..c9618241d9 100644 --- a/BlueBerry/Bundles/org.blueberry.ui.qt/src/internal/berryQtPluginActivator.cpp +++ b/BlueBerry/Bundles/org.blueberry.ui.qt/src/internal/berryQtPluginActivator.cpp @@ -1,72 +1,74 @@ /*=================================================================== BlueBerry Platform 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 "berryQtPluginActivator.h" #include "berryQtStyleManager.h" #include "berryQtDnDTweaklet.h" #include "berryQtImageTweaklet.h" #include "berryQtMessageDialogTweaklet.h" #include "berryQtWorkbenchTweaklet.h" #include "berryQtWorkbenchPageTweaklet.h" #include "berryQtWidgetsTweaklet.h" #include "berryQtStylePreferencePage.h" #include "defaultpresentation/berryQtWorkbenchPresentationFactory.h" namespace berry { QtPluginActivator::QtPluginActivator() { } QtPluginActivator::~QtPluginActivator() { } void QtPluginActivator::start(ctkPluginContext* context) { AbstractUICTKPlugin::start(context); BERRY_REGISTER_EXTENSION_CLASS(QtDnDTweaklet, context) BERRY_REGISTER_EXTENSION_CLASS(QtImageTweaklet, context); BERRY_REGISTER_EXTENSION_CLASS(QtMessageDialogTweaklet, context); BERRY_REGISTER_EXTENSION_CLASS(QtWidgetsTweaklet, context) BERRY_REGISTER_EXTENSION_CLASS(QtWorkbenchTweaklet, context) BERRY_REGISTER_EXTENSION_CLASS(QtWorkbenchPageTweaklet, context) BERRY_REGISTER_EXTENSION_CLASS(QtWorkbenchPresentationFactory, context) BERRY_REGISTER_EXTENSION_CLASS(QtStylePreferencePage, context) QtStyleManager* manager = new QtStyleManager(); styleManager = IQtStyleManager::Pointer(manager); context->registerService(manager); } void QtPluginActivator::stop(ctkPluginContext* context) { styleManager = 0; AbstractUICTKPlugin::stop(context); } } -Q_EXPORT_PLUGIN2(org_blueberry_ui_qt, berry::QtPluginActivator) +#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) + Q_EXPORT_PLUGIN2(org_blueberry_ui_qt, berry::QtPluginActivator) +#endif diff --git a/BlueBerry/Bundles/org.blueberry.ui.qt/src/internal/berryQtPluginActivator.h b/BlueBerry/Bundles/org.blueberry.ui.qt/src/internal/berryQtPluginActivator.h index 5c248d026a..97884f0a90 100644 --- a/BlueBerry/Bundles/org.blueberry.ui.qt/src/internal/berryQtPluginActivator.h +++ b/BlueBerry/Bundles/org.blueberry.ui.qt/src/internal/berryQtPluginActivator.h @@ -1,48 +1,51 @@ /*=================================================================== BlueBerry Platform 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 BERRYQTPLUGINACTIVATOR_H_ #define BERRYQTPLUGINACTIVATOR_H_ #include #include namespace berry { class QtPluginActivator : public QObject, public AbstractUICTKPlugin { Q_OBJECT +#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) + Q_PLUGIN_METADATA(IID "org_blueberry_ui_qt") +#endif Q_INTERFACES(ctkPluginActivator) public: QtPluginActivator(); ~QtPluginActivator(); void start(ctkPluginContext* context); void stop(ctkPluginContext* context); private: IQtStyleManager::Pointer styleManager; }; } #endif /* BERRYQTPLUGINACTIVATOR_H_ */ diff --git a/BlueBerry/Bundles/org.blueberry.ui.qt/src/internal/berryQtShell.cpp b/BlueBerry/Bundles/org.blueberry.ui.qt/src/internal/berryQtShell.cpp index 25c2e2f0ee..74b421c439 100755 --- a/BlueBerry/Bundles/org.blueberry.ui.qt/src/internal/berryQtShell.cpp +++ b/BlueBerry/Bundles/org.blueberry.ui.qt/src/internal/berryQtShell.cpp @@ -1,223 +1,224 @@ /*=================================================================== BlueBerry Platform 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 + #include "berryQtShell.h" #include "berryQtWidgetsTweakletImpl.h" #include "berryQtMainWindowControl.h" #include #include -#include #include #include #include namespace berry { QtShell::QtShell(QWidget* parent, Qt::WindowFlags flags) : updatesDisabled(false) { if (parent == 0 || flags.testFlag(Qt::Window)) { widget = new QtMainWindowControl(this, parent, flags); widget->setUpdatesEnabled(false); updatesDisabled = true; widget->setAttribute(Qt::WA_DeleteOnClose); } else { widget = new QtControlWidget(parent, this, flags | Qt::Dialog); widget->setObjectName("shell widget"); } } QtShell::~QtShell() { widget->deleteLater(); } void QtShell::SetBounds(const Rectangle& bounds) { widget->move(bounds.x, bounds.y); widget->resize(bounds.width, bounds.height); } Rectangle QtShell::GetBounds() const { const QRect& qRect = widget->frameGeometry(); const QSize& size = widget->size(); Rectangle rect(qRect.x(), qRect.y(), size.width(), size.height()); return rect; } void QtShell::SetLocation(int x, int y) { widget->move(x, y); } Point QtShell::ComputeSize(int /*wHint*/, int /*hHint*/, bool changed) { if (changed) widget->updateGeometry(); QSize size(widget->size()); Point point(size.width(), size.height()); return point; } std::string QtShell::GetText() const { return widget->windowTitle().toStdString(); } void QtShell::SetText(const std::string& text) { QString title(QString::fromStdString(text)); widget->setWindowTitle(title); widget->setObjectName(title); } bool QtShell::IsVisible() { return widget->isVisible(); } void QtShell::SetVisible(bool visible) { widget->setVisible(visible); } void QtShell::SetActive() { widget->activateWindow(); widget->raise(); } void* QtShell::GetControl() { return widget; } void QtShell::SetImages(const std::vector& /*images*/) { } bool QtShell::GetMaximized() { return widget->isMaximized(); } bool QtShell::GetMinimized() { return widget->isMinimized(); } void QtShell::SetMaximized(bool maximized) { maximized ? widget->showMaximized() : widget->showNormal(); } void QtShell::SetMinimized(bool minimized) { minimized ? widget->showMinimized() : widget->showNormal(); } void QtShell::AddShellListener(IShellListener::Pointer listener) { QVariant variant = widget->property(QtWidgetController::PROPERTY_ID); poco_assert(variant.isValid()); QtWidgetController::Pointer controller = variant.value(); poco_assert(controller != 0); controller->AddShellListener(listener); } void QtShell::RemoveShellListener(IShellListener::Pointer listener) { QVariant variant = widget->property(QtWidgetController::PROPERTY_ID); if (variant.isValid()) { QtWidgetController::Pointer controller = variant.value(); if (controller != 0) controller->RemoveShellListener(listener); } } void QtShell::Open(bool block) { if (updatesDisabled) { widget->setUpdatesEnabled(true); updatesDisabled = false; } widget->setWindowModality(block ? Qt::WindowModal : Qt::NonModal); widget->show(); } void QtShell::Close() { widget->close(); } std::vector QtShell::GetShells() { GuiWidgetsTweaklet* widgetTweaklet = Tweaklets::Get(GuiWidgetsTweaklet::KEY); std::vector allShells(widgetTweaklet->GetShells()); std::vector descendants; for (std::size_t i = 0; i < allShells.size(); ++i) { Shell::Pointer shell = allShells[i]; if (widgetTweaklet->GetShell(shell->GetControl()) == this) { descendants.push_back(shell); } } return descendants; } int QtShell::GetStyle() { Qt::WindowFlags qtFlags = widget->windowFlags(); int berryFlags = 0; if (!(qtFlags & Qt::FramelessWindowHint)) berryFlags |= Constants::BORDER; if (qtFlags & Qt::WindowTitleHint) berryFlags |= Constants::TITLE; if (qtFlags & Qt::WindowSystemMenuHint) berryFlags |= Constants::CLOSE; if (qtFlags & Qt::WindowMinimizeButtonHint) berryFlags |= Constants::MIN; if (qtFlags & Qt::WindowMaximizeButtonHint) berryFlags |= Constants::MAX; if (widget->windowModality() == Qt::WindowModal) berryFlags |= Constants::PRIMARY_MODAL; else if(widget->windowModality() == Qt::ApplicationModal) berryFlags |= Constants::APPLICATION_MODAL; return berryFlags; } QWidget* QtShell::GetWidget() { return widget; } } diff --git a/BlueBerry/Bundles/org.blueberry.ui.qt/src/internal/util/berryPresentablePartFolder.cpp b/BlueBerry/Bundles/org.blueberry.ui.qt/src/internal/util/berryPresentablePartFolder.cpp index f1488aa669..3358f8fb96 100755 --- a/BlueBerry/Bundles/org.blueberry.ui.qt/src/internal/util/berryPresentablePartFolder.cpp +++ b/BlueBerry/Bundles/org.blueberry.ui.qt/src/internal/util/berryPresentablePartFolder.cpp @@ -1,435 +1,436 @@ /*=================================================================== BlueBerry Platform 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 "internal/berryQtWidgetsTweaklet.h" + #include "berryPresentablePartFolder.h" #include "berryAbstractTabItem.h" -#include "internal/berryQtWidgetsTweaklet.h" #include #include #include namespace berry { PresentablePartFolder::ContentProxyListener::ContentProxyListener( PresentablePartFolder* folder) : folder(folder) { } GuiTk::IControlListener::Events::Types PresentablePartFolder::ContentProxyListener::GetEventTypes() const { return Events::MOVED & Events::RESIZED; } void PresentablePartFolder::ContentProxyListener::ControlMoved( GuiTk::ControlEvent::Pointer /*e*/) { folder->LayoutContent(); } void PresentablePartFolder::ContentProxyListener::ControlResized( GuiTk::ControlEvent::Pointer /*e*/) { } PresentablePartFolder::ShellListener::ShellListener(AbstractTabFolder* _folder) : folder(_folder) { } void PresentablePartFolder::ShellListener::ShellActivated(ShellEvent::Pointer /*e*/) { folder->ShellActive(true); } void PresentablePartFolder::ShellListener::ShellDeactivated( ShellEvent::Pointer /*e*/) { folder->ShellActive(false); } PresentablePartFolder::ChildPropertyChangeListener::ChildPropertyChangeListener( PresentablePartFolder* folder) : presentablePartFolder(folder) { } void PresentablePartFolder::ChildPropertyChangeListener::PropertyChange( Object::Pointer source, int property) { if (source.Cast () != 0) { IPresentablePart::Pointer part = source.Cast (); presentablePartFolder->ChildPropertyChanged(part, property); } } PartInfo PresentablePartFolder::tempPartInfo = PartInfo(); void PresentablePartFolder::LayoutContent() { if (current != 0) { Rectangle clientArea = DragUtil::GetDisplayBounds(contentProxy); Rectangle bounds = Tweaklets::Get(GuiWidgetsTweaklet::KEY)->ToControl( folder->GetControl()->parentWidget(), clientArea); current->SetBounds(bounds); } } void PresentablePartFolder::InternalRemove(IPresentablePart::Pointer toRemove) { AbstractTabItem* item = this->GetTab(toRemove); if (item != 0) { item->Dispose(); } // do not use item anymore! if (std::find(partList.begin(), partList.end(), toRemove) != partList.end()) { toRemove->RemovePropertyListener(childPropertyChangeListener); partList.remove(toRemove); } } void PresentablePartFolder::ChildPropertyChanged( IPresentablePart::Pointer part, int property) { AbstractTabItem* tab = this->GetTab(part); if (property == IPresentablePart::PROP_HIGHLIGHT_IF_BACK) { if (tab != 0 && this->GetCurrent() != part) {//Set bold if it doesn't currently have focus tab->SetBold(true); this->InitTab(tab, part); } } // else if (property == IPresentablePart::PROP_TOOLBAR) // { // if (tab != 0 && this->GetCurrent() == part) // { // folder->FlushToolbarSize(); // } // if (tab != 0) // { // this->InitTab(tab, part); // if (this->GetCurrent() == part) // { // this->Layout(true); // } // } else if (property == IPresentablePart::PROP_CONTENT_DESCRIPTION || property == IPresentablePart::PROP_PANE_MENU || property == IPresentablePart::PROP_TITLE) { if (tab != 0) { this->InitTab(tab, part); if (this->GetCurrent() == part) { this->Layout(true); } } } else if (property == IPresentablePart::PROP_PREFERRED_SIZE) { TabFolderEvent::Pointer event( new TabFolderEvent(TabFolderEvent::EVENT_PREFERRED_SIZE, tab, 0, 0)); folder->FireEvent(event); } else { if (tab != 0) this->InitTab(tab, part); } } PresentablePartFolder::~PresentablePartFolder() { Tweaklets::Get(QtWidgetsTweaklet::KEY)->GetShell(folder->GetControl())->RemoveShellListener( shellListener); for (std::list::iterator iter = partList.begin(); iter != partList.end(); ++iter) { (*iter)->RemovePropertyListener(childPropertyChangeListener); } for (QWidget* currentWidget = contentProxy; currentWidget != 0 && currentWidget != folder->GetControl()->parentWidget(); currentWidget = currentWidget->parentWidget()) { Tweaklets::Get(GuiWidgetsTweaklet::KEY)->RemoveControlListener(currentWidget, contentListener); } BERRY_DEBUG << "DELETING PresentablePartFolder and contentProxy\n"; delete folder; } void PresentablePartFolder::InitTab(AbstractTabItem* item, IPresentablePart::Pointer part) { tempPartInfo.Set(part); item->SetInfo(tempPartInfo); item->SetBusy(part->IsBusy()); if (part == this->GetCurrent()) { folder->SetSelectedInfo(tempPartInfo); //TODO Pane menu //folder->EnablePaneMenu(part->GetMenu() != 0); //setToolbar(part.getToolBar()); } } PresentablePartFolder::PresentablePartFolder(AbstractTabFolder* _folder) : folder(_folder), isVisible(true), shellListener(new ShellListener(folder)), childPropertyChangeListener(new ChildPropertyChangeListener(this)) { Shell::Pointer controlShell = Tweaklets::Get(QtWidgetsTweaklet::KEY)->GetShell(folder->GetControl()); controlShell->AddShellListener(shellListener); folder->ShellActive(Tweaklets::Get(QtWidgetsTweaklet::KEY)->GetActiveShell() == controlShell); //folder.getControl().addDisposeListener(tabDisposeListener); //toolbarProxy = new ProxyControl(folder.getToolbarParent()); // NOTE: if the shape of contentProxy changes, the fix for bug 85899 in EmptyTabFolder.computeSize may need adjustment. contentListener = new ContentProxyListener(this); contentProxy = new QtControlWidget(folder->GetContentParent(), 0); contentProxy->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); //contentProxy->setVisible(false); for (QWidget* currentWidget = contentProxy; currentWidget != 0 && currentWidget != folder->GetControl()->parentWidget(); currentWidget = currentWidget->parentWidget()) { Tweaklets::Get(GuiWidgetsTweaklet::KEY)->AddControlListener(currentWidget, contentListener); } folder->SetContent(contentProxy); } std::vector PresentablePartFolder::GetPartList() { std::vector items = folder->GetItems(); std::vector result; for (unsigned int i = 0; i < items.size(); i++) { result.push_back(this->GetPartForTab(items[i])); } return result; } void PresentablePartFolder::Insert(IPresentablePart::Pointer part, int idx) { poco_assert(folder->GetControl() != 0); if (this->GetTab(part) != 0) { if (this->IndexOf(part) != idx) this->Move(part, idx); return; } idx = std::min(idx, static_cast(folder->GetItemCount())); AbstractTabItem* item = 0; int style = 0; if (part->IsCloseable()) { style |= Constants::CLOSE; } item = folder->Add(idx, style); item->SetData(part); this->InitTab(item, part); part->AddPropertyListener(childPropertyChangeListener); partList.push_back(part); } void PresentablePartFolder::Remove(IPresentablePart::Pointer toRemove) { if (toRemove == current) { this->Select(IPresentablePart::Pointer(0)); } this->InternalRemove(toRemove); } void PresentablePartFolder::Move(IPresentablePart::Pointer part, int newIndex) { int currentIndex = this->IndexOf(part); if (currentIndex == newIndex) { return; } folder->Move(currentIndex, newIndex); //this->InternalRemove(part); //this->Insert(part, newIndex); //if (current == part) //{ // folder->SetSelection(this->GetTab(part)); //} } std::size_t PresentablePartFolder::Size() { return folder->GetItemCount(); } void PresentablePartFolder::SetBounds(const QRect& bounds) { QSize minSize = folder->ComputeSize(bounds.width(), Constants::DEFAULT); QRect newBounds(bounds); if (folder->GetState() == IStackPresentationSite::STATE_MINIMIZED && minSize.height() < bounds.height()) { newBounds.setHeight(minSize.height()); } // Set the tab folder's bounds folder->GetControl()->setGeometry(newBounds); this->Layout(false); } void PresentablePartFolder::Select(IPresentablePart::Pointer toSelect) { if (toSelect == current) { return; } if (toSelect != 0) { toSelect->SetVisible(true); } if (current != 0) { current->SetVisible(false); //setToolbar(null); } current = toSelect; AbstractTabItem* selectedItem = this->GetTab(toSelect); folder->SetSelection(selectedItem); if (selectedItem != 0) { // Determine if we need to un-bold this tab selectedItem->SetBold(false); this->InitTab(selectedItem, toSelect); } // else // { // setToolbar(null); // } this->Layout(true); } IPresentablePart::Pointer PresentablePartFolder::GetPartForTab( AbstractTabItem* tab) { if (tab == 0) { return IPresentablePart::Pointer(0); } IPresentablePart::Pointer part = tab->GetData().Cast (); return part; } AbstractTabItem* PresentablePartFolder::GetTab(IPresentablePart::Pointer part) { return folder->FindItem(part); } int PresentablePartFolder::IndexOf(IPresentablePart::Pointer part) { AbstractTabItem* item = this->GetTab(part); if (item == 0) { return -1; } return folder->IndexOf(item); } AbstractTabFolder* PresentablePartFolder::GetTabFolder() { return folder; } void PresentablePartFolder::SetVisible(bool isVisible) { this->isVisible = isVisible; this->GetTabFolder()->SetVisible(isVisible); if (isVisible) { this->Layout(true); } } void PresentablePartFolder::Layout(bool changed) { if (!isVisible) { // Don't bother with layout if we're not visible return; } // Lay out the tab folder and compute the client area folder->Layout(changed); //toolbarProxy.layout(); this->LayoutContent(); } IPresentablePart::Pointer PresentablePartFolder::GetCurrent() { return current; } } diff --git a/BlueBerry/Bundles/org.blueberry.ui/CMakeLists.txt b/BlueBerry/Bundles/org.blueberry.ui/CMakeLists.txt index 1a06997513..35fd0f80de 100644 --- a/BlueBerry/Bundles/org.blueberry.ui/CMakeLists.txt +++ b/BlueBerry/Bundles/org.blueberry.ui/CMakeLists.txt @@ -1,18 +1,22 @@ project(org_blueberry_ui) set(PLUGIN_exported_include_suffixes src src/application src/dialogs src/guitk src/handlers src/intro src/presentations src/services src/testing src/tweaklets src/util ) MACRO_CREATE_CTK_PLUGIN(EXPORT_DIRECTIVE BERRY_UI EXPORTED_INCLUDE_SUFFIXES ${PLUGIN_exported_include_suffixes}) + +if(MITK_USE_Qt5) + qt5_use_modules(${PLUGIN_TARGET} Widgets) +endif() diff --git a/BlueBerry/Bundles/org.blueberry.ui/src/berryGeometry.cpp b/BlueBerry/Bundles/org.blueberry.ui/src/berryGeometry.cpp index fa10ba0829..a47b2613b6 100755 --- a/BlueBerry/Bundles/org.blueberry.ui/src/berryGeometry.cpp +++ b/BlueBerry/Bundles/org.blueberry.ui/src/berryGeometry.cpp @@ -1,171 +1,166 @@ /*=================================================================== BlueBerry Platform 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. ===================================================================*/ -// needed under windows to suppress the definition of the -// min/max macros in windows.h, which would clash with -// std::numeric_limits<>::max() -#define NOMINMAX - #include "tweaklets/berryGuiWidgetsTweaklet.h" #include "berryGeometry.h" #include "berryConstants.h" #include namespace berry { int Geometry::GetDimension(const Rectangle& toMeasure, bool width) { if (width) { return toMeasure.width; } return toMeasure.height; } bool Geometry::IsHorizontal(int berrySideConstant) { return !(berrySideConstant == Constants::LEFT || berrySideConstant == Constants::RIGHT); } Rectangle Geometry::GetExtrudedEdge(const Rectangle& toExtrude, int size, int orientation) { Rectangle bounds(toExtrude); if (!IsHorizontal(orientation)) { bounds.width = size; } else { bounds.height = size; } if (orientation == Constants::RIGHT) { bounds.x = toExtrude.x + toExtrude.width - bounds.width; } else if (orientation == Constants::BOTTOM) { bounds.y = toExtrude.y + toExtrude.height - bounds.height; } Normalize(bounds); return bounds; } void Geometry::Normalize(Rectangle& rect) { if (rect.width < 0) { rect.width = -rect.width; rect.x -= rect.width; } if (rect.height < 0) { rect.height = -rect.height; rect.y -= rect.height; } } int Geometry::GetClosestSide(const Rectangle& boundary, const Point& toTest) { int sides[] = { Constants::LEFT, Constants::RIGHT, Constants::TOP, Constants::BOTTOM }; int closestSide = Constants::LEFT; int closestDistance = std::numeric_limits::max(); for (unsigned int idx = 0; idx < 4; idx++) { int side = sides[idx]; int distance = GetDistanceFromEdge(boundary, toTest, side); if (distance < closestDistance) { closestDistance = distance; closestSide = side; } } return closestSide; } int Geometry::GetDistanceFromEdge(const Rectangle& rectangle, const Point& testPoint, int edgeOfInterest) { if (edgeOfInterest == Constants::TOP) return testPoint.y - rectangle.y; else if (edgeOfInterest == Constants::BOTTOM) return rectangle.y + rectangle.height - testPoint.y; else if (edgeOfInterest == Constants::LEFT) return testPoint.x - rectangle.x; else if (edgeOfInterest == Constants::RIGHT) return rectangle.x + rectangle.width - testPoint.x; return 0; } int Geometry::GetOppositeSide(int directionConstant) { if (directionConstant == Constants::TOP) return Constants::BOTTOM; else if (directionConstant == Constants::BOTTOM) return Constants::TOP; else if (directionConstant == Constants::LEFT) return Constants::RIGHT; else if (directionConstant == Constants::RIGHT) return Constants::LEFT; return directionConstant; } Rectangle Geometry::ToControl(void* coordinateSystem, const Rectangle& toConvert) { return Tweaklets::Get(GuiWidgetsTweaklet::KEY)->ToControl(coordinateSystem, toConvert); } Point Geometry::ToControl(void* coordinateSystem, const Point& toConvert) { return Tweaklets::Get(GuiWidgetsTweaklet::KEY)->ToControl(coordinateSystem, toConvert); } Rectangle Geometry::ToDisplay(void* coordinateSystem, const Rectangle& toConvert) { return Tweaklets::Get(GuiWidgetsTweaklet::KEY)->ToDisplay(coordinateSystem, toConvert); } Point Geometry::ToDisplay(void* coordinateSystem, const Point& toConvert) { return Tweaklets::Get(GuiWidgetsTweaklet::KEY)->ToDisplay(coordinateSystem, toConvert); } } diff --git a/BlueBerry/Bundles/org.blueberry.ui/src/internal/berryEditorReference.cpp b/BlueBerry/Bundles/org.blueberry.ui/src/internal/berryEditorReference.cpp index 908e66f910..a6937bfb49 100644 --- a/BlueBerry/Bundles/org.blueberry.ui/src/internal/berryEditorReference.cpp +++ b/BlueBerry/Bundles/org.blueberry.ui/src/internal/berryEditorReference.cpp @@ -1,574 +1,574 @@ /*=================================================================== BlueBerry Platform 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 "berryEditorReference.h" - #include "tweaklets/berryWorkbenchPageTweaklet.h" +#include "berryEditorReference.h" + #include "berryEditorManager.h" #include "berryEditorDescriptor.h" #include "berryEditorRegistry.h" #include "berryEditorSite.h" #include "berryEditorAreaHelper.h" #include "berryWorkbenchPlugin.h" #include "berryWorkbenchPage.h" #include "berryNullEditorInput.h" #include "berryPartTester.h" #include "berryImageDescriptor.h" #include "berryPlatformUI.h" #include "berryIWorkbenchPartConstants.h" namespace berry { EditorReference::EditorReference(EditorManager* man, IEditorInput::Pointer input, EditorDescriptor::Pointer desc, IMemento::Pointer editorState) : manager(man), expectingInputChange(false), reportedMalfunctioningEditor(false) { this->InitListenersAndHandlers(); restoredInput = input; this->editorState = editorState; this->Init(desc->GetId(), "", desc->GetImageDescriptor(), desc->GetLabel(), ""); } EditorReference::EditorReference(EditorManager* man, IMemento::Pointer memento) : manager(man), expectingInputChange(false), reportedMalfunctioningEditor(false) { this->InitListenersAndHandlers(); this->editorMemento = memento; if (manager->UseIPersistableEditor()) { //editorState = editorMemento->GetChild(WorkbenchConstants::TAG_EDITOR_STATE); } else { editorState = 0; } // String id = memento.getString(IWorkbenchConstants.TAG_ID); // String title = memento.getString(IWorkbenchConstants.TAG_TITLE); // String tooltip = Util.safeString(memento // .getString(IWorkbenchConstants.TAG_TOOLTIP)); // String partName = memento // .getString(IWorkbenchConstants.TAG_PART_NAME); // // IMemento propBag = memento.getChild(IWorkbenchConstants.TAG_PROPERTIES); // if (propBag != null) // { // IMemento[] props = propBag // .getChildren(IWorkbenchConstants.TAG_PROPERTY); // for (int i = 0; i < props.length; i++) // { // propertyCache.put(props[i].getID(), props[i].getTextData()); // } // } // For compatibility set the part name to the title if not found // if (partName.empty()) // { // partName = title; // } // Get the editor descriptor. // EditorDescriptor::Pointer desc; // if (id != null) // { // desc = getDescriptor(id); // } // // desc may be null if id is null or desc is not found, but findImage below handles this // String location = memento.getString(IWorkbenchConstants.TAG_PATH); // IPath path = location == null ? null : new Path(location); // ImageDescriptor iDesc = this.manager.findImage(desc, path); // // this.name = memento.getString(IWorkbenchConstants.TAG_NAME); // if (this.name == null) // { // this.name = title; // } // setPinned("true".equals(memento.getString(IWorkbenchConstants.TAG_PINNED))); //$NON-NLS-1$ // // IMemento inputMem = memento.getChild(IWorkbenchConstants.TAG_INPUT); // if (inputMem != null) // { // this.factoryId = inputMem // .getString(IWorkbenchConstants.TAG_FACTORY_ID); // } // // init(id, title, tooltip, iDesc, partName, ""); //$NON-NLS-1$ } EditorDescriptor::Pointer EditorReference::GetDescriptor() { return this->GetDescriptor(this->GetId()); } EditorDescriptor::Pointer EditorReference::GetDescriptor(const std::string& id) { EditorDescriptor::Pointer desc; IEditorRegistry* reg = WorkbenchPlugin::GetDefault()->GetEditorRegistry(); desc = reg->FindEditor(id).Cast (); return desc; } void EditorReference::InitListenersAndHandlers() { // Create a property change listener to track the "close editors automatically" // preference and show/remove the pin icon on editors // Only 1 listener will be created in the EditorManager when necessary //this->manager->CheckCreateEditorPropListener(); // Create a keyboard shortcut handler for pinning editors // Only 1 handler will be created in the EditorManager when necessary //this->manager->CheckCreatePinEditorShortcutKeyHandler(); } PartPane::Pointer EditorReference::CreatePane() { PartPane::Pointer pane( new PartPane(IWorkbenchPartReference::Pointer(this), this->manager->page)); return pane; //return Tweaklets::Get(WorkbenchTweaklet::KEY)->CreateEditorPane(this, // this->manager->page); } void EditorReference::PinStatusUpdated() { //firePropertyChange(IWorkbenchPart.PROP_TITLE); } std::string EditorReference::GetFactoryId() { // IEditorPart editor = getEditor(false); // if (editor != null) // { // IPersistableElement persistable = editor.getEditorInput() // .getPersistable(); // if (persistable != null) // { // return persistable.getFactoryId(); // } // return null; // } // return factoryId; return ""; } std::string EditorReference::ComputePartName() { return WorkbenchPartReference::ComputePartName(); } std::string EditorReference::GetName() { if (part.IsNotNull()) { return this->GetEditor(false)->GetEditorInput()->GetName(); } return name; } IEditorPart::Pointer EditorReference::GetEditor(bool restore) { return this->GetPart(restore).Cast (); } void EditorReference::SetName(const std::string& name) { this->name = name; } IMemento::Pointer EditorReference::GetMemento() { return editorMemento; } IWorkbenchPage::Pointer EditorReference::GetPage() const { return IWorkbenchPage::Pointer(this->manager->page); } IEditorInput::Pointer EditorReference::GetEditorInput() { IEditorPart::Pointer part = this->GetEditor(false); if (part.IsNotNull()) { return part->GetEditorInput(); } return this->GetRestoredInput(); } IEditorInput::Pointer EditorReference::GetRestoredInput() { if (restoredInput.IsNotNull()) { return restoredInput; } // Get the input factory. // IMemento::Pointer editorMem = this->GetMemento(); // if (editorMem == null) // { // throw new PartInitException(NLS.bind(WorkbenchMessages.EditorManager_no_persisted_state, getId(), getName())); // } // IMemento inputMem = editorMem // .getChild(IWorkbenchConstants.TAG_INPUT); // String factoryID = null; // if (inputMem != null) // { // factoryID = inputMem // .getString(IWorkbenchConstants.TAG_FACTORY_ID); // } // if (factoryID == null) // { // throw new PartInitException(NLS.bind(WorkbenchMessages.EditorManager_no_input_factory_ID, getId(), getName())); // } // IAdaptable input = null; // String label = null; // debugging only // if (UIStats.isDebugging(UIStats.CREATE_PART_INPUT)) // { // label = getName() != null ? getName() : factoryID; // } // try // { // UIStats.start(UIStats.CREATE_PART_INPUT, label); // IElementFactory factory = PlatformUI.getWorkbench() // .getElementFactory(factoryID); // if (factory == null) // { // throw new PartInitException(NLS.bind(WorkbenchMessages.EditorManager_bad_element_factory, new Object[] // { factoryID, getId(), getName()})); // } // // // Get the input element. // input = factory.createElement(inputMem); // if (input == null) // { // throw new PartInitException(NLS.bind(WorkbenchMessages.EditorManager_create_element_returned_null, new Object[] // { factoryID, getId(), getName()})); // } // }finally // { // UIStats.end(UIStats.CREATE_PART_INPUT, input, label); // } // if (!(input instanceof IEditorInput)) // { // throw new PartInitException(NLS.bind(WorkbenchMessages.EditorManager_wrong_createElement_result, new Object[] // { factoryID, getId(), getName()})); // } // restoredInput = (IEditorInput) input; return restoredInput; } IWorkbenchPart::Pointer EditorReference::CreatePart() { if (EditorRegistry::EMPTY_EDITOR_ID == this->GetId()) { return this->GetEmptyEditor(this->GetDescriptor()); } IWorkbenchPart::Pointer result; // Try to restore the editor -- this does the real work of restoring the editor // try { result = this->CreatePartHelper().Cast (); } catch (PartInitException e) { // If unable to create the part, create an error part instead // and pass the error to the status handling facility // IStatus originalStatus = exception.getStatus(); // IStatus logStatus = StatusUtil.newStatus(originalStatus, // NLS.bind("Unable to create editor ID {0}: {1}", //$NON-NLS-1$ // getId(), originalStatus.getMessage())); // IStatus displayStatus = StatusUtil.newStatus(originalStatus, // NLS.bind(WorkbenchMessages.EditorManager_unableToCreateEditor, // originalStatus.getMessage())); WorkbenchPlugin::Log("Unable to create editor ID " + this->GetId() + ": " + e.displayText()); // Pass the error to the status handling facility //StatusManager.getManager().handle(logStatus); EditorDescriptor::Pointer descr = this->GetDescriptor(); std::string label = this->GetId(); if (descr.IsNotNull()) label = descr->GetLabel(); IEditorPart::Pointer part = Tweaklets::Get(WorkbenchPageTweaklet::KEY)->CreateErrorEditorPart(label, e.displayText()); if (part.IsNotNull()) { IEditorInput::Pointer input; try { input = this->GetEditorInput(); } catch (PartInitException e1) { input = new NullEditorInput(EditorReference::Pointer(this)); } PartPane::Pointer pane = this->GetPane(); pane->CreateControl( manager->page->GetEditorPresentation()->GetLayoutPart()->GetControl()); EditorSite::Pointer site( new EditorSite(IEditorReference::Pointer(this), part, manager->page, descr)); //site.setActionBars(new EditorActionBars(manager.page, site.getWorkbenchWindow(), getId())); part->Init(site, input); try { part->CreatePartControl(pane->GetControl()); } catch (...) { //content.dispose(); //StatusUtil.handleStatus(e, StatusManager.SHOW // | StatusManager.LOG); WorkbenchPlugin::Log("Error creating editor"); return IWorkbenchPart::Pointer(0); } result = part.Cast (); } } return result; } void EditorReference::PropertyChanged(Object::Pointer source, int propId) { // Detect badly behaved editors that don't fire PROP_INPUT events // when they're supposed to. This branch is only needed to handle // malfunctioning editors. if (propId == IWorkbenchPartConstants::PROP_INPUT) { expectingInputChange = false; } WorkbenchPartReference::PropertyChanged(source, propId); } bool EditorReference::SetInput(IEditorInput::Pointer input) { if (part.IsNotNull()) { if (part.Cast ().IsNotNull()) { IReusableEditor::Pointer editor = part.Cast (); expectingInputChange = true; editor->SetInput(input); // If the editor never fired a PROP_INPUT event, log the fact that we've discovered // a buggy editor and fire the event for free. Firing the event for free isn't required // and cannot be relied on (it only works if the input change was triggered by this // method, and there are definitely other cases where events will still be lost), // but older versions of the workbench did this so we fire it here in the spirit // of playing nice. if (expectingInputChange) { // Log the fact that this editor is broken this->ReportMalfunction( "Editor is not firing a PROP_INPUT event in response to IReusableEditor.setInput(...)"); //$NON-NLS-1$ // Fire the property for free (can't be relied on since there are other ways the input // can change, but we do it here to be consistent with older versions of the workbench) FirePropertyChange(IWorkbenchPartConstants::PROP_INPUT); } return editor->GetEditorInput() == input; } // Can't change the input if the editor already exists and isn't an IReusableEditor return false; } // Changing the input is trivial and always succeeds if the editor doesn't exist yet if (input != restoredInput) { restoredInput = input; //firePropertyChange(IWorkbenchPartConstants.PROP_INPUT); } return true; } void EditorReference::ReportMalfunction(const std::string& string) { if (!reportedMalfunctioningEditor) { reportedMalfunctioningEditor = true; std::string errorMessage = "Problem detected with part " + this->GetId(); //$NON-NLS-1$ if (part.IsNotNull()) { errorMessage.append("(class = ").append(part->GetClassName()).append( ")"); //$NON-NLS-1$ //$NON-NLS-2$ } errorMessage += ": " + string; //$NON-NLS-1$ //StatusManager.getManager().handle(StatusUtil.newStatus(getDescriptor().getPluginId(), errorMessage, null)); BERRY_ERROR << errorMessage << std::endl; } } IEditorPart::Pointer EditorReference::CreatePartHelper() { EditorSite::Pointer site; IEditorPart::Pointer part; try { IEditorInput::Pointer editorInput = this->GetEditorInput(); // Get the editor descriptor. std::string editorID = this->GetId(); EditorDescriptor::Pointer desc = this->GetDescriptor(); if (desc.IsNull()) { throw PartInitException("No editor descriptor for id " + editorID); } if (desc->IsInternal()) { // Create an editor instance. part = manager->CreatePart(desc); this->CreatePartProperties(part); } // else if (desc->GetId() == IEditorRegistry.SYSTEM_INPLACE_EDITOR_ID) // { // // part = ComponentSupport.getSystemInPlaceEditor(); // // if (part == null) // { // throw new PartInitException(WorkbenchMessages.EditorManager_no_in_place_support); // } // } else { throw PartInitException("Invalid editor descriptor for id " + editorID); } // Create a pane for this part PartPane::Pointer pane = this->GetPane(); pane->CreateControl(manager->page->GetEditorPresentation()->GetLayoutPart()->GetControl()); // Link everything up to the part reference (the part reference itself should not have // been modified until this point) site = manager->CreateSite(IEditorReference::Pointer(this), part, desc, editorInput); // if there is saved state that's appropriate, pass it on if (/*part instanceof IPersistableEditor &&*/editorState.IsNotNull()) { //part->RestoreState(editorState); } // Remember the site and the action bars (now that we've created them, we'll need to dispose // them if an exception occurs) //actionBars = (EditorActionBars) site.getActionBars(); part->CreatePartControl(pane->GetControl()); // The editor should now be fully created. Exercise its public interface, and sanity-check // it wherever possible. If it's going to throw exceptions or behave badly, it's much better // that it does so now while we can still cancel creation of the part. PartTester::TestEditor(part); return part; } catch (std::exception e) { throw PartInitException(e.what()); } } IEditorPart::Pointer EditorReference::GetEmptyEditor( EditorDescriptor::Pointer descr) { IEditorPart::Pointer part = Tweaklets::Get(WorkbenchPageTweaklet::KEY)->CreateErrorEditorPart("(Empty)", ""); IEditorInput::Pointer input; try { input = this->GetEditorInput(); } catch (PartInitException e1) { input = new NullEditorInput(EditorReference::Pointer(this)); } PartPane::Pointer pane = this->GetPane(); pane->CreateControl( manager->page->GetEditorPresentation()->GetLayoutPart()->GetControl()); EditorSite::Pointer site(new EditorSite(IEditorReference::Pointer(this), part, manager->page, descr)); //site.setActionBars(new EditorActionBars(manager.page, site.getWorkbenchWindow(), getId())); part->Init(site, input); try { part->CreatePartControl(pane->GetControl()); } catch (std::exception e) { //StatusManager.getManager().handle( // StatusUtil.newStatus(WorkbenchPlugin.PI_WORKBENCH, e)); BERRY_ERROR << e.what() << std::endl; return IEditorPart::Pointer(0); } this->part = part.Cast (); // Add a dispose listener to the part. This dispose listener does nothing but log an exception // if the part's widgets get disposed unexpectedly. The workbench part reference is the only // object that should dispose this control, and it will remove the listener before it does so. this->RefreshFromPart(); //this->ReleaseReferences(); if (this->GetPage().Cast ()->GetActiveEditorReference() != this) { //fireInternalPropertyChange(INTERNAL_PROPERTY_OPENED); } return part; } } diff --git a/BlueBerry/Bundles/org.blueberry.ui/src/internal/berryWorkbenchPlugin.cpp b/BlueBerry/Bundles/org.blueberry.ui/src/internal/berryWorkbenchPlugin.cpp index d6135c9df3..abd5852d19 100644 --- a/BlueBerry/Bundles/org.blueberry.ui/src/internal/berryWorkbenchPlugin.cpp +++ b/BlueBerry/Bundles/org.blueberry.ui/src/internal/berryWorkbenchPlugin.cpp @@ -1,329 +1,333 @@ /*=================================================================== BlueBerry Platform 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 "berryLog.h" #include "berryWorkbenchPlugin.h" #include "berryWorkbenchRegistryConstants.h" #include "berryWorkbench.h" #include "berryPlatform.h" #include "intro/berryEditorIntroAdapterPart.h" #include "berryImageDescriptor.h" #include #include namespace berry { bool WorkbenchPlugin::DEBUG = false; char WorkbenchPlugin::PREFERENCE_PAGE_CATEGORY_SEPARATOR = '/'; WorkbenchPlugin* WorkbenchPlugin::inst = 0; WorkbenchPlugin::WorkbenchPlugin() : AbstractUICTKPlugin() { inst = this; presentationFactory = 0; editorRegistry = 0; viewRegistry = 0; perspRegistry = 0; introRegistry = 0; } WorkbenchPlugin::~WorkbenchPlugin() { delete editorRegistry; delete viewRegistry; delete perspRegistry; delete introRegistry; } bool WorkbenchPlugin::HasExecutableExtension( IConfigurationElement::Pointer element, const std::string& extensionName) { std::string attr; if (element->GetAttribute(extensionName, attr)) return true; std::string elementText(element->GetValue()); if (elementText != "") return true; IConfigurationElement::vector children(element->GetChildren(extensionName)); if (children.size() == 1) { if (children[0]->GetAttribute(WorkbenchRegistryConstants::ATT_CLASS, attr)) return true; } return false; } bool WorkbenchPlugin::IsBundleLoadedForExecutableExtension( IConfigurationElement::Pointer element, const std::string& extensionName) { IBundle::Pointer bundle(WorkbenchPlugin::GetBundleForExecutableExtension(element, extensionName)); if (bundle.IsNull()) return true; return bundle->GetState() == IBundle::BUNDLE_ACTIVE; } IBundle::Pointer WorkbenchPlugin::GetBundleForExecutableExtension( IConfigurationElement::Pointer element, const std::string& extensionName) { // this code is derived heavily from // ConfigurationElement.createExecutableExtension. std::string prop; std::string executable; std::string contributorName; std::string::size_type i; if (extensionName != "") element->GetAttribute(extensionName, prop); else { // property not specified, try as element value prop = element->GetValue(); if (prop != "") { Poco::trimInPlace(prop); } } if (prop == "") { // property not defined, try as a child element IConfigurationElement::vector exec(element->GetChildren(extensionName)); if (exec.size() != 0) exec[0]->GetAttribute("plugin", contributorName); //$NON-NLS-1$ } else { // simple property or element value, parse it into its components i = prop.find_first_of(':'); if (i != std::string::npos) executable = Poco::trim(prop.substr(0, i)); else executable = prop; i = executable.find_first_of('/'); if (i != std::string::npos) contributorName = Poco::trim(executable.substr(0, i)); } if (contributorName == "") contributorName = element->GetContributor(); return Platform::GetBundle(contributorName); } WorkbenchPlugin* WorkbenchPlugin::GetDefault() { return inst; } std::size_t WorkbenchPlugin::GetBundleCount() { // TODO BundleContext GetBundles //return bundleContext->GetBundles().size(); return 0; } // ImageRegistry createImageRegistry() { // return WorkbenchImages.getImageRegistry(); // } IPerspectiveRegistry* WorkbenchPlugin::GetPerspectiveRegistry() { if (perspRegistry == 0) { perspRegistry = new PerspectiveRegistry(); // the load methods can touch on WorkbenchImages if an image is // missing so we need to wrap the call in // a startup block for the case where a custom descriptor exists on // startup that does not have an image // associated with it. See bug 196352. //StartupThreading.runWithoutExceptions(new StartupRunnable() { // public void runWithException() throws Throwable { perspRegistry->Load(); // } //}); } return perspRegistry; } // PreferenceManager getPreferenceManager() { // if (preferenceManager == null) { // preferenceManager = new WorkbenchPreferenceManager( // PREFERENCE_PAGE_CATEGORY_SEPARATOR); // // //Get the pages from the registry // PreferencePageRegistryReader registryReader = new PreferencePageRegistryReader( // getWorkbench()); // registryReader // .loadFromRegistry(Platform.getExtensionRegistry()); // preferenceManager.addPages(registryReader.getTopLevelNodes()); // // } // return preferenceManager; // } // ISharedImages getSharedImages() { // if (sharedImages == null) { // sharedImages = new SharedImages(); // } // return sharedImages; // } IIntroRegistry* WorkbenchPlugin::GetIntroRegistry() { if (introRegistry == 0) { introRegistry = new IntroRegistry(); } return introRegistry; } IViewRegistry* WorkbenchPlugin::GetViewRegistry() { if (!viewRegistry) viewRegistry = new ViewRegistry(); return viewRegistry; } IEditorRegistry* WorkbenchPlugin::GetEditorRegistry() { if (!editorRegistry) editorRegistry = new EditorRegistry(); return editorRegistry; } IPresentationFactory* WorkbenchPlugin::GetPresentationFactory() { if (presentationFactory != 0) return presentationFactory; std::string targetID = Workbench::GetInstance()->GetPresentationId(); presentationFactory = this->CreateExtension( WorkbenchRegistryConstants::PL_PRESENTATION_FACTORIES, "factory", targetID); if (presentationFactory == 0) WorkbenchPlugin::Log("Error creating presentation factory: " + targetID + " -- class is not an IPresentationFactory"); return presentationFactory; } void WorkbenchPlugin::Log(const std::string& message) { BERRY_INFO << "LOG: " << message << std::endl; //inst->GetLog().log(message); } void WorkbenchPlugin::Log(const Poco::RuntimeException& exc) { BERRY_INFO << "LOG: " << exc.message() << std::endl; //inst->GetLog().log(exc); } void WorkbenchPlugin::Log(const std::string& message, const Poco::RuntimeException& t) { PlatformException exc(message, t); WorkbenchPlugin::Log(exc); } void WorkbenchPlugin::Log(const std::string& clazz, const std::string& methodName, const Poco::RuntimeException& t) { std::string msg = "Exception in " + clazz + "." + methodName + ": " + t.what(); WorkbenchPlugin::Log(msg, t); } void WorkbenchPlugin::start(ctkPluginContext* context) { //context.addBundleListener(getBundleListener()); AbstractUICTKPlugin::start(context); bundleContext = context; BERRY_REGISTER_EXTENSION_CLASS(EditorIntroAdapterPart, context) // The UI plugin needs to be initialized so that it can install the callback in PrefUtil, // which needs to be done as early as possible, before the workbench // accesses any API preferences. // Bundle uiBundle = Platform.getBundle(PlatformUI.PLUGIN_ID); // try // { // // Attempt to load the activator of the ui bundle. This will force lazy start // // of the ui bundle. Using the bundle activator class here because it is a // // class that needs to be loaded anyway so it should not cause extra classes // // to be loaded. // if(uiBundle != null) // uiBundle.loadClass(UI_BUNDLE_ACTIVATOR); // } // catch (ClassNotFoundException e) // { // WorkbenchPlugin.log("Unable to load UI activator", e); //$NON-NLS-1$ // } /* * DO NOT RUN ANY OTHER CODE AFTER THIS LINE. If you do, then you are * likely to cause a deadlock in class loader code. Please see Bug 86450 * for more information. */ } //const std::vector WorkbenchPlugin::GetBundles() //{ // return bundleContext.IsNull() ? std::vector() : bundleContext->GetBundles(); //} ctkPluginContext* WorkbenchPlugin::GetPluginContext() { return bundleContext; } void WorkbenchPlugin::stop(ctkPluginContext* context) { AbstractUICTKPlugin::stop(context); delete perspRegistry; + // avoid possible crash, see bug #18399 + perspRegistry = 0; } bool WorkbenchPlugin::GetDataPath(Poco::Path& path) { QFileInfo fileInfo = bundleContext->getDataFile(""); path.assign(fileInfo.absolutePath().toStdString() + '/'); return fileInfo.isWritable(); } } -Q_EXPORT_PLUGIN2(org_blueberry_ui, berry::WorkbenchPlugin) +#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) + Q_EXPORT_PLUGIN2(org_blueberry_ui, berry::WorkbenchPlugin) +#endif diff --git a/BlueBerry/Bundles/org.blueberry.ui/src/internal/berryWorkbenchPlugin.h b/BlueBerry/Bundles/org.blueberry.ui/src/internal/berryWorkbenchPlugin.h index f4577ff2aa..7c7753a1b5 100644 --- a/BlueBerry/Bundles/org.blueberry.ui/src/internal/berryWorkbenchPlugin.h +++ b/BlueBerry/Bundles/org.blueberry.ui/src/internal/berryWorkbenchPlugin.h @@ -1,474 +1,477 @@ /*=================================================================== BlueBerry Platform 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 BERRYWORKBENCHPLUGIN_H_ #define BERRYWORKBENCHPLUGIN_H_ #include #include #include #include #include "berryAbstractUICTKPlugin.h" #include "berryPlatformUI.h" #include "presentations/berryIPresentationFactory.h" #include "berryViewRegistry.h" #include "berryEditorRegistry.h" #include "berryPerspectiveRegistry.h" #include "intro/berryIntroRegistry.h" namespace berry { /** * \ingroup org_blueberry_ui_internal * * This class represents the TOP of the workbench UI world * A plugin class is effectively an application wrapper * for a plugin & its classes. This class should be thought * of as the workbench UI's application class. * * This class is responsible for tracking various registries * font, preference, graphics, dialog store. * * This class is explicitly referenced by the * workbench plugin's "plugin.xml" and places it * into the UI start extension point of the main * overall application harness * * When is this class started? * When the Application * calls createExecutableExtension to create an executable * instance of our workbench class. */ class WorkbenchPlugin : public QObject, public AbstractUICTKPlugin { Q_OBJECT +#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) + Q_PLUGIN_METADATA(IID "org_blueberry_ui") +#endif Q_INTERFACES(ctkPluginActivator) private: //static const std::string UI_BUNDLE_ACTIVATOR = "org.blueberry.ui.internal.UIPlugin"; //$NON-NLS-1$ // Default instance of the receiver static WorkbenchPlugin* inst; // The presentation factory IPresentationFactory* presentationFactory; // Manager that maps resources to descriptors of editors to use EditorRegistry* editorRegistry; // The context within which this plugin was started. ctkPluginContext* bundleContext; // Other data. //WorkbenchPreferenceManager preferenceManager; ViewRegistry* viewRegistry; PerspectiveRegistry* perspRegistry; IntroRegistry* introRegistry; //SharedImages sharedImages; public: /** * Global workbench ui plugin flag. Only workbench implementation is allowed to use this flag * All other plugins, examples, or test cases must *not* use this flag. */ static bool DEBUG; /** * The character used to separate preference page category ids */ static char PREFERENCE_PAGE_CATEGORY_SEPARATOR; /** * Create an instance of the WorkbenchPlugin. The workbench plugin is * effectively the "application" for the workbench UI. The entire UI * operates as a good plugin citizen. */ WorkbenchPlugin(); ~WorkbenchPlugin(); /** * Creates an extension. If the extension plugin has not * been loaded a busy cursor will be activated during the duration of * the load. * * @param element the config element defining the extension * @param classAttribute the name of the attribute carrying the class * @return the extension object * @throws CoreException if the extension cannot be created */ // template // static E* CreateExtension(IConfigurationElement::ConstPointer element, // const std::string& classAttribute) { // try { // // If plugin has been loaded create extension. // // Otherwise, show busy cursor then create extension. // if (BundleUtility.isActivated(element.getDeclaringExtension() // .getNamespace())) { // return element.createExecutableExtension(classAttribute); // } // final Object[] ret = new Object[1]; // final CoreException[] exc = new CoreException[1]; // BusyIndicator.showWhile(null, new Runnable() { // public void run() { // try { // ret[0] = element // .createExecutableExtension(classAttribute); // } catch (CoreException e) { // exc[0] = e; // } // } // }); // if (exc[0] != null) { // throw exc[0]; // } // return ret[0]; // // } catch (CoreException core) { // throw core; // } catch (Exception e) { // throw new CoreException(new Status(IStatus.ERR, PI_WORKBENCH, // IStatus.ERR, WorkbenchMessages.WorkbenchPlugin_extension,e)); // } // } /** * Answers whether the provided element either has an attribute with the * given name or a child element with the given name with an attribute * called class. * * @param element * the element to test * @param extensionName * the name of the extension to test for * @return whether or not the extension is declared * @since 3.3 */ static bool HasExecutableExtension(IConfigurationElement::Pointer element, const std::string& extensionName); /** * Checks to see if the provided element has the syntax for an executable * extension with a given name that resides in a bundle that is already * active. Determining the bundle happens in one of two ways:
*
    *
  • The element has an attribute with the specified name or element text * in the form bundle.id/class.name[:optional attributes]
  • *
  • The element has a child element with the specified name that has a * plugin attribute
  • *
* * @param element * the element to test * @param extensionName * the name of the extension to test for * @return whether or not the bundle expressed by the above criteria is * active. If the bundle cannot be determined then the state of the * bundle that declared the element is returned. * @since 3.3 */ static bool IsBundleLoadedForExecutableExtension( IConfigurationElement::Pointer element, const std::string& extensionName); /** * Returns the bundle that contains the class referenced by an executable * extension. Determining the bundle happens in one of two ways:
*
    *
  • The element has an attribute with the specified name or element text * in the form bundle.id/class.name[:optional attributes]
  • *
  • The element has a child element with the specified name that has a * plugin attribute
  • *
* * @param element * the element to test * @param extensionName * the name of the extension to test for * @return the bundle referenced by the extension. If that bundle cannot be * determined the bundle that declared the element is returned. Note * that this may be null. * @since 3.3 */ static IBundle::Pointer GetBundleForExecutableExtension(IConfigurationElement::Pointer element, const std::string& extensionName); /** * Return the default instance of the receiver. This represents the runtime plugin. * @return WorkbenchPlugin * @see AbstractUICTKPlugin for the typical implementation pattern for plugin classes. */ static WorkbenchPlugin* GetDefault(); std::size_t GetBundleCount(); /** * Answer the manager that maps resource types to a the * description of the editor to use * @return IEditorRegistry the editor registry used * by this plug-in. */ IEditorRegistry* GetEditorRegistry(); /** * Returns the presentation factory with the given id, or null if not found. * @param targetID The id of the presentation factory to use. * @return IPresentationFactory or null * if not factory matches that id. */ IPresentationFactory* GetPresentationFactory(); protected: /** * Returns the image registry for this plugin. * * Where are the images? The images (typically gifs) are found in the same * plugins directory. * * @see ImageRegistry * * Note: The workbench uses the standard JFace ImageRegistry to track its * images. In addition the class WorkbenchGraphicResources provides * convenience access to the graphics resources and fast field access for * some of the commonly used graphical images. */ // ImageRegistry createImageRegistry(); private: /** * Looks up the configuration element with the given id on the given extension point * and instantiates the class specified by the class attributes. * * @param extensionPointId the extension point id (simple id) * @param elementName the name of the configuration element, or null * to match any element * @param targetID the target id * @return the instantiated extension object, or null if not found */ template C* CreateExtension(const std::string extensionPointId, const std::string& elementName, const std::string& targetID) { const IExtensionPoint* extensionPoint = Platform::GetExtensionPointService() ->GetExtensionPoint("" + PlatformUI::PLUGIN_ID + "." + extensionPointId); if (extensionPoint == 0) { WorkbenchPlugin ::Log("Unable to find extension. Extension point: " + extensionPointId + " not found"); //$NON-NLS-1$ //$NON-NLS-2$ return 0; } // Loop through the config elements. IConfigurationElement::Pointer targetElement(0); IConfigurationElement::vector elements(Platform::GetExtensionPointService() ->GetConfigurationElementsFor("" + PlatformUI::PLUGIN_ID + "." + extensionPointId)); for (unsigned int j = 0; j < elements.size(); j++) { if (elementName == "" || elementName == elements[j]->GetName()) { std::string strID; elements[j]->GetAttribute("id", strID); if (targetID == strID) { targetElement = elements[j]; break; } } } if (targetElement.IsNull()) { // log it since we cannot safely display a dialog. WorkbenchPlugin::Log("Unable to find extension: " + targetID //$NON-NLS-1$ + " in extension point: " + extensionPointId); //$NON-NLS-1$ return 0; } // Create the extension. try { C* impl = targetElement->CreateExecutableExtension("class"); //$NON-NLS-1$ if (impl == 0) { // support legacy BlueBerry extensions impl = targetElement->CreateExecutableExtension("class", C::GetManifestName()); } return impl; } catch (CoreException e) { // log it since we cannot safely display a dialog. WorkbenchPlugin::Log("Unable to create extension: " + targetID //$NON-NLS-1$ + " in extension point: " + extensionPointId); //$NON-NLS-1$ } return 0; } public: /** * Return the perspective registry. * @return IPerspectiveRegistry. The registry for the receiver. */ IPerspectiveRegistry* GetPerspectiveRegistry(); /** * Returns the introduction registry. * * @return the introduction registry. * @since 3.0 */ IIntroRegistry* GetIntroRegistry(); /** * Get the preference manager. * @return PreferenceManager the preference manager for * the receiver. */ // PreferenceManager getPreferenceManager(); /** * Returns the shared images for the workbench. * * @return the shared image manager */ // ISharedImages getSharedImages(); /** * Answer the view registry. * @return IViewRegistry the view registry for the * receiver. */ IViewRegistry* GetViewRegistry(); /** * Logs the given message to the platform log. * * If you have an exception in hand, call log(String, Throwable) instead. * * If you have a status object in hand call log(String, IStatus) instead. * * This convenience method is for internal use by the Workbench only and * must not be called outside the Workbench. * * @param message * A high level UI message describing when the problem happened. */ static void Log(const std::string& message); /** * Log the throwable. * @param t */ static void Log(const Poco::RuntimeException& exc); /** * Logs the given message and throwable to the platform log. * * If you have a status object in hand call log(String, IStatus) instead. * * This convenience method is for internal use by the Workbench only and * must not be called outside the Workbench. * * @param message * A high level UI message describing when the problem happened. * @param t * The throwable from where the problem actually occurred. */ static void Log(const std::string& message, const Poco::RuntimeException& t); /** * Logs the given throwable to the platform log, indicating the class and * method from where it is being logged (this is not necessarily where it * occurred). * * This convenience method is for internal use by the Workbench only and * must not be called outside the Workbench. * * @param clazz * The calling class. * @param methodName * The calling method name. * @param t * The throwable from where the problem actually occurred. */ static void Log(const std::string& clazz, const std::string& methodName, const Poco::RuntimeException& t); /* * (non-Javadoc) * @see org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext) */ void start(ctkPluginContext* context); /** * Return an array of all bundles contained in this workbench. * * @return an array of bundles in the workbench or an empty array if none * @since 3.0 */ //const std::vector GetBundles(); /** * Returns the bundle context associated with the workbench plug-in. * * @return the bundle context * @since 3.1 */ ctkPluginContext* GetPluginContext(); /* (non-Javadoc) * @see org.blueberry.ui.plugin.AbstractUICTKPlugin#stop(org.osgi.framework.BundleContext) */ void stop(ctkPluginContext* context); /** * FOR INTERNAL WORKBENCH USE ONLY. * * Returns the path to a location in the file system that can be used * to persist/restore state between workbench invocations. * If the location did not exist prior to this call it will be created. * Returns null if no such location is available. * * @return path to a location in the file system where this plug-in can * persist data between sessions, or null if no such * location is available. * @since 3.1 */ bool GetDataPath(Poco::Path& path); }; } #endif /*BERRYWORKBENCHPLUGIN_H_*/ diff --git a/BlueBerry/Bundles/org.blueberry.uitest/src/internal/berryPluginActivator.cpp b/BlueBerry/Bundles/org.blueberry.uitest/src/internal/berryPluginActivator.cpp index 1135ff4e0e..00ad1a8952 100644 --- a/BlueBerry/Bundles/org.blueberry.uitest/src/internal/berryPluginActivator.cpp +++ b/BlueBerry/Bundles/org.blueberry.uitest/src/internal/berryPluginActivator.cpp @@ -1,45 +1,47 @@ /*=================================================================== BlueBerry Platform 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 "berryPluginActivator.h" #include "berryUITestApplication.h" #include "util/berryEmptyPerspective.h" #include namespace berry { org_blueberry_uitest_Activator::org_blueberry_uitest_Activator() { } void org_blueberry_uitest_Activator::start(ctkPluginContext* context) { BERRY_REGISTER_EXTENSION_CLASS(UITestApplication, context) BERRY_REGISTER_EXTENSION_CLASS(EmptyPerspective, context) } void org_blueberry_uitest_Activator::stop(ctkPluginContext* context) { Q_UNUSED(context) } } -Q_EXPORT_PLUGIN2(org_blueberry_uitest, berry::org_blueberry_uitest_Activator) +#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) + Q_EXPORT_PLUGIN2(org_blueberry_uitest, berry::org_blueberry_uitest_Activator) +#endif diff --git a/BlueBerry/Bundles/org.blueberry.uitest/src/internal/berryPluginActivator.h b/BlueBerry/Bundles/org.blueberry.uitest/src/internal/berryPluginActivator.h index d470ebee6f..064af0d13c 100644 --- a/BlueBerry/Bundles/org.blueberry.uitest/src/internal/berryPluginActivator.h +++ b/BlueBerry/Bundles/org.blueberry.uitest/src/internal/berryPluginActivator.h @@ -1,42 +1,45 @@ /*=================================================================== BlueBerry Platform 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 BERRYPLUGINACTIVATOR_H #define BERRYPLUGINACTIVATOR_H #include namespace berry { class org_blueberry_uitest_Activator : public QObject, public ctkPluginActivator { Q_OBJECT +#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) + Q_PLUGIN_METADATA(IID "org_blueberry_uitest") +#endif Q_INTERFACES(ctkPluginActivator) public: org_blueberry_uitest_Activator(); void start(ctkPluginContext* context); void stop(ctkPluginContext* context); }; typedef org_blueberry_uitest_Activator PluginActivator; } #endif // BERRYPLUGINACTIVATOR_H diff --git a/BlueBerry/CMake/FunctionCreateBlueBerryApplication.cmake b/BlueBerry/CMake/FunctionCreateBlueBerryApplication.cmake index 5f08c8121c..a36a1a0ede 100644 --- a/BlueBerry/CMake/FunctionCreateBlueBerryApplication.cmake +++ b/BlueBerry/CMake/FunctionCreateBlueBerryApplication.cmake @@ -1,229 +1,229 @@ #! #! Create a BlueBerry application. #! #! \brief This function will create a BlueBerry application together with all #! necessary provisioning and configuration data and install support. #! #! \param NAME (required) The name of the executable. #! \param DESCRIPTION (optional) A human-readable description of your application. #! The usage depends on the CPack generator (on Windows, this is a descriptive #! text for the created shortcuts). #! \param SOURCES (optional) A list of source files to compile into your executable. Defaults #! to .cpp. #! \param PLUGINS (optional) A list of required plug-ins. Defaults to all known plug-ins. #! \param EXCLUDE_PLUGINS (optional) A list of plug-ins which should not be used. Mainly #! useful if PLUGINS was not used. #! \param LINK_LIBRARIES A list of libraries to be linked with the executable. #! \param LIBRARY_DIRS A list of directories to pass through to MITK_INSTALL_TARGETS #! \param SHOW_CONSOLE (option) Show the console output window (on Windows). #! \param NO_PROVISIONING (option) Do not create provisioning files. #! \param NO_INSTALL (option) Do not install this executable #! #! Assuming that there exists a file called MyApp.cpp, an example call looks like: #! \code #! FunctionCreateBlueBerryApplication( #! NAME MyApp #! DESCRIPTION "MyApp - New ways to explore medical data" #! EXCLUDE_PLUGINS org.mitk.gui.qt.extapplication #! SHOW_CONSOLE #! ) #! \endcode #! function(FunctionCreateBlueBerryApplication) macro_parse_arguments(_APP "NAME;DESCRIPTION;SOURCES;PLUGINS;EXCLUDE_PLUGINS;LINK_LIBRARIES;LIBRARY_DIRS" "SHOW_CONSOLE;NO_PROVISIONING;NO_INSTALL" ${ARGN}) if(NOT _APP_NAME) message(FATAL_ERROR "NAME argument cannot be empty.") endif() if(NOT _APP_SOURCES) set(_APP_SOURCES ${_APP_NAME}.cpp) endif() if(NOT _APP_PLUGINS) ctkFunctionGetAllPluginTargets(_APP_PLUGINS) else() set(_plugins ${_APP_PLUGINS}) set(_APP_PLUGINS) foreach(_plugin ${_plugins}) string(REPLACE "." "_" _plugin_target ${_plugin}) list(APPEND _APP_PLUGINS ${_plugin_target}) endforeach() # get all plug-in dependencies ctkFunctionGetPluginDependencies(_plugin_deps PLUGINS ${_APP_PLUGINS} ALL) # add the dependencies to the list of application plug-ins list(APPEND _APP_PLUGINS ${_plugin_deps}) endif() #------------------------------------------------------------------------ # Prerequesites #------------------------------------------------------------------------ find_package(MITK REQUIRED) find_package(Poco REQUIRED) # ----------------------------------------------------------------------- # Set up include and link dirs for the executable # ----------------------------------------------------------------------- include_directories( ${org_blueberry_osgi_INCLUDE_DIRS} ) # ----------------------------------------------------------------------- # Add executable icon (Windows) # ----------------------------------------------------------------------- set(WINDOWS_ICON_RESOURCE_FILE "") if(WIN32) if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/icons/${_APP_NAME}.rc") set(WINDOWS_ICON_RESOURCE_FILE "${CMAKE_CURRENT_SOURCE_DIR}/icons/${_APP_NAME}.rc") endif() endif() # ----------------------------------------------------------------------- # Create the executable and link libraries # ----------------------------------------------------------------------- set(_app_compile_flags ) if(WIN32) set(_app_compile_flags "${_app_compile_flags} -DPOCO_NO_UNWINDOWS -DWIN32_LEAN_AND_MEAN") endif() # Work-around for linking GDCM libraries, until GDCM provides proper # target exports. foreach(dir ${MODULES_PACKAGE_DEPENDS_DIRS}) if(EXISTS "${dir}/MITK_GDCM_Config.cmake") include("${dir}/MITK_GDCM_Config.cmake") break() endif() endforeach() if(ALL_LIBRARY_DIRS) list(REMOVE_DUPLICATES ALL_LIBRARY_DIRS) link_directories(${ALL_LIBRARY_DIRS}) endif() if(_APP_SHOW_CONSOLE) add_executable(${_APP_NAME} MACOSX_BUNDLE ${_APP_SOURCES} ${WINDOWS_ICON_RESOURCE_FILE}) else() add_executable(${_APP_NAME} MACOSX_BUNDLE WIN32 ${_APP_SOURCES} ${WINDOWS_ICON_RESOURCE_FILE}) endif() -mitk_use_modules(TARGET ${_APP_NAME} MODULES mbilog PACKAGES Poco Qt4|QtCore) +mitk_use_modules(TARGET ${_APP_NAME} MODULES mbilog PACKAGES Poco Qt4|QtCore Qt5|Core) set_target_properties(${_APP_NAME} PROPERTIES COMPILE_FLAGS "${_app_compile_flags}") target_link_libraries(${_APP_NAME} org_blueberry_osgi ${_APP_LINK_LIBRARIES}) if(WIN32) target_link_libraries(${_APP_NAME} ${QT_QTMAIN_LIBRARY}) endif() # ----------------------------------------------------------------------- # Add executable icon and bundle name (Mac) # ----------------------------------------------------------------------- if(APPLE) if( _APP_DESCRIPTION) set_target_properties(${_APP_NAME} PROPERTIES MACOSX_BUNDLE_NAME "${_APP_DESCRIPTION}") else() set_target_properties(${_APP_NAME} PROPERTIES MACOSX_BUNDLE_NAME "${_APP_NAME}") endif() set(icon_name "icon.icns") set(icon_full_path "${CMAKE_CURRENT_SOURCE_DIR}/icons/${icon_name}") if(EXISTS "${icon_full_path}") set_target_properties(${_APP_NAME} PROPERTIES MACOSX_BUNDLE_ICON_FILE "${icon_name}") file(COPY ${icon_full_path} DESTINATION "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${_APP_NAME}.app/Contents/Resources/") INSTALL (FILES ${icon_full_path} DESTINATION "${_APP_NAME}.app/Contents/Resources/") endif() endif() # ----------------------------------------------------------------------- # Set build time dependencies # ----------------------------------------------------------------------- # This ensures that all enabled plug-ins are up-to-date when the # executable is build. if(_APP_PLUGINS) ctkMacroGetAllProjectTargetLibraries("${_APP_PLUGINS}" _project_plugins) if(_APP_EXCLUDE_PLUGINS) set(_exclude_targets) foreach(_exclude_plugin ${_APP_EXCLUDE_PLUGINS}) string(REPLACE "." "_" _exclude_target ${_exclude_plugin}) list(APPEND _exclude_targets ${_exclude_target}) endforeach() list(REMOVE_ITEM _project_plugins ${_exclude_targets}) endif() if(_project_plugins) add_dependencies(${_APP_NAME} ${_project_plugins}) endif() endif() # ----------------------------------------------------------------------- # Additional files needed for the executable # ----------------------------------------------------------------------- if(NOT _APP_NO_PROVISIONING) # Create a provisioning file, listing all plug-ins set(_prov_file "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${_APP_NAME}.provisioning") FunctionCreateProvisioningFile(FILE ${_prov_file} PLUGINS ${_APP_PLUGINS} EXCLUDE_PLUGINS ${_APP_EXCLUDE_PLUGINS} ) endif() # Create a .ini file for initial parameters if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${_APP_NAME}.ini") configure_file(${_APP_NAME}.ini ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${_APP_NAME}.ini) endif() # Create batch files for Windows platforms if(WIN32) set(template_name "start${_APP_NAME}.bat.in") if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${template_name}") foreach(BUILD_TYPE debug release) mitkFunctionCreateWindowsBatchScript(${template_name} ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/start${_APP_NAME}_${BUILD_TYPE}.bat ${BUILD_TYPE}) endforeach() endif() endif(WIN32) # ----------------------------------------------------------------------- # Install support # ----------------------------------------------------------------------- if(NOT _APP_NO_INSTALL) # This installs all third-party CTK plug-ins FunctionInstallThirdPartyCTKPlugins(${_APP_PLUGINS} EXCLUDE ${_APP_EXCLUDE_PLUGINS}) if(COMMAND BlueBerryApplicationInstallHook) set(_real_app_plugins ${_APP_PLUGINS}) if(_APP_EXCLUDE_PLUGINS) list(REMOVE_ITEM _real_app_plugins ${_APP_EXCLUDE_PLUGINS}) endif() BlueBerryApplicationInstallHook(APP_NAME ${_APP_NAME} PLUGINS ${_real_app_plugins}) endif() # Install the executable MITK_INSTALL_TARGETS(EXECUTABLES ${_APP_NAME} LIBRARY_DIRS ${_APP_LIBRARY_DIRS} GLOB_PLUGINS ) if(NOT _APP_NO_PROVISIONING) # Install the provisioning file mitkFunctionInstallProvisioningFiles(${_prov_file}) endif() # On Linux, create a shell script to start a relocatable application if(UNIX AND NOT APPLE) install(PROGRAMS "${MITK_SOURCE_DIR}/CMake/RunInstalledApp.sh" DESTINATION "." RENAME ${_APP_NAME}.sh) endif() # Tell cpack the executables that you want in the start menu as links set(MITK_CPACK_PACKAGE_EXECUTABLES ${MITK_CPACK_PACKAGE_EXECUTABLES} "${_APP_NAME};${_APP_DESCRIPTION}" CACHE INTERNAL "Collecting windows shortcuts to executables") endif() endfunction() diff --git a/BlueBerry/CMakeLists.txt b/BlueBerry/CMakeLists.txt index 1e9821b1d0..3b77eba726 100644 --- a/BlueBerry/CMakeLists.txt +++ b/BlueBerry/CMakeLists.txt @@ -1,273 +1,285 @@ project(BlueBerry) -cmake_minimum_required(VERSION 2.8.5) +if (${CMAKE_SOURCE_DIR} EQUAL ${PROJECT_SOURCE_DIR}) + cmake_minimum_required(VERSION 2.8.9) +endif() set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/CMake/") include(MacroParseArguments) include(MacroConvertSchema) include(MacroOrganizeSources) include(MacroCreateCTKPlugin) include(MacroCreateQtHelp) include(MacroInstallCTKPlugin) include(FunctionCreateProvisioningFile) if(MSVC) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd4250 /wd4275 /wd4251 /wd4503") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DNOMINMAX /wd4250 /wd4275 /wd4251 /wd4503") endif() if(NOT CMAKE_RUNTIME_OUTPUT_DIRECTORY) set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/bin) endif() find_package(mbilog REQUIRED) include_directories(${mbilog_INCLUDE_DIRS}) - -find_package(Qt4 4.7 REQUIRED) +if(MITK_USE_Qt4) + find_package(Qt4 4.7 REQUIRED) +else() + find_package(Qt5Concurrent ${MITK_QT5_MINIMUM_VERSION} REQUIRED) + find_package(Qt5Help ${MITK_QT5_MINIMUM_VERSION} REQUIRED) + find_package(Qt5Sql ${MITK_QT5_MINIMUM_VERSION} REQUIRED) + find_package(Qt5WebKitWidgets ${MITK_QT5_MINIMUM_VERSION} REQUIRED) + find_package(Qt5Widgets ${MITK_QT5_MINIMUM_VERSION} REQUIRED) + find_package(Qt5Xml ${MITK_QT5_MINIMUM_VERSION} REQUIRED) +endif() if(QT_QMAKE_CHANGED) set(QT_HELPGENERATOR_EXECUTABLE NOTFOUND) set(QT_COLLECTIONGENERATOR_EXECUTABLE NOTFOUND) set(QT_ASSISTANT_EXECUTABLE NOTFOUND) set(QT_XMLPATTERNS_EXECUTABLE NOTFOUND) endif() find_program(QT_HELPGENERATOR_EXECUTABLE NAMES qhelpgenerator qhelpgenerator-qt4 qhelpgenerator4 PATHS ${QT_BINARY_DIR} NO_DEFAULT_PATH ) find_program(QT_COLLECTIONGENERATOR_EXECUTABLE NAMES qcollectiongenerator qcollectiongenerator-qt4 qcollectiongenerator4 PATHS ${QT_BINARY_DIR} NO_DEFAULT_PATH ) find_program(QT_ASSISTANT_EXECUTABLE NAMES assistant-qt4 assistant4 assistant PATHS ${QT_BINARY_DIR} NO_DEFAULT_PATH ) find_program(QT_XMLPATTERNS_EXECUTABLE NAMES xmlpatterns PATHS ${QT_BINARY_DIR} NO_DEFAULT_PATH ) find_package(Doxygen) option(BLUEBERRY_USE_QT_HELP "Enable support for integrating bundle documentation into Qt Help" ${DOXYGEN_FOUND}) mark_as_advanced(BLUEBERRY_USE_QT_HELP QT_HELPGENERATOR_EXECUTABLE QT_COLLECTIONGENERATOR_EXECUTABLE QT_ASSISTANT_EXECUTABLE QT_XMLPATTERNS_EXECUTABLE) if(BLUEBERRY_USE_QT_HELP) set(_force_blueberry_use_qt_help_to_off 0) if(NOT DOXYGEN_FOUND) message("> Forcing BLUEBERRY_USE_QT_HELP to OFF because Doxygen was not found.") set(_force_blueberry_use_qt_help_to_off 1) endif() if(DOXYGEN_FOUND AND DOXYGEN_VERSION VERSION_LESS 1.8.7) message("> Forcing BLUEBERRY_USE_QT_HELP to OFF because Doxygen version 1.8.7 or newer not found.") set(_force_blueberry_use_qt_help_to_off 1) endif() if(NOT QT_HELPGENERATOR_EXECUTABLE) message("> Forcing BLUEBERRY_USE_QT_HELP to OFF because QT_HELPGENERATOR_EXECUTABLE is empty.") set(_force_blueberry_use_qt_help_to_off 1) endif() if(NOT QT_XMLPATTERNS_EXECUTABLE) message("You have enabled Qt Help support, but QT_XMLPATTERNS_EXECUTABLE is empty") set(_force_blueberry_use_qt_help_to_off 1) endif() if(_force_blueberry_use_qt_help_to_off) set(BLUEBERRY_USE_QT_HELP OFF CACHE BOOL "Enable support for integrating bundle documentation into Qt Help" FORCE) endif() endif(BLUEBERRY_USE_QT_HELP) -include(${QT_USE_FILE}) +if(MITK_USE_Qt4) + include(${QT_USE_FILE}) +endif() # ========= CTK specific CMake stuff ============ cmake_policy(SET CMP0012 NEW) find_package(CTK REQUIRED) # Extract all library names starting with org_blueberry_ macro(GetMyTargetLibraries all_target_libraries varname) set(re_ctkplugin "^org_blueberry_[a-zA-Z0-9_]+$") set(_tmp_list) list(APPEND _tmp_list ${all_target_libraries}) ctkMacroListFilter(_tmp_list re_ctkplugin OUTPUT_VARIABLE ${varname}) endmacro() # ================================================ option(BLUEBERRY_BUILD_ALL_PLUGINS "Build all BlueBerry plugins (overriding selection)" OFF) mark_as_advanced(BLUEBERRY_BUILD_ALL_PLUGINS) if(BLUEBERRY_BUILD_ALL_PLUGINS) set(BLUEBERRY_BUILD_ALL_PLUGINS_OPTION "FORCE_BUILD_ALL") endif() option(BLUEBERRY_STATIC "Build all plugins as static libraries" OFF) mark_as_advanced(BLUEBERRY_STATIC) option(BLUEBERRY_DEBUG_SMARTPOINTER "Enable code for debugging smart pointers" OFF) mark_as_advanced(BLUEBERRY_DEBUG_SMARTPOINTER) find_package(Poco REQUIRED) find_package(Ant) find_package(Eclipse) set(BLUEBERRY_SOURCE_DIR ${BlueBerry_SOURCE_DIR}) set(BLUEBERRY_BINARY_DIR ${BlueBerry_BINARY_DIR}) set(BLUEBERRY_PLUGINS_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/Bundles) set(BLUEBERRY_PLUGINS_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/Bundles) set(OSGI_APP solstice) set(OSGI_UI_APP solstice_ui) if(Eclipse_DIR) set(BLUEBERRY_DOC_TOOLS_DIR "${Eclipse_DIR}" CACHE PATH "Directory containing additional tools needed for generating the documentation") else() set(BLUEBERRY_DOC_TOOLS_DIR "" CACHE PATH "Directory containing additional tools needed for generating the documentation") endif() set(BLUEBERRY_DEBUG_POSTFIX d) # Testing options if(DEFINED BLUEBERRY_BUILD_TESTING) option(BLUEBERRY_BUILD_TESTING "Build the BlueBerry tests." ${BLUEBERRY_BUILD_TESTING}) else() option(BLUEBERRY_BUILD_TESTING "Build the BlueBerry tests." ${BUILD_TESTING}) endif() if(WIN32) set(_gui_testing_default "ON") else() set(_gui_testing_default "OFF") endif() option(BLUEBERRY_ENABLE_GUI_TESTING "Enable the BlueBerry GUI tests" ${_gui_testing_default}) mark_as_advanced(BLUEBERRY_ENABLE_GUI_TESTING) if(BLUEBERRY_BUILD_TESTING) enable_testing() endif() # Add CTK plugins set(_ctk_plugins Bundles/org.blueberry.osgi:ON Bundles/org.blueberry.compat:OFF Bundles/org.blueberry.core.runtime:OFF Bundles/org.blueberry.core.expressions:OFF Bundles/org.blueberry.solstice.common:OFF Bundles/org.blueberry.core.commands:OFF Bundles/org.blueberry.core.jobs:OFF Bundles/org.blueberry.ui:OFF Bundles/org.blueberry.ui.qt:OFF Bundles/org.blueberry.ui.qt.help:OFF Bundles/org.blueberry.ui.qt.log:ON Bundles/org.blueberry.ui.qt.objectinspector:OFF ) set(_ctk_test_plugins ) set(_ctk_plugins_include_dirs ${Poco_INCLUDE_DIRS} ) include_directories(${_ctk_plugins_include_dirs}) if(BLUEBERRY_BUILD_TESTING) find_package(CppUnit REQUIRED) include(berryTestingHelpers) set(BLUEBERRY_TEST_APP "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${OSGI_APP}") get_target_property(_is_macosx_bundle ${OSGI_APP} MACOSX_BUNDLE) if(APPLE AND _is_macosx_bundle) set(BLUEBERRY_TEST_APP "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${OSGI_APP}.app/Contents/MacOS/${OSGI_APP}") endif() set(_ctk_testinfrastructure_plugins Bundles/org.blueberry.test:ON Bundles/org.blueberry.uitest:ON ) set(_ctk_test_plugins # Testing/org.blueberry.core.runtime.tests:ON # Testing/org.blueberry.osgi.tests:ON ) if(BLUEBERRY_ENABLE_GUI_TESTING) # list(APPEND _ctk_test_plugins Testing/org.blueberry.ui.tests:ON) set(BLUEBERRY_UI_TEST_APP "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${OSGI_UI_APP}") get_target_property(_is_macosx_bundle ${OSGI_UI_APP} MACOSX_BUNDLE) if(APPLE AND _is_macosx_bundle) set(BLUEBERRY_UI_TEST_APP "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${OSGI_UI_APP}.app/Contents/MacOS/${OSGI_UI_APP}") endif() endif() endif() set(BLUEBERRY_TESTING_PROVISIONING_FILE "${BlueBerry_BINARY_DIR}/BlueBerryTesting.provisioning") add_custom_target(BlueBerry) ctkMacroSetupPlugins(${_ctk_plugins} ${_ctk_testinfrastructure_plugins} ${_ctk_test_plugins} BUILD_OPTION_PREFIX BLUEBERRY_BUILD_ BUILD_ALL ${BLUEBERRY_BUILD_ALL_PLUGINS} COMPACT_OPTIONS) set(BLUEBERRY_PROVISIONING_FILE "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/BlueBerry.provisioning") FunctionCreateProvisioningFile( FILE ${BLUEBERRY_PROVISIONING_FILE} PLUGINS ${_ctk_plugins} ) FunctionCreateProvisioningFile( FILE ${BLUEBERRY_TESTING_PROVISIONING_FILE} INCLUDE ${BLUEBERRY_PROVISIONING_FILE} PLUGINS ${_ctk_testinfrastructure_plugins} ${_ctk_test_plugins} ) if(${CMAKE_PROJECT_NAME}_PLUGIN_LIBRARIES) add_dependencies(BlueBerry ${${CMAKE_PROJECT_NAME}_PLUGIN_LIBRARIES}) endif() set_property(TARGET ${${CMAKE_PROJECT_NAME}_PLUGIN_LIBRARIES} PROPERTY LABELS BlueBerry) set(BB_PLUGIN_USE_FILE "${BlueBerry_BINARY_DIR}/BlueBerryPluginUseFile.cmake") if(${PROJECT_NAME}_PLUGIN_LIBRARIES) ctkFunctionGeneratePluginUseFile(${BB_PLUGIN_USE_FILE}) else() file(REMOVE ${BB_PLUGIN_USE_FILE}) set(BB_PLUGIN_USE_FILE ) endif() # CTK Plugin Exports set(BB_PLUGIN_EXPORTS_FILE "${CMAKE_CURRENT_BINARY_DIR}/BlueBerryPluginExports.cmake") GetMyTargetLibraries("${${PROJECT_NAME}_PLUGIN_LIBRARIES}" my_plugin_targets) set(additional_export_targets mbilog) export(TARGETS ${my_plugin_targets} ${additional_export_targets} FILE ${BB_PLUGIN_EXPORTS_FILE}) add_subdirectory(Documentation) set(BLUEBERRY_QTPLUGIN_PATH ) if(CTK_QTDESIGNERPLUGINS_DIR AND EXISTS ${CTK_QTDESIGNERPLUGINS_DIR}) set(BLUEBERRY_QTPLUGIN_PATH "${CTK_QTDESIGNERPLUGINS_DIR}") endif() configure_file(BlueBerryConfig.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/BlueBerryConfig.cmake @ONLY) diff --git a/CMake/MITKDashboardDriverScript.cmake b/CMake/MITKDashboardDriverScript.cmake index 4c36060d43..4385481bba 100644 --- a/CMake/MITKDashboardDriverScript.cmake +++ b/CMake/MITKDashboardDriverScript.cmake @@ -1,485 +1,486 @@ # # Included from a dashboard script, this cmake file will drive the configure and build # steps of MITK # #----------------------------------------------------------------------------- # The following variable are expected to be define in the top-level script: set(expected_variables CTEST_NOTES_FILES CTEST_SITE CTEST_DASHBOARD_ROOT CTEST_CMAKE_COMMAND CTEST_CMAKE_GENERATOR WITH_MEMCHECK WITH_COVERAGE WITH_DOCUMENTATION CTEST_BUILD_CONFIGURATION CTEST_TEST_TIMEOUT CTEST_BUILD_FLAGS TEST_TO_EXCLUDE_REGEX CTEST_SOURCE_DIRECTORY CTEST_BINARY_DIRECTORY CTEST_BUILD_NAME SCRIPT_MODE CTEST_COVERAGE_COMMAND CTEST_MEMORYCHECK_COMMAND CTEST_GIT_COMMAND PROJECT_BUILD_DIR SUPERBUILD_TARGETS ) foreach(var ${expected_variables}) if(NOT DEFINED ${var}) message(FATAL_ERROR "Variable ${var} should be defined in top-level script !") endif() endforeach() +string(REPLACE " " "%20" _build_name_escaped "${CTEST_BUILD_NAME}") + # Check if "mbits" is reachable file(DOWNLOAD "http://mbits" "${CTEST_SCRIPT_DIRECTORY}/mbits.html" TIMEOUT 2 STATUS _status) list(GET _status 0 _status_code) if(_status_code EQUAL 6) # couldn't resovle host name set(MBITS_AVAILABLE 0) else() set(MBITS_AVAILABLE 1) endif() # # Site specific options # if(NOT CDASH_ADMIN_URL_PREFIX AND MBITS_AVAILABLE) set(CDASH_ADMIN_URL_PREFIX "http://mbits") endif() if(NOT MITK_THIRDPARTY_DOWNLOAD_PREFIX_URL AND MBITS_AVAILABLE) set(MITK_THIRDPARTY_DOWNLOAD_PREFIX_URL "http://mbits/dl-cache") endif() if(NOT DEFINED GIT_BRANCH OR GIT_BRANCH STREQUAL "") set(GIT_BRANCH "") else() set(GIT_BRANCH "-b ${GIT_BRANCH}") endif() # Should binary directory be cleaned? set(empty_binary_directory FALSE) # Attempt to build and test also if 'ctest_update' returned an error set(initial_force_build FALSE) # Set model options set(model "") if(SCRIPT_MODE STREQUAL "experimental") set(empty_binary_directory FALSE) set(initial_force_build TRUE) set(model Experimental) elseif(SCRIPT_MODE STREQUAL "continuous") set(empty_binary_directory FALSE) set(initial_force_build FALSE) set(model Continuous) elseif(SCRIPT_MODE STREQUAL "nightly") set(empty_binary_directory TRUE) set(initial_force_build TRUE) set(model Nightly) else() message(FATAL_ERROR "Unknown script mode: '${SCRIPT_MODE}'. Script mode should be either 'experimental', 'continuous' or 'nightly'") endif() #message("script_mode:${SCRIPT_MODE}") #message("model:${model}") #message("empty_binary_directory:${empty_binary_directory}") #message("force_build:${initial_force_build}") set(CTEST_CONFIGURATION_TYPE ${CTEST_BUILD_CONFIGURATION}) if(empty_binary_directory) message("Directory ${CTEST_BINARY_DIRECTORY} cleaned !") ctest_empty_binary_directory(${CTEST_BINARY_DIRECTORY}) endif() if(NOT DEFINED CTEST_CHECKOUT_DIR) set(CTEST_CHECKOUT_DIR ${CTEST_SOURCE_DIRECTORY}) endif() if(NOT EXISTS "${CTEST_CHECKOUT_DIR}") set(CTEST_CHECKOUT_COMMAND "\"${CTEST_GIT_COMMAND}\" clone ${GIT_BRANCH} ${GIT_REPOSITORY} \"${CTEST_CHECKOUT_DIR}\"") endif() set(CTEST_UPDATE_TYPE "git") set(CTEST_UPDATE_COMMAND "${CTEST_GIT_COMMAND}") #---------------------------------------------------------------------- # Utility macros #---------------------------------------------------------------------- function(func_build_target target build_dir) set(CTEST_BUILD_TARGET ${target}) ctest_build(BUILD "${build_dir}" APPEND RETURN_VALUE res NUMBER_ERRORS num_errors NUMBER_WARNINGS num_warnings) ctest_submit(PARTS Build RETRY_DELAY 3 RETRY_COUNT 3) if(num_errors) math(EXPR build_errors "${build_errors} + ${num_errors}") set(build_errors ${build_errors} PARENT_SCOPE) endif() if(num_warnings) math(EXPR build_warnings "${build_warnings} + ${num_warnings}") set(build_warnings ${build_warnings} PARENT_SCOPE) endif() endfunction() function(func_test label build_dir) if(NOT TESTING_PARALLEL_LEVEL) set(TESTING_PARALLEL_LEVEL 8) endif() if(label MATCHES "Unlabeled") set(_include_label EXCLUDE_LABEL .*) else() set(_include_label INCLUDE_LABEL ${label}) endif() ctest_test(BUILD "${build_dir}" ${_include_label} PARALLEL_LEVEL ${TESTING_PARALLEL_LEVEL} EXCLUDE ${TEST_TO_EXCLUDE_REGEX} RETURN_VALUE res ) ctest_submit(PARTS Test RETRY_DELAY 3 RETRY_COUNT 3) if(res) math(EXPR test_errors "${test_errors} + 1") set(test_errors ${test_errors} PARENT_SCOPE) endif() if(ARG3) set(WITH_COVERAGE ${ARG3}) endif() if(ARG4) set(WITH_MEMCHECK ${ARG4}) endif() if(WITH_COVERAGE AND CTEST_COVERAGE_COMMAND) message("----------- [ Coverage ${label} ] -----------") ctest_coverage(BUILD "${build_dir}" LABELS ${label}) ctest_submit(PARTS Coverage RETRY_DELAY 3 RETRY_COUNT 3) endif() if(WITH_MEMCHECK AND CTEST_MEMORYCHECK_COMMAND) if(NOT CTEST_MEMORYCHECK_SUPPRESSIONS_FILE) if(EXISTS "${CTEST_SOURCE_DIRECTORY}/CMake/valgrind.supp") set(CTEST_MEMORYCHECK_SUPPRESSIONS_FILE "${CTEST_SOURCE_DIRECTORY}/CMake/valgrind.supp") endif() endif() if(NOT CTEST_MEMORYCHECK_COMMAND_OPTIONS) set(CTEST_MEMORYCHECK_COMMAND_OPTIONS "-q --tool=memcheck --leak-check=yes --show-reachable=no --show-possibly-lost=no --workaround-gcc296-bugs=yes --num-callers=50") endif() ctest_memcheck(BUILD "${build_dir}" INCLUDE_LABEL ${label}) ctest_submit(PARTS MemCheck RETRY_DELAY 3 RETRY_COUNT 3) endif() endfunction() #--------------------------------------------------------------------- # run_ctest macro #--------------------------------------------------------------------- macro(run_ctest) set(build_warnings 0) set(build_errors 0) set(test_errors 0) ctest_start(${model}) ctest_update(SOURCE "${CTEST_CHECKOUT_DIR}" RETURN_VALUE res) if(res LESS 0) # update error math(EXPR build_errors "${build_errors} + 1") endif() set(force_build ${initial_force_build}) # Check if a forced run was requested set(cdash_remove_rerun_url ) if(CDASH_ADMIN_URL_PREFIX) - set(cdash_rerun_url "${CDASH_ADMIN_URL_PREFIX}/rerun/${CTEST_BUILD_NAME}") - set(cdash_remove_rerun_url "${CDASH_ADMIN_URL_PREFIX}/rerun/rerun.php?name=${CTEST_BUILD_NAME}&remove=1") + set(cdash_rerun_url "${CDASH_ADMIN_URL_PREFIX}/rerun/${_build_name_escaped}") + set(cdash_remove_rerun_url "${CDASH_ADMIN_URL_PREFIX}/rerun/rerun.php?name=${_build_name_escaped}&remove=1") file(DOWNLOAD "${cdash_rerun_url}" "${CTEST_BINARY_DIRECTORY}/tmp.txt" STATUS status ) list(GET status 0 error_code) file(READ "${CTEST_BINARY_DIRECTORY}/tmp.txt" rerun_content LIMIT 1) if(NOT error_code AND NOT rerun_content) set(force_build 1) endif() endif() if(COMMAND MITK_OVERRIDE_FORCE_BUILD) MITK_OVERRIDE_FORCE_BUILD(force_build) endif() # force a build if this is the first run and the build dir is empty if(NOT EXISTS "${CTEST_BINARY_DIRECTORY}/CMakeCache.txt") message("First time build - Initialize CMakeCache.txt") set(res 1) # Write initial cache. if(NOT DEFINED BUILD_TESTING) set(BUILD_TESTING ON) endif() # Write initial cache. file(WRITE "${CTEST_BINARY_DIRECTORY}/CMakeCache.txt" " CTEST_USE_LAUNCHERS:BOOL=${CTEST_USE_LAUNCHERS} CTEST_PROJECT_ADDITIONAL_TARGETS:INTERNAL=${CTEST_PROJECT_ADDITIONAL_TARGETS} BUILD_TESTING:BOOL=${BUILD_TESTING} MITK_CTEST_SCRIPT_MODE:STRING=${SCRIPT_MODE} CMAKE_BUILD_TYPE:STRING=${CTEST_BUILD_CONFIGURATION} WITH_COVERAGE:BOOL=${WITH_COVERAGE} MITK_THIRDPARTY_DOWNLOAD_PREFIX_URL:STRING=${MITK_THIRDPARTY_DOWNLOAD_PREFIX_URL} ${INITIAL_CMAKECACHE_OPTIONS} ") endif() if(res GREATER 0 OR force_build) # Clear the forced rerun request if(CDASH_ADMIN_URL_PREFIX AND cdash_remove_rerun_url) file(DOWNLOAD "${cdash_remove_rerun_url}" "${CTEST_BINARY_DIRECTORY}/tmp.txt") file(REMOVE "${CTEST_BINARY_DIRECTORY}/tmp.txt") endif() if(CTEST_PROJECT_NAME_SUPERBUILD) set(ctest_project_name_orig ${CTEST_PROJECT_NAME}) set(CTEST_PROJECT_NAME ${CTEST_PROJECT_NAME_SUPERBUILD}) endif() message("----------- [ Configure SuperBuild ] -----------") set_property(GLOBAL PROPERTY SubProject SuperBuild) set_property(GLOBAL PROPERTY Label SuperBuild) ctest_configure(BUILD "${CTEST_BINARY_DIRECTORY}" RETURN_VALUE res OPTIONS "${SUPERBUILD_CONFIG_OPTIONS}") if(res) math(EXPR build_errors "${build_errors} + 1") endif() # Project.xml is generated during the superbuild configure step ctest_submit(FILES "${CTEST_BINARY_DIRECTORY}/Project.xml" RETRY_DELAY 3 RETRY_COUNT 3) ctest_read_custom_files("${CTEST_BINARY_DIRECTORY}") ctest_submit(PARTS Configure RETRY_DELAY 3 RETRY_COUNT 3) # submit the update results *after* the submitting the Configure info, # otherwise CDash is somehow confused and cannot add the update info # to the superbuild project ctest_submit(PARTS Update RETRY_DELAY 3 RETRY_COUNT 3) # To get CTEST_PROJECT_SUBPROJECTS and CTEST_PROJECT_EXTERNALS definition include("${CTEST_BINARY_DIRECTORY}/CTestConfigSubProject.cmake") # Build top level (either all or the supplied targets at # superbuild level if(SUPERBUILD_TARGETS AND NOT build_errors) foreach(superbuild_target ${SUPERBUILD_TARGETS}) message("----------- [ Build ${superbuild_target} - SuperBuild ] -----------") func_build_target(${superbuild_target} "${CTEST_BINARY_DIRECTORY}") # runs only tests that have a LABELS property matching "SuperBuild" func_test("SuperBuild" "${CTEST_BINARY_DIRECTORY}") endforeach() # HACK Unfortunately ctest_coverage ignores the build argument, back-up the original dirs file(READ "${CTEST_BINARY_DIRECTORY}/CMakeFiles/TargetDirectories.txt" old_coverage_dirs) # explicitly build requested external projects as subprojects foreach(external_project_with_build_dir ${CTEST_PROJECT_EXTERNALS}) string(REPLACE "^^" ";" external_project_with_build_dir_list "${external_project_with_build_dir}") list(GET external_project_with_build_dir_list 0 external_project_name) list(GET external_project_with_build_dir_list 1 external_project_builddir) set_property(GLOBAL PROPERTY SubProject ${external_project_name}) set_property(GLOBAL PROPERTY Label ${external_project_name}) message("----------- [ Build ${external_project_name} ] -----------") func_build_target("${external_project_name}" "${CTEST_BINARY_DIRECTORY}") if(NOT build_errors) # HACK Unfortunately ctest_coverage ignores the build argument, try to force it... file(READ "${CTEST_BINARY_DIRECTORY}/${external_project_builddir}/CMakeFiles/TargetDirectories.txt" mitk_build_coverage_dirs) file(APPEND "${CTEST_BINARY_DIRECTORY}/CMakeFiles/TargetDirectories.txt" "${mitk_build_coverage_dirs}") message("----------- [ Test ${external_project_name} ] -----------") # runs only tests that have a LABELS property matching "${external_project_name}" func_test(${external_project_name} "${CTEST_BINARY_DIRECTORY}/${external_project_builddir}") # restore old coverage dirs file(WRITE "${CTEST_BINARY_DIRECTORY}/CMakeFiles/TargetDirectories.txt" "${old_coverage_dirs}") endif() endforeach() # switch back to SuperBuild label set_property(GLOBAL PROPERTY SubProject SuperBuild) set_property(GLOBAL PROPERTY Label SuperBuild) message("----------- [ Finish SuperBuild ] -----------") else() message("----------- [ Build SuperBuild ] -----------") endif() if(NOT build_errors) # build everything at superbuild level which has not yet been built func_build_target("" "${CTEST_BINARY_DIRECTORY}") endif() # runs only tests that have a LABELS property matching "SuperBuild" #func_test("SuperBuild" "${CTEST_BINARY_DIRECTORY}") set(build_dir "${CTEST_BINARY_DIRECTORY}/${PROJECT_BUILD_DIR}") if(CTEST_PROJECT_NAME_SUPERBUILD) set(CTEST_PROJECT_NAME ${ctest_project_name_orig}) endif() message("----------- [ Configure ${build_dir} ] -----------") # Configure target ctest_configure(BUILD "${build_dir}" OPTIONS "-DCTEST_USE_LAUNCHERS=${CTEST_USE_LAUNCHERS}" RETURN_VALUE res ) ctest_read_custom_files("${CTEST_BINARY_DIRECTORY}") ctest_submit(PARTS Configure RETRY_DELAY 3 RETRY_COUNT 3) if(res) math(EXPR build_errors "${build_errors} + 1") endif() foreach(subproject ${CTEST_PROJECT_SUBPROJECTS}) if(NOT build_errors) set_property(GLOBAL PROPERTY SubProject ${subproject}) set_property(GLOBAL PROPERTY Label ${subproject}) if(subproject MATCHES "Unlabeled") message("----------- [ Build All (Unlabeled) ] -----------") # Build target func_build_target("" "${build_dir}") else() message("----------- [ Build ${subproject} ] -----------") # Build target func_build_target(${subproject} "${build_dir}") endif() endif() endforeach() if(NOT build_errors) # HACK Unfortunately ctest_coverage ignores the build argument, try to force it... file(READ ${build_dir}/CMakeFiles/TargetDirectories.txt mitk_build_coverage_dirs) file(APPEND "${CTEST_BINARY_DIRECTORY}/CMakeFiles/TargetDirectories.txt" "${mitk_build_coverage_dirs}") foreach(subproject ${CTEST_PROJECT_SUBPROJECTS}) set_property(GLOBAL PROPERTY SubProject ${subproject}) set_property(GLOBAL PROPERTY Label ${subproject}) message("----------- [ Test ${subproject} ] -----------") # runs only tests that have a LABELS property matching "${subproject}" func_test(${subproject} "${build_dir}") endforeach() endif() # Build any additional target which is not build by "all" # i.e. the "package" target if(CTEST_PROJECT_ADDITIONAL_TARGETS AND NOT build_errors) foreach(additional_target ${CTEST_PROJECT_ADDITIONAL_TARGETS}) set_property(GLOBAL PROPERTY SubProject ${additional_target}) set_property(GLOBAL PROPERTY Label ${additional_target}) message("----------- [ Build ${additional_target} ] -----------") func_build_target(${additional_target} "${build_dir}") message("----------- [ Test ${additional_target} ] -----------") # runs only tests that have a LABELS property matching "${subproject}" func_test(${additional_target} "${build_dir}") endforeach() endif() if(WITH_DOCUMENTATION) message("----------- [ Build Documentation ] -----------") set(ctest_use_launchers_orig ${CTEST_USE_LAUNCHERS}) set(CTEST_USE_LAUNCHERS 0) # Build Documentation target set_property(GLOBAL PROPERTY SubProject Documentation) set_property(GLOBAL PROPERTY Label Documentation) func_build_target("doc" "${build_dir}") set(CTEST_USE_LAUNCHERS ${ctest_use_launchers_orig}) endif() set_property(GLOBAL PROPERTY SubProject SuperBuild) set_property(GLOBAL PROPERTY Label SuperBuild) # Global coverage ... if(WITH_COVERAGE AND CTEST_COVERAGE_COMMAND) message("----------- [ Global coverage ] -----------") ctest_coverage(BUILD "${build_dir}" APPEND) ctest_submit(PARTS Coverage RETRY_DELAY 3 RETRY_COUNT 3) endif() # Global dynamic analysis ... if(WITH_MEMCHECK AND CTEST_MEMORYCHECK_COMMAND) message("----------- [ Global memcheck ] -----------") ctest_memcheck(BUILD "${build_dir}") ctest_submit(PARTS MemCheck RETRY_DELAY 3 RETRY_COUNT 3) endif() # Note should be at the end ctest_submit(PARTS Notes RETRY_DELAY 3 RETRY_COUNT 3) # Send status to the "CDash Web Admin" if(CDASH_ADMIN_URL_PREFIX) set(cdash_admin_url "${CDASH_ADMIN_URL_PREFIX}/cdashadmin-web/index.php?pw=4da12ca9c06d46d3171d7f73974c900f") string(REGEX REPLACE ".*\\?project=(.*)&?" "\\1" _ctest_project "${CTEST_DROP_LOCATION}") - string(REPLACE " " "%20" _build_name_escaped "${CTEST_BUILD_NAME}") file(DOWNLOAD "${cdash_admin_url}&action=submit&name=${_build_name_escaped}&hasTestErrors=${test_errors}&hasBuildErrors=${build_errors}&hasBuildWarnings=${build_warnings}&ctestDropSite=${CTEST_DROP_SITE}&ctestProject=${_ctest_project}" "${CTEST_BINARY_DIRECTORY}/cdashadmin.txt" STATUS status ) list(GET status 0 error_code) list(GET status 1 error_msg) if(error_code) message(FATAL_ERROR "error: Failed to communicate with cdashadmin-web - ${error_msg}") endif() endif() endif() # Clear the CTEST_CHECKOUT_COMMAND variable to prevent continuous clients # to try to checkout again set(CTEST_CHECKOUT_COMMAND "") endmacro() if(SCRIPT_MODE STREQUAL "continuous") while(1) run_ctest() # Loop no faster than once every 5 minutes message("Wait for 5 minutes ...") ctest_sleep(300) endwhile() else() run_ctest() endif() diff --git a/CMake/MITKDashboardSetup.cmake b/CMake/MITKDashboardSetup.cmake index c32e91b87a..33d4415c84 100644 --- a/CMake/MITKDashboardSetup.cmake +++ b/CMake/MITKDashboardSetup.cmake @@ -1,208 +1,154 @@ # This file is intended to be included at the end of a custom MITKDashboardScript.TEMPLATE.cmake file list(APPEND CTEST_NOTES_FILES "${CTEST_SCRIPT_DIRECTORY}/${CTEST_SCRIPT_NAME}") # # Automatically determined properties # set(MY_OPERATING_SYSTEM ) if(UNIX) # Download a utility script set(url "http://mitk.org/git/?p=MITK.git;a=blob_plain;f=CMake/mitkDetectOS.sh;hb=${hb}") set(dest "${CTEST_SCRIPT_DIRECTORY}/mitkDetectOS.sh") downloadFile("${url}" "${dest}") execute_process(COMMAND sh "${dest}" RESULT_VARIABLE _result OUTPUT_VARIABLE _out OUTPUT_STRIP_TRAILING_WHITESPACE) if(NOT _result) set(MY_OPERATING_SYSTEM "${_out}") endif() endif() if(NOT MY_OPERATING_SYSTEM) set(MY_OPERATING_SYSTEM "${CMAKE_HOST_SYSTEM}") # Windows 7, Linux-2.6.32, Darwin... endif() site_name(CTEST_SITE) if(NOT DEFINED MITK_USE_QT) set(MITK_USE_QT 1) endif() if(MITK_USE_QT) if(NOT QT_QMAKE_EXECUTABLE) find_program(QT_QMAKE_EXECUTABLE NAMES qmake qmake-qt4 HINTS ${QT_BINARY_DIR}) endif() execute_process(COMMAND ${QT_QMAKE_EXECUTABLE} --version OUTPUT_VARIABLE MY_QT_VERSION RESULT_VARIABLE qmake_error) if(qmake_error) message(FATAL_ERROR "Error when executing ${QT_QMAKE_EXECUTABLE} --version\n${qmake_error}") endif() string(REGEX REPLACE ".*Qt version ([0-9.]+) .*" "\\1" MY_QT_VERSION ${MY_QT_VERSION}) endif() # # Project specific properties # if(NOT CTEST_BUILD_NAME) if(MITK_USE_QT) set(CTEST_BUILD_NAME "${MY_OPERATING_SYSTEM} ${MY_COMPILER} Qt${MY_QT_VERSION} ${CTEST_BUILD_CONFIGURATION}") else() set(CTEST_BUILD_NAME "${MY_OPERATING_SYSTEM} ${MY_COMPILER} ${CTEST_BUILD_CONFIGURATION}") endif() set(CTEST_BUILD_NAME "${CTEST_BUILD_NAME}${CTEST_BUILD_NAME_SUFFIX}") endif() set(PROJECT_BUILD_DIR "MITK-build") set(CTEST_PATH "$ENV{PATH}") if(WIN32) set(ANN_BINARY_DIR "${CTEST_BINARY_DIRECTORY}/ANN-build/${CTEST_BUILD_CONFIGURATION}") set(CPPUNIT_BINARY_DIR "${CTEST_BINARY_DIRECTORY}/CppUnit-build/${CTEST_BUILD_CONFIGURATION}") set(GLUT_BINARY_DIR "${CTEST_BINARY_DIRECTORY}/GLUT-build/${CTEST_BUILD_CONFIGURATION}") set(GLEW_BINARY_DIR "${CTEST_BINARY_DIRECTORY}/GLEW-build/${CTEST_BUILD_CONFIGURATION}") set(TINYXML_BINARY_DIR "${CTEST_BINARY_DIRECTORY}/tinyxml-build/${CTEST_BUILD_CONFIGURATION}") set(QWT_BINARY_DIR "${CTEST_BINARY_DIRECTORY}/Qwt-build/${CTEST_BUILD_CONFIGURATION}") - set(QXT_BINARY_DIR "${CTEST_BINARY_DIRECTORY}/Qxt-build/${CTEST_BUILD_CONFIGURATION}") set(VTK_BINARY_DIR "${CTEST_BINARY_DIRECTORY}/VTK-build/bin/${CTEST_BUILD_CONFIGURATION}") set(ACVD_BINARY_DIR "${CTEST_BINARY_DIRECTORY}/ACVD-build/bin/${CTEST_BUILD_CONFIGURATION}") set(ITK_BINARY_DIR "${CTEST_BINARY_DIRECTORY}/ITK-build/bin/${CTEST_BUILD_CONFIGURATION}") set(BOOST_BINARY_DIR "${CTEST_BINARY_DIRECTORY}/Boost-install/lib") set(GDCM_BINARY_DIR "${CTEST_BINARY_DIRECTORY}/GDCM-build/bin/${CTEST_BUILD_CONFIGURATION}") set(DCMTK_BINARY_DIR "${CTEST_BINARY_DIRECTORY}/DCMTK-install/bin/${CTEST_BUILD_CONFIGURATION}") set(OPENCV_BINARY_DIR "${CTEST_BINARY_DIRECTORY}/OpenCV-build/bin/${CTEST_BUILD_CONFIGURATION}") set(POCO_BINARY_DIR "${CTEST_BINARY_DIRECTORY}/Poco-install/lib") set(SOFA_BINARY_DIR "${CTEST_BINARY_DIRECTORY}/SOFA-build/bin/${CTEST_BUILD_CONFIGURATION}") set(BLUEBERRY_OSGI_DIR "${CTEST_BINARY_DIRECTORY}/MITK-build/bin/BlueBerry/org.blueberry.osgi/bin/${CTEST_BUILD_CONFIGURATION}") - set(CTEST_PATH "${CTEST_PATH};${CPPUNIT_BINARY_DIR};${QT_BINARY_DIR};${VTK_BINARY_DIR};${ANN_BINARY_DIR};${GLUT_BINARY_DIR};${GLEW_BINARY_DIR};${TINYXML_BINARY_DIR};${QWT_BINARY_DIR};${QXT_BINARY_DIR};${ACVD_BINARY_DIR};${ITK_BINARY_DIR};${BOOST_BINARY_DIR};${GDCM_BINARY_DIR};${DCMTK_BINARY_DIR};${OPENCV_BINARY_DIR};${POCO_BINARY_DIR};${SOFA_BINARY_DIR};${BLUEBERRY_OSGI_DIR}") + set(CTEST_PATH "${CTEST_PATH};${CPPUNIT_BINARY_DIR};${QT_BINARY_DIR};${VTK_BINARY_DIR};${ANN_BINARY_DIR};${GLUT_BINARY_DIR};${GLEW_BINARY_DIR};${TINYXML_BINARY_DIR};${QWT_BINARY_DIR};${ACVD_BINARY_DIR};${ITK_BINARY_DIR};${BOOST_BINARY_DIR};${GDCM_BINARY_DIR};${DCMTK_BINARY_DIR};${OPENCV_BINARY_DIR};${POCO_BINARY_DIR};${SOFA_BINARY_DIR};${BLUEBERRY_OSGI_DIR}") endif() set(ENV{PATH} "${CTEST_PATH}") set(SUPERBUILD_TARGETS "") # If the dashscript doesn't define a GIT_REPOSITORY variable, let's define it here. if(NOT DEFINED GIT_REPOSITORY OR GIT_REPOSITORY STREQUAL "") set(GIT_REPOSITORY "http://git.mitk.org/MITK.git") endif() # # Display build info # message("Site name: ${CTEST_SITE}") message("Build name: ${CTEST_BUILD_NAME}") message("Script Mode: ${SCRIPT_MODE}") message("Coverage: ${WITH_COVERAGE}, MemCheck: ${WITH_MEMCHECK}") # # Set initial cache options # if(${CMAKE_VERSION} VERSION_GREATER "2.8.9") set(CTEST_USE_LAUNCHERS 1) set(ENV{CTEST_USE_LAUNCHERS_DEFAULT} 1) endif() # Remove this if block after all dartclients work if(DEFINED ADDITIONNAL_CMAKECACHE_OPTION) message(WARNING "Rename ADDITIONNAL to ADDITIONAL in your dartlclient script: ${CTEST_SCRIPT_DIRECTORY}/${CTEST_SCRIPT_NAME}") set(ADDITIONAL_CMAKECACHE_OPTION ${ADDITIONNAL_CMAKECACHE_OPTION}) endif() -if(NOT DEFINED MITK_USE_ACVD) - set(MITK_USE_ACVD 1) -endif() - -if(NOT DEFINED MITK_USE_Boost) - set(MITK_USE_Boost 1) -endif() - -if(NOT DEFINED MITK_USE_OpenCV) - set(MITK_USE_OpenCV 1) -endif() - -if(NOT DEFINED MITK_USE_Poco) - set(MITK_USE_Poco 1) -endif() - -if(NOT DEFINED MITK_USE_Python) - if(WIN32) - set(MITK_USE_Python FALSE) - else() - set(MITK_USE_Python TRUE) - endif() -endif() - -if(NOT DEFINED MITK_USE_SOFA) - set(MITK_USE_SOFA 1) +if(NOT DEFINED MITK_BUILD_CONFIGURATION) + set(MITK_BUILD_CONFIGURATION "All") endif() if(NOT DEFINED MITK_VTK_DEBUG_LEAKS) set(MITK_VTK_DEBUG_LEAKS 1) endif() -if(NOT DEFINED MITK_BUILD_ALL_APPS) - set(MITK_BUILD_ALL_APPS TRUE) -endif() - -if(NOT DEFINED BLUEBERRY_BUILD_ALL_PLUGINS) - set(BLUEBERRY_BUILD_ALL_PLUGINS TRUE) -endif() - -if(NOT DEFINED MITK_BUILD_ALL_PLUGINS) - set(MITK_BUILD_ALL_PLUGINS TRUE) -endif() - -if(NOT DEFINED MITK_BUILD_EXAMPLES) - set(MITK_BUILD_EXAMPLES TRUE) -endif() - -if(NOT BUILD_DiffusionMiniApps) - set(BUILD_DiffusionMiniApps TRUE) -endif() set(INITIAL_CMAKECACHE_OPTIONS " -BLUEBERRY_BUILD_ALL_PLUGINS:BOOL=${MITK_BUILD_ALL_PLUGINS} -MITK_BUILD_ALL_PLUGINS:BOOL=${MITK_BUILD_ALL_PLUGINS} -MITK_BUILD_ALL_APPS:BOOL=${MITK_BUILD_ALL_APPS} -MITK_BUILD_EXAMPLES:BOOL=${MITK_BUILD_EXAMPLES} SUPERBUILD_EXCLUDE_MITKBUILD_TARGET:BOOL=TRUE -MITK_USE_ACVD:BOOL=${MITK_USE_ACVD} -MITK_USE_Boost:BOOL=${MITK_USE_Boost} -MITK_USE_OpenCV:BOOL=${MITK_USE_OpenCV} -MITK_USE_Poco:BOOL=${MITK_USE_Poco} -MITK_USE_Python:BOOL=${MITK_USE_Python} -MITK_USE_SOFA:BOOL=${MITK_USE_SOFA} -MITK_USE_QT:BOOL=${MITK_USE_QT} +MITK_BUILD_CONFIGURATION:STRING=${MITK_BUILD_CONFIGURATION} MITK_VTK_DEBUG_LEAKS:BOOL=${MITK_VTK_DEBUG_LEAKS} ${ADDITIONAL_CMAKECACHE_OPTION} ") if(MITK_USE_QT) set(INITIAL_CMAKECACHE_OPTIONS "${INITIAL_CMAKECACHE_OPTIONS} QT_QMAKE_EXECUTABLE:FILEPATH=${QT_QMAKE_EXECUTABLE}") endif() # Write a cache file for populating the MITK initial cache (not the superbuild cache). # This can be used to provide variables which are not passed through the # superbuild process to the MITK configure step) if(MITK_INITIAL_CACHE) set(mitk_cache_file "${CTEST_SCRIPT_DIRECTORY}/mitk_initial_cache.txt") file(WRITE "${mitk_cache_file}" "${MITK_INITIAL_CACHE}") set(INITIAL_CMAKECACHE_OPTIONS "${INITIAL_CMAKECACHE_OPTIONS} MITK_INITIAL_CACHE_FILE:INTERNAL=${mitk_cache_file} ") endif() # # Download and include dashboard driver script # set(url "http://mitk.org/git/?p=MITK.git;a=blob_plain;f=CMake/MITKDashboardDriverScript.cmake;hb=${hb}") set(dest ${CTEST_SCRIPT_DIRECTORY}/${CTEST_SCRIPT_NAME}.driver) downloadFile("${url}" "${dest}") include(${dest}) diff --git a/CMake/PackageDepends/MITK_Qxt_Config.cmake b/CMake/PackageDepends/MITK_Qxt_Config.cmake deleted file mode 100644 index f0ee7c0e44..0000000000 --- a/CMake/PackageDepends/MITK_Qxt_Config.cmake +++ /dev/null @@ -1,9 +0,0 @@ -# first look for the superbuild Qxt version, pointed to by Qxt_DIR -find_package(Qxt QUIET NO_MODULE) -if(NOT Qxt_FOUND) - # now try invoking a FindQxt.cmake script - find_package(Qxt REQUIRED) -endif() - -list(APPEND ALL_LIBRARIES ${Qxt_LIBRARIES}) -list(APPEND ALL_INCLUDE_DIRECTORIES ${Qxt_INCLUDE_DIRS}) diff --git a/CMake/mitkBuildConfigurationAll.cmake b/CMake/mitkBuildConfigurationAll.cmake index 6e58614be3..ce327e5028 100644 --- a/CMake/mitkBuildConfigurationAll.cmake +++ b/CMake/mitkBuildConfigurationAll.cmake @@ -1,35 +1,37 @@ set(MITK_CONFIG_PACKAGES ) set(_package_excludes Python OpenCL SYSTEM_Boost Boost_LIBRARIES SOFA_PLUGINS SOFA_PLUGINS_DIR SUPERBUILD KWSTYLE MICRON_TRACKER OPTITRACK_TRACKER TOF_KINECT TOF_KINECTV2 TOF_MESASR4000 TOF_PMDCAMBOARD TOF_PMDCAMCUBE ) get_cmake_property(_cache_vars CACHE_VARIABLES) foreach(_cache_var ${_cache_vars}) string(REGEX REPLACE "MITK_USE_(.+)" "\\1" _package "${_cache_var}") if(_package AND NOT _package STREQUAL _cache_var) list(FIND _package_excludes ${_package} _index) if(_index EQUAL -1) list(APPEND MITK_CONFIG_PACKAGES ${_package}) endif() endif() endforeach() set(MITK_BUILD_ALL_APPS ON CACHE BOOL "Build all MITK applications" FORCE) set(MITK_BUILD_ALL_PLUGINS ON CACHE BOOL "Build all MITK plugins" FORCE) set(MITK_BUILD_EXAMPLES ON CACHE BOOL "Build the MITK examples" FORCE) +set(BLUEBERRY_BUILD_ALL_PLUGINS ON CACHE BOOL "Build all BlueBerry plugins" FORCE) +set(BUILD_DiffusionMiniApps ON CACHE BOOL "Build MITK Diffusion MiniApps" FORCE) diff --git a/CMake/mitkBuildConfigurationDefault.cmake b/CMake/mitkBuildConfigurationDefault.cmake index 1b59e1adbf..c0deb791b6 100644 --- a/CMake/mitkBuildConfigurationDefault.cmake +++ b/CMake/mitkBuildConfigurationDefault.cmake @@ -1,22 +1,23 @@ set(MITK_CONFIG_PACKAGES + ACVD QT BLUEBERRY ) set(MITK_CONFIG_PLUGINS org.mitk.gui.qt.datamanager org.mitk.gui.qt.stdmultiwidgeteditor org.mitk.gui.qt.dicom org.mitk.gui.qt.imagenavigator org.mitk.gui.qt.measurementtoolbox org.mitk.gui.qt.properties org.mitk.gui.qt.segmentation org.mitk.gui.qt.volumevisualization org.mitk.planarfigure org.mitk.gui.qt.moviemaker org.mitk.gui.qt.pointsetinteraction org.mitk.gui.qt.registration org.mitk.gui.qt.remeshing org.mitk.gui.qt.viewnavigator org.mitk.gui.qt.imagecropper ) diff --git a/CMake/mitkBuildConfigurationWorkbenchRelease.cmake b/CMake/mitkBuildConfigurationWorkbenchRelease.cmake new file mode 100644 index 0000000000..d354b0bb40 --- /dev/null +++ b/CMake/mitkBuildConfigurationWorkbenchRelease.cmake @@ -0,0 +1,3 @@ +include(${CMAKE_CURRENT_LIST_DIR}/mitkBuildConfigurationDefault.cmake) + +set(MITK_VTK_DEBUG_LEAKS OFF CACHE BOOL "Enable VTK Debug Leaks" FORCE) diff --git a/CMake/mitkFunctionGetLibrarySearchPaths.cmake b/CMake/mitkFunctionGetLibrarySearchPaths.cmake index 60585b675e..8ca66499b5 100644 --- a/CMake/mitkFunctionGetLibrarySearchPaths.cmake +++ b/CMake/mitkFunctionGetLibrarySearchPaths.cmake @@ -1,177 +1,174 @@ function(mitkFunctionGetLibrarySearchPaths search_path intermediate_dir) set(_dir_candidates ${MITK_VTK_LIBRARY_DIRS} ${MITK_ITK_LIBRARY_DIRS} "${MITK_BINARY_DIR}/bin" "${MITK_BINARY_DIR}/bin/plugins") # Determine the Qt4/5 library installation prefix set(_qmake_location ) if(MITK_USE_Qt4) set(_qmake_location ${QT_QMAKE_EXECUTABLE}) elseif(MITK_USE_Qt5 AND TARGET ${Qt5Core_QMAKE_EXECUTABLE}) get_property(_qmake_location TARGET ${Qt5Core_QMAKE_EXECUTABLE} PROPERTY IMPORT_LOCATION) endif() if(_qmake_location) if(NOT _qt_install_libs) if(WIN32) execute_process(COMMAND ${_qmake_location} -query QT_INSTALL_BINS OUTPUT_VARIABLE _qt_install_libs OUTPUT_STRIP_TRAILING_WHITESPACE) else() execute_process(COMMAND ${_qmake_location} -query QT_INSTALL_LIBS OUTPUT_VARIABLE _qt_install_libs OUTPUT_STRIP_TRAILING_WHITESPACE) endif() file(TO_CMAKE_PATH "${_qt_install_libs}" _qt_install_libs) set(_qt_install_libs ${_qt_install_libs} CACHE INTERNAL "Qt library installation prefix" FORCE) endif() if(_qt_install_libs) list(APPEND _dir_candidates ${_qt_install_libs}) endif() elseif(MITK_USE_QT) message(WARNING "The qmake executable could not be found.") endif() get_property(_additional_paths GLOBAL PROPERTY MITK_ADDITIONAL_LIBRARY_SEARCH_PATHS) if(_additional_paths) list(APPEND _dir_candidates ${_additional_paths}) endif() if(VTK_DIR) find_package(VTK QUIET) if(VTK_RUNTIME_LIBRARY_DIRS) list(APPEND _dir_candidates ${VTK_RUNTIME_LIBRARY_DIRS}) endif() endif() # The code below is sub-optimal. It makes assumptions about # the structure of the build directories, pointed to by # the *_DIR variables. Instead, we should rely on package # specific "LIBRARY_DIRS" variables, if they exist. if(WIN32) if(DCMTK_DIR) list(APPEND _dir_candidates "${DCMTK_DIR}/bin") endif() if(OpenCV_DIR) list(APPEND _dir_candidates "${OpenCV_DIR}/bin") endif() if(SOFA_DIR) list(APPEND _dir_candidates "${SOFA_DIR}/bin") endif() if(Python_DIR) list(APPEND _dir_candidates "${Python_DIR}/bin") endif() if(SimpleITK_DIR) list(APPEND _dir_candidates "${SimpleITK_DIR}/bin") endif() list(APPEND _dir_candidates "${ITK_DIR}/bin") else() if(DCMTK_DIR) list(APPEND _dir_candidates "${DCMTK_DIR}/lib") endif() if(OpenCV_DIR) list(APPEND _dir_candidates "${OpenCV_DIR}/lib") endif() if(SOFA_DIR) list(APPEND _dir_candidates "${SOFA_DIR}/lib") endif() if(Python_DIR) list(APPEND _dir_candidates "${Python_DIR}/lib") endif() if(SimpleITK_DIR) list(APPEND _dir_candidates "${SimpleITK_DIR}/lib") endif() list(APPEND _dir_candidates "${ITK_DIR}/lib") endif() if(MITK_USE_Python AND CTK_PYTHONQT_INSTALL_DIR) list(APPEND _dir_candidates "${CTK_PYTHONQT_INSTALL_DIR}/bin") endif() if(MITK_USE_Boost AND MITK_USE_Boost_LIBRARIES AND NOT MITK_USE_SYSTEM_Boost) list(APPEND _dir_candidates "${Boost_LIBRARY_DIR}") endif() if(ACVD_DIR) list(APPEND _dir_candidates "${ACVD_DIR}/bin") endif() if(ANN_DIR) list(APPEND _dir_candidates "${ANN_DIR}") endif() if(CppUnit_DIR) list(APPEND _dir_candidates "${CppUnit_DIR}") endif() if(GLUT_DIR) list(APPEND _dir_candidates "${GLUT_DIR}") endif() if(GDCM_DIR) list(APPEND _dir_candidates "${GDCM_DIR}/bin") endif() if(GLEW_DIR) list(APPEND _dir_candidates "${GLEW_DIR}") endif() if(tinyxml_DIR) list(APPEND _dir_candidates "${tinyxml_DIR}") endif() if(Poco_DIR) list(APPEND _dir_candidates "${Poco_DIR}/lib") endif() if(Qwt_DIR) list(APPEND _dir_candidates "${Qwt_DIR}") endif() - if(Qxt_DIR) - list(APPEND _dir_candidates "${Qxt_DIR}") - endif() if(MITK_USE_TOF_PMDO3 OR MITK_USE_TOF_PMDCAMCUBE OR MITK_USE_TOF_PMDCAMBOARD) list(APPEND _dir_candidates "${MITK_PMD_SDK_DIR}/plugins" "${MITK_PMD_SDK_DIR}/bin") endif() if(MITK_USE_CTK) list(APPEND _dir_candidates "${CTK_LIBRARY_DIRS}") foreach(_ctk_library ${CTK_LIBRARIES}) if(${_ctk_library}_LIBRARY_DIRS) list(APPEND _dir_candidates "${${_ctk_library}_LIBRARY_DIRS}") endif() endforeach() endif() if(MITK_USE_BLUEBERRY) if(DEFINED CTK_PLUGIN_RUNTIME_OUTPUT_DIRECTORY) if(IS_ABSOLUTE "${CTK_PLUGIN_RUNTIME_OUTPUT_DIRECTORY}") list(APPEND _dir_candidates "${CTK_PLUGIN_RUNTIME_OUTPUT_DIRECTORY}") else() list(APPEND _dir_candidates "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${CTK_PLUGIN_RUNTIME_OUTPUT_DIRECTORY}") endif() endif() endif() if(MITK_LIBRARY_DIRS) list(APPEND _dir_candidates ${MITK_LIBRARY_DIRS}) endif() list(REMOVE_DUPLICATES _dir_candidates) set(_search_dirs ) foreach(_dir ${_dir_candidates}) if(EXISTS "${_dir}/${intermediate_dir}") list(APPEND _search_dirs "${_dir}/${intermediate_dir}") else() list(APPEND _search_dirs "${_dir}") endif() endforeach() # Special handling for "internal" search dirs. The intermediate directory # might not have been created yet, so we can't check for its existence. # Hence we just add it for Windows without checking. set(_internal_search_dirs "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}" "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/plugins") if(WIN32) foreach(_dir ${_internal_search_dirs}) set(_search_dirs "${_dir}/${intermediate_dir}" ${_search_dirs}) endforeach() else() set(_search_dirs ${_internal_search_dirs} ${_search_dirs}) endif() list(REMOVE_DUPLICATES _search_dirs) set(${search_path} ${_search_dirs} PARENT_SCOPE) endfunction() diff --git a/CMake/mitkSetupVariables.cmake b/CMake/mitkSetupVariables.cmake index e4024464d4..e17a239081 100644 --- a/CMake/mitkSetupVariables.cmake +++ b/CMake/mitkSetupVariables.cmake @@ -1,106 +1,106 @@ #----------------------------------- # Basic MITK CMake variables #----------------------------------- # MITK_VERSION set(MITK_VERSION_MAJOR "2014") -set(MITK_VERSION_MINOR "03") +set(MITK_VERSION_MINOR "10") set(MITK_VERSION_PATCH "99") set(MITK_VERSION_STRING "${MITK_VERSION_MAJOR}.${MITK_VERSION_MINOR}.${MITK_VERSION_PATCH}") if(MITK_VERSION_PATCH STREQUAL "99") set(MITK_VERSION_STRING "${MITK_VERSION_STRING}-${MITK_REVISION_SHORTID}") endif() # Needed early on for redirecting the BlueBerry documentation output dir set(MITK_DOXYGEN_OUTPUT_DIR ${PROJECT_BINARY_DIR}/Documentation/Doxygen CACHE PATH "Output directory for doxygen generated documentation." ) if(NOT UNIX AND NOT MINGW) set(MITK_WIN32_FORCE_STATIC "STATIC" CACHE INTERNAL "Use this variable to always build static libraries on non-unix platforms") endif() if(MITK_BUILD_ALL_PLUGINS) set(MITK_BUILD_ALL_PLUGINS_OPTION "FORCE_BUILD_ALL") endif() #----------------------------------- # Find external dependencies #----------------------------------- # Qt support if(MITK_USE_QT) if(DESIRED_QT_VERSION MATCHES 4) find_package(Qt4 ${MITK_QT4_MINIMUM_VERSION} REQUIRED) elseif(DESIRED_QT_VERSION MATCHES 5) find_package(Qt5Core ${MITK_QT5_MINIMUM_VERSION} REQUIRED) # at least Core required endif() endif() #----------------------------------- # Configuration of module system #----------------------------------- set(MODULES_CONF_DIRNAME modulesConf) set(MODULES_CONF_DIRS ${MITK_BINARY_DIR}/${MODULES_CONF_DIRNAME}) # Configure module naming conventions set(MITK_MODULE_NAME_REGEX_MATCH "^[A-Z].*$") set(MITK_MODULE_NAME_REGEX_NOT_MATCH "^[Mm][Ii][Tt][Kk].*$") set(MITK_MODULE_NAME_PREFIX "Mitk") set(MITK_MODULE_NAME_DEFAULTS_TO_DIRECTORY_NAME 1) #----------------------------------- # Configuration of the buid-in MITK pixel types #----------------------------------- # create a list of types for template instantiations of itk image access functions function(_create_type_seq TYPES seq_var seqdim_var) set(_seq ) set(_seq_dim ) string(REPLACE "," ";" _pixeltypes "${TYPES}") foreach(_pixeltype ${_pixeltypes}) set(_seq "${_seq}(${_pixeltype})") set(_seq_dim "${_seq_dim}((${_pixeltype},dim))") endforeach() set(${seq_var} "${_seq}" PARENT_SCOPE) set(${seqdim_var} "${_seq_dim}" PARENT_SCOPE) endfunction() set(MITK_ACCESSBYITK_PIXEL_TYPES ) set(MITK_ACCESSBYITK_PIXEL_TYPES_SEQ ) set(MITK_ACCESSBYITK_TYPES_DIMN_SEQ ) # concatenate only the simple pixel types to the MITK_ACCESSBYITK_PIXEL_TYPE_SEQ list # see Bug 12682 for detailed information foreach(_type INTEGRAL FLOATING) set(_typelist "${MITK_ACCESSBYITK_${_type}_PIXEL_TYPES}") if(_typelist) if(MITK_ACCESSBYITK_PIXEL_TYPES) set(MITK_ACCESSBYITK_PIXEL_TYPES "${MITK_ACCESSBYITK_PIXEL_TYPES},${_typelist}") else() set(MITK_ACCESSBYITK_PIXEL_TYPES "${_typelist}") endif() endif() _create_type_seq("${_typelist}" MITK_ACCESSBYITK_${_type}_PIXEL_TYPES_SEQ MITK_ACCESSBYITK_${_type}_TYPES_DIMN_SEQ) set(MITK_ACCESSBYITK_PIXEL_TYPES_SEQ "${MITK_ACCESSBYITK_PIXEL_TYPES_SEQ}${MITK_ACCESSBYITK_${_type}_PIXEL_TYPES_SEQ}") set(MITK_ACCESSBYITK_TYPES_DIMN_SEQ "${MITK_ACCESSBYITK_TYPES_DIMN_SEQ}${MITK_ACCESSBYITK_${_type}_TYPES_DIMN_SEQ}") endforeach() # separate processing of the COMPOSITE list to avoid its concatenation to the global list _create_type_seq(${MITK_ACCESSBYITK_COMPOSITE_PIXEL_TYPES} MITK_ACCESSBYITK_COMPOSITE_PIXEL_TYPES_SEQ MITK_ACCESSBYITK_COMPOSITE_TYPES_DIMN_SEQ) # separate processing of the VECTOR list to avoid its concatenation to the global list _create_type_seq(${MITK_ACCESSBYITK_VECTOR_PIXEL_TYPES} MITK_ACCESSBYITK_VECTOR_PIXEL_TYPES_SEQ MITK_ACCESSBYITK_VECTOR_TYPES_DIMN_SEQ) set(MITK_ACCESSBYITK_DIMENSIONS_SEQ ) string(REPLACE "," ";" _dimensions "${MITK_ACCESSBYITK_DIMENSIONS}") foreach(_dimension ${_dimensions}) set(MITK_ACCESSBYITK_DIMENSIONS_SEQ "${MITK_ACCESSBYITK_DIMENSIONS_SEQ}(${_dimension})") endforeach() diff --git a/CMake/mitkTestPluginGenerator.cmake b/CMake/mitkTestPluginGenerator.cmake index 001229ec94..971860cbcf 100644 --- a/CMake/mitkTestPluginGenerator.cmake +++ b/CMake/mitkTestPluginGenerator.cmake @@ -1,110 +1,113 @@ if(BUILD_TESTING) set(proj GP) # Means GenerateProject (use a short name due to Windows limitations) set(test_project_out_dir "${MITK_BINARY_DIR}") set(test_project_source_dir "${MITK_BINARY_DIR}/${proj}") set(test_project_binary_dir "${MITK_BINARY_DIR}/${proj}-bin") add_test(NAME mitkPluginGeneratorCleanTest COMMAND ${CMAKE_COMMAND} -E remove_directory "${test_project_source_dir}" ) set_tests_properties(mitkPluginGeneratorCleanTest PROPERTIES LABELS "MITK;BlueBerry") add_test(NAME mitkPluginGeneratorCleanTest2 COMMAND ${CMAKE_COMMAND} -E remove_directory "${test_project_binary_dir}" ) set_tests_properties(mitkPluginGeneratorCleanTest2 PROPERTIES LABELS "MITK;BlueBerry") add_test(NAME mitkPluginGeneratorCleanTest3 COMMAND ${CMAKE_COMMAND} -E make_directory "${test_project_binary_dir}" ) set_tests_properties(mitkPluginGeneratorCleanTest3 PROPERTIES DEPENDS mitkPluginGeneratorCleanTest2 LABELS "MITK;BlueBerry") add_test(NAME mitkPluginGeneratorCreateTest COMMAND ${exec_target} --project-name "${proj}" --project-app-name "TestApp" -ps org.test.plugin -pn "Test Plugin" -vn "Test View" -o ${test_project_out_dir} -y -n ) set_tests_properties(mitkPluginGeneratorCreateTest PROPERTIES DEPENDS "${exec_target};mitkPluginGeneratorCleanTest;mitkPluginGeneratorCleanTest3" LABELS "MITK;BlueBerry") set(configure_options -DMITK_DIR:PATH=${MITK_BINARY_DIR} -DCMAKE_C_COMPILER:STRING=${CMAKE_C_COMPILER} -DCMAKE_CXX_COMPILER:STRING=${CMAKE_CXX_COMPILER} + -DCMAKE_OSX_SYSROOT:PATH=${CMAKE_OSX_SYSROOT} + -DCMAKE_OSX_DEPLOYMENT_TARGET:STRING=${CMAKE_OSX_DEPLOYMENT_TARGET} + -DCMAKE_OSX_ARCHITECTURES:STRING=${CMAKE_OSX_ARCHITECTURES} -G${CMAKE_GENERATOR} ) if(MITK_USE_Qt4) list(APPEND configure_options -DQT_QMAKE_EXECUTABLE:FILEPATH=${QT_QMAKE_EXECUTABLE}) endif() if(CMAKE_PREFIX_PATH) list(APPEND configure_options -DCMAKE_PREFIX_PATH:PATH=${CMAKE_PREFIX_PATH}) endif() if(CMAKE_CONFIGURATION_TYPES) foreach(config ${CMAKE_CONFIGURATION_TYPES}) add_test(NAME mitkPluginGeneratorConfigureTest-${config} CONFIGURATIONS ${config} WORKING_DIRECTORY "${test_project_binary_dir}" COMMAND ${CMAKE_COMMAND} ${configure_options} "${test_project_source_dir}") set_tests_properties(mitkPluginGeneratorConfigureTest-${config} PROPERTIES DEPENDS mitkPluginGeneratorCreateTest LABELS "MITK;BlueBerry") add_test(NAME mitkPluginGeneratorBuildTest-${config} CONFIGURATIONS ${config} COMMAND ${CMAKE_COMMAND} --build ${test_project_binary_dir} --config ${config}) set_tests_properties(mitkPluginGeneratorBuildTest-${config} PROPERTIES DEPENDS mitkPluginGeneratorConfigureTest-${config} LABELS "MITK;BlueBerry") endforeach() else() add_test(NAME mitkPluginGeneratorConfigureTest-${CMAKE_BUILD_TYPE} WORKING_DIRECTORY "${test_project_binary_dir}" COMMAND ${CMAKE_COMMAND} ${configure_options} -DCMAKE_BUILD_TYPE:STRING=${CMAKE_BUILD_TYPE} "${test_project_source_dir}") set_tests_properties(mitkPluginGeneratorConfigureTest-${CMAKE_BUILD_TYPE} PROPERTIES DEPENDS mitkPluginGeneratorCreateTest LABELS "MITK;BlueBerry") add_test(NAME mitkPluginGeneratorBuildTest-${CMAKE_BUILD_TYPE} COMMAND ${CMAKE_COMMAND} --build ${test_project_binary_dir} --config ${CMAKE_BUILD_TYPE}) set_tests_properties(mitkPluginGeneratorBuildTest-${CMAKE_BUILD_TYPE} PROPERTIES DEPENDS mitkPluginGeneratorConfigureTest-${CMAKE_BUILD_TYPE} LABELS "MITK;BlueBerry") endif() set(package_test_configurations) if(WIN32) # Only test packaging if build type is "Release" on Windows set(package_test_configurations CONFIGURATIONS Release) endif() if(NOT MITK_FAST_TESTING) if(WIN32) # Only test packaging if build type is "Release" on Windows add_test(NAME mitkPluginGeneratorPackageTest CONFIGURATIONS Release COMMAND ${CMAKE_COMMAND} --build ${test_project_binary_dir}/${proj}-build --config Release --target package) set_tests_properties(mitkPluginGeneratorPackageTest PROPERTIES DEPENDS mitkPluginGeneratorBuildTest-Release TIMEOUT 6000 LABELS "MITK;BlueBerry;PACKAGE_TESTS") elseif(CMAKE_BUILD_TYPE) add_test(mitkPluginGeneratorPackageTest ${CMAKE_COMMAND} --build ${test_project_binary_dir}/${proj}-build --config ${CMAKE_BUILD_TYPE} --target package) set_tests_properties(mitkPluginGeneratorPackageTest PROPERTIES DEPENDS mitkPluginGeneratorBuildTest-${CMAKE_BUILD_TYPE} TIMEOUT 6000 LABELS "MITK;BlueBerry;PACKAGE_TESTS") endif() endif() endif() diff --git a/CMake/mitkTestProjectTemplate.cmake b/CMake/mitkTestProjectTemplate.cmake index 5fda20517f..64019cc556 100644 --- a/CMake/mitkTestProjectTemplate.cmake +++ b/CMake/mitkTestProjectTemplate.cmake @@ -1,110 +1,113 @@ if(BUILD_TESTING) include(ExternalProject) set(proj PT) # Means ProjectTemplate (use a short name due to Windows limitations) set(MITK-ProjectTemplate_SOURCE_DIR "${MITK_BINARY_DIR}/${proj}") set(MITK-ProjectTemplate_BINARY_DIR "${MITK_BINARY_DIR}/${proj}-bin") add_test(NAME mitkProjectTemplateRmSrcTest COMMAND ${CMAKE_COMMAND} -E remove_directory "${MITK-ProjectTemplate_SOURCE_DIR}" ) set_tests_properties(mitkProjectTemplateRmSrcTest PROPERTIES LABELS "MITK;BlueBerry") add_test(NAME mitkProjectTemplateRmBinTest COMMAND ${CMAKE_COMMAND} -E remove_directory "${MITK-ProjectTemplate_BINARY_DIR}" ) set_tests_properties(mitkProjectTemplateRmBinTest PROPERTIES LABELS "MITK;BlueBerry") add_test(NAME mitkProjectTemplateMakeBinTest COMMAND ${CMAKE_COMMAND} -E make_directory "${MITK-ProjectTemplate_BINARY_DIR}" ) set_tests_properties(mitkProjectTemplateMakeBinTest PROPERTIES DEPENDS mitkProjectTemplateRmBinTest LABELS "MITK;BlueBerry") add_test(NAME mitkProjectTemplateCloneTest COMMAND ${GIT_EXECUTABLE} clone http://git.mitk.org/MITK-ProjectTemplate.git ${MITK-ProjectTemplate_SOURCE_DIR} ) set_tests_properties(mitkProjectTemplateCloneTest PROPERTIES DEPENDS mitkProjectTemplateRmSrcTest LABELS "MITK;BlueBerry") set(configure_options -DMITK_DIR:PATH=${MITK_BINARY_DIR} -DCMAKE_C_COMPILER:STRING=${CMAKE_C_COMPILER} -DCMAKE_CXX_COMPILER:STRING=${CMAKE_CXX_COMPILER} + -DCMAKE_OSX_SYSROOT:PATH=${CMAKE_OSX_SYSROOT} + -DCMAKE_OSX_DEPLOYMENT_TARGET:STRING=${CMAKE_OSX_DEPLOYMENT_TARGET} + -DCMAKE_OSX_ARCHITECTURES:STRING=${CMAKE_OSX_ARCHITECTURES} -DAwesomeProject_BUILD_ALL_PLUGINS:BOOL=ON -DAwesomeProject_BUILD_ALL_APPS:BOOL=ON -G${CMAKE_GENERATOR} ) if(MITK_USE_Qt4) list(APPEND configure_options -DQT_QMAKE_EXECUTABLE:FILEPATH=${QT_QMAKE_EXECUTABLE}) endif() if(CMAKE_PREFIX_PATH) list(APPEND configure_options -DCMAKE_PREFIX_PATH:PATH=${CMAKE_PREFIX_PATH}) endif() if(CMAKE_CONFIGURATION_TYPES) foreach(config ${CMAKE_CONFIGURATION_TYPES}) add_test(NAME mitkProjectTemplateConfigureTest-${config} CONFIGURATIONS ${config} WORKING_DIRECTORY "${MITK-ProjectTemplate_BINARY_DIR}" COMMAND ${CMAKE_COMMAND} ${configure_options} "${MITK-ProjectTemplate_SOURCE_DIR}") set_tests_properties(mitkProjectTemplateConfigureTest-${config} PROPERTIES DEPENDS "mitkProjectTemplateCloneTest;mitkProjectTemplateMakeBinTest" LABELS "MITK;BlueBerry") add_test(NAME mitkProjectTemplateBuildTest-${config} CONFIGURATIONS ${config} COMMAND ${CMAKE_COMMAND} --build ${MITK-ProjectTemplate_BINARY_DIR} --config ${config}) set_tests_properties(mitkProjectTemplateBuildTest-${config} PROPERTIES DEPENDS mitkProjectTemplateConfigureTest-${config} LABELS "MITK;BlueBerry") endforeach() else() add_test(NAME mitkProjectTemplateConfigureTest-${CMAKE_BUILD_TYPE} WORKING_DIRECTORY "${MITK-ProjectTemplate_BINARY_DIR}" COMMAND ${CMAKE_COMMAND} ${configure_options} -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} "${MITK-ProjectTemplate_SOURCE_DIR}") set_tests_properties(mitkProjectTemplateConfigureTest-${CMAKE_BUILD_TYPE} PROPERTIES DEPENDS "mitkProjectTemplateCloneTest;mitkProjectTemplateMakeBinTest" LABELS "MITK;BlueBerry") add_test(NAME mitkProjectTemplateBuildTest-${CMAKE_BUILD_TYPE} COMMAND ${CMAKE_COMMAND} --build ${MITK-ProjectTemplate_BINARY_DIR} --config ${CMAKE_BUILD_TYPE}) set_tests_properties(mitkProjectTemplateBuildTest-${CMAKE_BUILD_TYPE} PROPERTIES DEPENDS mitkProjectTemplateConfigureTest-${CMAKE_BUILD_TYPE} LABELS "MITK;BlueBerry") endif() set(package_test_configurations) if(WIN32) # Only test packaging if build type is "Release" on Windows set(package_test_configurations CONFIGURATIONS Release) endif() if(NOT MITK_FAST_TESTING) if(WIN32) # Only test packaging if build type is "Release" on Windows add_test(NAME mitkProjectTemplatePackageTest CONFIGURATIONS Release COMMAND ${CMAKE_COMMAND} --build ${MITK-ProjectTemplate_BINARY_DIR}/AwesomeProject-build --config Release --target package) set_tests_properties(mitkProjectTemplatePackageTest PROPERTIES DEPENDS mitkProjectTemplateBuildTest-Release TIMEOUT 6000 LABELS "MITK;BlueBerry;PACKAGE_TESTS") elseif(CMAKE_BUILD_TYPE) add_test(NAME mitkProjectTemplatePackageTest COMMAND ${CMAKE_COMMAND} --build ${MITK-ProjectTemplate_BINARY_DIR}/AwesomeProject-build --config ${CMAKE_BUILD_TYPE} --target package) set_tests_properties(mitkProjectTemplatePackageTest PROPERTIES DEPENDS mitkProjectTemplateBuildTest-${CMAKE_BUILD_TYPE} TIMEOUT 6000 LABELS "MITK;BlueBerry;PACKAGE_TESTS") endif() endif() endif() diff --git a/CMakeExternals/ACVD.cmake b/CMakeExternals/ACVD.cmake index 54fc13cf3d..409417331f 100644 --- a/CMakeExternals/ACVD.cmake +++ b/CMakeExternals/ACVD.cmake @@ -1,42 +1,42 @@ #----------------------------------------------------------------------------- # ACVD #----------------------------------------------------------------------------- if(MITK_USE_ACVD) # Sanity checks if(DEFINED ACVD_DIR AND NOT EXISTS ${ACVD_DIR}) message(FATAL_ERROR "ACVD_DIR variable is defined but corresponds to non-existing directory") endif() set(proj ACVD) set(proj_DEPENDENCIES VTK) set(ACVD_DEPENDS ${proj}) set(additional_cmake_args -DUSE_MULTITHREADING:BOOL=ON -DVTK_DIR:PATH=${VTK_DIR} ) - set(ACVD_PATCH_COMMAND ${CMAKE_COMMAND} -DTEMPLATE_FILE:FILEPATH=${MITK_SOURCE_DIR}/CMakeExternals/EmptyFileForPatching.dummy -P ${MITK_SOURCE_DIR}/CMakeExternals/PatchACVD.cmake) + set(ACVD_PATCH_COMMAND ${CMAKE_COMMAND} -DDESIRED_QT_VERSION:STRING=${DESIRED_QT_VERSION} -DTEMPLATE_FILE:FILEPATH=${MITK_SOURCE_DIR}/CMakeExternals/EmptyFileForPatching.dummy -P ${MITK_SOURCE_DIR}/CMakeExternals/PatchACVD.cmake) if(NOT DEFINED ACVD_DIR) ExternalProject_Add(${proj} SOURCE_DIR ${CMAKE_BINARY_DIR}/${proj}-src BINARY_DIR ${proj}-build PREFIX ${proj}-cmake URL ${MITK_THIRDPARTY_DOWNLOAD_PREFIX_URL}/ACVD-vtk6_2d8f5ea5.tar.gz URL_MD5 ecc97728a86798b35c20eef964b094c9 PATCH_COMMAND ${ACVD_PATCH_COMMAND} INSTALL_COMMAND "" CMAKE_GENERATOR ${gen} CMAKE_ARGS ${ep_common_args} ${additional_cmake_args} DEPENDS ${proj_DEPENDENCIES} ) set(ACVD_DIR ${CMAKE_CURRENT_BINARY_DIR}/${proj}-build) else() mitkMacroEmptyExternalProject(${proj} "${proj_DEPENDENCIES}") endif() endif() diff --git a/CMakeExternals/CTK.cmake b/CMakeExternals/CTK.cmake index e4fe546732..aa003da1d2 100644 --- a/CMakeExternals/CTK.cmake +++ b/CMakeExternals/CTK.cmake @@ -1,98 +1,105 @@ #----------------------------------------------------------------------------- # CTK #----------------------------------------------------------------------------- if(MITK_USE_CTK) # Sanity checks if(DEFINED CTK_DIR AND NOT EXISTS ${CTK_DIR}) message(FATAL_ERROR "CTK_DIR variable is defined but corresponds to non-existing directory") endif() set(proj CTK) set(proj_DEPENDENCIES ) set(CTK_DEPENDS ${proj}) if(NOT DEFINED CTK_DIR) set(revision_tag 9331130f) #IF(${proj}_REVISION_TAG) # SET(revision_tag ${${proj}_REVISION_TAG}) #ENDIF() set(ctk_optional_cache_args ) if(MITK_USE_Python) if(NOT MITK_USE_SYSTEM_PYTHON) list(APPEND proj_DEPENDENCIES Python) endif() list(APPEND ctk_optional_cache_args -DCTK_LIB_Scripting/Python/Widgets:BOOL=ON -DCTK_ENABLE_Python_Wrapping:BOOL=ON -DCTK_APP_ctkSimplePythonShell:BOOL=ON -DPYTHON_EXECUTABLE:FILEPATH=${PYTHON_EXECUTABLE} -DPYTHON_INCLUDE_DIR:PATH=${PYTHON_INCLUDE_DIR} -DPYTHON_INCLUDE_DIR2:PATH=${PYTHON_INCLUDE_DIR2} -DPYTHON_LIBRARY:FILEPATH=${PYTHON_LIBRARY} ) else() list(APPEND ctk_optional_cache_args -DCTK_LIB_Scripting/Python/Widgets:BOOL=OFF -DCTK_ENABLE_Python_Wrapping:BOOL=OFF -DCTK_APP_ctkSimplePythonShell:BOOL=OFF ) endif() if(MITK_USE_DCMTK) list(APPEND ctk_optional_cache_args -DDCMTK_DIR:PATH=${DCMTK_DIR} ) list(APPEND proj_DEPENDENCIES DCMTK) else() list(APPEND ctk_optional_cache_args -DDCMTK_URL:STRING=${MITK_THIRDPARTY_DOWNLOAD_PREFIX_URL}/CTK_DCMTK_085525e6.tar.gz ) endif() + set (ctk_qt_args -DCTK_QT_VERSION:STRING=${DESIRED_QT_VERSION}) + + if (DESIRED_QT_VERSION MATCHES "5") + list(APPEND ctk_qt_args -DQT5_INSTALL_PREFIX:FILEPATH=${QT5_INSTALL_PREFIX}) + else() + list(APPEND ctk_qt_args -DQT_QMAKE_EXECUTABLE:FILEPATH=${QT_QMAKE_EXECUTABLE}) + endif() + FOREACH(type RUNTIME ARCHIVE LIBRARY) IF(DEFINED CTK_PLUGIN_${type}_OUTPUT_DIRECTORY) LIST(APPEND mitk_optional_cache_args -DCTK_PLUGIN_${type}_OUTPUT_DIRECTORY:PATH=${CTK_PLUGIN_${type}_OUTPUT_DIRECTORY}) ENDIF() ENDFOREACH() ExternalProject_Add(${proj} SOURCE_DIR ${CMAKE_BINARY_DIR}/${proj}-src BINARY_DIR ${proj}-build PREFIX ${proj}-cmake URL ${MITK_THIRDPARTY_DOWNLOAD_PREFIX_URL}/CTK_${revision_tag}.tar.gz URL_MD5 c6f66556103c8d0dcae4e7db5eb0f77e UPDATE_COMMAND "" INSTALL_COMMAND "" CMAKE_GENERATOR ${gen} CMAKE_ARGS ${ep_common_args} ${ctk_optional_cache_args} - -DDESIRED_QT_VERSION:STRING=${DESIRED_QT_VERSION} - -DQT_QMAKE_EXECUTABLE:FILEPATH=${QT_QMAKE_EXECUTABLE} + ${ctk_qt_args} -DGit_EXECUTABLE:FILEPATH=${GIT_EXECUTABLE} -DGIT_EXECUTABLE:FILEPATH=${GIT_EXECUTABLE} -DCTK_LIB_CommandLineModules/Backend/LocalProcess:BOOL=ON -DCTK_LIB_CommandLineModules/Frontend/QtGui:BOOL=ON -DCTK_LIB_PluginFramework:BOOL=ON -DCTK_LIB_DICOM/Widgets:BOOL=ON -DCTK_LIB_XNAT/Core:BOOL=ON -DCTK_PLUGIN_org.commontk.eventadmin:BOOL=ON -DCTK_PLUGIN_org.commontk.configadmin:BOOL=ON -DCTK_USE_GIT_PROTOCOL:BOOL=OFF -DDCMTK_URL:STRING=${MITK_THIRDPARTY_DOWNLOAD_PREFIX_URL}/CTK_DCMTK_085525e6.tar.gz -DqRestAPI_URL:STRING=${MITK_THIRDPARTY_DOWNLOAD_PREFIX_URL}/qRestAPI_5f3a03b1.tar.gz DEPENDS ${proj_DEPENDENCIES} ) set(CTK_DIR ${CMAKE_CURRENT_BINARY_DIR}/${proj}-build) else() mitkMacroEmptyExternalProject(${proj} "${proj_DEPENDENCIES}") endif() endif() diff --git a/CMakeExternals/Eigen.cmake b/CMakeExternals/Eigen.cmake index 6f3ee885b2..da5fd0af63 100644 --- a/CMakeExternals/Eigen.cmake +++ b/CMakeExternals/Eigen.cmake @@ -1,30 +1,30 @@ #----------------------------------------------------------------------------- # Eigen #----------------------------------------------------------------------------- # Sanity checks if(DEFINED Eigen_DIR AND NOT EXISTS ${Eigen_DIR}) message(FATAL_ERROR "Eigen_DIR variable is defined but corresponds to non-existing directory") endif() set(proj Eigen) set(proj_DEPENDENCIES ) set(Eigen_DEPENDS ${proj}) if(NOT DEFINED Eigen_DIR) ExternalProject_Add(${proj} - PREFIX ${CMAKE_BINARY_DIR}/${proj}-cmake - URL ${MITK_THIRDPARTY_DOWNLOAD_PREFIX_URL}/Eigen-3.2.2-headers-only.tar.gz - URL_MD5 d0a7fe82ab7bd39bf577afebe287aa20 - CMAKE_ARGS - -DCMAKE_INSTALL_PREFIX:PATH=${CMAKE_CURRENT_BINARY_DIR}/${proj}-src -) + PREFIX ${CMAKE_BINARY_DIR}/${proj}-cmake + URL ${MITK_THIRDPARTY_DOWNLOAD_PREFIX_URL}/Eigen-3.2.2-headers-only.tar.gz + URL_MD5 d0a7fe82ab7bd39bf577afebe287aa20 + CMAKE_ARGS + -DCMAKE_INSTALL_PREFIX:PATH=${CMAKE_CURRENT_BINARY_DIR}/${proj}-src + ) set(Eigen_DIR ${CMAKE_CURRENT_BINARY_DIR}/${proj}-src) else() mitkMacroEmptyExternalProject(${proj} "${proj_DEPENDENCIES}") endif() diff --git a/CMakeExternals/PatchACVD.cmake b/CMakeExternals/PatchACVD.cmake index d7caa9ace7..73d4e09987 100644 --- a/CMakeExternals/PatchACVD.cmake +++ b/CMakeExternals/PatchACVD.cmake @@ -1,54 +1,61 @@ +set(path "CMakeLists.txt") +file(STRINGS ${path} contents NEWLINE_CONSUME) +if(DESIRED_QT_VERSION MATCHES "5") + string(REPLACE "find_package(VTK" "find_package(Qt5Widgets REQUIRED)\nfind_package(VTK" contents ${contents}) +endif() +string(REPLACE "ENDIF(BUILD_VOLUMEPROCESSING)" "ENDIF(BUILD_VOLUMEPROCESSING)\n\nCONFIGURE_FILE(ACVDConfig.cmake.in ACVDConfig.cmake @ONLY)" contents ${contents}) +set(CONTENTS ${contents}) +configure_file(${TEMPLATE_FILE} ${path} @ONLY) + # Create Config.cmake file to make ACVD findable through config mode of find_package() file(WRITE "ACVDConfig.cmake.in" "set(ACVD_INCLUDE_DIRS \"@VTKSURFACE_INCLUDE_DIR@;@VTKDISCRETEREMESHING_INCLUDE_DIR@;@VTKVOLUMEPROCESSING_INCLUDE_DIR@\") set(ACVD_LIBRARY_DIRS \"@PROJECT_BINARY_DIR@/bin\") set(ACVD_LIBRARIES vtkSurface vtkDiscreteRemeshing vtkVolumeProcessing) add_definitions(-DDOmultithread)") -file(APPEND "CMakeLists.txt" "CONFIGURE_FILE(ACVDConfig.cmake.in ACVDConfig.cmake @ONLY)") - # Add vtkVersionMacros.h header file set(path "Common/vtkCurvatureMeasure.cxx") file(STRINGS ${path} contents NEWLINE_CONSUME) string(REPLACE "vtkNeighbourhoodComputation.h\"" "vtkNeighbourhoodComputation.h\"\n#include " contents ${contents}) set(CONTENTS ${contents}) configure_file(${TEMPLATE_FILE} ${path} @ONLY) # Add missing VTK_EXPORT to class declaration set(path "VolumeProcessing/vtkImageDataCleanLabels.h") file(STRINGS ${path} contents NEWLINE_CONSUME) string(REPLACE "ss" "ss VTK_EXPORT" contents ${contents}) set(CONTENTS ${contents}) configure_file(${TEMPLATE_FILE} ${path} @ONLY) # Replace int by vtkIdType, which are types of different size (x64) set(path "DiscreteRemeshing/vtkVerticesProcessing.h") file(STRINGS ${path} contents NEWLINE_CONSUME) string(REPLACE "int N" "vtkIdType N" contents ${contents}) set(CONTENTS ${contents}) configure_file(${TEMPLATE_FILE} ${path} @ONLY) # Replace VTK 5 module names by VTK 6 module names # Link to POSIX thread library set(path "DiscreteRemeshing/CMakeLists.txt") file(STRINGS ${path} contents NEWLINE_CONSUME) string(REPLACE "vtkCommon" "vtkCommonCore" contents ${contents}) string(REPLACE "vtkFiltering" "vtkFiltersCore" contents ${contents}) string(REPLACE "vtkImaging" "vtkImagingCore" contents ${contents}) string(REPLACE "vtkIO" "vtkIOCore" contents ${contents}) string(REPLACE "vtkRendering" "vtkRenderingCore" contents ${contents}) string(REPLACE "vtkHybrid" "vtkFiltersHybrid vtkImagingHybrid" contents ${contents}) string(REPLACE "ENDFOREACH(loop_var)" "ENDFOREACH()\nendif()" contents ${contents}) string(REPLACE "FOREACH(loop_var" "option(ACVD_BUILD_EXAMPLES \"build examples\" OFF) if(ACVD_BUILD_EXAMPLES) FOREACH(loop_var" contents ${contents}) set(CONTENTS ${contents}) configure_file(${TEMPLATE_FILE} ${path} @ONLY) diff --git a/CMakeExternals/Qxt.cmake b/CMakeExternals/Qxt.cmake deleted file mode 100644 index 3e56c585ef..0000000000 --- a/CMakeExternals/Qxt.cmake +++ /dev/null @@ -1,43 +0,0 @@ -#----------------------------------------------------------------------------- -# Qxt -#----------------------------------------------------------------------------- - -if(MITK_USE_Qxt) - -# Sanity checks -if(DEFINED Qxt_DIR AND NOT EXISTS ${Qxt_DIR}) - message(FATAL_ERROR "Qxt_DIR variable is defined but corresponds to non-existing directory") -endif() - -set(proj Qxt) -set(proj_DEPENDENCIES ) -set(${proj}_DEPENDS ${proj}) - -if(NOT DEFINED ${proj}_DIR) - - set(patch_cmd ${CMAKE_COMMAND} -Dproj:STRING=${proj} -Dproj_target:STRING=QxtCore -P ${CMAKE_CURRENT_LIST_DIR}/GenerateDefaultCMakeBuildSystem.cmake) - - ExternalProject_Add(${proj} - SOURCE_DIR ${CMAKE_BINARY_DIR}/${proj}-src - BINARY_DIR ${proj}-build - PREFIX ${proj}-cmake - URL ${MITK_THIRDPARTY_DOWNLOAD_PREFIX_URL}/libqxt-3e7424f842d4.tar.gz - URL_MD5 a41a1e6d114cdabfc655f278176ca062 - PATCH_COMMAND ${patch_cmd} - INSTALL_COMMAND "" - CMAKE_GENERATOR ${gen} - CMAKE_ARGS - ${ep_common_args} - ${qt_project_args} - DEPENDS ${proj_DEPENDENCIES} - ) - - set(${proj}_DIR ${CMAKE_CURRENT_BINARY_DIR}/${proj}-build) - -else() - - mitkMacroEmptyExternalProject(${proj} "${proj_DEPENDENCIES}") - -endif() - -endif() diff --git a/CMakeExternals/QxtCMakeLists.txt b/CMakeExternals/QxtCMakeLists.txt deleted file mode 100644 index cfc018037b..0000000000 --- a/CMakeExternals/QxtCMakeLists.txt +++ /dev/null @@ -1,559 +0,0 @@ -if(DESIRED_QT_VERSION MATCHES 5) - cmake_minimum_required(VERSION 2.8.12) -else() - cmake_minimum_required(VERSION 2.8.4) -endif() - -project(Qxt) - -set(${PROJECT_NAME}_MAJOR_VERSION 0) -set(${PROJECT_NAME}_MINOR_VERSION 6) -set(${PROJECT_NAME}_PATCH_VERSION 99) -set(${PROJECT_NAME}_VERSION ${${PROJECT_NAME}_MAJOR_VERSION}.${${PROJECT_NAME}_MINOR_VERSION}.${${PROJECT_NAME}_PATCH_VERSION}) - -macro(_qt_generate_mocs) - foreach(file ${ARGN}) - get_filename_component(source_path ${file} PATH) - get_filename_component(source_name ${file} NAME_WE) - get_filename_component(source_ext ${file} EXT) - - set(moc_file ${CMAKE_CURRENT_BINARY_DIR}/${source_path}/moc_${source_name}.cpp) - if(DESIRED_QT_VERSION MATCHES "4") - QT4_GENERATE_MOC(${file} ${moc_file}) - else() - qt5_generate_moc(${file} ${moc_file}) - endif() - set_property(SOURCE ${source_path}/${source_name}.cpp APPEND PROPERTY - OBJECT_DEPENDS ${moc_file}) - endforeach() -endmacro() - -macro(_qt_wrap_cpp) - if(DESIRED_QT_VERSION MATCHES "4") - qt4_wrap_cpp(${ARGN}) - else() - qt5_wrap_cpp(${ARGN}) - endif() -endmacro() - -macro(_qt_add_resources) - if(DESIRED_QT_VERSION MATCHES "4") - qt4_add_resources(${ARGN}) - else() - qt5_add_resources(${ARGN}) - endif() -endmacro() - -set(${PROJECT_NAME}_LIBRARIES - QxtCore - QxtWidgets - QxtNetwork - QxtWeb -) - -set(QXT_CORE_MOC_HEADERS - qxtabstractconnectionmanager.h - qxtboundfunction.h - qxtcsvmodel.h - qxtdaemon.h - qxtdeplex.h - qxtdeplex_p.h - qxtfifo.h - qxtfilelock.h - qxtjob.h - qxtjob_p.h - qxtlinesocket.h - qxtlinesocket_p.h - qxtlocale.h - qxtlogger.h - qxtlogger_p.h - qxtmultisignalwaiter.h - qxtnamespace.h - qxtpipe.h - qxtpipe_p.h - qxtpointerlist.h - qxtsignalgroup.h - qxtsignalwaiter.h - qxtslotjob.h - qxtslotjob_p.h - qxtstdio.h - qxtstdio_p.h - qxtstdstreambufdevice.h - qxtrpcservice.h - qxtrpcservice_p.h -) - -set(QXT_GUI_MOC_HEADERS - qxtbasespinbox.h - qxtcheckcombobox.h - qxtcheckcombobox_p.h - qxtconfigdialog.h - qxtconfigdialog_p.h - qxtconfigwidget.h - qxtconfigwidget_p.h - qxtconfirmationmessage.h - qxtcountrycombobox.h - qxtcountrycombobox_p.h - qxtcountrymodel.h - qxtcountrymodel_p.h - qxtcrumbview.h - qxtcrumbview_p.h - qxtflowview.h - qxtflowview_p.h - qxtgroupbox.h - qxtheaderview.h - qxtitemdelegate.h - qxtitemdelegate_p.h - qxtlabel.h - qxtletterboxwidget.h - qxtletterboxwidget_p.h - qxtlineedit.h - qxtlistwidget.h - qxtlistwidget_p.h - qxtlanguagecombobox.h - qxtlanguagecombobox_p.h - qxtprogresslabel.h - qxtproxystyle.h - qxtpushbutton.h - qxtspanslider.h - qxtspanslider_p.h - qxtstars.h - qxtstringspinbox.h - qxtstringvalidator.h - qxttablewidget.h - qxttablewidget_p.h - qxttabwidget.h - qxttabwidget_p.h - qxttooltip_p.h - qxttreewidget.h - qxttreewidget_p.h - - qxtscheduleheaderwidget.h - qxtscheduleitemdelegate.h - qxtscheduleview.h - qxtscheduleviewheadermodel_p.h - qxtscheduleview_p.h - - qxtsortfilterproxymodel.h - qxtfilterdialog.h - qxtfilterdialog_p.h - qxtlookuplineedit.h - - # !qws:!symbian - #qxtapplication.h - #qxtglobalshortcut.h -) - -set(QXT_NETWORK_MOC_HEADERS - qxtjsonrpcclient.h - qxtsmtp.h - qxtrpcpeer.h - qxtsmtp_p.h - qxtsslserver.h - qxtsslconnectionmanager.h - qxttcpconnectionmanager.h - qxttcpconnectionmanager_p.h - qxtxmlrpcclient.h -) - -set(QXT_WEB_MOC_HEADERS - qxtabstracthttpconnector.h - qxtabstractwebservice.h - qxtabstractwebsessionmanager.h - qxtabstractwebsessionmanager_p.h - qxthttpsessionmanager.h - qxtwebcontent.h - qxtwebservicedirectory.h - qxtwebservicedirectory_p.h - qxtwebslotservice.h - qxtwebcgiservice.h - qxtwebcgiservice_p.h -) - -set(QXT_NETWORK_MANUAL_MOC_HEADERS - qxtjsonrpccall.h - qxtxmlrpccall.h -) - -set(QXT_CORE_SOURCES - qxtabstractconnectionmanager.cpp - qxtabstractfileloggerengine.cpp - qxtabstractiologgerengine.cpp - qxtbasicfileloggerengine.cpp - qxtbasicstdloggerengine.cpp - qxtcommandoptions.cpp - qxtcsvmodel.cpp - qxtdaemon.cpp - qxtdatastreamsignalserializer.cpp - qxtdeplex.cpp - qxterror.cpp - qxtfifo.cpp - qxtfilelock.cpp - qxtglobal.cpp - qxthmac.cpp - qxtlocale.cpp - qxtjson.cpp - qxtjob.cpp - qxtlinesocket.cpp - qxtlinkedtree.cpp - qxtlogger.cpp - qxtloggerengine.cpp - qxtlogstream.cpp - qxtmetaobject.cpp - qxtmodelserializer.cpp - qxtmultisignalwaiter.cpp - qxtnull.cpp - qxtpipe.cpp - qxtpointerlist.cpp - qxtsignalgroup.cpp - qxtsignalwaiter.cpp - qxtslotjob.cpp - qxtslotmapper.cpp - qxtstdio.cpp - qxtstdstreambufdevice.cpp - qxttimer.cpp - qxtrpcservice.cpp - qxtxmlfileloggerengine.cpp -) - -set(QXT_GUI_SOURCES - qxtbasespinbox.cpp - qxtcheckcombobox.cpp - qxtconfigdialog.cpp - qxtconfigwidget.cpp - qxtconfirmationmessage.cpp - qxtcountrymodel.cpp - qxtcountrycombobox.cpp - qxtcrumbview.cpp - qxtflowview.cpp - qxtflowview_p.cpp - qxtgroupbox.cpp - qxtheaderview.cpp - qxtitemdelegate.cpp - qxtlabel.cpp - qxtletterboxwidget.cpp - qxtlineedit.cpp - qxtlistwidget.cpp - qxtlistwidgetitem.cpp - qxtlanguagecombobox.cpp - qxtprogresslabel.cpp - qxtproxystyle.cpp - qxtpushbutton.cpp - qxtspanslider.cpp - qxtstars.cpp - qxtstringspinbox.cpp - qxtstringvalidator.cpp - qxttablewidget.cpp - qxttablewidgetitem.cpp - qxttabwidget.cpp - qxttooltip.cpp - qxttreewidget.cpp - qxttreewidgetitem.cpp - - qxtscheduleitemdelegate.cpp - qxtscheduleview.cpp - qxtscheduleview_p.cpp - qxtscheduleviewheadermodel_p.cpp - qxtstyleoptionscheduleviewitem.cpp - qxtscheduleheaderwidget.cpp - - qxtsortfilterproxymodel.cpp - qxtfilterdialog.cpp - qxtlookuplineedit.cpp - - # !qws:!symbian - #qxtapplication.cpp - #qxtglobalshortcut.cpp -) - -set(QXT_NETWORK_SOURCES - qxtjsonrpccall.cpp - qxtjsonrpcclient.cpp - qxtmailattachment.cpp - qxtmailmessage.cpp - qxtrpcpeer.cpp - qxtsmtp.cpp - qxtsslserver.cpp - qxtsslconnectionmanager.cpp - qxttcpconnectionmanager.cpp - qxtxmlrpccall.cpp - qxtxmlrpcclient.cpp - qxtxmlrpc_p.cpp -) - -set(QXT_WEB_SOURCES - qxtabstracthttpconnector.cpp - qxtabstractwebservice.cpp - qxtabstractwebsessionmanager.cpp - qxthtmltemplate.cpp - qxthttpserverconnector.cpp - qxthttpsessionmanager.cpp - qxtscgiserverconnector.cpp - qxtwebcontent.cpp - qxtwebevent.cpp - qxtwebservicedirectory.cpp - qxtwebslotservice.cpp - qxtwebcgiservice.cpp -) - -if(UNIX) - list(APPEND QXT_CORE_MOC_HEADERS unix/qxtserialdevice.h unix/qxtserialdevice_p.h) - list(APPEND QXT_CORE_SOURCES - unix/qxtfilelock_unix.cpp unix/qxtserialdevice.cpp unix/qxtserialdevice_unix.cpp) - if(APPLE) - list(APPEND QXT_GUI_SOURCES - #mac/qxtapplication_mac.cpp - #mac/qxtglobalshortcut_mac.cpp - ) - else() - if(DESIRED_QT_VERSION MATCHES "5") - find_package(Qt5X11Extras REQUIRED) - endif() - list(APPEND QXT_GUI_SOURCES - #x11/qxtapplication_x11.cpp - #x11/qxtglobalshortcut_x11.cpp - x11/qxtscreen_x11.cpp - #x11/qxtwindowsystem_x11.cpp - ) - endif() -endif() - -if(NOT APPLE) - list(APPEND QXT_GUI_SOURCES - qxtscreen.cpp - #qxtwindowsystem.cpp - ) -endif() - -if(WIN32) - list(APPEND QXT_CORE_SOURCES win/qxtfilelock_win.cpp) - list(APPEND QXT_GUI_SOURCES - #win/qxtapplication_win.cpp - #win/qxtglobalshortcut_win.cpp - win/qxtscreen_win.cpp - #win/qxtwindowsystem_win.cpp - ) -endif() - -set(_qxt_core_moc_headers ) -foreach(_header ${QXT_CORE_MOC_HEADERS}) - list(APPEND _qxt_core_moc_headers src/core/${_header}) -endforeach() - -set(_qxt_gui_moc_headers ) -foreach(_header ${QXT_GUI_MOC_HEADERS}) - list(APPEND _qxt_gui_moc_headers src/widgets/${_header}) -endforeach() - -set(_qxt_network_moc_headers ) -foreach(_header ${QXT_NETWORK_MOC_HEADERS}) - list(APPEND _qxt_network_moc_headers src/network/${_header}) -endforeach() - -set(_qxt_network_manual_moc_headers ) -foreach(_header ${QXT_NETWORK_MANUAL_MOC_HEADERS}) - list(APPEND _qxt_network_manual_moc_headers src/network/${_header}) -endforeach() - -set(_qxt_web_moc_headers ) -foreach(_header ${QXT_WEB_MOC_HEADERS}) - list(APPEND _qxt_web_moc_headers src/web/${_header}) -endforeach() - -set(_qxt_core_sources ) -foreach(_source ${QXT_CORE_SOURCES}) - list(APPEND _qxt_core_sources src/core/${_source}) -endforeach() - -set(_qxt_gui_sources ) -foreach(_source ${QXT_GUI_SOURCES}) - list(APPEND _qxt_gui_sources src/widgets/${_source}) -endforeach() - -set(_qxt_network_sources ) -foreach(_source ${QXT_NETWORK_SOURCES}) - list(APPEND _qxt_network_sources src/network/${_source}) -endforeach() - -set(_qxt_web_sources ) -foreach(_source ${QXT_WEB_SOURCES}) - list(APPEND _qxt_web_sources src/web/${_source}) -endforeach() - -set(_qxt_gui_resources src/widgets/resources.qrc) - -set(${PROJECT_NAME}_INCLUDE_DIRS - ${CMAKE_CURRENT_SOURCE_DIR}/src/core - ${CMAKE_CURRENT_SOURCE_DIR}/include/QxtCore - ${CMAKE_CURRENT_SOURCE_DIR}/src/widgets - ${CMAKE_CURRENT_SOURCE_DIR}/include/QxtWidgets - ${CMAKE_CURRENT_SOURCE_DIR}/src/network - ${CMAKE_CURRENT_SOURCE_DIR}/include/QxtNetwork - ${CMAKE_CURRENT_SOURCE_DIR}/src/web - ${CMAKE_CURRENT_SOURCE_DIR}/include/QxtWeb - ) - -include_directories(${${PROJECT_NAME}_INCLUDE_DIRS}) - -if(DESIRED_QT_VERSION MATCHES "4") - find_package(Qt4 REQUIRED) - set(QT_USE_QTNETWORK 1) - set(QT_USE_QTDESIGNER 1) - include(${QT_USE_FILE}) - if("${QT_VERSION_MAJOR}.${QT_VERSION_MINOR}" VERSION_LESS "4.8") - # We add the QT_NO_OPENSSL definition in case of Qt < 4.8 because - # the Qxt SSL code uses QSsl::TlsV1SslV3 which added in Qt 4.8. - # So even if Qt 4.7 was compiled with OpenSSL support, we manually - # disable it in Qxt to simplify the build system stuff and to avoid - # bumping the minimum required Qt version for MITK - add_definitions(-DQT_NO_OPENSSL) - endif() -else() - if (WIN32) - cmake_policy(SET CMP0020 NEW) # Automatically link Qt executables to qtmain target on Windows - endif() - find_package(Qt5 COMPONENTS Network Designer Widgets REQUIRED) -endif() - -# Build the QxtCore library -_qt_wrap_cpp(_qxt_core_sources ${_qxt_core_moc_headers}) - -add_library(QxtCore SHARED ${_qxt_core_sources}) -if(DESIRED_QT_VERSION MATCHES "4") - target_link_libraries(QxtCore ${QT_LIBRARIES}) -else() - target_link_libraries(QxtCore Qt5::Core) -endif() - -set_target_properties(QxtCore PROPERTIES - SOVERSION ${${PROJECT_NAME}_VERSION} - COMPILE_DEFINITIONS "BUILD_QXT_CORE") - -# Build the QxtWidgets (formerly QxtGui) library -_qt_wrap_cpp(_qxt_gui_sources ${_qxt_gui_moc_headers}) -_qt_add_resources(_qxt_gui_sources ${_qxt_gui_resources}) - -if(DESIRED_QT_VERSION MATCHES "4") - set(QxtGui_link_libraries ${QT_LIBRARIES}) -else() - set(QxtGui_link_libraries Qt5::Widgets) - if(UNIX AND NOT APPLE) - list(APPEND QxtGui_link_libraries Qt5::X11Extras) - endif() -endif() -if(APPLE) - find_library(CARBON_FW NAMES Carbon) - list(APPEND QxtGui_link_libraries ${CARBON_FW}) -endif() -add_library(QxtWidgets SHARED ${_qxt_gui_sources}) -target_link_libraries(QxtWidgets QxtCore ${QxtGui_link_libraries}) - -set_target_properties(QxtWidgets PROPERTIES - SOVERSION ${${PROJECT_NAME}_VERSION} - COMPILE_DEFINITIONS "BUILD_QXT_GUI") - -# Build the QxtNetwork library -_qt_wrap_cpp(_qxt_network_sources ${_qxt_network_moc_headers}) -_qt_add_resources(_qxt_network_sources ${_qxt_network_resources}) - -# The generate moc_* sources are included directly in .cpp files -_qt_generate_mocs(${_qxt_network_manual_moc_headers}) -include_directories(${CMAKE_CURRENT_BINARY_DIR}/src/network) - -add_library(QxtNetwork SHARED ${_qxt_network_sources}) -if(DESIRED_QT_VERSION MATCHES "4") - target_link_libraries(QxtNetwork QxtCore ${QT_LIBRARIES}) -else() - target_link_libraries(QxtNetwork Qt5::Network) -endif() - -set_target_properties(QxtNetwork PROPERTIES - SOVERSION ${${PROJECT_NAME}_VERSION} - COMPILE_DEFINITIONS "BUILD_QXT_NETWORK") - -# Build the QxtWeb library -_qt_wrap_cpp(_qxt_web_sources ${_qxt_web_moc_headers}) - -add_library(QxtWeb SHARED ${_qxt_web_sources}) -target_link_libraries(QxtWeb QxtCore QxtNetwork ${QT_LIBRARIES}) - -set_target_properties(QxtWeb PROPERTIES - SOVERSION ${${PROJECT_NAME}_VERSION} - COMPILE_DEFINITIONS "BUILD_QXT_WEB") - - -# Build the designer plug-in - -set(_qxt_designer_sources - src/designer/qxtbasespinboxplugin.cpp - src/designer/qxtcheckcomboboxplugin.cpp - src/designer/qxtcountrycomboboxplugin.cpp - src/designer/qxtdesignerplugin.cpp - src/designer/qxtdesignerplugins.cpp - src/designer/qxtflowviewplugin.cpp - src/designer/qxtgroupboxplugin.cpp - src/designer/qxtlabelplugin.cpp - src/designer/qxtlanguagecomboboxplugin.cpp - src/designer/qxtletterboxwidgetplugin.cpp - src/designer/qxtlineeditplugin.cpp - src/designer/qxtlistwidgetplugin.cpp - src/designer/qxtprogresslabelplugin.cpp - src/designer/qxtpushbuttonplugin.cpp - src/designer/qxtspansliderplugin.cpp - src/designer/qxtstarsplugin.cpp - src/designer/qxtstringspinboxplugin.cpp - src/designer/qxttablewidgetplugin.cpp - src/designer/qxttreewidgetplugin.cpp -) - -set(wrap_cpp_options ) -if(DESIRED_QT_VERSION MATCHES "5") - list(APPEND wrap_cpp_options TARGET QxtDesignerPlugins) -endif() - -_qt_wrap_cpp(_qxt_designer_sources - src/designer/qxtbasespinboxplugin.h - src/designer/qxtcheckcomboboxplugin.h - src/designer/qxtcountrycomboboxplugin.h - src/designer/qxtdesignerplugins.h - src/designer/qxtflowviewplugin.h - src/designer/qxtgroupboxplugin.h - src/designer/qxtlabelplugin.h - src/designer/qxtlanguagecomboboxplugin.h - src/designer/qxtletterboxwidgetplugin.h - src/designer/qxtlineeditplugin.h - src/designer/qxtlistwidgetplugin.h - src/designer/qxtprogresslabelplugin.h - src/designer/qxtpushbuttonplugin.h - src/designer/qxtspansliderplugin.h - src/designer/qxtstarsplugin.h - src/designer/qxtstringspinboxplugin.h - src/designer/qxttablewidgetplugin.h - src/designer/qxttreewidgetplugin.h - ${wrap_cpp_options} -) - -_qt_add_resources(_qxt_designer_sources src/designer/resources.qrc) -add_library(QxtDesignerPlugins SHARED ${_qxt_designer_sources}) -if(DESIRED_QT_VERSION MATCHES "4") - target_link_libraries(QxtDesignerPlugins QxtWidgets QxtCore ${QT_LIBRARIES}) -else() - target_link_libraries(QxtDesignerPlugins QxtWidgets QxtCore Qt5::Designer) -endif() - -set_target_properties(QxtDesignerPlugins PROPERTIES - SOVERSION ${${PROJECT_NAME}_VERSION} - COMPILE_DEFINITIONS BUILD_QXT_DESIGNER) - - -# Config files -configure_file(${PROJECT_NAME}Config.cmake.in - ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake @ONLY) -export(TARGETS ${Qxt_LIBRARIES} FILE ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Exports.cmake) - -# Version information -configure_file( - ${CMAKE_CURRENT_SOURCE_DIR}/${PROJECT_NAME}ConfigVersion.cmake.in - ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake - @ONLY - ) diff --git a/CMakeLists.txt b/CMakeLists.txt index b88ed89574..927124dca6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,1084 +1,1084 @@ set(DESIRED_QT_VERSION 4 CACHE STRING "Pick a version of Qt to use: 4 or 5") if(DESIRED_QT_VERSION MATCHES "4") cmake_minimum_required(VERSION 2.8.9) else() cmake_minimum_required(VERSION 2.8.12) endif() #----------------------------------------------------------------------------- # Include ctest launchers for dashboard in case of makefile generator #----------------------------------------------------------------------------- if(${CMAKE_VERSION} VERSION_GREATER "2.8.9") include(CTestUseLaunchers) endif() #----------------------------------------------------------------------------- # Set a default build type if none was specified #----------------------------------------------------------------------------- if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) message(STATUS "Setting build type to 'Debug' as none was specified.") set(CMAKE_BUILD_TYPE Debug CACHE STRING "Choose the type of build." FORCE) # Set the possible values of build type for cmake-gui set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release" "MinSizeRel" "RelWithDebInfo") endif() #----------------------------------------------------------------------------- # Superbuild Option - Enabled by default #----------------------------------------------------------------------------- option(MITK_USE_SUPERBUILD "Build MITK and the projects it depends on via SuperBuild.cmake." ON) if(MITK_USE_SUPERBUILD) project(MITK-superbuild) set(MITK_SOURCE_DIR ${PROJECT_SOURCE_DIR}) set(MITK_BINARY_DIR ${PROJECT_BINARY_DIR}) else() project(MITK) endif() #----------------------------------------------------------------------------- # Warn if source or build path is too long #----------------------------------------------------------------------------- if(WIN32) set(_src_dir_length_max 50) set(_bin_dir_length_max 50) if(MITK_USE_SUPERBUILD) set(_src_dir_length_max 43) # _src_dir_length_max - strlen(ITK-src) set(_bin_dir_length_max 40) # _bin_dir_length_max - strlen(MITK-build) endif() string(LENGTH "${MITK_SOURCE_DIR}" _src_n) string(LENGTH "${MITK_BINARY_DIR}" _bin_n) # The warnings should be converted to errors if(_src_n GREATER _src_dir_length_max) message(WARNING "MITK source code directory path length is too long (${_src_n} > ${_src_dir_length_max})." "Please move the MITK source code directory to a directory with a shorter path." ) endif() if(_bin_n GREATER _bin_dir_length_max) message(WARNING "MITK build directory path length is too long (${_bin_n} > ${_bin_dir_length_max})." "Please move the MITK build directory to a directory with a shorter path." ) endif() endif() #----------------------------------------------------------------------------- # See http://cmake.org/cmake/help/cmake-2-8-docs.html#section_Policies for details #----------------------------------------------------------------------------- set(project_policies CMP0001 # NEW: CMAKE_BACKWARDS_COMPATIBILITY should no longer be used. CMP0002 # NEW: Logical target names must be globally unique. CMP0003 # NEW: Libraries linked via full path no longer produce linker search paths. CMP0004 # NEW: Libraries linked may NOT have leading or trailing whitespace. CMP0005 # NEW: Preprocessor definition values are now escaped automatically. CMP0006 # NEW: Installing MACOSX_BUNDLE targets requires a BUNDLE DESTINATION. CMP0007 # NEW: List command no longer ignores empty elements. CMP0008 # NEW: Libraries linked by full-path must have a valid library file name. CMP0009 # NEW: FILE GLOB_RECURSE calls should not follow symlinks by default. CMP0010 # NEW: Bad variable reference syntax is an error. CMP0011 # NEW: Included scripts do automatic cmake_policy PUSH and POP. CMP0012 # NEW: if() recognizes numbers and boolean constants. CMP0013 # NEW: Duplicate binary directories are not allowed. - CMP0014 # NEW: Input directories must have CMakeLists.txt - CMP0020 # NEW: Automatically link Qt executables to qtmain target on Windows + CMP0014 # NEW: Input directories must have CMakeLists.txt. + CMP0020 # NEW: Automatically link Qt executables to qtmain target on Windows. + CMP0028 # NEW: Double colon in target name means ALIAS or IMPORTED target. ) foreach(policy ${project_policies}) if(POLICY ${policy}) cmake_policy(SET ${policy} NEW) endif() endforeach() #----------------------------------------------------------------------------- # Update CMake module path #------------------------------------------------------------------------------ set(MITK_CMAKE_DIR ${MITK_SOURCE_DIR}/CMake) set(CMAKE_MODULE_PATH ${MITK_CMAKE_DIR} ${CMAKE_MODULE_PATH} ) #----------------------------------------------------------------------------- # CMake function(s) and macro(s) #----------------------------------------------------------------------------- include(mitkMacroEmptyExternalProject) include(mitkFunctionGenerateProjectXml) include(mitkFunctionSuppressWarnings) include(mitkFunctionEnableBuildConfiguration) include(FeatureSummary) SUPPRESS_VC_DEPRECATED_WARNINGS() #----------------------------------------------------------------------------- # Output directories. #----------------------------------------------------------------------------- foreach(type LIBRARY RUNTIME ARCHIVE) # Make sure the directory exists if(DEFINED MITK_CMAKE_${type}_OUTPUT_DIRECTORY AND NOT EXISTS ${MITK_CMAKE_${type}_OUTPUT_DIRECTORY}) message("Creating directory MITK_CMAKE_${type}_OUTPUT_DIRECTORY: ${MITK_CMAKE_${type}_OUTPUT_DIRECTORY}") file(MAKE_DIRECTORY "${MITK_CMAKE_${type}_OUTPUT_DIRECTORY}") endif() if(MITK_USE_SUPERBUILD) set(output_dir ${MITK_BINARY_DIR}/bin) if(NOT DEFINED MITK_CMAKE_${type}_OUTPUT_DIRECTORY) set(MITK_CMAKE_${type}_OUTPUT_DIRECTORY ${MITK_BINARY_DIR}/MITK-build/bin) endif() else() if(NOT DEFINED MITK_CMAKE_${type}_OUTPUT_DIRECTORY) set(output_dir ${MITK_BINARY_DIR}/bin) else() set(output_dir ${MITK_CMAKE_${type}_OUTPUT_DIRECTORY}) endif() endif() set(CMAKE_${type}_OUTPUT_DIRECTORY ${output_dir} CACHE INTERNAL "Single output directory for building all libraries.") mark_as_advanced(CMAKE_${type}_OUTPUT_DIRECTORY) endforeach() #----------------------------------------------------------------------------- # Additional MITK Options (also shown during superbuild) #----------------------------------------------------------------------------- option(BUILD_SHARED_LIBS "Build MITK with shared libraries" ON) option(WITH_COVERAGE "Enable/Disable coverage" OFF) option(BUILD_TESTING "Test the project" ON) macro(env_option name doc value) set(_value $ENV{${name}}) if("${_value}" STREQUAL "") set(_value ${value}) endif() option(${name} "${doc}" ${_value}) endmacro() # ----------------------------------------- # Qt version related variables env_option(MITK_USE_QT "Use Nokia's Qt library" ON) set(MITK_DESIRED_QT_VERSION ${DESIRED_QT_VERSION}) if(MITK_USE_QT) # find the package at the very beginning, so that QT4_FOUND is available if(DESIRED_QT_VERSION MATCHES 4) set(MITK_QT4_MINIMUM_VERSION 4.7) find_package(Qt4 ${MITK_QT4_MINIMUM_VERSION} REQUIRED) set(MITK_USE_Qt4 TRUE) set(MITK_USE_Qt5 FALSE) endif() if(DESIRED_QT_VERSION MATCHES 5) set(MITK_QT5_MINIMUM_VERSION 5.0.0) set(MITK_USE_Qt4 FALSE) set(MITK_USE_Qt5 TRUE) set(QT5_INSTALL_PREFIX "" CACHE PATH "The install location of Qt5") set(CMAKE_PREFIX_PATH ${CMAKE_PREFIX_PATH} ${QT5_INSTALL_PREFIX}) find_package(Qt5Core ${MITK_QT5_MINIMUM_VERSION} REQUIRED) + find_package(Qt5Concurrent ${MITK_QT5_MINIMUM_VERSION} REQUIRED) + find_package(Qt5OpenGL ${MITK_QT5_MINIMUM_VERSION} REQUIRED) + find_package(Qt5PrintSupport ${MITK_QT5_MINIMUM_VERSION} REQUIRED) + find_package(Qt5Sql ${MITK_QT5_MINIMUM_VERSION} REQUIRED) + find_package(Qt5Svg ${MITK_QT5_MINIMUM_VERSION} REQUIRED) + find_package(Qt5WebKit ${MITK_QT5_MINIMUM_VERSION} REQUIRED) + find_package(Qt5WebKitWidgets ${MITK_QT5_MINIMUM_VERSION} REQUIRED) + find_package(Qt5Widgets ${MITK_QT5_MINIMUM_VERSION} REQUIRED) + find_package(Qt5Xml ${MITK_QT5_MINIMUM_VERSION} REQUIRED) endif() else() set(MITK_USE_Qt4 FALSE) set(MITK_USE_Qt5 FALSE) endif() # ----------------------------------------- # MITK_USE_* build variables env_option(MITK_BUILD_ALL_APPS "Build all MITK applications" OFF) set(MITK_BUILD_TUTORIAL OFF CACHE INTERNAL "Deprecated! Use MITK_BUILD_EXAMPLES instead!") env_option(MITK_BUILD_EXAMPLES "Build the MITK Examples" ${MITK_BUILD_TUTORIAL}) env_option(MITK_USE_ACVD "Use Approximated Centroidal Voronoi Diagrams" OFF) env_option(MITK_USE_CppUnit "Use CppUnit for unit tests" ON) if(BUILD_TESTING AND NOT MITK_USE_CppUnit) message("> Forcing MITK_USE_CppUnit to ON because BUILD_TESTING=ON") set(MITK_USE_CppUnit ON CACHE BOOL "Use CppUnit for unit tests" FORCE) endif() env_option(MITK_USE_GLEW "Use the GLEW library" ON) env_option(MITK_USE_Boost "Use the Boost C++ library" OFF) -env_option(MITK_USE_BLUEBERRY "Build the BlueBerry platform" ${MITK_USE_Qt4}) -env_option(MITK_USE_CTK "Use CTK in MITK" ${MITK_USE_Qt4}) +env_option(MITK_USE_BLUEBERRY "Build the BlueBerry platform" ON) +env_option(MITK_USE_CTK "Use CTK in MITK" ON) env_option(MITK_USE_DCMTK "EXPERIMENTAL, superbuild only: Use DCMTK in MITK" ${MITK_USE_CTK}) env_option(MITK_USE_OpenCV "Use Intel's OpenCV library" OFF) env_option(MITK_USE_OpenCL "Use OpenCL GPU-Computing library" OFF) env_option(MITK_USE_Poco "Use the Poco library" ON) env_option(MITK_USE_SOFA "Use Simulation Open Framework Architecture" OFF) env_option(MITK_USE_Python "Use Python wrapping in MITK" OFF) env_option(MITK_USE_SimpleITK "Use the SimpleITK library" OFF) set(MITK_USE_CableSwig ${MITK_USE_Python}) option(MITK_ENABLE_PIC_READER "Enable support for reading the DKFZ pic file format." ON) set(MITK_BUILD_CONFIGURATION "Custom" CACHE STRING "Use pre-defined MITK configurations") -set_property(CACHE MITK_BUILD_CONFIGURATION PROPERTY STRINGS Custom Default mitkDiffusion All) +set_property(CACHE MITK_BUILD_CONFIGURATION PROPERTY STRINGS Custom Default WorkbenchRelease mitkDiffusion All) mitkFunctionEnableBuildConfiguration() mark_as_advanced(MITK_BUILD_ALL_APPS MITK_USE_CppUnit MITK_USE_GLEW MITK_USE_CTK MITK_USE_DCMTK MITK_ENABLE_PIC_READER MITK_BUILD_CONFIGURATION ) if(MITK_USE_Python) if(APPLE) message(WARNING "Python wrapping is unsuported on mac OSX!") set(MITK_USE_Python OFF CACHE BOOL "Use Python wrapping in MITK" FORCE) else() option(MITK_USE_SYSTEM_PYTHON "Use the system python runtime" OFF) # SimpleITK is required when python is enabled set(MITK_USE_SimpleITK ON CACHE BOOL "Use the SimpleITK library" FORCE) if(MITK_USE_SYSTEM_PYTHON) FIND_PACKAGE(PythonLibs REQUIRED) FIND_PACKAGE(PythonInterp REQUIRED) else() FIND_PACKAGE(PythonLibs) FIND_PACKAGE(PythonInterp) endif() endif() endif() if(MITK_USE_Boost) option(MITK_USE_SYSTEM_Boost "Use the system Boost" OFF) set(MITK_USE_Boost_LIBRARIES "" CACHE STRING "A semi-colon separated list of required Boost libraries") endif() -if(MITK_USE_BLUEBERRY AND NOT MITK_USE_Qt4) - message("> Forcing MITK_USE_BLUEBERRY to OFF because Qt4 is not used.") - set(MITK_USE_BLUEBERRY OFF CACHE BOOL "Build the BlueBerry application platform" FORCE) -endif() - -if(MITK_USE_CTK AND NOT MITK_USE_Qt4) - message("> Forcing MITK_USE_CTK to OFF because Qt4 is not used.") - set(MITK_USE_CTK OFF CACHE BOOL "Use CTK in MITK" FORCE) -endif() - if(MITK_USE_BLUEBERRY) option(MITK_BUILD_ALL_PLUGINS "Build all MITK plugins" OFF) mark_as_advanced(MITK_BUILD_ALL_PLUGINS) if(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() endif() if(MITK_USE_CTK AND NOT MITK_USE_DCMTK) message("> Forcing MITK_USE_DCMTK to ON because of MITK_USE_CTK") set(MITK_USE_DCMTK ON CACHE BOOL "Use DCMTK in MITK" FORCE) endif() if(MITK_USE_SOFA) # SOFA requires at least CMake 2.8.8 set(SOFA_CMAKE_VERSION 2.8.8) if(${CMAKE_VERSION} VERSION_LESS ${SOFA_CMAKE_VERSION}) set(MITK_USE_SOFA OFF CACHE BOOL "" FORCE) message(WARNING "Switched off MITK_USE_SOFA\n Minimum required CMake version: ${SOFA_CMAKE_VERSION}\n Installed CMake version: ${CMAKE_VERSION}") endif() # SOFA/ITK combination requires at least MSVC 2010 if(MSVC_VERSION AND MSVC_VERSION LESS 1600) set(MITK_USE_SOFA OFF CACHE BOOL "" FORCE) message(WARNING "Switched off MITK_USE_SOFA\n MSVC versions less than 2010 are not supported.") endif() # SOFA requires boost library if(MITK_USE_SOFA AND NOT MITK_USE_Boost) message("Forcing MITK_USE_Boost to ON because of MITK_USE_SOFA") set(MITK_USE_Boost ON CACHE BOOL "" FORCE) endif() # SOFA requires boost system library list(FIND MITK_USE_Boost_LIBRARIES system _result) if(_result LESS 0) message("Adding 'system' to MITK_USE_Boost_LIBRARIES.") list(APPEND MITK_USE_Boost_LIBRARIES system) endif() # SOFA requires boost thread library list(FIND MITK_USE_Boost_LIBRARIES thread _result) if(_result LESS 0) message("Adding 'thread' to MITK_USE_Boost_LIBRARIES.") list(APPEND MITK_USE_Boost_LIBRARIES thread) endif() # Simulation plugin requires boost chrono library list(FIND MITK_USE_Boost_LIBRARIES chrono _result) if(_result LESS 0) message("Adding 'chrono' to MITK_USE_Boost_LIBRARIES.") list(APPEND MITK_USE_Boost_LIBRARIES chrono) endif() set(MITK_USE_Boost_LIBRARIES ${MITK_USE_Boost_LIBRARIES} CACHE STRING "" FORCE) # Allow setting external SOFA plugins directory and SOFA plugins set(MITK_USE_SOFA_PLUGINS_DIR ${MITK_USE_SOFA_PLUGINS_DIR} CACHE PATH "External SOFA plugins directory" FORCE) set(MITK_USE_SOFA_PLUGINS ${MITK_USE_SOFA_PLUGINS} CACHE PATH "List of semicolon-separated plugin names" FORCE) endif() # Customize the default pixel types for multiplex macros 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 "itk::RGBPixel, itk::RGBAPixel" 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") mark_as_advanced(MITK_ACCESSBYITK_INTEGRAL_PIXEL_TYPES MITK_ACCESSBYITK_FLOATING_PIXEL_TYPES MITK_ACCESSBYITK_COMPOSITE_PIXEL_TYPES MITK_ACCESSBYITK_DIMENSIONS ) # consistency checks if(NOT MITK_ACCESSBYITK_INTEGRAL_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" FORCE) endif() if(NOT MITK_ACCESSBYITK_FLOATING_PIXEL_TYPES) set(MITK_ACCESSBYITK_FLOATING_PIXEL_TYPES "double, float" CACHE STRING "List of floating pixel types used in AccessByItk and InstantiateAccessFunction macros" FORCE) endif() if(NOT MITK_ACCESSBYITK_COMPOSITE_PIXEL_TYPES) set(MITK_ACCESSBYITK_COMPOSITE_PIXEL_TYPES "itk::RGBPixel, itk::RGBAPixel" CACHE STRING "List of composite pixel types used in AccessByItk and InstantiateAccessFunction macros" FORCE) endif() if(NOT MITK_ACCESSBYITK_VECTOR_PIXEL_TYPES) string(REPLACE "," ";" _integral_types ${MITK_ACCESSBYITK_INTEGRAL_PIXEL_TYPES}) string(REPLACE "," ";" _floating_types ${MITK_ACCESSBYITK_FLOATING_PIXEL_TYPES}) foreach(_scalar_type ${_integral_types} ${_floating_types}) set(MITK_ACCESSBYITK_VECTOR_PIXEL_TYPES "${MITK_ACCESSBYITK_VECTOR_PIXEL_TYPES}itk::VariableLengthVector<${_scalar_type}>,") endforeach() string(LENGTH "${MITK_ACCESSBYITK_VECTOR_PIXEL_TYPES}" _length) math(EXPR _length "${_length} - 1") string(SUBSTRING "${MITK_ACCESSBYITK_VECTOR_PIXEL_TYPES}" 0 ${_length} MITK_ACCESSBYITK_VECTOR_PIXEL_TYPES) set(MITK_ACCESSBYITK_VECTOR_PIXEL_TYPES ${MITK_ACCESSBYITK_VECTOR_PIXEL_TYPES} CACHE STRING "List of vector pixel types used in AccessByItk and InstantiateAccessFunction macros for itk::VectorImage types" FORCE) endif() if(NOT MITK_ACCESSBYITK_DIMENSIONS) set(MITK_ACCESSBYITK_DIMENSIONS "2,3" CACHE STRING "List of dimensions used in AccessByItk and InstantiateAccessFunction macros") endif() #----------------------------------------------------------------------------- # Project.xml #----------------------------------------------------------------------------- # A list of topologically ordered targets set(CTEST_PROJECT_SUBPROJECTS) if(MITK_USE_BLUEBERRY) list(APPEND CTEST_PROJECT_SUBPROJECTS BlueBerry) endif() list(APPEND CTEST_PROJECT_SUBPROJECTS MITK-Core MITK-CoreUI MITK-IGT MITK-ToF MITK-DTI MITK-Registration MITK-Modules # all modules not contained in a specific subproject MITK-Plugins # all plugins not contained in a specific subproject MITK-Examples Unlabeled # special "subproject" catching all unlabeled targets and tests ) # Configure CTestConfigSubProject.cmake that could be used by CTest scripts configure_file(${MITK_SOURCE_DIR}/CTestConfigSubProject.cmake.in ${MITK_BINARY_DIR}/CTestConfigSubProject.cmake) if(CTEST_PROJECT_ADDITIONAL_TARGETS) # those targets will be executed at the end of the ctest driver script # and they also get their own subproject label set(subproject_list "${CTEST_PROJECT_SUBPROJECTS};${CTEST_PROJECT_ADDITIONAL_TARGETS}") else() set(subproject_list "${CTEST_PROJECT_SUBPROJECTS}") endif() # Generate Project.xml file expected by the CTest driver script mitkFunctionGenerateProjectXml(${MITK_BINARY_DIR} MITK "${subproject_list}" ${MITK_USE_SUPERBUILD}) #----------------------------------------------------------------------------- # Superbuild script #----------------------------------------------------------------------------- if(MITK_USE_SUPERBUILD) include("${CMAKE_CURRENT_SOURCE_DIR}/SuperBuild.cmake") # Print configuration summary message("\n\n") feature_summary( DESCRIPTION "------- FEATURE SUMMARY FOR ${PROJECT_NAME} -------" WHAT ALL) return() endif() #***************************************************************************** #**************************** END OF SUPERBUILD **************************** #***************************************************************************** #----------------------------------------------------------------------------- # CMake function(s) and macro(s) #----------------------------------------------------------------------------- include(WriteBasicConfigVersionFile) include(CheckCXXSourceCompiles) include(mitkFunctionCheckCompilerFlags) include(mitkFunctionGetGccVersion) include(MacroParseArguments) include(mitkFunctionSuppressWarnings) # includes several functions include(mitkFunctionOrganizeSources) include(mitkFunctionGetVersion) include(mitkFunctionGetVersionDescription) include(mitkFunctionCreateWindowsBatchScript) include(mitkFunctionInstallProvisioningFiles) include(mitkFunctionInstallAutoLoadModules) include(mitkFunctionGetLibrarySearchPaths) include(mitkFunctionCompileSnippets) include(mitkFunctionUseModules) include(mitkMacroCreateModuleConf) include(mitkFunctionCheckModuleDependencies) include(mitkFunctionCreateModule) include(mitkMacroCreateExecutable) include(mitkMacroCheckModule) include(mitkMacroCreateModuleTests) include(mitkFunctionAddCustomModuleTest) include(mitkMacroUseModule) include(mitkMacroMultiplexPicType) include(mitkMacroInstall) include(mitkMacroInstallHelperApp) include(mitkMacroInstallTargets) include(mitkMacroGenerateToolsLibrary) include(mitkMacroGetLinuxDistribution) include(mitkMacroGetPMDPlatformString) #----------------------------------------------------------------------------- # Set MITK specific options and variables (NOT available during superbuild) #----------------------------------------------------------------------------- # ASK THE USER TO SHOW THE CONSOLE WINDOW FOR CoreApp and mitkWorkbench option(MITK_SHOW_CONSOLE_WINDOW "Use this to enable or disable the console window when starting MITK GUI Applications" ON) mark_as_advanced(MITK_SHOW_CONSOLE_WINDOW) # TODO: check if necessary option(USE_ITKZLIB "Use the ITK zlib for pic compression." ON) mark_as_advanced(USE_ITKZLIB) if(NOT MITK_FAST_TESTING) if(DEFINED MITK_CTEST_SCRIPT_MODE AND (MITK_CTEST_SCRIPT_MODE STREQUAL "continuous" OR MITK_CTEST_SCRIPT_MODE STREQUAL "experimental") ) set(MITK_FAST_TESTING 1) endif() endif() #----------------------------------------------------------------------------- # Get MITK version info #----------------------------------------------------------------------------- mitkFunctionGetVersion(${MITK_SOURCE_DIR} MITK) mitkFunctionGetVersionDescription(${MITK_SOURCE_DIR} MITK) #----------------------------------------------------------------------------- # Installation preparation # # These should be set before any MITK install macros are used #----------------------------------------------------------------------------- # on Mac OSX all BlueBerry plugins get copied into every # application bundle (.app directory) specified here if(MITK_USE_BLUEBERRY AND APPLE) include("${CMAKE_CURRENT_SOURCE_DIR}/Applications/AppList.cmake") foreach(mitk_app ${MITK_APPS}) # extract option_name string(REPLACE "^^" "\\;" target_info ${mitk_app}) set(target_info_list ${target_info}) list(GET target_info_list 1 option_name) list(GET target_info_list 0 app_name) # check if the application is enabled if(${option_name} OR MITK_BUILD_ALL_APPS) set(MACOSX_BUNDLE_NAMES ${MACOSX_BUNDLE_NAMES} Mitk${app_name}) endif() endforeach() endif() #----------------------------------------------------------------------------- # Set symbol visibility Flags #----------------------------------------------------------------------------- # MinGW does not export all symbols automatically, so no need to set flags if(CMAKE_COMPILER_IS_GNUCXX AND NOT MINGW) set(VISIBILITY_CXX_FLAGS ) #"-fvisibility=hidden -fvisibility-inlines-hidden") endif() #----------------------------------------------------------------------------- # Set coverage Flags #----------------------------------------------------------------------------- if(WITH_COVERAGE) if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU") set(coverage_flags "-g -fprofile-arcs -ftest-coverage -O0 -DNDEBUG") set(COVERAGE_CXX_FLAGS ${coverage_flags}) set(COVERAGE_C_FLAGS ${coverage_flags}) endif() endif() #----------------------------------------------------------------------------- # MITK C/CXX Flags #----------------------------------------------------------------------------- set(MITK_C_FLAGS "${COVERAGE_C_FLAGS}") set(MITK_C_FLAGS_DEBUG ) set(MITK_C_FLAGS_RELEASE ) set(MITK_CXX_FLAGS "${VISIBILITY_CXX_FLAGS} ${COVERAGE_CXX_FLAGS}") set(MITK_CXX_FLAGS_DEBUG ) set(MITK_CXX_FLAGS_RELEASE ) set(MITK_EXE_LINKER_FLAGS ) set(MITK_SHARED_LINKER_FLAGS ) if(WIN32) - set(MITK_CXX_FLAGS "${MITK_CXX_FLAGS} -D_WIN32_WINNT=0x0501 -DPOCO_NO_UNWINDOWS -DWIN32_LEAN_AND_MEAN") + set(MITK_CXX_FLAGS "${MITK_CXX_FLAGS} -D_WIN32_WINNT=0x0501 -DPOCO_NO_UNWINDOWS -DWIN32_LEAN_AND_MEAN -DNOMINMAX") set(MITK_CXX_FLAGS "${MITK_CXX_FLAGS} /wd4231") # warning C4231: nonstandard extension used : 'extern' before template explicit instantiation # the following line should be removed after fixing bug 17637 mitkFunctionCheckCompilerFlags("/wd4316" MITK_CXX_FLAGS) # warning C4316: object alignment on heap endif() if(NOT MSVC_VERSION) foreach(_flag -Wall -Wextra -Wpointer-arith -Winvalid-pch -Wcast-align -Wwrite-strings -Wno-error=gnu -Wno-error=unknown-pragmas # The strict-overflow warning is generated by ITK template code -Wno-error=strict-overflow -Woverloaded-virtual -Wstrict-null-sentinel #-Wold-style-cast #-Wsign-promo # the following two lines should be removed after ITK-3097 has # been resolved, see also MITK bug 15279 -Wno-unused-local-typedefs -Wno-array-bounds -fdiagnostics-show-option ) mitkFunctionCheckCAndCXXCompilerFlags(${_flag} MITK_C_FLAGS MITK_CXX_FLAGS) endforeach() endif() if(CMAKE_COMPILER_IS_GNUCXX AND NOT APPLE) mitkFunctionCheckCompilerFlags("-Wl,--no-undefined" MITK_SHARED_LINKER_FLAGS) mitkFunctionCheckCompilerFlags("-Wl,--as-needed" MITK_SHARED_LINKER_FLAGS) endif() if(CMAKE_COMPILER_IS_GNUCXX) mitkFunctionGetGccVersion(${CMAKE_CXX_COMPILER} GCC_VERSION) # With older version of gcc supporting the flag -fstack-protector-all, an extra dependency to libssp.so # is introduced. If gcc is smaller than 4.4.0 and the build type is Release let's not include the flag. # Doing so should allow to build package made for distribution using older linux distro. if(${GCC_VERSION} VERSION_GREATER "4.4.0" OR (CMAKE_BUILD_TYPE STREQUAL "Debug" AND ${GCC_VERSION} VERSION_LESS "4.4.0")) mitkFunctionCheckCAndCXXCompilerFlags("-fstack-protector-all" MITK_C_FLAGS MITK_CXX_FLAGS) endif() if(MINGW) # suppress warnings about auto imported symbols set(MITK_SHARED_LINKER_FLAGS "-Wl,--enable-auto-import ${MITK_SHARED_LINKER_FLAGS}") endif() set(MITK_CXX_FLAGS_RELEASE "-D_FORTIFY_SOURCE=2 ${MITK_CXX_FLAGS_RELEASE}") endif() set(MITK_MODULE_LINKER_FLAGS ${MITK_SHARED_LINKER_FLAGS}) set(MITK_EXE_LINKER_FLAGS ${MITK_SHARED_LINKER_FLAGS}) #----------------------------------------------------------------------------- # MITK Packages #----------------------------------------------------------------------------- set(MITK_MODULES_PACKAGE_DEPENDS_DIR ${MITK_SOURCE_DIR}/CMake/PackageDepends) set(MODULES_PACKAGE_DEPENDS_DIRS ${MITK_MODULES_PACKAGE_DEPENDS_DIR}) #----------------------------------------------------------------------------- # Testing #----------------------------------------------------------------------------- if(BUILD_TESTING) enable_testing() include(CTest) mark_as_advanced(TCL_TCLSH DART_ROOT) option(MITK_ENABLE_RENDERING_TESTING OFF "Enable the MITK rendering tests. Requires x-server in Linux.") #Rendering testing does not work for Linux nightlies, thus it is disabled per default #and activated for Mac and Windows. if(WIN32 OR APPLE) set(MITK_ENABLE_RENDERING_TESTING ON) endif() mark_as_advanced( MITK_ENABLE_RENDERING_TESTING ) # Setup file for setting custom ctest vars configure_file( CMake/CTestCustom.cmake.in ${MITK_BINARY_DIR}/CTestCustom.cmake @ONLY ) # Configuration for the CMake-generated test driver set(CMAKE_TESTDRIVER_EXTRA_INCLUDES "#include ") set(CMAKE_TESTDRIVER_BEFORE_TESTMAIN " try {") set(CMAKE_TESTDRIVER_AFTER_TESTMAIN " } catch( std::exception & excp ) { fprintf(stderr,\"%s\\n\",excp.what()); return EXIT_FAILURE; } catch( ... ) { printf(\"Exception caught in the test driver\\n\"); return EXIT_FAILURE; } ") set(MITK_TEST_OUTPUT_DIR "${MITK_BINARY_DIR}/test_output") if(NOT EXISTS ${MITK_TEST_OUTPUT_DIR}) file(MAKE_DIRECTORY ${MITK_TEST_OUTPUT_DIR}) endif() # Test the external project template if(MITK_USE_BLUEBERRY) include(mitkTestProjectTemplate) endif() # Test the package target include(mitkPackageTest) endif() configure_file(mitkTestingConfig.h.in ${MITK_BINARY_DIR}/mitkTestingConfig.h) #----------------------------------------------------------------------------- # MITK_SUPERBUILD_BINARY_DIR #----------------------------------------------------------------------------- # If MITK_SUPERBUILD_BINARY_DIR isn't defined, it means MITK is *NOT* build using Superbuild. # In that specific case, MITK_SUPERBUILD_BINARY_DIR should default to MITK_BINARY_DIR if(NOT DEFINED MITK_SUPERBUILD_BINARY_DIR) set(MITK_SUPERBUILD_BINARY_DIR ${MITK_BINARY_DIR}) endif() #----------------------------------------------------------------------------- # Compile Utilities and set-up MITK variables #----------------------------------------------------------------------------- include(mitkSetupVariables) #----------------------------------------------------------------------------- # Cleanup #----------------------------------------------------------------------------- file(GLOB _MODULES_CONF_FILES ${PROJECT_BINARY_DIR}/${MODULES_CONF_DIRNAME}/*.cmake) if(_MODULES_CONF_FILES) file(REMOVE ${_MODULES_CONF_FILES}) endif() add_subdirectory(Utilities) if(MITK_USE_BLUEBERRY) # We need to hack a little bit because MITK applications may need # to enable certain BlueBerry plug-ins. However, these plug-ins # are validated separately from the MITK plug-ins and know nothing # about potential MITK plug-in dependencies of the applications. Hence # we cannot pass the MITK application list to the BlueBerry # ctkMacroSetupPlugins call but need to extract the BlueBerry dependencies # from the applications and set them explicitly. include("${CMAKE_CURRENT_SOURCE_DIR}/Applications/AppList.cmake") foreach(mitk_app ${MITK_APPS}) # extract target_dir and option_name string(REPLACE "^^" "\\;" target_info ${mitk_app}) set(target_info_list ${target_info}) list(GET target_info_list 0 target_dir) list(GET target_info_list 1 option_name) # check if the application is enabled and if target_libraries.cmake exists if((${option_name} OR MITK_BUILD_ALL_APPS) AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/Applications/${target_dir}/target_libraries.cmake") include("${CMAKE_CURRENT_SOURCE_DIR}/Applications/${target_dir}/target_libraries.cmake") foreach(_target_dep ${target_libraries}) if(_target_dep MATCHES org_blueberry_) string(REPLACE _ . _app_bb_dep ${_target_dep}) # explicitly set the build option for the BlueBerry plug-in set(BLUEBERRY_BUILD_${_app_bb_dep} ON CACHE BOOL "Build the ${_app_bb_dep} plug-in") endif() endforeach() endif() endforeach() set(mbilog_DIR "${mbilog_BINARY_DIR}") if(MITK_BUILD_ALL_PLUGINS) set(BLUEBERRY_BUILD_ALL_PLUGINS ON) endif() set(BLUEBERRY_XPDOC_OUTPUT_DIR ${MITK_DOXYGEN_OUTPUT_DIR}/html/extension-points/html/) add_subdirectory(BlueBerry) set(BlueBerry_DIR ${CMAKE_CURRENT_BINARY_DIR}/BlueBerry CACHE PATH "The directory containing a CMake configuration file for BlueBerry" FORCE) include(mitkMacroCreateCTKPlugin) endif() #----------------------------------------------------------------------------- # Set C/CXX and linker flags for MITK code #----------------------------------------------------------------------------- set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${MITK_CXX_FLAGS}") set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} ${MITK_CXX_FLAGS_DEBUG}") set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} ${MITK_CXX_FLAGS_RELEASE}") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${MITK_C_FLAGS}") set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} ${MITK_C_FLAGS_DEBUG}") set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} ${MITK_C_FLAGS_RELEASE}") set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${MITK_EXE_LINKER_FLAGS}") set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} ${MITK_SHARED_LINKER_FLAGS}") set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} ${MITK_MODULE_LINKER_FLAGS}") #----------------------------------------------------------------------------- # Add custom targets representing CDash subprojects #----------------------------------------------------------------------------- foreach(subproject ${CTEST_PROJECT_SUBPROJECTS}) if(NOT TARGET ${subproject} AND NOT subproject MATCHES "Unlabeled") add_custom_target(${subproject}) endif() endforeach() #----------------------------------------------------------------------------- # Add subdirectories #----------------------------------------------------------------------------- add_subdirectory(Core) add_subdirectory(Modules) if(MITK_USE_BLUEBERRY) find_package(BlueBerry REQUIRED) set(MITK_DEFAULT_SUBPROJECTS MITK-Plugins) # Plug-in testing (needs some work to be enabled again) if(BUILD_TESTING) include(berryTestingHelpers) set(BLUEBERRY_UI_TEST_APP "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/CoreApp") if(TARGET CoreApp) get_target_property(_is_macosx_bundle CoreApp MACOSX_BUNDLE) if(APPLE AND _is_macosx_bundle) set(BLUEBERRY_UI_TEST_APP "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/CoreApp.app/Contents/MacOS/CoreApp") endif() endif() set(BLUEBERRY_TEST_APP_ID "org.mitk.qt.coreapplication") endif() include("${CMAKE_CURRENT_SOURCE_DIR}/Plugins/PluginList.cmake") set(mitk_plugins_fullpath ) foreach(mitk_plugin ${MITK_EXT_PLUGINS}) list(APPEND mitk_plugins_fullpath Plugins/${mitk_plugin}) endforeach() if(EXISTS ${MITK_PRIVATE_MODULES}/PluginList.cmake) include(${MITK_PRIVATE_MODULES}/PluginList.cmake) foreach(mitk_plugin ${MITK_PRIVATE_PLUGINS}) list(APPEND mitk_plugins_fullpath ${MITK_PRIVATE_MODULES}/${mitk_plugin}) endforeach() endif() if(MITK_BUILD_EXAMPLES) include("${CMAKE_CURRENT_SOURCE_DIR}/Examples/Plugins/PluginList.cmake") set(mitk_example_plugins_fullpath ) foreach(mitk_example_plugin ${MITK_EXAMPLE_PLUGINS}) list(APPEND mitk_example_plugins_fullpath Examples/Plugins/${mitk_example_plugin}) list(APPEND mitk_plugins_fullpath Examples/Plugins/${mitk_example_plugin}) endforeach() endif() # Specify which plug-ins belong to this project macro(GetMyTargetLibraries all_target_libraries varname) set(re_ctkplugin_mitk "^org_mitk_[a-zA-Z0-9_]+$") set(re_ctkplugin_bb "^org_blueberry_[a-zA-Z0-9_]+$") set(_tmp_list) list(APPEND _tmp_list ${all_target_libraries}) ctkMacroListFilter(_tmp_list re_ctkplugin_mitk re_ctkplugin_bb OUTPUT_VARIABLE ${varname}) endmacro() # Get infos about application directories and build options include("${CMAKE_CURRENT_SOURCE_DIR}/Applications/AppList.cmake") set(mitk_apps_fullpath ) foreach(mitk_app ${MITK_APPS}) list(APPEND mitk_apps_fullpath "${CMAKE_CURRENT_SOURCE_DIR}/Applications/${mitk_app}") endforeach() if (mitk_plugins_fullpath) ctkMacroSetupPlugins(${mitk_plugins_fullpath} BUILD_OPTION_PREFIX MITK_BUILD_ APPS ${mitk_apps_fullpath} BUILD_ALL ${MITK_BUILD_ALL_PLUGINS} COMPACT_OPTIONS) endif() set(MITK_PLUGIN_USE_FILE "${MITK_BINARY_DIR}/MitkPluginUseFile.cmake") if(${PROJECT_NAME}_PLUGIN_LIBRARIES) ctkFunctionGeneratePluginUseFile(${MITK_PLUGIN_USE_FILE}) else() file(REMOVE ${MITK_PLUGIN_USE_FILE}) set(MITK_PLUGIN_USE_FILE ) endif() # 11.3.13, change, muellerm: activate python bundle if python and blueberry is active if( MITK_USE_Python ) set(MITK_BUILD_org.mitk.gui.qt.python ON) endif() endif() #----------------------------------------------------------------------------- # Documentation #----------------------------------------------------------------------------- add_subdirectory(Documentation) #----------------------------------------------------------------------------- # Installation #----------------------------------------------------------------------------- # set MITK cpack variables # These are the default variables, which can be overwritten ( see below ) include(mitkSetupCPack) set(use_default_config ON) # MITK_APPS is set in Applications/AppList.cmake (included somewhere above # if MITK_USE_BLUEBERRY is set to ON). if(MITK_APPS) set(activated_apps_no 0) list(LENGTH MITK_APPS app_count) # Check how many apps have been enabled # If more than one app has been activated, the we use the # default CPack configuration. Otherwise that apps configuration # will be used, if present. foreach(mitk_app ${MITK_APPS}) # extract option_name string(REPLACE "^^" "\\;" target_info ${mitk_app}) set(target_info_list ${target_info}) list(GET target_info_list 1 option_name) # check if the application is enabled if(${option_name} OR MITK_BUILD_ALL_APPS) MATH(EXPR activated_apps_no "${activated_apps_no} + 1") endif() endforeach() if(app_count EQUAL 1 AND (activated_apps_no EQUAL 1 OR MITK_BUILD_ALL_APPS)) # Corner case if there is only one app in total set(use_project_cpack ON) elseif(activated_apps_no EQUAL 1 AND NOT MITK_BUILD_ALL_APPS) # Only one app is enabled (no "build all" flag set) set(use_project_cpack ON) else() # Less or more then one app is enabled set(use_project_cpack OFF) endif() foreach(mitk_app ${MITK_APPS}) # extract target_dir and option_name string(REPLACE "^^" "\\;" target_info ${mitk_app}) set(target_info_list ${target_info}) list(GET target_info_list 0 target_dir) list(GET target_info_list 1 option_name) # check if the application is enabled if(${option_name} OR MITK_BUILD_ALL_APPS) # check whether application specific configuration files will be used if(use_project_cpack) # use files if they exist if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/Applications/${target_dir}/CPackOptions.cmake") include("${CMAKE_CURRENT_SOURCE_DIR}/Applications/${target_dir}/CPackOptions.cmake") endif() if(EXISTS "${PROJECT_SOURCE_DIR}/Applications/${target_dir}/CPackConfig.cmake.in") set(CPACK_PROJECT_CONFIG_FILE "${PROJECT_BINARY_DIR}/Applications/${target_dir}/CPackConfig.cmake") configure_file(${PROJECT_SOURCE_DIR}/Applications/${target_dir}/CPackConfig.cmake.in ${CPACK_PROJECT_CONFIG_FILE} @ONLY) set(use_default_config OFF) endif() endif() # add link to the list list(APPEND CPACK_CREATE_DESKTOP_LINKS "${target_dir}") endif() endforeach() endif() # if no application specific configuration file was used, use default if(use_default_config) configure_file(${MITK_SOURCE_DIR}/MITKCPackOptions.cmake.in ${MITK_BINARY_DIR}/MITKCPackOptions.cmake @ONLY) set(CPACK_PROJECT_CONFIG_FILE "${MITK_BINARY_DIR}/MITKCPackOptions.cmake") endif() # include CPack model once all variables are set include(CPack) # Additional installation rules include(mitkInstallRules) #----------------------------------------------------------------------------- # Last configuration steps #----------------------------------------------------------------------------- set(MITK_EXPORTS_FILE "${MITK_BINARY_DIR}/MitkExports.cmake") file(REMOVE ${MITK_EXPORTS_FILE}) set(targets_to_export) get_property(module_targets GLOBAL PROPERTY MITK_MODULE_TARGETS) if(module_targets) list(APPEND targets_to_export ${module_targets}) endif() if(MITK_USE_BLUEBERRY) if(MITK_PLUGIN_LIBRARIES) list(APPEND targets_to_export ${MITK_PLUGIN_LIBRARIES}) endif() endif() export(TARGETS ${targets_to_export} APPEND FILE ${MITK_EXPORTS_FILE}) set(MITK_EXPORTED_TARGET_PROPERTIES ) foreach(target_to_export ${targets_to_export}) get_target_property(autoload_targets ${target_to_export} MITK_AUTOLOAD_TARGETS) if(autoload_targets) set(MITK_EXPORTED_TARGET_PROPERTIES "${MITK_EXPORTED_TARGET_PROPERTIES} set_target_properties(${target_to_export} PROPERTIES MITK_AUTOLOAD_TARGETS \"${autoload_targets}\")") endif() get_target_property(autoload_dir ${target_to_export} MITK_AUTOLOAD_DIRECTORY) if(autoload_dir) set(MITK_EXPORTED_TARGET_PROPERTIES "${MITK_EXPORTED_TARGET_PROPERTIES} set_target_properties(${target_to_export} PROPERTIES MITK_AUTOLOAD_DIRECTORY \"${autoload_dir}\")") endif() endforeach() get_property(MITK_ADDITIONAL_LIBRARY_SEARCH_PATHS_CONFIG GLOBAL PROPERTY MITK_ADDITIONAL_LIBRARY_SEARCH_PATHS) configure_file(${MITK_SOURCE_DIR}/CMake/ToolExtensionITKFactory.cpp.in ${MITK_BINARY_DIR}/ToolExtensionITKFactory.cpp.in COPYONLY) configure_file(${MITK_SOURCE_DIR}/CMake/ToolExtensionITKFactoryLoader.cpp.in ${MITK_BINARY_DIR}/ToolExtensionITKFactoryLoader.cpp.in COPYONLY) configure_file(${MITK_SOURCE_DIR}/CMake/ToolGUIExtensionITKFactory.cpp.in ${MITK_BINARY_DIR}/ToolGUIExtensionITKFactory.cpp.in COPYONLY) set(VISIBILITY_AVAILABLE 0) set(visibility_test_flag "") mitkFunctionCheckCompilerFlags("-fvisibility=hidden" visibility_test_flag) if(visibility_test_flag) # The compiler understands -fvisiblity=hidden (probably gcc >= 4 or Clang) set(VISIBILITY_AVAILABLE 1) endif() configure_file(mitkExportMacros.h.in ${MITK_BINARY_DIR}/mitkExportMacros.h) configure_file(mitkVersion.h.in ${MITK_BINARY_DIR}/mitkVersion.h) configure_file(mitkConfig.h.in ${MITK_BINARY_DIR}/mitkConfig.h) set(IPFUNC_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/Utilities/ipFunc) set(UTILITIES_DIR ${CMAKE_CURRENT_SOURCE_DIR}/Utilities) file(GLOB _MODULES_CONF_FILES RELATIVE ${PROJECT_BINARY_DIR}/${MODULES_CONF_DIRNAME} ${PROJECT_BINARY_DIR}/${MODULES_CONF_DIRNAME}/*.cmake) set(MITK_MODULE_NAMES) foreach(_module ${_MODULES_CONF_FILES}) string(REPLACE Config.cmake "" _module_name ${_module}) list(APPEND MITK_MODULE_NAMES ${_module_name}) endforeach() configure_file(mitkConfig.h.in ${MITK_BINARY_DIR}/mitkConfig.h) configure_file(MITKConfig.cmake.in ${MITK_BINARY_DIR}/MITKConfig.cmake @ONLY) write_basic_config_version_file(${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake VERSION ${MITK_VERSION_STRING} COMPATIBILITY AnyNewerVersion) # If we are under Windows, create two batch files which correctly # set up the environment for the application and for Visual Studio if(WIN32) include(mitkFunctionCreateWindowsBatchScript) set(VS_SOLUTION_FILE "${PROJECT_BINARY_DIR}/${PROJECT_NAME}.sln") foreach(VS_BUILD_TYPE debug release) mitkFunctionCreateWindowsBatchScript("${MITK_SOURCE_DIR}/CMake/StartVS.bat.in" ${PROJECT_BINARY_DIR}/StartVS_${VS_BUILD_TYPE}.bat ${VS_BUILD_TYPE}) endforeach() endif(WIN32) #----------------------------------------------------------------------------- # MITK Applications #----------------------------------------------------------------------------- # This must come after MITKConfig.h was generated, since applications # might do a find_package(MITK REQUIRED). add_subdirectory(Applications) #----------------------------------------------------------------------------- # MITK Examples #----------------------------------------------------------------------------- if(MITK_BUILD_EXAMPLES) # This must come after MITKConfig.h was generated, since applications # might do a find_package(MITK REQUIRED). add_subdirectory(Examples) endif() #----------------------------------------------------------------------------- # Print configuration summary #----------------------------------------------------------------------------- message("\n\n") feature_summary( DESCRIPTION "------- FEATURE SUMMARY FOR ${PROJECT_NAME} -------" WHAT ALL ) diff --git a/Core/Code/DataManagement/mitkImageVtkReadAccessor.cpp b/Core/Code/DataManagement/mitkImageVtkReadAccessor.cpp index c3f8c3af71..61c439bb3c 100644 --- a/Core/Code/DataManagement/mitkImageVtkReadAccessor.cpp +++ b/Core/Code/DataManagement/mitkImageVtkReadAccessor.cpp @@ -1,61 +1,61 @@ /*=================================================================== 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 "mitkImageVtkReadAccessor.h" #include "mitkImage.h" #include const mitk::Image* mitk::ImageVtkReadAccessor::GetImage() const { return m_Image; } mitk::ImageVtkReadAccessor::ImageVtkReadAccessor( ImageConstPointer iP, const mitk::ImageDataItem* iDI, const vtkImageData* imageDataVtk) - : ImageAccessorBase(NULL, iDI) + : ImageAccessorBase(iP, iDI) , m_Image(iP.GetPointer()) , m_ImageDataVtk(imageDataVtk) { m_Image->m_VtkReadersLock.Lock(); m_Image->m_VtkReaders.push_back(this); //printf("m_VtkReaders.size(): %d\n", (int) m_Image->m_VtkReaders.size()); m_Image->m_VtkReadersLock.Unlock(); } mitk::ImageVtkReadAccessor::~ImageVtkReadAccessor() { m_Image->m_VtkReadersLock.Lock(); std::vector::iterator it = std::find(m_Image->m_VtkReaders.begin(), m_Image->m_VtkReaders.end(), this); if (it != m_Image->m_VtkReaders.end()) { m_Image->m_VtkReaders.erase(it); } //printf("m_VtkReaders.size(): %d\n", (int) m_Image->m_VtkReaders.size()); m_Image->m_VtkReadersLock.Unlock(); } const vtkImageData*mitk::ImageVtkReadAccessor::GetVtkImageData() const { return m_ImageDataVtk; } diff --git a/Core/Code/Internal/mitkImageVtkLegacyIO.cpp b/Core/Code/Internal/mitkImageVtkLegacyIO.cpp index 4ceb996638..a24fd7ed91 100644 --- a/Core/Code/Internal/mitkImageVtkLegacyIO.cpp +++ b/Core/Code/Internal/mitkImageVtkLegacyIO.cpp @@ -1,107 +1,107 @@ /*=================================================================== 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 "mitkImageVtkLegacyIO.h" #include "mitkImage.h" #include "mitkIOMimeTypes.h" #include "mitkImageVtkReadAccessor.h" #include #include #include #include #include namespace mitk { ImageVtkLegacyIO::ImageVtkLegacyIO() - : AbstractFileIO(Image::GetStaticNameOfClass(), IOMimeTypes::VTK_IMAGE_MIMETYPE(), "VTK XML Image") + : AbstractFileIO(Image::GetStaticNameOfClass(), IOMimeTypes::VTK_IMAGE_LEGACY_MIMETYPE(), "VTK Legacy Image") { this->RegisterService(); } std::vector ImageVtkLegacyIO::Read() { // The legay vtk reader cannot work with input streams const std::string fileName = this->GetLocalFileName(); vtkSmartPointer reader = vtkSmartPointer::New(); reader->SetFileName(fileName.c_str()); reader->Update(); if ( reader->GetOutput() != NULL ) { mitk::Image::Pointer output = mitk::Image::New(); output->Initialize(reader->GetOutput()); output->SetVolume(reader->GetOutput()->GetScalarPointer()); std::vector result; result.push_back(output.GetPointer()); return result; } else { mitkThrow() << "vtkStructuredPointsReader error: " << vtkErrorCode::GetStringFromErrorCode(reader->GetErrorCode()); } } IFileIO::ConfidenceLevel ImageVtkLegacyIO::GetReaderConfidenceLevel() const { if (AbstractFileIO::GetReaderConfidenceLevel() == Unsupported) return Unsupported; vtkSmartPointer reader = vtkSmartPointer::New(); reader->SetFileName(this->GetLocalFileName().c_str()); if (reader->IsFileStructuredPoints()) { return Supported; } return Unsupported; } void ImageVtkLegacyIO::Write() { ValidateOutputLocation(); const Image* input = dynamic_cast(this->GetInput()); vtkSmartPointer writer = vtkSmartPointer::New(); // The legacy vtk image writer cannot write to streams LocalFile localFile(this); writer->SetFileName(localFile.GetFileName().c_str()); - ImageVtkReadAccessor vtkReadAccessor(Image::ConstPointer(input), NULL, NULL); + ImageVtkReadAccessor vtkReadAccessor(Image::ConstPointer(input), NULL, input->GetVtkImageData()); writer->SetInputData(const_cast(vtkReadAccessor.GetVtkImageData())); if (writer->Write() == 0 || writer->GetErrorCode() != 0 ) { mitkThrow() << "vtkStructuredPointesWriter error: " << vtkErrorCode::GetStringFromErrorCode(writer->GetErrorCode()); } } IFileIO::ConfidenceLevel ImageVtkLegacyIO::GetWriterConfidenceLevel() const { if (AbstractFileIO::GetWriterConfidenceLevel() == Unsupported) return Unsupported; const Image* input = static_cast(this->GetInput()); if (input->GetDimension() == 3) return Supported; else if (input->GetDimension() < 3) return PartiallySupported; return Unsupported; } ImageVtkLegacyIO* ImageVtkLegacyIO::IOClone() const { return new ImageVtkLegacyIO(*this); } } diff --git a/Core/Code/Internal/mitkImageVtkXmlIO.cpp b/Core/Code/Internal/mitkImageVtkXmlIO.cpp index cb8c35da10..881f70b890 100644 --- a/Core/Code/Internal/mitkImageVtkXmlIO.cpp +++ b/Core/Code/Internal/mitkImageVtkXmlIO.cpp @@ -1,142 +1,142 @@ /*=================================================================== 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 "mitkImageVtkXmlIO.h" #include "mitkImage.h" #include "mitkIOMimeTypes.h" #include "mitkImageVtkReadAccessor.h" #include #include #include #include #include namespace mitk { class VtkXMLImageDataReader : public ::vtkXMLImageDataReader { public: static VtkXMLImageDataReader *New() { return new VtkXMLImageDataReader(); } vtkTypeMacro(VtkXMLImageDataReader,vtkXMLImageDataReader) void SetStream(std::istream* is) { this->Stream = is; } std::istream* GetStream() const { return this->Stream; } }; class VtkXMLImageDataWriter : public ::vtkXMLImageDataWriter { public: static VtkXMLImageDataWriter *New() { return new VtkXMLImageDataWriter(); } vtkTypeMacro(VtkXMLImageDataWriter,vtkXMLImageDataWriter) void SetStream(std::ostream* os) { this->Stream = os; } std::ostream* GetStream() const { return this->Stream; } }; ImageVtkXmlIO::ImageVtkXmlIO() : AbstractFileIO(Image::GetStaticNameOfClass(), IOMimeTypes::VTK_IMAGE_MIMETYPE(), "VTK XML Image") { this->RegisterService(); } std::vector ImageVtkXmlIO::Read() { vtkSmartPointer reader = vtkSmartPointer::New(); if (this->GetInputStream()) { reader->SetStream(this->GetInputStream()); } else { reader->SetFileName(this->GetInputLocation().c_str()); } reader->Update(); if (reader->GetOutput() != NULL) { mitk::Image::Pointer output = mitk::Image::New(); output->Initialize(reader->GetOutput()); output->SetVolume(reader->GetOutput()->GetScalarPointer()); std::vector result; result.push_back(output.GetPointer()); return result; } else { mitkThrow() << "vtkXMLImageDataReader error: " << vtkErrorCode::GetStringFromErrorCode(reader->GetErrorCode()); } } IFileIO::ConfidenceLevel ImageVtkXmlIO::GetReaderConfidenceLevel() const { if (AbstractFileIO::GetReaderConfidenceLevel() == Unsupported) return Unsupported; if (this->GetInputStream() == NULL) { // check if the xml vtk reader can handle the file vtkSmartPointer xmlReader = vtkSmartPointer::New(); if (xmlReader->CanReadFile(this->GetInputLocation().c_str()) != 0) { return Supported; } return Unsupported; } // in case of an input stream, VTK does not seem to have methods for // validating it return Supported; } void ImageVtkXmlIO::Write() { ValidateOutputLocation(); const Image* input = dynamic_cast(this->GetInput()); vtkSmartPointer writer = vtkSmartPointer::New(); if (this->GetOutputStream()) { writer->SetStream(this->GetOutputStream()); } else { writer->SetFileName(this->GetOutputLocation().c_str()); } - ImageVtkReadAccessor vtkReadAccessor(Image::ConstPointer(input), NULL, NULL); + ImageVtkReadAccessor vtkReadAccessor(Image::ConstPointer(input), NULL, input->GetVtkImageData()); writer->SetInputData(const_cast(vtkReadAccessor.GetVtkImageData())); if (writer->Write() == 0 || writer->GetErrorCode() != 0 ) { mitkThrow() << "vtkXMLImageDataWriter error: " << vtkErrorCode::GetStringFromErrorCode(writer->GetErrorCode()); } } IFileIO::ConfidenceLevel ImageVtkXmlIO::GetWriterConfidenceLevel() const { if (AbstractFileIO::GetWriterConfidenceLevel() == Unsupported) return Unsupported; const Image* input = static_cast(this->GetInput()); if (input->GetDimension() == 3) return Supported; else if (input->GetDimension() < 3) return PartiallySupported; return Unsupported; } ImageVtkXmlIO* ImageVtkXmlIO::IOClone() const { return new ImageVtkXmlIO(*this); } } diff --git a/Core/CppMicroServices/third_party/miniz.c b/Core/CppMicroServices/third_party/miniz.c index 32c9d5090e..cdaba92086 100644 --- a/Core/CppMicroServices/third_party/miniz.c +++ b/Core/CppMicroServices/third_party/miniz.c @@ -1,4925 +1,4929 @@ /* miniz.c v1.15 - public domain deflate/inflate, zlib-subset, ZIP reading/writing/appending, PNG writing See "unlicense" statement at the end of this file. Rich Geldreich , last updated Oct. 13, 2013 Implements RFC 1950: http://www.ietf.org/rfc/rfc1950.txt and RFC 1951: http://www.ietf.org/rfc/rfc1951.txt Most API's defined in miniz.c are optional. For example, to disable the archive related functions just define MINIZ_NO_ARCHIVE_APIS, or to get rid of all stdio usage define MINIZ_NO_STDIO (see the list below for more macros). * Change History 10/13/13 v1.15 r4 - Interim bugfix release while I work on the next major release with Zip64 support (almost there!): - Critical fix for the MZ_ZIP_FLAG_DO_NOT_SORT_CENTRAL_DIRECTORY bug (thanks kahmyong.moon@hp.com) which could cause locate files to not find files. This bug would only have occured in earlier versions if you explicitly used this flag, OR if you used mz_zip_extract_archive_file_to_heap() or mz_zip_add_mem_to_archive_file_in_place() (which used this flag). If you can't switch to v1.15 but want to fix this bug, just remove the uses of this flag from both helper funcs (and of course don't use the flag). - Bugfix in mz_zip_reader_extract_to_mem_no_alloc() from kymoon when pUser_read_buf is not NULL and compressed size is > uncompressed size - Fixing mz_zip_reader_extract_*() funcs so they don't try to extract compressed data from directory entries, to account for weird zipfiles which contain zero-size compressed data on dir entries. Hopefully this fix won't cause any issues on weird zip archives, because it assumes the low 16-bits of zip external attributes are DOS attributes (which I believe they always are in practice). - Fixing mz_zip_reader_is_file_a_directory() so it doesn't check the internal attributes, just the filename and external attributes - mz_zip_reader_init_file() - missing MZ_FCLOSE() call if the seek failed - Added cmake support for Linux builds which builds all the examples, tested with clang v3.3 and gcc v4.6. - Clang fix for tdefl_write_image_to_png_file_in_memory() from toffaletti - Merged MZ_FORCEINLINE fix from hdeanclark - Fix include before config #ifdef, thanks emil.brink - Added tdefl_write_image_to_png_file_in_memory_ex(): supports Y flipping (super useful for OpenGL apps), and explicit control over the compression level (so you can set it to 1 for real-time compression). - Merged in some compiler fixes from paulharris's github repro. - Retested this build under Windows (VS 2010, including static analysis), tcc 0.9.26, gcc v4.6 and clang v3.3. - Added example6.c, which dumps an image of the mandelbrot set to a PNG file. - Modified example2 to help test the MZ_ZIP_FLAG_DO_NOT_SORT_CENTRAL_DIRECTORY flag more. - In r3: Bugfix to mz_zip_writer_add_file() found during merge: Fix possible src file fclose() leak if alignment bytes+local header file write faiiled - In r4: Minor bugfix to mz_zip_writer_add_from_zip_reader(): Was pushing the wrong central dir header offset, appears harmless in this release, but it became a problem in the zip64 branch 5/20/12 v1.14 - MinGW32/64 GCC 4.6.1 compiler fixes: added MZ_FORCEINLINE, #include (thanks fermtect). 5/19/12 v1.13 - From jason@cornsyrup.org and kelwert@mtu.edu - Fix mz_crc32() so it doesn't compute the wrong CRC-32's when mz_ulong is 64-bit. - Temporarily/locally slammed in "typedef unsigned long mz_ulong" and re-ran a randomized regression test on ~500k files. - Eliminated a bunch of warnings when compiling with GCC 32-bit/64. - Ran all examples, miniz.c, and tinfl.c through MSVC 2008's /analyze (static analysis) option and fixed all warnings (except for the silly "Use of the comma-operator in a tested expression.." analysis warning, which I purposely use to work around a MSVC compiler warning). - Created 32-bit and 64-bit Codeblocks projects/workspace. Built and tested Linux executables. The codeblocks workspace is compatible with Linux+Win32/x64. - Added miniz_tester solution/project, which is a useful little app derived from LZHAM's tester app that I use as part of the regression test. - Ran miniz.c and tinfl.c through another series of regression testing on ~500,000 files and archives. - Modified example5.c so it purposely disables a bunch of high-level functionality (MINIZ_NO_STDIO, etc.). (Thanks to corysama for the MINIZ_NO_STDIO bug report.) - Fix ftell() usage in examples so they exit with an error on files which are too large (a limitation of the examples, not miniz itself). 4/12/12 v1.12 - More comments, added low-level example5.c, fixed a couple minor level_and_flags issues in the archive API's. level_and_flags can now be set to MZ_DEFAULT_COMPRESSION. Thanks to Bruce Dawson for the feedback/bug report. 5/28/11 v1.11 - Added statement from unlicense.org 5/27/11 v1.10 - Substantial compressor optimizations: - Level 1 is now ~4x faster than before. The L1 compressor's throughput now varies between 70-110MB/sec. on a - Core i7 (actual throughput varies depending on the type of data, and x64 vs. x86). - Improved baseline L2-L9 compression perf. Also, greatly improved compression perf. issues on some file types. - Refactored the compression code for better readability and maintainability. - Added level 10 compression level (L10 has slightly better ratio than level 9, but could have a potentially large drop in throughput on some files). 5/15/11 v1.09 - Initial stable release. * Low-level Deflate/Inflate implementation notes: Compression: Use the "tdefl" API's. The compressor supports raw, static, and dynamic blocks, lazy or greedy parsing, match length filtering, RLE-only, and Huffman-only streams. It performs and compresses approximately as well as zlib. Decompression: Use the "tinfl" API's. The entire decompressor is implemented as a single function coroutine: see tinfl_decompress(). It supports decompression into a 32KB (or larger power of 2) wrapping buffer, or into a memory block large enough to hold the entire file. The low-level tdefl/tinfl API's do not make any use of dynamic memory allocation. * zlib-style API notes: miniz.c implements a fairly large subset of zlib. There's enough functionality present for it to be a drop-in zlib replacement in many apps: The z_stream struct, optional memory allocation callbacks deflateInit/deflateInit2/deflate/deflateReset/deflateEnd/deflateBound inflateInit/inflateInit2/inflate/inflateEnd compress, compress2, compressBound, uncompress CRC-32, Adler-32 - Using modern, minimal code size, CPU cache friendly routines. Supports raw deflate streams or standard zlib streams with adler-32 checking. Limitations: The callback API's are not implemented yet. No support for gzip headers or zlib static dictionaries. I've tried to closely emulate zlib's various flavors of stream flushing and return status codes, but there are no guarantees that miniz.c pulls this off perfectly. * PNG writing: See the tdefl_write_image_to_png_file_in_memory() function, originally written by Alex Evans. Supports 1-4 bytes/pixel images. * ZIP archive API notes: The ZIP archive API's where designed with simplicity and efficiency in mind, with just enough abstraction to get the job done with minimal fuss. There are simple API's to retrieve file information, read files from existing archives, create new archives, append new files to existing archives, or clone archive data from one archive to another. It supports archives located in memory or the heap, on disk (using stdio.h), or you can specify custom file read/write callbacks. - Archive reading: Just call this function to read a single file from a disk archive: void *mz_zip_extract_archive_file_to_heap(const char *pZip_filename, const char *pArchive_name, size_t *pSize, mz_uint zip_flags); For more complex cases, use the "mz_zip_reader" functions. Upon opening an archive, the entire central directory is located and read as-is into memory, and subsequent file access only occurs when reading individual files. - Archives file scanning: The simple way is to use this function to scan a loaded archive for a specific file: int mz_zip_reader_locate_file(mz_zip_archive *pZip, const char *pName, const char *pComment, mz_uint flags); The locate operation can optionally check file comments too, which (as one example) can be used to identify multiple versions of the same file in an archive. This function uses a simple linear search through the central directory, so it's not very fast. Alternately, you can iterate through all the files in an archive (using mz_zip_reader_get_num_files()) and retrieve detailed info on each file by calling mz_zip_reader_file_stat(). - Archive creation: Use the "mz_zip_writer" functions. The ZIP writer immediately writes compressed file data to disk and builds an exact image of the central directory in memory. The central directory image is written all at once at the end of the archive file when the archive is finalized. The archive writer can optionally align each file's local header and file data to any power of 2 alignment, which can be useful when the archive will be read from optical media. Also, the writer supports placing arbitrary data blobs at the very beginning of ZIP archives. Archives written using either feature are still readable by any ZIP tool. - Archive appending: The simple way to add a single file to an archive is to call this function: mz_bool mz_zip_add_mem_to_archive_file_in_place(const char *pZip_filename, const char *pArchive_name, const void *pBuf, size_t buf_size, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags); The archive will be created if it doesn't already exist, otherwise it'll be appended to. Note the appending is done in-place and is not an atomic operation, so if something goes wrong during the operation it's possible the archive could be left without a central directory (although the local file headers and file data will be fine, so the archive will be recoverable). For more complex archive modification scenarios: 1. The safest way is to use a mz_zip_reader to read the existing archive, cloning only those bits you want to preserve into a new archive using using the mz_zip_writer_add_from_zip_reader() function (which compiles the compressed file data as-is). When you're done, delete the old archive and rename the newly written archive, and you're done. This is safe but requires a bunch of temporary disk space or heap memory. 2. Or, you can convert an mz_zip_reader in-place to an mz_zip_writer using mz_zip_writer_init_from_reader(), append new files as needed, then finalize the archive which will write an updated central directory to the original archive. (This is basically what mz_zip_add_mem_to_archive_file_in_place() does.) There's a possibility that the archive's central directory could be lost with this method if anything goes wrong, though. - ZIP archive support limitations: No zip64 or spanning support. Extraction functions can only handle unencrypted, stored or deflated files. Requires streams capable of seeking. * This is a header file library, like stb_image.c. To get only a header file, either cut and paste the below header, or create miniz.h, #define MINIZ_HEADER_FILE_ONLY, and then include miniz.c from it. * Important: For best perf. be sure to customize the below macros for your target platform: #define MINIZ_USE_UNALIGNED_LOADS_AND_STORES 1 #define MINIZ_LITTLE_ENDIAN 1 #define MINIZ_HAS_64BIT_REGISTERS 1 * On platforms using glibc, Be sure to "#define _LARGEFILE64_SOURCE 1" before including miniz.c to ensure miniz uses the 64-bit variants: fopen64(), stat64(), etc. Otherwise you won't be able to process large files (i.e. 32-bit stat() fails for me on files > 0x7FFFFFFF bytes). */ #ifndef MINIZ_HEADER_INCLUDED #define MINIZ_HEADER_INCLUDED #include // Defines to completely disable specific portions of miniz.c: // If all macros here are defined the only functionality remaining will be CRC-32, adler-32, tinfl, and tdefl. // Define MINIZ_NO_STDIO to disable all usage and any functions which rely on stdio for file I/O. //#define MINIZ_NO_STDIO // If MINIZ_NO_TIME is specified then the ZIP archive functions will not be able to get the current time, or // get/set file times, and the C run-time funcs that get/set times won't be called. // The current downside is the times written to your archives will be from 1979. //#define MINIZ_NO_TIME // Define MINIZ_NO_ARCHIVE_APIS to disable all ZIP archive API's. //#define MINIZ_NO_ARCHIVE_APIS // Define MINIZ_NO_ARCHIVE_APIS to disable all writing related ZIP archive API's. //#define MINIZ_NO_ARCHIVE_WRITING_APIS // Define MINIZ_NO_ZLIB_APIS to remove all ZLIB-style compression/decompression API's. //#define MINIZ_NO_ZLIB_APIS // Define MINIZ_NO_ZLIB_COMPATIBLE_NAME to disable zlib names, to prevent conflicts against stock zlib. //#define MINIZ_NO_ZLIB_COMPATIBLE_NAMES // Define MINIZ_NO_MALLOC to disable all calls to malloc, free, and realloc. // Note if MINIZ_NO_MALLOC is defined then the user must always provide custom user alloc/free/realloc // callbacks to the zlib and archive API's, and a few stand-alone helper API's which don't provide custom user // functions (such as tdefl_compress_mem_to_heap() and tinfl_decompress_mem_to_heap()) won't work. //#define MINIZ_NO_MALLOC #if defined(__TINYC__) && (defined(__linux) || defined(__linux__)) // TODO: Work around "error: include file 'sys\utime.h' when compiling with tcc on Linux #define MINIZ_NO_TIME #endif #if !defined(MINIZ_NO_TIME) && !defined(MINIZ_NO_ARCHIVE_APIS) #include #endif #if defined(_M_IX86) || defined(_M_X64) || defined(__i386__) || defined(__i386) || defined(__i486__) || defined(__i486) || defined(i386) || defined(__ia64__) || defined(__x86_64__) // MINIZ_X86_OR_X64_CPU is only used to help set the below macros. #define MINIZ_X86_OR_X64_CPU 1 #endif #if (__BYTE_ORDER__==__ORDER_LITTLE_ENDIAN__) || MINIZ_X86_OR_X64_CPU // Set MINIZ_LITTLE_ENDIAN to 1 if the processor is little endian. #define MINIZ_LITTLE_ENDIAN 1 #endif #if MINIZ_X86_OR_X64_CPU // Set MINIZ_USE_UNALIGNED_LOADS_AND_STORES to 1 on CPU's that permit efficient integer loads and stores from unaligned addresses. #define MINIZ_USE_UNALIGNED_LOADS_AND_STORES 1 #endif #if defined(_M_X64) || defined(_WIN64) || defined(__MINGW64__) || defined(_LP64) || defined(__LP64__) || defined(__ia64__) || defined(__x86_64__) // Set MINIZ_HAS_64BIT_REGISTERS to 1 if operations on 64-bit integers are reasonably fast (and don't involve compiler generated calls to helper functions). #define MINIZ_HAS_64BIT_REGISTERS 1 #endif #ifdef __cplusplus extern "C" { #endif // ------------------- zlib-style API Definitions. // For more compatibility with zlib, miniz.c uses unsigned long for some parameters/struct members. Beware: mz_ulong can be either 32 or 64-bits! typedef unsigned long mz_ulong; // mz_free() internally uses the MZ_FREE() macro (which by default calls free() unless you've modified the MZ_MALLOC macro) to release a block allocated from the heap. void mz_free(void *p); #define MZ_ADLER32_INIT (1) // mz_adler32() returns the initial adler-32 value to use when called with ptr==NULL. mz_ulong mz_adler32(mz_ulong adler, const unsigned char *ptr, size_t buf_len); #define MZ_CRC32_INIT (0) // mz_crc32() returns the initial CRC-32 value to use when called with ptr==NULL. mz_ulong mz_crc32(mz_ulong crc, const unsigned char *ptr, size_t buf_len); // Compression strategies. enum { MZ_DEFAULT_STRATEGY = 0, MZ_FILTERED = 1, MZ_HUFFMAN_ONLY = 2, MZ_RLE = 3, MZ_FIXED = 4 }; // Method #define MZ_DEFLATED 8 #ifndef MINIZ_NO_ZLIB_APIS // Heap allocation callbacks. // Note that mz_alloc_func parameter types purpsosely differ from zlib's: items/size is size_t, not unsigned long. typedef void *(*mz_alloc_func)(void *opaque, size_t items, size_t size); typedef void (*mz_free_func)(void *opaque, void *address); typedef void *(*mz_realloc_func)(void *opaque, void *address, size_t items, size_t size); #define MZ_VERSION "9.1.15" #define MZ_VERNUM 0x91F0 #define MZ_VER_MAJOR 9 #define MZ_VER_MINOR 1 #define MZ_VER_REVISION 15 #define MZ_VER_SUBREVISION 0 // Flush values. For typical usage you only need MZ_NO_FLUSH and MZ_FINISH. The other values are for advanced use (refer to the zlib docs). enum { MZ_NO_FLUSH = 0, MZ_PARTIAL_FLUSH = 1, MZ_SYNC_FLUSH = 2, MZ_FULL_FLUSH = 3, MZ_FINISH = 4, MZ_BLOCK = 5 }; // Return status codes. MZ_PARAM_ERROR is non-standard. enum { MZ_OK = 0, MZ_STREAM_END = 1, MZ_NEED_DICT = 2, MZ_ERRNO = -1, MZ_STREAM_ERROR = -2, MZ_DATA_ERROR = -3, MZ_MEM_ERROR = -4, MZ_BUF_ERROR = -5, MZ_VERSION_ERROR = -6, MZ_PARAM_ERROR = -10000 }; // Compression levels: 0-9 are the standard zlib-style levels, 10 is best possible compression (not zlib compatible, and may be very slow), MZ_DEFAULT_COMPRESSION=MZ_DEFAULT_LEVEL. enum { MZ_NO_COMPRESSION = 0, MZ_BEST_SPEED = 1, MZ_BEST_COMPRESSION = 9, MZ_UBER_COMPRESSION = 10, MZ_DEFAULT_LEVEL = 6, MZ_DEFAULT_COMPRESSION = -1 }; // Window bits #define MZ_DEFAULT_WINDOW_BITS 15 struct mz_internal_state; // Compression/decompression stream struct. typedef struct mz_stream_s { const unsigned char *next_in; // pointer to next byte to read unsigned int avail_in; // number of bytes available at next_in mz_ulong total_in; // total number of bytes consumed so far unsigned char *next_out; // pointer to next byte to write unsigned int avail_out; // number of bytes that can be written to next_out mz_ulong total_out; // total number of bytes produced so far char *msg; // error msg (unused) struct mz_internal_state *state; // internal state, allocated by zalloc/zfree mz_alloc_func zalloc; // optional heap allocation function (defaults to malloc) mz_free_func zfree; // optional heap free function (defaults to free) void *opaque; // heap alloc function user pointer int data_type; // data_type (unused) mz_ulong adler; // adler32 of the source or uncompressed data mz_ulong reserved; // not used } mz_stream; typedef mz_stream *mz_streamp; // Returns the version string of miniz.c. const char *mz_version(void); // mz_deflateInit() initializes a compressor with default options: // Parameters: // pStream must point to an initialized mz_stream struct. // level must be between [MZ_NO_COMPRESSION, MZ_BEST_COMPRESSION]. // level 1 enables a specially optimized compression function that's been optimized purely for performance, not ratio. // (This special func. is currently only enabled when MINIZ_USE_UNALIGNED_LOADS_AND_STORES and MINIZ_LITTLE_ENDIAN are defined.) // Return values: // MZ_OK on success. // MZ_STREAM_ERROR if the stream is bogus. // MZ_PARAM_ERROR if the input parameters are bogus. // MZ_MEM_ERROR on out of memory. int mz_deflateInit(mz_streamp pStream, int level); // mz_deflateInit2() is like mz_deflate(), except with more control: // Additional parameters: // method must be MZ_DEFLATED // window_bits must be MZ_DEFAULT_WINDOW_BITS (to wrap the deflate stream with zlib header/adler-32 footer) or -MZ_DEFAULT_WINDOW_BITS (raw deflate/no header or footer) // mem_level must be between [1, 9] (it's checked but ignored by miniz.c) int mz_deflateInit2(mz_streamp pStream, int level, int method, int window_bits, int mem_level, int strategy); // Quickly resets a compressor without having to reallocate anything. Same as calling mz_deflateEnd() followed by mz_deflateInit()/mz_deflateInit2(). int mz_deflateReset(mz_streamp pStream); // mz_deflate() compresses the input to output, consuming as much of the input and producing as much output as possible. // Parameters: // pStream is the stream to read from and write to. You must initialize/update the next_in, avail_in, next_out, and avail_out members. // flush may be MZ_NO_FLUSH, MZ_PARTIAL_FLUSH/MZ_SYNC_FLUSH, MZ_FULL_FLUSH, or MZ_FINISH. // Return values: // MZ_OK on success (when flushing, or if more input is needed but not available, and/or there's more output to be written but the output buffer is full). // MZ_STREAM_END if all input has been consumed and all output bytes have been written. Don't call mz_deflate() on the stream anymore. // MZ_STREAM_ERROR if the stream is bogus. // MZ_PARAM_ERROR if one of the parameters is invalid. // MZ_BUF_ERROR if no forward progress is possible because the input and/or output buffers are empty. (Fill up the input buffer or free up some output space and try again.) int mz_deflate(mz_streamp pStream, int flush); // mz_deflateEnd() deinitializes a compressor: // Return values: // MZ_OK on success. // MZ_STREAM_ERROR if the stream is bogus. int mz_deflateEnd(mz_streamp pStream); // mz_deflateBound() returns a (very) conservative upper bound on the amount of data that could be generated by deflate(), assuming flush is set to only MZ_NO_FLUSH or MZ_FINISH. mz_ulong mz_deflateBound(mz_streamp pStream, mz_ulong source_len); // Single-call compression functions mz_compress() and mz_compress2(): // Returns MZ_OK on success, or one of the error codes from mz_deflate() on failure. int mz_compress(unsigned char *pDest, mz_ulong *pDest_len, const unsigned char *pSource, mz_ulong source_len); int mz_compress2(unsigned char *pDest, mz_ulong *pDest_len, const unsigned char *pSource, mz_ulong source_len, int level); // mz_compressBound() returns a (very) conservative upper bound on the amount of data that could be generated by calling mz_compress(). mz_ulong mz_compressBound(mz_ulong source_len); // Initializes a decompressor. int mz_inflateInit(mz_streamp pStream); // mz_inflateInit2() is like mz_inflateInit() with an additional option that controls the window size and whether or not the stream has been wrapped with a zlib header/footer: // window_bits must be MZ_DEFAULT_WINDOW_BITS (to parse zlib header/footer) or -MZ_DEFAULT_WINDOW_BITS (raw deflate). int mz_inflateInit2(mz_streamp pStream, int window_bits); // Decompresses the input stream to the output, consuming only as much of the input as needed, and writing as much to the output as possible. // Parameters: // pStream is the stream to read from and write to. You must initialize/update the next_in, avail_in, next_out, and avail_out members. // flush may be MZ_NO_FLUSH, MZ_SYNC_FLUSH, or MZ_FINISH. // On the first call, if flush is MZ_FINISH it's assumed the input and output buffers are both sized large enough to decompress the entire stream in a single call (this is slightly faster). // MZ_FINISH implies that there are no more source bytes available beside what's already in the input buffer, and that the output buffer is large enough to hold the rest of the decompressed data. // Return values: // MZ_OK on success. Either more input is needed but not available, and/or there's more output to be written but the output buffer is full. // MZ_STREAM_END if all needed input has been consumed and all output bytes have been written. For zlib streams, the adler-32 of the decompressed data has also been verified. // MZ_STREAM_ERROR if the stream is bogus. // MZ_DATA_ERROR if the deflate stream is invalid. // MZ_PARAM_ERROR if one of the parameters is invalid. // MZ_BUF_ERROR if no forward progress is possible because the input buffer is empty but the inflater needs more input to continue, or if the output buffer is not large enough. Call mz_inflate() again // with more input data, or with more room in the output buffer (except when using single call decompression, described above). int mz_inflate(mz_streamp pStream, int flush); // Deinitializes a decompressor. int mz_inflateEnd(mz_streamp pStream); // Single-call decompression. // Returns MZ_OK on success, or one of the error codes from mz_inflate() on failure. int mz_uncompress(unsigned char *pDest, mz_ulong *pDest_len, const unsigned char *pSource, mz_ulong source_len); // Returns a string description of the specified error code, or NULL if the error code is invalid. const char *mz_error(int err); // Redefine zlib-compatible names to miniz equivalents, so miniz.c can be used as a drop-in replacement for the subset of zlib that miniz.c supports. // Define MINIZ_NO_ZLIB_COMPATIBLE_NAMES to disable zlib-compatibility if you use zlib in the same project. #ifndef MINIZ_NO_ZLIB_COMPATIBLE_NAMES typedef unsigned char Byte; typedef unsigned int uInt; typedef mz_ulong uLong; typedef Byte Bytef; typedef uInt uIntf; typedef char charf; typedef int intf; typedef void *voidpf; typedef uLong uLongf; typedef void *voidp; typedef void *const voidpc; #define Z_NULL 0 #define Z_NO_FLUSH MZ_NO_FLUSH #define Z_PARTIAL_FLUSH MZ_PARTIAL_FLUSH #define Z_SYNC_FLUSH MZ_SYNC_FLUSH #define Z_FULL_FLUSH MZ_FULL_FLUSH #define Z_FINISH MZ_FINISH #define Z_BLOCK MZ_BLOCK #define Z_OK MZ_OK #define Z_STREAM_END MZ_STREAM_END #define Z_NEED_DICT MZ_NEED_DICT #define Z_ERRNO MZ_ERRNO #define Z_STREAM_ERROR MZ_STREAM_ERROR #define Z_DATA_ERROR MZ_DATA_ERROR #define Z_MEM_ERROR MZ_MEM_ERROR #define Z_BUF_ERROR MZ_BUF_ERROR #define Z_VERSION_ERROR MZ_VERSION_ERROR #define Z_PARAM_ERROR MZ_PARAM_ERROR #define Z_NO_COMPRESSION MZ_NO_COMPRESSION #define Z_BEST_SPEED MZ_BEST_SPEED #define Z_BEST_COMPRESSION MZ_BEST_COMPRESSION #define Z_DEFAULT_COMPRESSION MZ_DEFAULT_COMPRESSION #define Z_DEFAULT_STRATEGY MZ_DEFAULT_STRATEGY #define Z_FILTERED MZ_FILTERED #define Z_HUFFMAN_ONLY MZ_HUFFMAN_ONLY #define Z_RLE MZ_RLE #define Z_FIXED MZ_FIXED #define Z_DEFLATED MZ_DEFLATED #define Z_DEFAULT_WINDOW_BITS MZ_DEFAULT_WINDOW_BITS #define alloc_func mz_alloc_func #define free_func mz_free_func #define internal_state mz_internal_state #define z_stream mz_stream #define deflateInit mz_deflateInit #define deflateInit2 mz_deflateInit2 #define deflateReset mz_deflateReset #define deflate mz_deflate #define deflateEnd mz_deflateEnd #define deflateBound mz_deflateBound #define compress mz_compress #define compress2 mz_compress2 #define compressBound mz_compressBound #define inflateInit mz_inflateInit #define inflateInit2 mz_inflateInit2 #define inflate mz_inflate #define inflateEnd mz_inflateEnd #define uncompress mz_uncompress #define crc32 mz_crc32 #define adler32 mz_adler32 #define MAX_WBITS 15 #define MAX_MEM_LEVEL 9 #define zError mz_error #define ZLIB_VERSION MZ_VERSION #define ZLIB_VERNUM MZ_VERNUM #define ZLIB_VER_MAJOR MZ_VER_MAJOR #define ZLIB_VER_MINOR MZ_VER_MINOR #define ZLIB_VER_REVISION MZ_VER_REVISION #define ZLIB_VER_SUBREVISION MZ_VER_SUBREVISION #define zlibVersion mz_version #define zlib_version mz_version() #endif // #ifndef MINIZ_NO_ZLIB_COMPATIBLE_NAMES #endif // MINIZ_NO_ZLIB_APIS // ------------------- Types and macros typedef unsigned char mz_uint8; typedef signed short mz_int16; typedef unsigned short mz_uint16; typedef unsigned int mz_uint32; typedef unsigned int mz_uint; typedef long long mz_int64; typedef unsigned long long mz_uint64; typedef int mz_bool; #define MZ_FALSE (0) #define MZ_TRUE (1) // An attempt to work around MSVC's spammy "warning C4127: conditional expression is constant" message. #ifdef _MSC_VER #define MZ_MACRO_END while (0, 0) #else #define MZ_MACRO_END while (0) #endif // ------------------- ZIP archive reading/writing #ifndef MINIZ_NO_ARCHIVE_APIS enum { MZ_ZIP_MAX_IO_BUF_SIZE = 64*1024, MZ_ZIP_MAX_ARCHIVE_FILENAME_SIZE = 260, MZ_ZIP_MAX_ARCHIVE_FILE_COMMENT_SIZE = 256 }; typedef struct { mz_uint32 m_file_index; mz_uint32 m_central_dir_ofs; mz_uint16 m_version_made_by; mz_uint16 m_version_needed; mz_uint16 m_bit_flag; mz_uint16 m_method; #ifndef MINIZ_NO_TIME time_t m_time; #endif mz_uint32 m_crc32; mz_uint64 m_comp_size; mz_uint64 m_uncomp_size; mz_uint16 m_internal_attr; mz_uint32 m_external_attr; mz_uint64 m_local_header_ofs; mz_uint32 m_comment_size; char m_filename[MZ_ZIP_MAX_ARCHIVE_FILENAME_SIZE]; char m_comment[MZ_ZIP_MAX_ARCHIVE_FILE_COMMENT_SIZE]; } mz_zip_archive_file_stat; typedef size_t (*mz_file_read_func)(void *pOpaque, mz_uint64 file_ofs, void *pBuf, size_t n); typedef size_t (*mz_file_write_func)(void *pOpaque, mz_uint64 file_ofs, const void *pBuf, size_t n); struct mz_zip_internal_state_tag; typedef struct mz_zip_internal_state_tag mz_zip_internal_state; typedef enum { MZ_ZIP_MODE_INVALID = 0, MZ_ZIP_MODE_READING = 1, MZ_ZIP_MODE_WRITING = 2, MZ_ZIP_MODE_WRITING_HAS_BEEN_FINALIZED = 3 } mz_zip_mode; typedef struct mz_zip_archive_tag { mz_uint64 m_archive_size; mz_uint64 m_archive_file_ofs; mz_uint64 m_central_directory_file_ofs; mz_uint m_total_files; mz_zip_mode m_zip_mode; mz_uint m_file_offset_alignment; mz_alloc_func m_pAlloc; mz_free_func m_pFree; mz_realloc_func m_pRealloc; void *m_pAlloc_opaque; mz_file_read_func m_pRead; mz_file_write_func m_pWrite; void *m_pIO_opaque; mz_zip_internal_state *m_pState; } mz_zip_archive; typedef enum { MZ_ZIP_FLAG_CASE_SENSITIVE = 0x0100, MZ_ZIP_FLAG_IGNORE_PATH = 0x0200, MZ_ZIP_FLAG_COMPRESSED_DATA = 0x0400, MZ_ZIP_FLAG_DO_NOT_SORT_CENTRAL_DIRECTORY = 0x0800 } mz_zip_flags; // ZIP archive reading // Inits a ZIP archive reader. // These functions read and validate the archive's central directory. mz_bool mz_zip_reader_init(mz_zip_archive *pZip, mz_uint64 size, mz_uint32 flags); mz_bool mz_zip_reader_init_mem(mz_zip_archive *pZip, const void *pMem, size_t size, mz_uint32 flags); #ifndef MINIZ_NO_STDIO mz_bool mz_zip_reader_init_file(mz_zip_archive *pZip, const char *pFilename, mz_uint32 flags); #endif // Returns the total number of files in the archive. mz_uint mz_zip_reader_get_num_files(mz_zip_archive *pZip); // Returns detailed information about an archive file entry. mz_bool mz_zip_reader_file_stat(mz_zip_archive *pZip, mz_uint file_index, mz_zip_archive_file_stat *pStat); // Determines if an archive file entry is a directory entry. mz_bool mz_zip_reader_is_file_a_directory(mz_zip_archive *pZip, mz_uint file_index); mz_bool mz_zip_reader_is_file_encrypted(mz_zip_archive *pZip, mz_uint file_index); // Retrieves the filename of an archive file entry. // Returns the number of bytes written to pFilename, or if filename_buf_size is 0 this function returns the number of bytes needed to fully store the filename. mz_uint mz_zip_reader_get_filename(mz_zip_archive *pZip, mz_uint file_index, char *pFilename, mz_uint filename_buf_size); // Attempts to locates a file in the archive's central directory. // Valid flags: MZ_ZIP_FLAG_CASE_SENSITIVE, MZ_ZIP_FLAG_IGNORE_PATH // Returns -1 if the file cannot be found. int mz_zip_reader_locate_file(mz_zip_archive *pZip, const char *pName, const char *pComment, mz_uint flags); // Extracts a archive file to a memory buffer using no memory allocation. mz_bool mz_zip_reader_extract_to_mem_no_alloc(mz_zip_archive *pZip, mz_uint file_index, void *pBuf, size_t buf_size, mz_uint flags, void *pUser_read_buf, size_t user_read_buf_size); mz_bool mz_zip_reader_extract_file_to_mem_no_alloc(mz_zip_archive *pZip, const char *pFilename, void *pBuf, size_t buf_size, mz_uint flags, void *pUser_read_buf, size_t user_read_buf_size); // Extracts a archive file to a memory buffer. mz_bool mz_zip_reader_extract_to_mem(mz_zip_archive *pZip, mz_uint file_index, void *pBuf, size_t buf_size, mz_uint flags); mz_bool mz_zip_reader_extract_file_to_mem(mz_zip_archive *pZip, const char *pFilename, void *pBuf, size_t buf_size, mz_uint flags); // Extracts a archive file to a dynamically allocated heap buffer. void *mz_zip_reader_extract_to_heap(mz_zip_archive *pZip, mz_uint file_index, size_t *pSize, mz_uint flags); void *mz_zip_reader_extract_file_to_heap(mz_zip_archive *pZip, const char *pFilename, size_t *pSize, mz_uint flags); // Extracts a archive file using a callback function to output the file's data. mz_bool mz_zip_reader_extract_to_callback(mz_zip_archive *pZip, mz_uint file_index, mz_file_write_func pCallback, void *pOpaque, mz_uint flags); mz_bool mz_zip_reader_extract_file_to_callback(mz_zip_archive *pZip, const char *pFilename, mz_file_write_func pCallback, void *pOpaque, mz_uint flags); #ifndef MINIZ_NO_STDIO // Extracts a archive file to a disk file and sets its last accessed and modified times. // This function only extracts files, not archive directory records. mz_bool mz_zip_reader_extract_to_file(mz_zip_archive *pZip, mz_uint file_index, const char *pDst_filename, mz_uint flags); mz_bool mz_zip_reader_extract_file_to_file(mz_zip_archive *pZip, const char *pArchive_filename, const char *pDst_filename, mz_uint flags); #endif // Ends archive reading, freeing all allocations, and closing the input archive file if mz_zip_reader_init_file() was used. mz_bool mz_zip_reader_end(mz_zip_archive *pZip); // ZIP archive writing #ifndef MINIZ_NO_ARCHIVE_WRITING_APIS // Inits a ZIP archive writer. mz_bool mz_zip_writer_init(mz_zip_archive *pZip, mz_uint64 existing_size); mz_bool mz_zip_writer_init_heap(mz_zip_archive *pZip, size_t size_to_reserve_at_beginning, size_t initial_allocation_size); #ifndef MINIZ_NO_STDIO mz_bool mz_zip_writer_init_file(mz_zip_archive *pZip, const char *pFilename, mz_uint64 size_to_reserve_at_beginning); #endif // Converts a ZIP archive reader object into a writer object, to allow efficient in-place file appends to occur on an existing archive. // For archives opened using mz_zip_reader_init_file, pFilename must be the archive's filename so it can be reopened for writing. If the file can't be reopened, mz_zip_reader_end() will be called. // For archives opened using mz_zip_reader_init_mem, the memory block must be growable using the realloc callback (which defaults to realloc unless you've overridden it). // Finally, for archives opened using mz_zip_reader_init, the mz_zip_archive's user provided m_pWrite function cannot be NULL. // Note: In-place archive modification is not recommended unless you know what you're doing, because if execution stops or something goes wrong before // the archive is finalized the file's central directory will be hosed. mz_bool mz_zip_writer_init_from_reader(mz_zip_archive *pZip, const char *pFilename); // Adds the contents of a memory buffer to an archive. These functions record the current local time into the archive. // To add a directory entry, call this method with an archive name ending in a forwardslash with empty buffer. // level_and_flags - compression level (0-10, see MZ_BEST_SPEED, MZ_BEST_COMPRESSION, etc.) logically OR'd with zero or more mz_zip_flags, or just set to MZ_DEFAULT_COMPRESSION. mz_bool mz_zip_writer_add_mem(mz_zip_archive *pZip, const char *pArchive_name, const void *pBuf, size_t buf_size, mz_uint level_and_flags); mz_bool mz_zip_writer_add_mem_ex(mz_zip_archive *pZip, const char *pArchive_name, const void *pBuf, size_t buf_size, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags, mz_uint64 uncomp_size, mz_uint32 uncomp_crc32); #ifndef MINIZ_NO_STDIO // Adds the contents of a disk file to an archive. This function also records the disk file's modified time into the archive. // level_and_flags - compression level (0-10, see MZ_BEST_SPEED, MZ_BEST_COMPRESSION, etc.) logically OR'd with zero or more mz_zip_flags, or just set to MZ_DEFAULT_COMPRESSION. mz_bool mz_zip_writer_add_file(mz_zip_archive *pZip, const char *pArchive_name, const char *pSrc_filename, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags); #endif // Adds a file to an archive by fully cloning the data from another archive. // This function fully clones the source file's compressed data (no recompression), along with its full filename, extra data, and comment fields. mz_bool mz_zip_writer_add_from_zip_reader(mz_zip_archive *pZip, mz_zip_archive *pSource_zip, mz_uint file_index); // Finalizes the archive by writing the central directory records followed by the end of central directory record. // After an archive is finalized, the only valid call on the mz_zip_archive struct is mz_zip_writer_end(). // An archive must be manually finalized by calling this function for it to be valid. mz_bool mz_zip_writer_finalize_archive(mz_zip_archive *pZip); mz_bool mz_zip_writer_finalize_heap_archive(mz_zip_archive *pZip, void **pBuf, size_t *pSize); // Ends archive writing, freeing all allocations, and closing the output file if mz_zip_writer_init_file() was used. // Note for the archive to be valid, it must have been finalized before ending. mz_bool mz_zip_writer_end(mz_zip_archive *pZip); // Misc. high-level helper functions: // mz_zip_add_mem_to_archive_file_in_place() efficiently (but not atomically) appends a memory blob to a ZIP archive. // level_and_flags - compression level (0-10, see MZ_BEST_SPEED, MZ_BEST_COMPRESSION, etc.) logically OR'd with zero or more mz_zip_flags, or just set to MZ_DEFAULT_COMPRESSION. mz_bool mz_zip_add_mem_to_archive_file_in_place(const char *pZip_filename, const char *pArchive_name, const void *pBuf, size_t buf_size, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags); // Reads a single file from an archive into a heap block. // Returns NULL on failure. void *mz_zip_extract_archive_file_to_heap(const char *pZip_filename, const char *pArchive_name, size_t *pSize, mz_uint zip_flags); #endif // #ifndef MINIZ_NO_ARCHIVE_WRITING_APIS #endif // #ifndef MINIZ_NO_ARCHIVE_APIS // ------------------- Low-level Decompression API Definitions // Decompression flags used by tinfl_decompress(). // TINFL_FLAG_PARSE_ZLIB_HEADER: If set, the input has a valid zlib header and ends with an adler32 checksum (it's a valid zlib stream). Otherwise, the input is a raw deflate stream. // TINFL_FLAG_HAS_MORE_INPUT: If set, there are more input bytes available beyond the end of the supplied input buffer. If clear, the input buffer contains all remaining input. // TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF: If set, the output buffer is large enough to hold the entire decompressed stream. If clear, the output buffer is at least the size of the dictionary (typically 32KB). // TINFL_FLAG_COMPUTE_ADLER32: Force adler-32 checksum computation of the decompressed bytes. enum { TINFL_FLAG_PARSE_ZLIB_HEADER = 1, TINFL_FLAG_HAS_MORE_INPUT = 2, TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF = 4, TINFL_FLAG_COMPUTE_ADLER32 = 8 }; // High level decompression functions: // tinfl_decompress_mem_to_heap() decompresses a block in memory to a heap block allocated via malloc(). // On entry: // pSrc_buf, src_buf_len: Pointer and size of the Deflate or zlib source data to decompress. // On return: // Function returns a pointer to the decompressed data, or NULL on failure. // *pOut_len will be set to the decompressed data's size, which could be larger than src_buf_len on uncompressible data. // The caller must call mz_free() on the returned block when it's no longer needed. void *tinfl_decompress_mem_to_heap(const void *pSrc_buf, size_t src_buf_len, size_t *pOut_len, int flags); // tinfl_decompress_mem_to_mem() decompresses a block in memory to another block in memory. // Returns TINFL_DECOMPRESS_MEM_TO_MEM_FAILED on failure, or the number of bytes written on success. #define TINFL_DECOMPRESS_MEM_TO_MEM_FAILED ((size_t)(-1)) size_t tinfl_decompress_mem_to_mem(void *pOut_buf, size_t out_buf_len, const void *pSrc_buf, size_t src_buf_len, int flags); // tinfl_decompress_mem_to_callback() decompresses a block in memory to an internal 32KB buffer, and a user provided callback function will be called to flush the buffer. // Returns 1 on success or 0 on failure. typedef int (*tinfl_put_buf_func_ptr)(const void* pBuf, int len, void *pUser); int tinfl_decompress_mem_to_callback(const void *pIn_buf, size_t *pIn_buf_size, tinfl_put_buf_func_ptr pPut_buf_func, void *pPut_buf_user, int flags); struct tinfl_decompressor_tag; typedef struct tinfl_decompressor_tag tinfl_decompressor; // Max size of LZ dictionary. #define TINFL_LZ_DICT_SIZE 32768 // Return status. typedef enum { TINFL_STATUS_BAD_PARAM = -3, TINFL_STATUS_ADLER32_MISMATCH = -2, TINFL_STATUS_FAILED = -1, TINFL_STATUS_DONE = 0, TINFL_STATUS_NEEDS_MORE_INPUT = 1, TINFL_STATUS_HAS_MORE_OUTPUT = 2 } tinfl_status; // Initializes the decompressor to its initial state. #define tinfl_init(r) do { (r)->m_state = 0; } MZ_MACRO_END #define tinfl_get_adler32(r) (r)->m_check_adler32 // Main low-level decompressor coroutine function. This is the only function actually needed for decompression. All the other functions are just high-level helpers for improved usability. // This is a universal API, i.e. it can be used as a building block to build any desired higher level decompression API. In the limit case, it can be called once per every byte input or output. tinfl_status tinfl_decompress(tinfl_decompressor *r, const mz_uint8 *pIn_buf_next, size_t *pIn_buf_size, mz_uint8 *pOut_buf_start, mz_uint8 *pOut_buf_next, size_t *pOut_buf_size, const mz_uint32 decomp_flags); // Internal/private bits follow. enum { TINFL_MAX_HUFF_TABLES = 3, TINFL_MAX_HUFF_SYMBOLS_0 = 288, TINFL_MAX_HUFF_SYMBOLS_1 = 32, TINFL_MAX_HUFF_SYMBOLS_2 = 19, TINFL_FAST_LOOKUP_BITS = 10, TINFL_FAST_LOOKUP_SIZE = 1 << TINFL_FAST_LOOKUP_BITS }; typedef struct { mz_uint8 m_code_size[TINFL_MAX_HUFF_SYMBOLS_0]; mz_int16 m_look_up[TINFL_FAST_LOOKUP_SIZE], m_tree[TINFL_MAX_HUFF_SYMBOLS_0 * 2]; } tinfl_huff_table; #if MINIZ_HAS_64BIT_REGISTERS #define TINFL_USE_64BIT_BITBUF 1 #endif #if TINFL_USE_64BIT_BITBUF typedef mz_uint64 tinfl_bit_buf_t; #define TINFL_BITBUF_SIZE (64) #else typedef mz_uint32 tinfl_bit_buf_t; #define TINFL_BITBUF_SIZE (32) #endif struct tinfl_decompressor_tag { mz_uint32 m_state, m_num_bits, m_zhdr0, m_zhdr1, m_z_adler32, m_final, m_type, m_check_adler32, m_dist, m_counter, m_num_extra, m_table_sizes[TINFL_MAX_HUFF_TABLES]; tinfl_bit_buf_t m_bit_buf; size_t m_dist_from_out_buf_start; tinfl_huff_table m_tables[TINFL_MAX_HUFF_TABLES]; mz_uint8 m_raw_header[4], m_len_codes[TINFL_MAX_HUFF_SYMBOLS_0 + TINFL_MAX_HUFF_SYMBOLS_1 + 137]; }; // ------------------- Low-level Compression API Definitions // Set TDEFL_LESS_MEMORY to 1 to use less memory (compression will be slightly slower, and raw/dynamic blocks will be output more frequently). #define TDEFL_LESS_MEMORY 0 // tdefl_init() compression flags logically OR'd together (low 12 bits contain the max. number of probes per dictionary search): // TDEFL_DEFAULT_MAX_PROBES: The compressor defaults to 128 dictionary probes per dictionary search. 0=Huffman only, 1=Huffman+LZ (fastest/crap compression), 4095=Huffman+LZ (slowest/best compression). enum { TDEFL_HUFFMAN_ONLY = 0, TDEFL_DEFAULT_MAX_PROBES = 128, TDEFL_MAX_PROBES_MASK = 0xFFF }; // TDEFL_WRITE_ZLIB_HEADER: If set, the compressor outputs a zlib header before the deflate data, and the Adler-32 of the source data at the end. Otherwise, you'll get raw deflate data. // TDEFL_COMPUTE_ADLER32: Always compute the adler-32 of the input data (even when not writing zlib headers). // TDEFL_GREEDY_PARSING_FLAG: Set to use faster greedy parsing, instead of more efficient lazy parsing. // TDEFL_NONDETERMINISTIC_PARSING_FLAG: Enable to decrease the compressor's initialization time to the minimum, but the output may vary from run to run given the same input (depending on the contents of memory). // TDEFL_RLE_MATCHES: Only look for RLE matches (matches with a distance of 1) // TDEFL_FILTER_MATCHES: Discards matches <= 5 chars if enabled. // TDEFL_FORCE_ALL_STATIC_BLOCKS: Disable usage of optimized Huffman tables. // TDEFL_FORCE_ALL_RAW_BLOCKS: Only use raw (uncompressed) deflate blocks. // The low 12 bits are reserved to control the max # of hash probes per dictionary lookup (see TDEFL_MAX_PROBES_MASK). enum { TDEFL_WRITE_ZLIB_HEADER = 0x01000, TDEFL_COMPUTE_ADLER32 = 0x02000, TDEFL_GREEDY_PARSING_FLAG = 0x04000, TDEFL_NONDETERMINISTIC_PARSING_FLAG = 0x08000, TDEFL_RLE_MATCHES = 0x10000, TDEFL_FILTER_MATCHES = 0x20000, TDEFL_FORCE_ALL_STATIC_BLOCKS = 0x40000, TDEFL_FORCE_ALL_RAW_BLOCKS = 0x80000 }; // High level compression functions: // tdefl_compress_mem_to_heap() compresses a block in memory to a heap block allocated via malloc(). // On entry: // pSrc_buf, src_buf_len: Pointer and size of source block to compress. // flags: The max match finder probes (default is 128) logically OR'd against the above flags. Higher probes are slower but improve compression. // On return: // Function returns a pointer to the compressed data, or NULL on failure. // *pOut_len will be set to the compressed data's size, which could be larger than src_buf_len on uncompressible data. // The caller must free() the returned block when it's no longer needed. void *tdefl_compress_mem_to_heap(const void *pSrc_buf, size_t src_buf_len, size_t *pOut_len, int flags); // tdefl_compress_mem_to_mem() compresses a block in memory to another block in memory. // Returns 0 on failure. size_t tdefl_compress_mem_to_mem(void *pOut_buf, size_t out_buf_len, const void *pSrc_buf, size_t src_buf_len, int flags); // Compresses an image to a compressed PNG file in memory. // On entry: // pImage, w, h, and num_chans describe the image to compress. num_chans may be 1, 2, 3, or 4. // The image pitch in bytes per scanline will be w*num_chans. The leftmost pixel on the top scanline is stored first in memory. // level may range from [0,10], use MZ_NO_COMPRESSION, MZ_BEST_SPEED, MZ_BEST_COMPRESSION, etc. or a decent default is MZ_DEFAULT_LEVEL // If flip is true, the image will be flipped on the Y axis (useful for OpenGL apps). // On return: // Function returns a pointer to the compressed data, or NULL on failure. // *pLen_out will be set to the size of the PNG image file. // The caller must mz_free() the returned heap block (which will typically be larger than *pLen_out) when it's no longer needed. void *tdefl_write_image_to_png_file_in_memory_ex(const void *pImage, int w, int h, int num_chans, size_t *pLen_out, mz_uint level, mz_bool flip); void *tdefl_write_image_to_png_file_in_memory(const void *pImage, int w, int h, int num_chans, size_t *pLen_out); // Output stream interface. The compressor uses this interface to write compressed data. It'll typically be called TDEFL_OUT_BUF_SIZE at a time. typedef mz_bool (*tdefl_put_buf_func_ptr)(const void* pBuf, int len, void *pUser); // tdefl_compress_mem_to_output() compresses a block to an output stream. The above helpers use this function internally. mz_bool tdefl_compress_mem_to_output(const void *pBuf, size_t buf_len, tdefl_put_buf_func_ptr pPut_buf_func, void *pPut_buf_user, int flags); enum { TDEFL_MAX_HUFF_TABLES = 3, TDEFL_MAX_HUFF_SYMBOLS_0 = 288, TDEFL_MAX_HUFF_SYMBOLS_1 = 32, TDEFL_MAX_HUFF_SYMBOLS_2 = 19, TDEFL_LZ_DICT_SIZE = 32768, TDEFL_LZ_DICT_SIZE_MASK = TDEFL_LZ_DICT_SIZE - 1, TDEFL_MIN_MATCH_LEN = 3, TDEFL_MAX_MATCH_LEN = 258 }; // TDEFL_OUT_BUF_SIZE MUST be large enough to hold a single entire compressed output block (using static/fixed Huffman codes). #if TDEFL_LESS_MEMORY enum { TDEFL_LZ_CODE_BUF_SIZE = 24 * 1024, TDEFL_OUT_BUF_SIZE = (TDEFL_LZ_CODE_BUF_SIZE * 13 ) / 10, TDEFL_MAX_HUFF_SYMBOLS = 288, TDEFL_LZ_HASH_BITS = 12, TDEFL_LEVEL1_HASH_SIZE_MASK = 4095, TDEFL_LZ_HASH_SHIFT = (TDEFL_LZ_HASH_BITS + 2) / 3, TDEFL_LZ_HASH_SIZE = 1 << TDEFL_LZ_HASH_BITS }; #else enum { TDEFL_LZ_CODE_BUF_SIZE = 64 * 1024, TDEFL_OUT_BUF_SIZE = (TDEFL_LZ_CODE_BUF_SIZE * 13 ) / 10, TDEFL_MAX_HUFF_SYMBOLS = 288, TDEFL_LZ_HASH_BITS = 15, TDEFL_LEVEL1_HASH_SIZE_MASK = 4095, TDEFL_LZ_HASH_SHIFT = (TDEFL_LZ_HASH_BITS + 2) / 3, TDEFL_LZ_HASH_SIZE = 1 << TDEFL_LZ_HASH_BITS }; #endif // The low-level tdefl functions below may be used directly if the above helper functions aren't flexible enough. The low-level functions don't make any heap allocations, unlike the above helper functions. typedef enum { TDEFL_STATUS_BAD_PARAM = -2, TDEFL_STATUS_PUT_BUF_FAILED = -1, TDEFL_STATUS_OKAY = 0, TDEFL_STATUS_DONE = 1, } tdefl_status; // Must map to MZ_NO_FLUSH, MZ_SYNC_FLUSH, etc. enums typedef enum { TDEFL_NO_FLUSH = 0, TDEFL_SYNC_FLUSH = 2, TDEFL_FULL_FLUSH = 3, TDEFL_FINISH = 4 } tdefl_flush; // tdefl's compression state structure. typedef struct { tdefl_put_buf_func_ptr m_pPut_buf_func; void *m_pPut_buf_user; mz_uint m_flags, m_max_probes[2]; int m_greedy_parsing; mz_uint m_adler32, m_lookahead_pos, m_lookahead_size, m_dict_size; mz_uint8 *m_pLZ_code_buf, *m_pLZ_flags, *m_pOutput_buf, *m_pOutput_buf_end; mz_uint m_num_flags_left, m_total_lz_bytes, m_lz_code_buf_dict_pos, m_bits_in, m_bit_buffer; mz_uint m_saved_match_dist, m_saved_match_len, m_saved_lit, m_output_flush_ofs, m_output_flush_remaining, m_finished, m_block_index, m_wants_to_finish; tdefl_status m_prev_return_status; const void *m_pIn_buf; void *m_pOut_buf; size_t *m_pIn_buf_size, *m_pOut_buf_size; tdefl_flush m_flush; const mz_uint8 *m_pSrc; size_t m_src_buf_left, m_out_buf_ofs; mz_uint8 m_dict[TDEFL_LZ_DICT_SIZE + TDEFL_MAX_MATCH_LEN - 1]; mz_uint16 m_huff_count[TDEFL_MAX_HUFF_TABLES][TDEFL_MAX_HUFF_SYMBOLS]; mz_uint16 m_huff_codes[TDEFL_MAX_HUFF_TABLES][TDEFL_MAX_HUFF_SYMBOLS]; mz_uint8 m_huff_code_sizes[TDEFL_MAX_HUFF_TABLES][TDEFL_MAX_HUFF_SYMBOLS]; mz_uint8 m_lz_code_buf[TDEFL_LZ_CODE_BUF_SIZE]; mz_uint16 m_next[TDEFL_LZ_DICT_SIZE]; mz_uint16 m_hash[TDEFL_LZ_HASH_SIZE]; mz_uint8 m_output_buf[TDEFL_OUT_BUF_SIZE]; } tdefl_compressor; // Initializes the compressor. // There is no corresponding deinit() function because the tdefl API's do not dynamically allocate memory. // pBut_buf_func: If NULL, output data will be supplied to the specified callback. In this case, the user should call the tdefl_compress_buffer() API for compression. // If pBut_buf_func is NULL the user should always call the tdefl_compress() API. // flags: See the above enums (TDEFL_HUFFMAN_ONLY, TDEFL_WRITE_ZLIB_HEADER, etc.) tdefl_status tdefl_init(tdefl_compressor *d, tdefl_put_buf_func_ptr pPut_buf_func, void *pPut_buf_user, int flags); // Compresses a block of data, consuming as much of the specified input buffer as possible, and writing as much compressed data to the specified output buffer as possible. tdefl_status tdefl_compress(tdefl_compressor *d, const void *pIn_buf, size_t *pIn_buf_size, void *pOut_buf, size_t *pOut_buf_size, tdefl_flush flush); // tdefl_compress_buffer() is only usable when the tdefl_init() is called with a non-NULL tdefl_put_buf_func_ptr. // tdefl_compress_buffer() always consumes the entire input buffer. tdefl_status tdefl_compress_buffer(tdefl_compressor *d, const void *pIn_buf, size_t in_buf_size, tdefl_flush flush); tdefl_status tdefl_get_prev_return_status(tdefl_compressor *d); mz_uint32 tdefl_get_adler32(tdefl_compressor *d); // Can't use tdefl_create_comp_flags_from_zip_params if MINIZ_NO_ZLIB_APIS isn't defined, because it uses some of its macros. #ifndef MINIZ_NO_ZLIB_APIS // Create tdefl_compress() flags given zlib-style compression parameters. // level may range from [0,10] (where 10 is absolute max compression, but may be much slower on some files) // window_bits may be -15 (raw deflate) or 15 (zlib) // strategy may be either MZ_DEFAULT_STRATEGY, MZ_FILTERED, MZ_HUFFMAN_ONLY, MZ_RLE, or MZ_FIXED mz_uint tdefl_create_comp_flags_from_zip_params(int level, int window_bits, int strategy); #endif // #ifndef MINIZ_NO_ZLIB_APIS #ifdef __cplusplus } #endif #endif // MINIZ_HEADER_INCLUDED // ------------------- End of Header: Implementation follows. (If you only want the header, define MINIZ_HEADER_FILE_ONLY.) #ifndef MINIZ_HEADER_FILE_ONLY typedef unsigned char mz_validate_uint16[sizeof(mz_uint16)==2 ? 1 : -1]; typedef unsigned char mz_validate_uint32[sizeof(mz_uint32)==4 ? 1 : -1]; typedef unsigned char mz_validate_uint64[sizeof(mz_uint64)==8 ? 1 : -1]; #include #include #define MZ_ASSERT(x) assert(x) #ifdef MINIZ_NO_MALLOC #define MZ_MALLOC(x) NULL #define MZ_FREE(x) (void)x, ((void)0) #define MZ_REALLOC(p, x) NULL #else #define MZ_MALLOC(x) malloc(x) #define MZ_FREE(x) free(x) #define MZ_REALLOC(p, x) realloc(p, x) #endif #define MZ_MAX(a,b) (((a)>(b))?(a):(b)) #define MZ_MIN(a,b) (((a)<(b))?(a):(b)) #define MZ_CLEAR_OBJ(obj) memset(&(obj), 0, sizeof(obj)) #if MINIZ_USE_UNALIGNED_LOADS_AND_STORES && MINIZ_LITTLE_ENDIAN #define MZ_READ_LE16(p) *((const mz_uint16 *)(p)) #define MZ_READ_LE32(p) *((const mz_uint32 *)(p)) #else #define MZ_READ_LE16(p) ((mz_uint32)(((const mz_uint8 *)(p))[0]) | ((mz_uint32)(((const mz_uint8 *)(p))[1]) << 8U)) #define MZ_READ_LE32(p) ((mz_uint32)(((const mz_uint8 *)(p))[0]) | ((mz_uint32)(((const mz_uint8 *)(p))[1]) << 8U) | ((mz_uint32)(((const mz_uint8 *)(p))[2]) << 16U) | ((mz_uint32)(((const mz_uint8 *)(p))[3]) << 24U)) #endif #ifdef _MSC_VER #define MZ_FORCEINLINE __forceinline #elif defined(__GNUC__) #define MZ_FORCEINLINE inline __attribute__((__always_inline__)) #else #define MZ_FORCEINLINE inline #endif #ifdef __cplusplus extern "C" { #endif // ------------------- zlib-style API's mz_ulong mz_adler32(mz_ulong adler, const unsigned char *ptr, size_t buf_len) { mz_uint32 i, s1 = (mz_uint32)(adler & 0xffff), s2 = (mz_uint32)(adler >> 16); size_t block_len = buf_len % 5552; if (!ptr) return MZ_ADLER32_INIT; while (buf_len) { for (i = 0; i + 7 < block_len; i += 8, ptr += 8) { s1 += ptr[0], s2 += s1; s1 += ptr[1], s2 += s1; s1 += ptr[2], s2 += s1; s1 += ptr[3], s2 += s1; s1 += ptr[4], s2 += s1; s1 += ptr[5], s2 += s1; s1 += ptr[6], s2 += s1; s1 += ptr[7], s2 += s1; } for ( ; i < block_len; ++i) s1 += *ptr++, s2 += s1; s1 %= 65521U, s2 %= 65521U; buf_len -= block_len; block_len = 5552; } return (s2 << 16) + s1; } // Karl Malbrain's compact CRC-32. See "A compact CCITT crc16 and crc32 C implementation that balances processor cache usage against speed": http://www.geocities.com/malbrain/ mz_ulong mz_crc32(mz_ulong crc, const mz_uint8 *ptr, size_t buf_len) { static const mz_uint32 s_crc32[16] = { 0, 0x1db71064, 0x3b6e20c8, 0x26d930ac, 0x76dc4190, 0x6b6b51f4, 0x4db26158, 0x5005713c, 0xedb88320, 0xf00f9344, 0xd6d6a3e8, 0xcb61b38c, 0x9b64c2b0, 0x86d3d2d4, 0xa00ae278, 0xbdbdf21c }; mz_uint32 crcu32 = (mz_uint32)crc; if (!ptr) return MZ_CRC32_INIT; crcu32 = ~crcu32; while (buf_len--) { mz_uint8 b = *ptr++; crcu32 = (crcu32 >> 4) ^ s_crc32[(crcu32 & 0xF) ^ (b & 0xF)]; crcu32 = (crcu32 >> 4) ^ s_crc32[(crcu32 & 0xF) ^ (b >> 4)]; } return ~crcu32; } void mz_free(void *p) { MZ_FREE(p); } #ifndef MINIZ_NO_ZLIB_APIS static void *def_alloc_func(void *opaque, size_t items, size_t size) { (void)opaque, (void)items, (void)size; return MZ_MALLOC(items * size); } static void def_free_func(void *opaque, void *address) { (void)opaque, (void)address; MZ_FREE(address); } static void *def_realloc_func(void *opaque, void *address, size_t items, size_t size) { (void)opaque, (void)address, (void)items, (void)size; return MZ_REALLOC(address, items * size); } const char *mz_version(void) { return MZ_VERSION; } int mz_deflateInit(mz_streamp pStream, int level) { return mz_deflateInit2(pStream, level, MZ_DEFLATED, MZ_DEFAULT_WINDOW_BITS, 9, MZ_DEFAULT_STRATEGY); } int mz_deflateInit2(mz_streamp pStream, int level, int method, int window_bits, int mem_level, int strategy) { tdefl_compressor *pComp; mz_uint comp_flags = TDEFL_COMPUTE_ADLER32 | tdefl_create_comp_flags_from_zip_params(level, window_bits, strategy); if (!pStream) return MZ_STREAM_ERROR; if ((method != MZ_DEFLATED) || ((mem_level < 1) || (mem_level > 9)) || ((window_bits != MZ_DEFAULT_WINDOW_BITS) && (-window_bits != MZ_DEFAULT_WINDOW_BITS))) return MZ_PARAM_ERROR; pStream->data_type = 0; pStream->adler = MZ_ADLER32_INIT; pStream->msg = NULL; pStream->reserved = 0; pStream->total_in = 0; pStream->total_out = 0; if (!pStream->zalloc) pStream->zalloc = def_alloc_func; if (!pStream->zfree) pStream->zfree = def_free_func; pComp = (tdefl_compressor *)pStream->zalloc(pStream->opaque, 1, sizeof(tdefl_compressor)); if (!pComp) return MZ_MEM_ERROR; pStream->state = (struct mz_internal_state *)pComp; if (tdefl_init(pComp, NULL, NULL, comp_flags) != TDEFL_STATUS_OKAY) { mz_deflateEnd(pStream); return MZ_PARAM_ERROR; } return MZ_OK; } int mz_deflateReset(mz_streamp pStream) { if ((!pStream) || (!pStream->state) || (!pStream->zalloc) || (!pStream->zfree)) return MZ_STREAM_ERROR; pStream->total_in = pStream->total_out = 0; tdefl_init((tdefl_compressor*)pStream->state, NULL, NULL, ((tdefl_compressor*)pStream->state)->m_flags); return MZ_OK; } int mz_deflate(mz_streamp pStream, int flush) { size_t in_bytes, out_bytes; mz_ulong orig_total_in, orig_total_out; int mz_status = MZ_OK; if ((!pStream) || (!pStream->state) || (flush < 0) || (flush > MZ_FINISH) || (!pStream->next_out)) return MZ_STREAM_ERROR; if (!pStream->avail_out) return MZ_BUF_ERROR; if (flush == MZ_PARTIAL_FLUSH) flush = MZ_SYNC_FLUSH; if (((tdefl_compressor*)pStream->state)->m_prev_return_status == TDEFL_STATUS_DONE) return (flush == MZ_FINISH) ? MZ_STREAM_END : MZ_BUF_ERROR; orig_total_in = pStream->total_in; orig_total_out = pStream->total_out; for ( ; ; ) { tdefl_status defl_status; in_bytes = pStream->avail_in; out_bytes = pStream->avail_out; defl_status = tdefl_compress((tdefl_compressor*)pStream->state, pStream->next_in, &in_bytes, pStream->next_out, &out_bytes, (tdefl_flush)flush); pStream->next_in += (mz_uint)in_bytes; pStream->avail_in -= (mz_uint)in_bytes; pStream->total_in += (mz_uint)in_bytes; pStream->adler = tdefl_get_adler32((tdefl_compressor*)pStream->state); pStream->next_out += (mz_uint)out_bytes; pStream->avail_out -= (mz_uint)out_bytes; pStream->total_out += (mz_uint)out_bytes; if (defl_status < 0) { mz_status = MZ_STREAM_ERROR; break; } else if (defl_status == TDEFL_STATUS_DONE) { mz_status = MZ_STREAM_END; break; } else if (!pStream->avail_out) break; else if ((!pStream->avail_in) && (flush != MZ_FINISH)) { if ((flush) || (pStream->total_in != orig_total_in) || (pStream->total_out != orig_total_out)) break; return MZ_BUF_ERROR; // Can't make forward progress without some input. } } return mz_status; } int mz_deflateEnd(mz_streamp pStream) { if (!pStream) return MZ_STREAM_ERROR; if (pStream->state) { pStream->zfree(pStream->opaque, pStream->state); pStream->state = NULL; } return MZ_OK; } mz_ulong mz_deflateBound(mz_streamp pStream, mz_ulong source_len) { (void)pStream; // This is really over conservative. (And lame, but it's actually pretty tricky to compute a true upper bound given the way tdefl's blocking works.) return MZ_MAX(128 + (source_len * 110) / 100, 128 + source_len + ((source_len / (31 * 1024)) + 1) * 5); } int mz_compress2(unsigned char *pDest, mz_ulong *pDest_len, const unsigned char *pSource, mz_ulong source_len, int level) { int status; mz_stream stream; memset(&stream, 0, sizeof(stream)); // In case mz_ulong is 64-bits (argh I hate longs). if ((source_len | *pDest_len) > 0xFFFFFFFFU) return MZ_PARAM_ERROR; stream.next_in = pSource; stream.avail_in = (mz_uint32)source_len; stream.next_out = pDest; stream.avail_out = (mz_uint32)*pDest_len; status = mz_deflateInit(&stream, level); if (status != MZ_OK) return status; status = mz_deflate(&stream, MZ_FINISH); if (status != MZ_STREAM_END) { mz_deflateEnd(&stream); return (status == MZ_OK) ? MZ_BUF_ERROR : status; } *pDest_len = stream.total_out; return mz_deflateEnd(&stream); } int mz_compress(unsigned char *pDest, mz_ulong *pDest_len, const unsigned char *pSource, mz_ulong source_len) { return mz_compress2(pDest, pDest_len, pSource, source_len, MZ_DEFAULT_COMPRESSION); } mz_ulong mz_compressBound(mz_ulong source_len) { return mz_deflateBound(NULL, source_len); } typedef struct { tinfl_decompressor m_decomp; mz_uint m_dict_ofs, m_dict_avail, m_first_call, m_has_flushed; int m_window_bits; mz_uint8 m_dict[TINFL_LZ_DICT_SIZE]; tinfl_status m_last_status; } inflate_state; int mz_inflateInit2(mz_streamp pStream, int window_bits) { inflate_state *pDecomp; if (!pStream) return MZ_STREAM_ERROR; if ((window_bits != MZ_DEFAULT_WINDOW_BITS) && (-window_bits != MZ_DEFAULT_WINDOW_BITS)) return MZ_PARAM_ERROR; pStream->data_type = 0; pStream->adler = 0; pStream->msg = NULL; pStream->total_in = 0; pStream->total_out = 0; pStream->reserved = 0; if (!pStream->zalloc) pStream->zalloc = def_alloc_func; if (!pStream->zfree) pStream->zfree = def_free_func; pDecomp = (inflate_state*)pStream->zalloc(pStream->opaque, 1, sizeof(inflate_state)); if (!pDecomp) return MZ_MEM_ERROR; pStream->state = (struct mz_internal_state *)pDecomp; tinfl_init(&pDecomp->m_decomp); pDecomp->m_dict_ofs = 0; pDecomp->m_dict_avail = 0; pDecomp->m_last_status = TINFL_STATUS_NEEDS_MORE_INPUT; pDecomp->m_first_call = 1; pDecomp->m_has_flushed = 0; pDecomp->m_window_bits = window_bits; return MZ_OK; } int mz_inflateInit(mz_streamp pStream) { return mz_inflateInit2(pStream, MZ_DEFAULT_WINDOW_BITS); } int mz_inflate(mz_streamp pStream, int flush) { inflate_state* pState; mz_uint n, first_call, decomp_flags = TINFL_FLAG_COMPUTE_ADLER32; size_t in_bytes, out_bytes, orig_avail_in; tinfl_status status; if ((!pStream) || (!pStream->state)) return MZ_STREAM_ERROR; if (flush == MZ_PARTIAL_FLUSH) flush = MZ_SYNC_FLUSH; if ((flush) && (flush != MZ_SYNC_FLUSH) && (flush != MZ_FINISH)) return MZ_STREAM_ERROR; pState = (inflate_state*)pStream->state; if (pState->m_window_bits > 0) decomp_flags |= TINFL_FLAG_PARSE_ZLIB_HEADER; orig_avail_in = pStream->avail_in; first_call = pState->m_first_call; pState->m_first_call = 0; if (pState->m_last_status < 0) return MZ_DATA_ERROR; if (pState->m_has_flushed && (flush != MZ_FINISH)) return MZ_STREAM_ERROR; pState->m_has_flushed |= (flush == MZ_FINISH); if ((flush == MZ_FINISH) && (first_call)) { // MZ_FINISH on the first call implies that the input and output buffers are large enough to hold the entire compressed/decompressed file. decomp_flags |= TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF; in_bytes = pStream->avail_in; out_bytes = pStream->avail_out; status = tinfl_decompress(&pState->m_decomp, pStream->next_in, &in_bytes, pStream->next_out, pStream->next_out, &out_bytes, decomp_flags); pState->m_last_status = status; pStream->next_in += (mz_uint)in_bytes; pStream->avail_in -= (mz_uint)in_bytes; pStream->total_in += (mz_uint)in_bytes; pStream->adler = tinfl_get_adler32(&pState->m_decomp); pStream->next_out += (mz_uint)out_bytes; pStream->avail_out -= (mz_uint)out_bytes; pStream->total_out += (mz_uint)out_bytes; if (status < 0) return MZ_DATA_ERROR; else if (status != TINFL_STATUS_DONE) { pState->m_last_status = TINFL_STATUS_FAILED; return MZ_BUF_ERROR; } return MZ_STREAM_END; } // flush != MZ_FINISH then we must assume there's more input. if (flush != MZ_FINISH) decomp_flags |= TINFL_FLAG_HAS_MORE_INPUT; if (pState->m_dict_avail) { n = MZ_MIN(pState->m_dict_avail, pStream->avail_out); memcpy(pStream->next_out, pState->m_dict + pState->m_dict_ofs, n); pStream->next_out += n; pStream->avail_out -= n; pStream->total_out += n; pState->m_dict_avail -= n; pState->m_dict_ofs = (pState->m_dict_ofs + n) & (TINFL_LZ_DICT_SIZE - 1); return ((pState->m_last_status == TINFL_STATUS_DONE) && (!pState->m_dict_avail)) ? MZ_STREAM_END : MZ_OK; } for ( ; ; ) { in_bytes = pStream->avail_in; out_bytes = TINFL_LZ_DICT_SIZE - pState->m_dict_ofs; status = tinfl_decompress(&pState->m_decomp, pStream->next_in, &in_bytes, pState->m_dict, pState->m_dict + pState->m_dict_ofs, &out_bytes, decomp_flags); pState->m_last_status = status; pStream->next_in += (mz_uint)in_bytes; pStream->avail_in -= (mz_uint)in_bytes; pStream->total_in += (mz_uint)in_bytes; pStream->adler = tinfl_get_adler32(&pState->m_decomp); pState->m_dict_avail = (mz_uint)out_bytes; n = MZ_MIN(pState->m_dict_avail, pStream->avail_out); memcpy(pStream->next_out, pState->m_dict + pState->m_dict_ofs, n); pStream->next_out += n; pStream->avail_out -= n; pStream->total_out += n; pState->m_dict_avail -= n; pState->m_dict_ofs = (pState->m_dict_ofs + n) & (TINFL_LZ_DICT_SIZE - 1); if (status < 0) return MZ_DATA_ERROR; // Stream is corrupted (there could be some uncompressed data left in the output dictionary - oh well). else if ((status == TINFL_STATUS_NEEDS_MORE_INPUT) && (!orig_avail_in)) return MZ_BUF_ERROR; // Signal caller that we can't make forward progress without supplying more input or by setting flush to MZ_FINISH. else if (flush == MZ_FINISH) { // The output buffer MUST be large to hold the remaining uncompressed data when flush==MZ_FINISH. if (status == TINFL_STATUS_DONE) return pState->m_dict_avail ? MZ_BUF_ERROR : MZ_STREAM_END; // status here must be TINFL_STATUS_HAS_MORE_OUTPUT, which means there's at least 1 more byte on the way. If there's no more room left in the output buffer then something is wrong. else if (!pStream->avail_out) return MZ_BUF_ERROR; } else if ((status == TINFL_STATUS_DONE) || (!pStream->avail_in) || (!pStream->avail_out) || (pState->m_dict_avail)) break; } return ((status == TINFL_STATUS_DONE) && (!pState->m_dict_avail)) ? MZ_STREAM_END : MZ_OK; } int mz_inflateEnd(mz_streamp pStream) { if (!pStream) return MZ_STREAM_ERROR; if (pStream->state) { pStream->zfree(pStream->opaque, pStream->state); pStream->state = NULL; } return MZ_OK; } int mz_uncompress(unsigned char *pDest, mz_ulong *pDest_len, const unsigned char *pSource, mz_ulong source_len) { mz_stream stream; int status; memset(&stream, 0, sizeof(stream)); // In case mz_ulong is 64-bits (argh I hate longs). if ((source_len | *pDest_len) > 0xFFFFFFFFU) return MZ_PARAM_ERROR; stream.next_in = pSource; stream.avail_in = (mz_uint32)source_len; stream.next_out = pDest; stream.avail_out = (mz_uint32)*pDest_len; status = mz_inflateInit(&stream); if (status != MZ_OK) return status; status = mz_inflate(&stream, MZ_FINISH); if (status != MZ_STREAM_END) { mz_inflateEnd(&stream); return ((status == MZ_BUF_ERROR) && (!stream.avail_in)) ? MZ_DATA_ERROR : status; } *pDest_len = stream.total_out; return mz_inflateEnd(&stream); } const char *mz_error(int err) { static struct { int m_err; const char *m_pDesc; } s_error_descs[] = { { MZ_OK, "" }, { MZ_STREAM_END, "stream end" }, { MZ_NEED_DICT, "need dictionary" }, { MZ_ERRNO, "file error" }, { MZ_STREAM_ERROR, "stream error" }, { MZ_DATA_ERROR, "data error" }, { MZ_MEM_ERROR, "out of memory" }, { MZ_BUF_ERROR, "buf error" }, { MZ_VERSION_ERROR, "version error" }, { MZ_PARAM_ERROR, "parameter error" } }; mz_uint i; for (i = 0; i < sizeof(s_error_descs) / sizeof(s_error_descs[0]); ++i) if (s_error_descs[i].m_err == err) return s_error_descs[i].m_pDesc; return NULL; } #endif //MINIZ_NO_ZLIB_APIS // ------------------- Low-level Decompression (completely independent from all compression API's) #define TINFL_MEMCPY(d, s, l) memcpy(d, s, l) #define TINFL_MEMSET(p, c, l) memset(p, c, l) #define TINFL_CR_BEGIN switch(r->m_state) { case 0: #define TINFL_CR_RETURN(state_index, result) do { status = result; r->m_state = state_index; goto common_exit; case state_index:; } MZ_MACRO_END #define TINFL_CR_RETURN_FOREVER(state_index, result) do { for ( ; ; ) { TINFL_CR_RETURN(state_index, result); } } MZ_MACRO_END #define TINFL_CR_FINISH } // TODO: If the caller has indicated that there's no more input, and we attempt to read beyond the input buf, then something is wrong with the input because the inflator never // reads ahead more than it needs to. Currently TINFL_GET_BYTE() pads the end of the stream with 0's in this scenario. #define TINFL_GET_BYTE(state_index, c) do { \ if (pIn_buf_cur >= pIn_buf_end) { \ for ( ; ; ) { \ if (decomp_flags & TINFL_FLAG_HAS_MORE_INPUT) { \ TINFL_CR_RETURN(state_index, TINFL_STATUS_NEEDS_MORE_INPUT); \ if (pIn_buf_cur < pIn_buf_end) { \ c = *pIn_buf_cur++; \ break; \ } \ } else { \ c = 0; \ break; \ } \ } \ } else c = *pIn_buf_cur++; } MZ_MACRO_END #define TINFL_NEED_BITS(state_index, n) do { mz_uint c; TINFL_GET_BYTE(state_index, c); bit_buf |= (((tinfl_bit_buf_t)c) << num_bits); num_bits += 8; } while (num_bits < (mz_uint)(n)) #define TINFL_SKIP_BITS(state_index, n) do { if (num_bits < (mz_uint)(n)) { TINFL_NEED_BITS(state_index, n); } bit_buf >>= (n); num_bits -= (n); } MZ_MACRO_END #define TINFL_GET_BITS(state_index, b, n) do { if (num_bits < (mz_uint)(n)) { TINFL_NEED_BITS(state_index, n); } b = bit_buf & ((1 << (n)) - 1); bit_buf >>= (n); num_bits -= (n); } MZ_MACRO_END // TINFL_HUFF_BITBUF_FILL() is only used rarely, when the number of bytes remaining in the input buffer falls below 2. // It reads just enough bytes from the input stream that are needed to decode the next Huffman code (and absolutely no more). It works by trying to fully decode a // Huffman code by using whatever bits are currently present in the bit buffer. If this fails, it reads another byte, and tries again until it succeeds or until the // bit buffer contains >=15 bits (deflate's max. Huffman code size). #define TINFL_HUFF_BITBUF_FILL(state_index, pHuff) \ do { \ temp = (pHuff)->m_look_up[bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)]; \ if (temp >= 0) { \ code_len = temp >> 9; \ if ((code_len) && (num_bits >= code_len)) \ break; \ } else if (num_bits > TINFL_FAST_LOOKUP_BITS) { \ code_len = TINFL_FAST_LOOKUP_BITS; \ do { \ temp = (pHuff)->m_tree[~temp + ((bit_buf >> code_len++) & 1)]; \ } while ((temp < 0) && (num_bits >= (code_len + 1))); if (temp >= 0) break; \ } TINFL_GET_BYTE(state_index, c); bit_buf |= (((tinfl_bit_buf_t)c) << num_bits); num_bits += 8; \ } while (num_bits < 15); // TINFL_HUFF_DECODE() decodes the next Huffman coded symbol. It's more complex than you would initially expect because the zlib API expects the decompressor to never read // beyond the final byte of the deflate stream. (In other words, when this macro wants to read another byte from the input, it REALLY needs another byte in order to fully // decode the next Huffman code.) Handling this properly is particularly important on raw deflate (non-zlib) streams, which aren't followed by a byte aligned adler-32. // The slow path is only executed at the very end of the input buffer. #define TINFL_HUFF_DECODE(state_index, sym, pHuff) do { \ int temp; mz_uint code_len, c; \ if (num_bits < 15) { \ if ((pIn_buf_end - pIn_buf_cur) < 2) { \ TINFL_HUFF_BITBUF_FILL(state_index, pHuff); \ } else { \ bit_buf |= (((tinfl_bit_buf_t)pIn_buf_cur[0]) << num_bits) | (((tinfl_bit_buf_t)pIn_buf_cur[1]) << (num_bits + 8)); pIn_buf_cur += 2; num_bits += 16; \ } \ } \ if ((temp = (pHuff)->m_look_up[bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)]) >= 0) \ code_len = temp >> 9, temp &= 511; \ else { \ code_len = TINFL_FAST_LOOKUP_BITS; do { temp = (pHuff)->m_tree[~temp + ((bit_buf >> code_len++) & 1)]; } while (temp < 0); \ } sym = temp; bit_buf >>= code_len; num_bits -= code_len; } MZ_MACRO_END tinfl_status tinfl_decompress(tinfl_decompressor *r, const mz_uint8 *pIn_buf_next, size_t *pIn_buf_size, mz_uint8 *pOut_buf_start, mz_uint8 *pOut_buf_next, size_t *pOut_buf_size, const mz_uint32 decomp_flags) { static const int s_length_base[31] = { 3,4,5,6,7,8,9,10,11,13, 15,17,19,23,27,31,35,43,51,59, 67,83,99,115,131,163,195,227,258,0,0 }; static const int s_length_extra[31]= { 0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0,0,0 }; static const int s_dist_base[32] = { 1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193, 257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577,0,0}; static const int s_dist_extra[32] = { 0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13}; static const mz_uint8 s_length_dezigzag[19] = { 16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15 }; static const int s_min_table_sizes[3] = { 257, 1, 4 }; tinfl_status status = TINFL_STATUS_FAILED; mz_uint32 num_bits, dist, counter, num_extra; tinfl_bit_buf_t bit_buf; const mz_uint8 *pIn_buf_cur = pIn_buf_next, *const pIn_buf_end = pIn_buf_next + *pIn_buf_size; mz_uint8 *pOut_buf_cur = pOut_buf_next, *const pOut_buf_end = pOut_buf_next + *pOut_buf_size; size_t out_buf_size_mask = (decomp_flags & TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF) ? (size_t)-1 : ((pOut_buf_next - pOut_buf_start) + *pOut_buf_size) - 1, dist_from_out_buf_start; // Ensure the output buffer's size is a power of 2, unless the output buffer is large enough to hold the entire output file (in which case it doesn't matter). if (((out_buf_size_mask + 1) & out_buf_size_mask) || (pOut_buf_next < pOut_buf_start)) { *pIn_buf_size = *pOut_buf_size = 0; return TINFL_STATUS_BAD_PARAM; } num_bits = r->m_num_bits; bit_buf = r->m_bit_buf; dist = r->m_dist; counter = r->m_counter; num_extra = r->m_num_extra; dist_from_out_buf_start = r->m_dist_from_out_buf_start; TINFL_CR_BEGIN bit_buf = num_bits = dist = counter = num_extra = r->m_zhdr0 = r->m_zhdr1 = 0; r->m_z_adler32 = r->m_check_adler32 = 1; if (decomp_flags & TINFL_FLAG_PARSE_ZLIB_HEADER) { TINFL_GET_BYTE(1, r->m_zhdr0); TINFL_GET_BYTE(2, r->m_zhdr1); counter = (((r->m_zhdr0 * 256 + r->m_zhdr1) % 31 != 0) || (r->m_zhdr1 & 32) || ((r->m_zhdr0 & 15) != 8)); if (!(decomp_flags & TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF)) counter |= (((1U << (8U + (r->m_zhdr0 >> 4))) > 32768U) || ((out_buf_size_mask + 1) < (size_t)(1U << (8U + (r->m_zhdr0 >> 4))))); if (counter) { TINFL_CR_RETURN_FOREVER(36, TINFL_STATUS_FAILED); } } do { TINFL_GET_BITS(3, r->m_final, 3); r->m_type = r->m_final >> 1; if (r->m_type == 0) { TINFL_SKIP_BITS(5, num_bits & 7); for (counter = 0; counter < 4; ++counter) { if (num_bits) TINFL_GET_BITS(6, r->m_raw_header[counter], 8); else TINFL_GET_BYTE(7, r->m_raw_header[counter]); } if ((counter = (r->m_raw_header[0] | (r->m_raw_header[1] << 8))) != (mz_uint)(0xFFFF ^ (r->m_raw_header[2] | (r->m_raw_header[3] << 8)))) { TINFL_CR_RETURN_FOREVER(39, TINFL_STATUS_FAILED); } while ((counter) && (num_bits)) { TINFL_GET_BITS(51, dist, 8); while (pOut_buf_cur >= pOut_buf_end) { TINFL_CR_RETURN(52, TINFL_STATUS_HAS_MORE_OUTPUT); } *pOut_buf_cur++ = (mz_uint8)dist; counter--; } while (counter) { size_t n; while (pOut_buf_cur >= pOut_buf_end) { TINFL_CR_RETURN(9, TINFL_STATUS_HAS_MORE_OUTPUT); } while (pIn_buf_cur >= pIn_buf_end) { if (decomp_flags & TINFL_FLAG_HAS_MORE_INPUT) { TINFL_CR_RETURN(38, TINFL_STATUS_NEEDS_MORE_INPUT); } else { TINFL_CR_RETURN_FOREVER(40, TINFL_STATUS_FAILED); } } n = MZ_MIN(MZ_MIN((size_t)(pOut_buf_end - pOut_buf_cur), (size_t)(pIn_buf_end - pIn_buf_cur)), counter); TINFL_MEMCPY(pOut_buf_cur, pIn_buf_cur, n); pIn_buf_cur += n; pOut_buf_cur += n; counter -= (mz_uint)n; } } else if (r->m_type == 3) { TINFL_CR_RETURN_FOREVER(10, TINFL_STATUS_FAILED); } else { if (r->m_type == 1) { mz_uint8 *p = r->m_tables[0].m_code_size; mz_uint i; r->m_table_sizes[0] = 288; r->m_table_sizes[1] = 32; TINFL_MEMSET(r->m_tables[1].m_code_size, 5, 32); for ( i = 0; i <= 143; ++i) *p++ = 8; for ( ; i <= 255; ++i) *p++ = 9; for ( ; i <= 279; ++i) *p++ = 7; for ( ; i <= 287; ++i) *p++ = 8; } else { for (counter = 0; counter < 3; counter++) { TINFL_GET_BITS(11, r->m_table_sizes[counter], "\05\05\04"[counter]); r->m_table_sizes[counter] += s_min_table_sizes[counter]; } MZ_CLEAR_OBJ(r->m_tables[2].m_code_size); for (counter = 0; counter < r->m_table_sizes[2]; counter++) { mz_uint s; TINFL_GET_BITS(14, s, 3); r->m_tables[2].m_code_size[s_length_dezigzag[counter]] = (mz_uint8)s; } r->m_table_sizes[2] = 19; } for ( ; (int)r->m_type >= 0; r->m_type--) { int tree_next, tree_cur; tinfl_huff_table *pTable; mz_uint i, j, used_syms, total, sym_index, next_code[17], total_syms[16]; pTable = &r->m_tables[r->m_type]; MZ_CLEAR_OBJ(total_syms); MZ_CLEAR_OBJ(pTable->m_look_up); MZ_CLEAR_OBJ(pTable->m_tree); for (i = 0; i < r->m_table_sizes[r->m_type]; ++i) total_syms[pTable->m_code_size[i]]++; used_syms = 0, total = 0; next_code[0] = next_code[1] = 0; for (i = 1; i <= 15; ++i) { used_syms += total_syms[i]; next_code[i + 1] = (total = ((total + total_syms[i]) << 1)); } if ((65536 != total) && (used_syms > 1)) { TINFL_CR_RETURN_FOREVER(35, TINFL_STATUS_FAILED); } for (tree_next = -1, sym_index = 0; sym_index < r->m_table_sizes[r->m_type]; ++sym_index) { mz_uint rev_code = 0, l, cur_code, code_size = pTable->m_code_size[sym_index]; if (!code_size) continue; cur_code = next_code[code_size]++; for (l = code_size; l > 0; l--, cur_code >>= 1) rev_code = (rev_code << 1) | (cur_code & 1); if (code_size <= TINFL_FAST_LOOKUP_BITS) { mz_int16 k = (mz_int16)((code_size << 9) | sym_index); while (rev_code < TINFL_FAST_LOOKUP_SIZE) { pTable->m_look_up[rev_code] = k; rev_code += (1 << code_size); } continue; } if (0 == (tree_cur = pTable->m_look_up[rev_code & (TINFL_FAST_LOOKUP_SIZE - 1)])) { pTable->m_look_up[rev_code & (TINFL_FAST_LOOKUP_SIZE - 1)] = (mz_int16)tree_next; tree_cur = tree_next; tree_next -= 2; } rev_code >>= (TINFL_FAST_LOOKUP_BITS - 1); for (j = code_size; j > (TINFL_FAST_LOOKUP_BITS + 1); j--) { tree_cur -= ((rev_code >>= 1) & 1); if (!pTable->m_tree[-tree_cur - 1]) { pTable->m_tree[-tree_cur - 1] = (mz_int16)tree_next; tree_cur = tree_next; tree_next -= 2; } else tree_cur = pTable->m_tree[-tree_cur - 1]; } tree_cur -= ((rev_code >>= 1) & 1); pTable->m_tree[-tree_cur - 1] = (mz_int16)sym_index; } if (r->m_type == 2) { for (counter = 0; counter < (r->m_table_sizes[0] + r->m_table_sizes[1]); ) { mz_uint s; TINFL_HUFF_DECODE(16, dist, &r->m_tables[2]); if (dist < 16) { r->m_len_codes[counter++] = (mz_uint8)dist; continue; } if ((dist == 16) && (!counter)) { TINFL_CR_RETURN_FOREVER(17, TINFL_STATUS_FAILED); } num_extra = "\02\03\07"[dist - 16]; TINFL_GET_BITS(18, s, num_extra); s += "\03\03\013"[dist - 16]; TINFL_MEMSET(r->m_len_codes + counter, (dist == 16) ? r->m_len_codes[counter - 1] : 0, s); counter += s; } if ((r->m_table_sizes[0] + r->m_table_sizes[1]) != counter) { TINFL_CR_RETURN_FOREVER(21, TINFL_STATUS_FAILED); } TINFL_MEMCPY(r->m_tables[0].m_code_size, r->m_len_codes, r->m_table_sizes[0]); TINFL_MEMCPY(r->m_tables[1].m_code_size, r->m_len_codes + r->m_table_sizes[0], r->m_table_sizes[1]); } } for ( ; ; ) { mz_uint8 *pSrc; for ( ; ; ) { if (((pIn_buf_end - pIn_buf_cur) < 4) || ((pOut_buf_end - pOut_buf_cur) < 2)) { TINFL_HUFF_DECODE(23, counter, &r->m_tables[0]); if (counter >= 256) break; while (pOut_buf_cur >= pOut_buf_end) { TINFL_CR_RETURN(24, TINFL_STATUS_HAS_MORE_OUTPUT); } *pOut_buf_cur++ = (mz_uint8)counter; } else { int sym2; mz_uint code_len; #if TINFL_USE_64BIT_BITBUF if (num_bits < 30) { bit_buf |= (((tinfl_bit_buf_t)MZ_READ_LE32(pIn_buf_cur)) << num_bits); pIn_buf_cur += 4; num_bits += 32; } #else if (num_bits < 15) { bit_buf |= (((tinfl_bit_buf_t)MZ_READ_LE16(pIn_buf_cur)) << num_bits); pIn_buf_cur += 2; num_bits += 16; } #endif if ((sym2 = r->m_tables[0].m_look_up[bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)]) >= 0) code_len = sym2 >> 9; else { code_len = TINFL_FAST_LOOKUP_BITS; do { sym2 = r->m_tables[0].m_tree[~sym2 + ((bit_buf >> code_len++) & 1)]; } while (sym2 < 0); } counter = sym2; bit_buf >>= code_len; num_bits -= code_len; if (counter & 256) break; #if !TINFL_USE_64BIT_BITBUF if (num_bits < 15) { bit_buf |= (((tinfl_bit_buf_t)MZ_READ_LE16(pIn_buf_cur)) << num_bits); pIn_buf_cur += 2; num_bits += 16; } #endif if ((sym2 = r->m_tables[0].m_look_up[bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)]) >= 0) code_len = sym2 >> 9; else { code_len = TINFL_FAST_LOOKUP_BITS; do { sym2 = r->m_tables[0].m_tree[~sym2 + ((bit_buf >> code_len++) & 1)]; } while (sym2 < 0); } bit_buf >>= code_len; num_bits -= code_len; pOut_buf_cur[0] = (mz_uint8)counter; if (sym2 & 256) { pOut_buf_cur++; counter = sym2; break; } pOut_buf_cur[1] = (mz_uint8)sym2; pOut_buf_cur += 2; } } if ((counter &= 511) == 256) break; num_extra = s_length_extra[counter - 257]; counter = s_length_base[counter - 257]; if (num_extra) { mz_uint extra_bits; TINFL_GET_BITS(25, extra_bits, num_extra); counter += extra_bits; } TINFL_HUFF_DECODE(26, dist, &r->m_tables[1]); num_extra = s_dist_extra[dist]; dist = s_dist_base[dist]; if (num_extra) { mz_uint extra_bits; TINFL_GET_BITS(27, extra_bits, num_extra); dist += extra_bits; } dist_from_out_buf_start = pOut_buf_cur - pOut_buf_start; if ((dist > dist_from_out_buf_start) && (decomp_flags & TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF)) { TINFL_CR_RETURN_FOREVER(37, TINFL_STATUS_FAILED); } pSrc = pOut_buf_start + ((dist_from_out_buf_start - dist) & out_buf_size_mask); if ((MZ_MAX(pOut_buf_cur, pSrc) + counter) > pOut_buf_end) { while (counter--) { while (pOut_buf_cur >= pOut_buf_end) { TINFL_CR_RETURN(53, TINFL_STATUS_HAS_MORE_OUTPUT); } *pOut_buf_cur++ = pOut_buf_start[(dist_from_out_buf_start++ - dist) & out_buf_size_mask]; } continue; } #if MINIZ_USE_UNALIGNED_LOADS_AND_STORES else if ((counter >= 9) && (counter <= dist)) { const mz_uint8 *pSrc_end = pSrc + (counter & ~7); do { ((mz_uint32 *)pOut_buf_cur)[0] = ((const mz_uint32 *)pSrc)[0]; ((mz_uint32 *)pOut_buf_cur)[1] = ((const mz_uint32 *)pSrc)[1]; pOut_buf_cur += 8; } while ((pSrc += 8) < pSrc_end); if ((counter &= 7) < 3) { if (counter) { pOut_buf_cur[0] = pSrc[0]; if (counter > 1) pOut_buf_cur[1] = pSrc[1]; pOut_buf_cur += counter; } continue; } } #endif do { pOut_buf_cur[0] = pSrc[0]; pOut_buf_cur[1] = pSrc[1]; pOut_buf_cur[2] = pSrc[2]; pOut_buf_cur += 3; pSrc += 3; } while ((int)(counter -= 3) > 2); if ((int)counter > 0) { pOut_buf_cur[0] = pSrc[0]; if ((int)counter > 1) pOut_buf_cur[1] = pSrc[1]; pOut_buf_cur += counter; } } } } while (!(r->m_final & 1)); if (decomp_flags & TINFL_FLAG_PARSE_ZLIB_HEADER) { TINFL_SKIP_BITS(32, num_bits & 7); for (counter = 0; counter < 4; ++counter) { mz_uint s; if (num_bits) TINFL_GET_BITS(41, s, 8); else TINFL_GET_BYTE(42, s); r->m_z_adler32 = (r->m_z_adler32 << 8) | s; } } TINFL_CR_RETURN_FOREVER(34, TINFL_STATUS_DONE); TINFL_CR_FINISH common_exit: r->m_num_bits = num_bits; r->m_bit_buf = bit_buf; r->m_dist = dist; r->m_counter = counter; r->m_num_extra = num_extra; r->m_dist_from_out_buf_start = dist_from_out_buf_start; *pIn_buf_size = pIn_buf_cur - pIn_buf_next; *pOut_buf_size = pOut_buf_cur - pOut_buf_next; if ((decomp_flags & (TINFL_FLAG_PARSE_ZLIB_HEADER | TINFL_FLAG_COMPUTE_ADLER32)) && (status >= 0)) { const mz_uint8 *ptr = pOut_buf_next; size_t buf_len = *pOut_buf_size; mz_uint32 i, s1 = r->m_check_adler32 & 0xffff, s2 = r->m_check_adler32 >> 16; size_t block_len = buf_len % 5552; while (buf_len) { for (i = 0; i + 7 < block_len; i += 8, ptr += 8) { s1 += ptr[0], s2 += s1; s1 += ptr[1], s2 += s1; s1 += ptr[2], s2 += s1; s1 += ptr[3], s2 += s1; s1 += ptr[4], s2 += s1; s1 += ptr[5], s2 += s1; s1 += ptr[6], s2 += s1; s1 += ptr[7], s2 += s1; } for ( ; i < block_len; ++i) s1 += *ptr++, s2 += s1; s1 %= 65521U, s2 %= 65521U; buf_len -= block_len; block_len = 5552; } r->m_check_adler32 = (s2 << 16) + s1; if ((status == TINFL_STATUS_DONE) && (decomp_flags & TINFL_FLAG_PARSE_ZLIB_HEADER) && (r->m_check_adler32 != r->m_z_adler32)) status = TINFL_STATUS_ADLER32_MISMATCH; } return status; } // Higher level helper functions. void *tinfl_decompress_mem_to_heap(const void *pSrc_buf, size_t src_buf_len, size_t *pOut_len, int flags) { tinfl_decompressor decomp; void *pBuf = NULL, *pNew_buf; size_t src_buf_ofs = 0, out_buf_capacity = 0; *pOut_len = 0; tinfl_init(&decomp); for ( ; ; ) { size_t src_buf_size = src_buf_len - src_buf_ofs, dst_buf_size = out_buf_capacity - *pOut_len, new_out_buf_capacity; tinfl_status status = tinfl_decompress(&decomp, (const mz_uint8*)pSrc_buf + src_buf_ofs, &src_buf_size, (mz_uint8*)pBuf, pBuf ? (mz_uint8*)pBuf + *pOut_len : NULL, &dst_buf_size, (flags & ~TINFL_FLAG_HAS_MORE_INPUT) | TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF); if ((status < 0) || (status == TINFL_STATUS_NEEDS_MORE_INPUT)) { MZ_FREE(pBuf); *pOut_len = 0; return NULL; } src_buf_ofs += src_buf_size; *pOut_len += dst_buf_size; if (status == TINFL_STATUS_DONE) break; new_out_buf_capacity = out_buf_capacity * 2; if (new_out_buf_capacity < 128) new_out_buf_capacity = 128; pNew_buf = MZ_REALLOC(pBuf, new_out_buf_capacity); if (!pNew_buf) { MZ_FREE(pBuf); *pOut_len = 0; return NULL; } pBuf = pNew_buf; out_buf_capacity = new_out_buf_capacity; } return pBuf; } size_t tinfl_decompress_mem_to_mem(void *pOut_buf, size_t out_buf_len, const void *pSrc_buf, size_t src_buf_len, int flags) { tinfl_decompressor decomp; tinfl_status status; tinfl_init(&decomp); status = tinfl_decompress(&decomp, (const mz_uint8*)pSrc_buf, &src_buf_len, (mz_uint8*)pOut_buf, (mz_uint8*)pOut_buf, &out_buf_len, (flags & ~TINFL_FLAG_HAS_MORE_INPUT) | TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF); return (status != TINFL_STATUS_DONE) ? TINFL_DECOMPRESS_MEM_TO_MEM_FAILED : out_buf_len; } int tinfl_decompress_mem_to_callback(const void *pIn_buf, size_t *pIn_buf_size, tinfl_put_buf_func_ptr pPut_buf_func, void *pPut_buf_user, int flags) { int result = 0; tinfl_decompressor decomp; mz_uint8 *pDict = (mz_uint8*)MZ_MALLOC(TINFL_LZ_DICT_SIZE); size_t in_buf_ofs = 0, dict_ofs = 0; if (!pDict) return TINFL_STATUS_FAILED; tinfl_init(&decomp); for ( ; ; ) { size_t in_buf_size = *pIn_buf_size - in_buf_ofs, dst_buf_size = TINFL_LZ_DICT_SIZE - dict_ofs; tinfl_status status = tinfl_decompress(&decomp, (const mz_uint8*)pIn_buf + in_buf_ofs, &in_buf_size, pDict, pDict + dict_ofs, &dst_buf_size, (flags & ~(TINFL_FLAG_HAS_MORE_INPUT | TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF))); in_buf_ofs += in_buf_size; if ((dst_buf_size) && (!(*pPut_buf_func)(pDict + dict_ofs, (int)dst_buf_size, pPut_buf_user))) break; if (status != TINFL_STATUS_HAS_MORE_OUTPUT) { result = (status == TINFL_STATUS_DONE); break; } dict_ofs = (dict_ofs + dst_buf_size) & (TINFL_LZ_DICT_SIZE - 1); } MZ_FREE(pDict); *pIn_buf_size = in_buf_ofs; return result; } // ------------------- Low-level Compression (independent from all decompression API's) // Purposely making these tables static for faster init and thread safety. static const mz_uint16 s_tdefl_len_sym[256] = { 257,258,259,260,261,262,263,264,265,265,266,266,267,267,268,268,269,269,269,269,270,270,270,270,271,271,271,271,272,272,272,272, 273,273,273,273,273,273,273,273,274,274,274,274,274,274,274,274,275,275,275,275,275,275,275,275,276,276,276,276,276,276,276,276, 277,277,277,277,277,277,277,277,277,277,277,277,277,277,277,277,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278, 279,279,279,279,279,279,279,279,279,279,279,279,279,279,279,279,280,280,280,280,280,280,280,280,280,280,280,280,280,280,280,280, 281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281, 282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282, 283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283, 284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,285 }; static const mz_uint8 s_tdefl_len_extra[256] = { 0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3, 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,0 }; static const mz_uint8 s_tdefl_small_dist_sym[512] = { 0,1,2,3,4,4,5,5,6,6,6,6,7,7,7,7,8,8,8,8,8,8,8,8,9,9,9,9,9,9,9,9,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,11,11,11,11,11,11, 11,11,11,11,11,11,11,11,11,11,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,13, 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,14,14,14,14,14,14,14,14,14,14,14,14, 14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14, 14,14,14,14,14,14,14,14,14,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15, 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,16,16,16,16,16,16,16,16,16,16,16,16,16, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,17,17,17,17,17,17,17,17,17,17,17,17,17,17, 17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17, 17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17, 17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17 }; static const mz_uint8 s_tdefl_small_dist_extra[512] = { 0,0,0,0,1,1,1,1,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5, 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, 7,7,7,7,7,7,7,7 }; static const mz_uint8 s_tdefl_large_dist_sym[128] = { 0,0,18,19,20,20,21,21,22,22,22,22,23,23,23,23,24,24,24,24,24,24,24,24,25,25,25,25,25,25,25,25,26,26,26,26,26,26,26,26,26,26,26,26, 26,26,26,26,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28, 28,28,28,28,28,28,28,28,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29 }; static const mz_uint8 s_tdefl_large_dist_extra[128] = { 0,0,8,8,9,9,9,9,10,10,10,10,10,10,10,10,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13 }; // Radix sorts tdefl_sym_freq[] array by 16-bit key m_key. Returns ptr to sorted values. typedef struct { mz_uint16 m_key, m_sym_index; } tdefl_sym_freq; static tdefl_sym_freq* tdefl_radix_sort_syms(mz_uint num_syms, tdefl_sym_freq* pSyms0, tdefl_sym_freq* pSyms1) { mz_uint32 total_passes = 2, pass_shift, pass, i, hist[256 * 2]; tdefl_sym_freq* pCur_syms = pSyms0, *pNew_syms = pSyms1; MZ_CLEAR_OBJ(hist); for (i = 0; i < num_syms; i++) { mz_uint freq = pSyms0[i].m_key; hist[freq & 0xFF]++; hist[256 + ((freq >> 8) & 0xFF)]++; } while ((total_passes > 1) && (num_syms == hist[(total_passes - 1) * 256])) total_passes--; for (pass_shift = 0, pass = 0; pass < total_passes; pass++, pass_shift += 8) { const mz_uint32* pHist = &hist[pass << 8]; mz_uint offsets[256], cur_ofs = 0; for (i = 0; i < 256; i++) { offsets[i] = cur_ofs; cur_ofs += pHist[i]; } for (i = 0; i < num_syms; i++) pNew_syms[offsets[(pCur_syms[i].m_key >> pass_shift) & 0xFF]++] = pCur_syms[i]; { tdefl_sym_freq* t = pCur_syms; pCur_syms = pNew_syms; pNew_syms = t; } } return pCur_syms; } // tdefl_calculate_minimum_redundancy() originally written by: Alistair Moffat, alistair@cs.mu.oz.au, Jyrki Katajainen, jyrki@diku.dk, November 1996. static void tdefl_calculate_minimum_redundancy(tdefl_sym_freq *A, int n) { int root, leaf, next, avbl, used, dpth; if (n==0) return; else if (n==1) { A[0].m_key = 1; return; } A[0].m_key += A[1].m_key; root = 0; leaf = 2; for (next=1; next < n-1; next++) { if (leaf>=n || A[root].m_key=n || (root=0; next--) A[next].m_key = A[A[next].m_key].m_key+1; avbl = 1; used = dpth = 0; root = n-2; next = n-1; while (avbl>0) { while (root>=0 && (int)A[root].m_key==dpth) { used++; root--; } while (avbl>used) { A[next--].m_key = (mz_uint16)(dpth); avbl--; } avbl = 2*used; dpth++; used = 0; } } // Limits canonical Huffman code table's max code size. enum { TDEFL_MAX_SUPPORTED_HUFF_CODESIZE = 32 }; static void tdefl_huffman_enforce_max_code_size(int *pNum_codes, int code_list_len, int max_code_size) { int i; mz_uint32 total = 0; if (code_list_len <= 1) return; for (i = max_code_size + 1; i <= TDEFL_MAX_SUPPORTED_HUFF_CODESIZE; i++) pNum_codes[max_code_size] += pNum_codes[i]; for (i = max_code_size; i > 0; i--) total += (((mz_uint32)pNum_codes[i]) << (max_code_size - i)); while (total != (1UL << max_code_size)) { pNum_codes[max_code_size]--; for (i = max_code_size - 1; i > 0; i--) if (pNum_codes[i]) { pNum_codes[i]--; pNum_codes[i + 1] += 2; break; } total--; } } static void tdefl_optimize_huffman_table(tdefl_compressor *d, int table_num, int table_len, int code_size_limit, int static_table) { int i, j, l, num_codes[1 + TDEFL_MAX_SUPPORTED_HUFF_CODESIZE]; mz_uint next_code[TDEFL_MAX_SUPPORTED_HUFF_CODESIZE + 1]; MZ_CLEAR_OBJ(num_codes); if (static_table) { for (i = 0; i < table_len; i++) num_codes[d->m_huff_code_sizes[table_num][i]]++; } else { tdefl_sym_freq syms0[TDEFL_MAX_HUFF_SYMBOLS], syms1[TDEFL_MAX_HUFF_SYMBOLS], *pSyms; int num_used_syms = 0; const mz_uint16 *pSym_count = &d->m_huff_count[table_num][0]; for (i = 0; i < table_len; i++) if (pSym_count[i]) { syms0[num_used_syms].m_key = (mz_uint16)pSym_count[i]; syms0[num_used_syms++].m_sym_index = (mz_uint16)i; } pSyms = tdefl_radix_sort_syms(num_used_syms, syms0, syms1); tdefl_calculate_minimum_redundancy(pSyms, num_used_syms); for (i = 0; i < num_used_syms; i++) num_codes[pSyms[i].m_key]++; tdefl_huffman_enforce_max_code_size(num_codes, num_used_syms, code_size_limit); MZ_CLEAR_OBJ(d->m_huff_code_sizes[table_num]); MZ_CLEAR_OBJ(d->m_huff_codes[table_num]); for (i = 1, j = num_used_syms; i <= code_size_limit; i++) for (l = num_codes[i]; l > 0; l--) d->m_huff_code_sizes[table_num][pSyms[--j].m_sym_index] = (mz_uint8)(i); } next_code[1] = 0; for (j = 0, i = 2; i <= code_size_limit; i++) next_code[i] = j = ((j + num_codes[i - 1]) << 1); for (i = 0; i < table_len; i++) { mz_uint rev_code = 0, code, code_size; if ((code_size = d->m_huff_code_sizes[table_num][i]) == 0) continue; code = next_code[code_size]++; for (l = code_size; l > 0; l--, code >>= 1) rev_code = (rev_code << 1) | (code & 1); d->m_huff_codes[table_num][i] = (mz_uint16)rev_code; } } #define TDEFL_PUT_BITS(b, l) do { \ mz_uint bits = b; mz_uint len = l; MZ_ASSERT(bits <= ((1U << len) - 1U)); \ d->m_bit_buffer |= (bits << d->m_bits_in); d->m_bits_in += len; \ while (d->m_bits_in >= 8) { \ if (d->m_pOutput_buf < d->m_pOutput_buf_end) \ *d->m_pOutput_buf++ = (mz_uint8)(d->m_bit_buffer); \ d->m_bit_buffer >>= 8; \ d->m_bits_in -= 8; \ } \ } MZ_MACRO_END #define TDEFL_RLE_PREV_CODE_SIZE() { if (rle_repeat_count) { \ if (rle_repeat_count < 3) { \ d->m_huff_count[2][prev_code_size] = (mz_uint16)(d->m_huff_count[2][prev_code_size] + rle_repeat_count); \ while (rle_repeat_count--) packed_code_sizes[num_packed_code_sizes++] = prev_code_size; \ } else { \ d->m_huff_count[2][16] = (mz_uint16)(d->m_huff_count[2][16] + 1); packed_code_sizes[num_packed_code_sizes++] = 16; packed_code_sizes[num_packed_code_sizes++] = (mz_uint8)(rle_repeat_count - 3); \ } rle_repeat_count = 0; } } #define TDEFL_RLE_ZERO_CODE_SIZE() { if (rle_z_count) { \ if (rle_z_count < 3) { \ d->m_huff_count[2][0] = (mz_uint16)(d->m_huff_count[2][0] + rle_z_count); while (rle_z_count--) packed_code_sizes[num_packed_code_sizes++] = 0; \ } else if (rle_z_count <= 10) { \ d->m_huff_count[2][17] = (mz_uint16)(d->m_huff_count[2][17] + 1); packed_code_sizes[num_packed_code_sizes++] = 17; packed_code_sizes[num_packed_code_sizes++] = (mz_uint8)(rle_z_count - 3); \ } else { \ d->m_huff_count[2][18] = (mz_uint16)(d->m_huff_count[2][18] + 1); packed_code_sizes[num_packed_code_sizes++] = 18; packed_code_sizes[num_packed_code_sizes++] = (mz_uint8)(rle_z_count - 11); \ } rle_z_count = 0; } } static mz_uint8 s_tdefl_packed_code_size_syms_swizzle[] = { 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 }; static void tdefl_start_dynamic_block(tdefl_compressor *d) { int num_lit_codes, num_dist_codes, num_bit_lengths; mz_uint i, total_code_sizes_to_pack, num_packed_code_sizes, rle_z_count, rle_repeat_count, packed_code_sizes_index; mz_uint8 code_sizes_to_pack[TDEFL_MAX_HUFF_SYMBOLS_0 + TDEFL_MAX_HUFF_SYMBOLS_1], packed_code_sizes[TDEFL_MAX_HUFF_SYMBOLS_0 + TDEFL_MAX_HUFF_SYMBOLS_1], prev_code_size = 0xFF; d->m_huff_count[0][256] = 1; tdefl_optimize_huffman_table(d, 0, TDEFL_MAX_HUFF_SYMBOLS_0, 15, MZ_FALSE); tdefl_optimize_huffman_table(d, 1, TDEFL_MAX_HUFF_SYMBOLS_1, 15, MZ_FALSE); for (num_lit_codes = 286; num_lit_codes > 257; num_lit_codes--) if (d->m_huff_code_sizes[0][num_lit_codes - 1]) break; for (num_dist_codes = 30; num_dist_codes > 1; num_dist_codes--) if (d->m_huff_code_sizes[1][num_dist_codes - 1]) break; memcpy(code_sizes_to_pack, &d->m_huff_code_sizes[0][0], num_lit_codes); memcpy(code_sizes_to_pack + num_lit_codes, &d->m_huff_code_sizes[1][0], num_dist_codes); total_code_sizes_to_pack = num_lit_codes + num_dist_codes; num_packed_code_sizes = 0; rle_z_count = 0; rle_repeat_count = 0; memset(&d->m_huff_count[2][0], 0, sizeof(d->m_huff_count[2][0]) * TDEFL_MAX_HUFF_SYMBOLS_2); for (i = 0; i < total_code_sizes_to_pack; i++) { mz_uint8 code_size = code_sizes_to_pack[i]; if (!code_size) { TDEFL_RLE_PREV_CODE_SIZE(); if (++rle_z_count == 138) { TDEFL_RLE_ZERO_CODE_SIZE(); } } else { TDEFL_RLE_ZERO_CODE_SIZE(); if (code_size != prev_code_size) { TDEFL_RLE_PREV_CODE_SIZE(); d->m_huff_count[2][code_size] = (mz_uint16)(d->m_huff_count[2][code_size] + 1); packed_code_sizes[num_packed_code_sizes++] = code_size; } else if (++rle_repeat_count == 6) { TDEFL_RLE_PREV_CODE_SIZE(); } } prev_code_size = code_size; } if (rle_repeat_count) { TDEFL_RLE_PREV_CODE_SIZE(); } else { TDEFL_RLE_ZERO_CODE_SIZE(); } tdefl_optimize_huffman_table(d, 2, TDEFL_MAX_HUFF_SYMBOLS_2, 7, MZ_FALSE); TDEFL_PUT_BITS(2, 2); TDEFL_PUT_BITS(num_lit_codes - 257, 5); TDEFL_PUT_BITS(num_dist_codes - 1, 5); for (num_bit_lengths = 18; num_bit_lengths >= 0; num_bit_lengths--) if (d->m_huff_code_sizes[2][s_tdefl_packed_code_size_syms_swizzle[num_bit_lengths]]) break; num_bit_lengths = MZ_MAX(4, (num_bit_lengths + 1)); TDEFL_PUT_BITS(num_bit_lengths - 4, 4); for (i = 0; (int)i < num_bit_lengths; i++) TDEFL_PUT_BITS(d->m_huff_code_sizes[2][s_tdefl_packed_code_size_syms_swizzle[i]], 3); for (packed_code_sizes_index = 0; packed_code_sizes_index < num_packed_code_sizes; ) { mz_uint code = packed_code_sizes[packed_code_sizes_index++]; MZ_ASSERT(code < TDEFL_MAX_HUFF_SYMBOLS_2); TDEFL_PUT_BITS(d->m_huff_codes[2][code], d->m_huff_code_sizes[2][code]); if (code >= 16) TDEFL_PUT_BITS(packed_code_sizes[packed_code_sizes_index++], "\02\03\07"[code - 16]); } } static void tdefl_start_static_block(tdefl_compressor *d) { mz_uint i; mz_uint8 *p = &d->m_huff_code_sizes[0][0]; for (i = 0; i <= 143; ++i) *p++ = 8; for ( ; i <= 255; ++i) *p++ = 9; for ( ; i <= 279; ++i) *p++ = 7; for ( ; i <= 287; ++i) *p++ = 8; memset(d->m_huff_code_sizes[1], 5, 32); tdefl_optimize_huffman_table(d, 0, 288, 15, MZ_TRUE); tdefl_optimize_huffman_table(d, 1, 32, 15, MZ_TRUE); TDEFL_PUT_BITS(1, 2); } static const mz_uint mz_bitmasks[17] = { 0x0000, 0x0001, 0x0003, 0x0007, 0x000F, 0x001F, 0x003F, 0x007F, 0x00FF, 0x01FF, 0x03FF, 0x07FF, 0x0FFF, 0x1FFF, 0x3FFF, 0x7FFF, 0xFFFF }; #if MINIZ_USE_UNALIGNED_LOADS_AND_STORES && MINIZ_LITTLE_ENDIAN && MINIZ_HAS_64BIT_REGISTERS static mz_bool tdefl_compress_lz_codes(tdefl_compressor *d) { mz_uint flags; mz_uint8 *pLZ_codes; mz_uint8 *pOutput_buf = d->m_pOutput_buf; mz_uint8 *pLZ_code_buf_end = d->m_pLZ_code_buf; mz_uint64 bit_buffer = d->m_bit_buffer; mz_uint bits_in = d->m_bits_in; #define TDEFL_PUT_BITS_FAST(b, l) { bit_buffer |= (((mz_uint64)(b)) << bits_in); bits_in += (l); } flags = 1; for (pLZ_codes = d->m_lz_code_buf; pLZ_codes < pLZ_code_buf_end; flags >>= 1) { if (flags == 1) flags = *pLZ_codes++ | 0x100; if (flags & 1) { mz_uint s0, s1, n0, n1, sym, num_extra_bits; mz_uint match_len = pLZ_codes[0], match_dist = *(const mz_uint16 *)(pLZ_codes + 1); pLZ_codes += 3; MZ_ASSERT(d->m_huff_code_sizes[0][s_tdefl_len_sym[match_len]]); TDEFL_PUT_BITS_FAST(d->m_huff_codes[0][s_tdefl_len_sym[match_len]], d->m_huff_code_sizes[0][s_tdefl_len_sym[match_len]]); TDEFL_PUT_BITS_FAST(match_len & mz_bitmasks[s_tdefl_len_extra[match_len]], s_tdefl_len_extra[match_len]); // This sequence coaxes MSVC into using cmov's vs. jmp's. s0 = s_tdefl_small_dist_sym[match_dist & 511]; n0 = s_tdefl_small_dist_extra[match_dist & 511]; s1 = s_tdefl_large_dist_sym[match_dist >> 8]; n1 = s_tdefl_large_dist_extra[match_dist >> 8]; sym = (match_dist < 512) ? s0 : s1; num_extra_bits = (match_dist < 512) ? n0 : n1; MZ_ASSERT(d->m_huff_code_sizes[1][sym]); TDEFL_PUT_BITS_FAST(d->m_huff_codes[1][sym], d->m_huff_code_sizes[1][sym]); TDEFL_PUT_BITS_FAST(match_dist & mz_bitmasks[num_extra_bits], num_extra_bits); } else { mz_uint lit = *pLZ_codes++; MZ_ASSERT(d->m_huff_code_sizes[0][lit]); TDEFL_PUT_BITS_FAST(d->m_huff_codes[0][lit], d->m_huff_code_sizes[0][lit]); if (((flags & 2) == 0) && (pLZ_codes < pLZ_code_buf_end)) { flags >>= 1; lit = *pLZ_codes++; MZ_ASSERT(d->m_huff_code_sizes[0][lit]); TDEFL_PUT_BITS_FAST(d->m_huff_codes[0][lit], d->m_huff_code_sizes[0][lit]); if (((flags & 2) == 0) && (pLZ_codes < pLZ_code_buf_end)) { flags >>= 1; lit = *pLZ_codes++; MZ_ASSERT(d->m_huff_code_sizes[0][lit]); TDEFL_PUT_BITS_FAST(d->m_huff_codes[0][lit], d->m_huff_code_sizes[0][lit]); } } } if (pOutput_buf >= d->m_pOutput_buf_end) return MZ_FALSE; *(mz_uint64*)pOutput_buf = bit_buffer; pOutput_buf += (bits_in >> 3); bit_buffer >>= (bits_in & ~7); bits_in &= 7; } #undef TDEFL_PUT_BITS_FAST d->m_pOutput_buf = pOutput_buf; d->m_bits_in = 0; d->m_bit_buffer = 0; while (bits_in) { mz_uint32 n = MZ_MIN(bits_in, 16); TDEFL_PUT_BITS((mz_uint)bit_buffer & mz_bitmasks[n], n); bit_buffer >>= n; bits_in -= n; } TDEFL_PUT_BITS(d->m_huff_codes[0][256], d->m_huff_code_sizes[0][256]); return (d->m_pOutput_buf < d->m_pOutput_buf_end); } #else static mz_bool tdefl_compress_lz_codes(tdefl_compressor *d) { mz_uint flags; mz_uint8 *pLZ_codes; flags = 1; for (pLZ_codes = d->m_lz_code_buf; pLZ_codes < d->m_pLZ_code_buf; flags >>= 1) { if (flags == 1) flags = *pLZ_codes++ | 0x100; if (flags & 1) { mz_uint sym, num_extra_bits; mz_uint match_len = pLZ_codes[0], match_dist = (pLZ_codes[1] | (pLZ_codes[2] << 8)); pLZ_codes += 3; MZ_ASSERT(d->m_huff_code_sizes[0][s_tdefl_len_sym[match_len]]); TDEFL_PUT_BITS(d->m_huff_codes[0][s_tdefl_len_sym[match_len]], d->m_huff_code_sizes[0][s_tdefl_len_sym[match_len]]); TDEFL_PUT_BITS(match_len & mz_bitmasks[s_tdefl_len_extra[match_len]], s_tdefl_len_extra[match_len]); if (match_dist < 512) { sym = s_tdefl_small_dist_sym[match_dist]; num_extra_bits = s_tdefl_small_dist_extra[match_dist]; } else { sym = s_tdefl_large_dist_sym[match_dist >> 8]; num_extra_bits = s_tdefl_large_dist_extra[match_dist >> 8]; } MZ_ASSERT(d->m_huff_code_sizes[1][sym]); TDEFL_PUT_BITS(d->m_huff_codes[1][sym], d->m_huff_code_sizes[1][sym]); TDEFL_PUT_BITS(match_dist & mz_bitmasks[num_extra_bits], num_extra_bits); } else { mz_uint lit = *pLZ_codes++; MZ_ASSERT(d->m_huff_code_sizes[0][lit]); TDEFL_PUT_BITS(d->m_huff_codes[0][lit], d->m_huff_code_sizes[0][lit]); } } TDEFL_PUT_BITS(d->m_huff_codes[0][256], d->m_huff_code_sizes[0][256]); return (d->m_pOutput_buf < d->m_pOutput_buf_end); } #endif // MINIZ_USE_UNALIGNED_LOADS_AND_STORES && MINIZ_LITTLE_ENDIAN && MINIZ_HAS_64BIT_REGISTERS static mz_bool tdefl_compress_block(tdefl_compressor *d, mz_bool static_block) { if (static_block) tdefl_start_static_block(d); else tdefl_start_dynamic_block(d); return tdefl_compress_lz_codes(d); } static int tdefl_flush_block(tdefl_compressor *d, int flush) { mz_uint saved_bit_buf, saved_bits_in; mz_uint8 *pSaved_output_buf; mz_bool comp_block_succeeded = MZ_FALSE; int n, use_raw_block = ((d->m_flags & TDEFL_FORCE_ALL_RAW_BLOCKS) != 0) && (d->m_lookahead_pos - d->m_lz_code_buf_dict_pos) <= d->m_dict_size; mz_uint8 *pOutput_buf_start = ((d->m_pPut_buf_func == NULL) && ((*d->m_pOut_buf_size - d->m_out_buf_ofs) >= TDEFL_OUT_BUF_SIZE)) ? ((mz_uint8 *)d->m_pOut_buf + d->m_out_buf_ofs) : d->m_output_buf; d->m_pOutput_buf = pOutput_buf_start; d->m_pOutput_buf_end = d->m_pOutput_buf + TDEFL_OUT_BUF_SIZE - 16; MZ_ASSERT(!d->m_output_flush_remaining); d->m_output_flush_ofs = 0; d->m_output_flush_remaining = 0; *d->m_pLZ_flags = (mz_uint8)(*d->m_pLZ_flags >> d->m_num_flags_left); d->m_pLZ_code_buf -= (d->m_num_flags_left == 8); if ((d->m_flags & TDEFL_WRITE_ZLIB_HEADER) && (!d->m_block_index)) { TDEFL_PUT_BITS(0x78, 8); TDEFL_PUT_BITS(0x01, 8); } TDEFL_PUT_BITS(flush == TDEFL_FINISH, 1); pSaved_output_buf = d->m_pOutput_buf; saved_bit_buf = d->m_bit_buffer; saved_bits_in = d->m_bits_in; if (!use_raw_block) comp_block_succeeded = tdefl_compress_block(d, (d->m_flags & TDEFL_FORCE_ALL_STATIC_BLOCKS) || (d->m_total_lz_bytes < 48)); // If the block gets expanded, forget the current contents of the output buffer and send a raw block instead. if ( ((use_raw_block) || ((d->m_total_lz_bytes) && ((d->m_pOutput_buf - pSaved_output_buf + 1U) >= d->m_total_lz_bytes))) && ((d->m_lookahead_pos - d->m_lz_code_buf_dict_pos) <= d->m_dict_size) ) { mz_uint i; d->m_pOutput_buf = pSaved_output_buf; d->m_bit_buffer = saved_bit_buf, d->m_bits_in = saved_bits_in; TDEFL_PUT_BITS(0, 2); if (d->m_bits_in) { TDEFL_PUT_BITS(0, 8 - d->m_bits_in); } for (i = 2; i; --i, d->m_total_lz_bytes ^= 0xFFFF) { TDEFL_PUT_BITS(d->m_total_lz_bytes & 0xFFFF, 16); } for (i = 0; i < d->m_total_lz_bytes; ++i) { TDEFL_PUT_BITS(d->m_dict[(d->m_lz_code_buf_dict_pos + i) & TDEFL_LZ_DICT_SIZE_MASK], 8); } } // Check for the extremely unlikely (if not impossible) case of the compressed block not fitting into the output buffer when using dynamic codes. else if (!comp_block_succeeded) { d->m_pOutput_buf = pSaved_output_buf; d->m_bit_buffer = saved_bit_buf, d->m_bits_in = saved_bits_in; tdefl_compress_block(d, MZ_TRUE); } if (flush) { if (flush == TDEFL_FINISH) { if (d->m_bits_in) { TDEFL_PUT_BITS(0, 8 - d->m_bits_in); } if (d->m_flags & TDEFL_WRITE_ZLIB_HEADER) { mz_uint i, a = d->m_adler32; for (i = 0; i < 4; i++) { TDEFL_PUT_BITS((a >> 24) & 0xFF, 8); a <<= 8; } } } else { mz_uint i, z = 0; TDEFL_PUT_BITS(0, 3); if (d->m_bits_in) { TDEFL_PUT_BITS(0, 8 - d->m_bits_in); } for (i = 2; i; --i, z ^= 0xFFFF) { TDEFL_PUT_BITS(z & 0xFFFF, 16); } } } MZ_ASSERT(d->m_pOutput_buf < d->m_pOutput_buf_end); memset(&d->m_huff_count[0][0], 0, sizeof(d->m_huff_count[0][0]) * TDEFL_MAX_HUFF_SYMBOLS_0); memset(&d->m_huff_count[1][0], 0, sizeof(d->m_huff_count[1][0]) * TDEFL_MAX_HUFF_SYMBOLS_1); d->m_pLZ_code_buf = d->m_lz_code_buf + 1; d->m_pLZ_flags = d->m_lz_code_buf; d->m_num_flags_left = 8; d->m_lz_code_buf_dict_pos += d->m_total_lz_bytes; d->m_total_lz_bytes = 0; d->m_block_index++; if ((n = (int)(d->m_pOutput_buf - pOutput_buf_start)) != 0) { if (d->m_pPut_buf_func) { *d->m_pIn_buf_size = d->m_pSrc - (const mz_uint8 *)d->m_pIn_buf; if (!(*d->m_pPut_buf_func)(d->m_output_buf, n, d->m_pPut_buf_user)) return (d->m_prev_return_status = TDEFL_STATUS_PUT_BUF_FAILED); } else if (pOutput_buf_start == d->m_output_buf) { int bytes_to_copy = (int)MZ_MIN((size_t)n, (size_t)(*d->m_pOut_buf_size - d->m_out_buf_ofs)); memcpy((mz_uint8 *)d->m_pOut_buf + d->m_out_buf_ofs, d->m_output_buf, bytes_to_copy); d->m_out_buf_ofs += bytes_to_copy; if ((n -= bytes_to_copy) != 0) { d->m_output_flush_ofs = bytes_to_copy; d->m_output_flush_remaining = n; } } else { d->m_out_buf_ofs += n; } } return d->m_output_flush_remaining; } #if MINIZ_USE_UNALIGNED_LOADS_AND_STORES #define TDEFL_READ_UNALIGNED_WORD(p) *(const mz_uint16*)(p) static MZ_FORCEINLINE void tdefl_find_match(tdefl_compressor *d, mz_uint lookahead_pos, mz_uint max_dist, mz_uint max_match_len, mz_uint *pMatch_dist, mz_uint *pMatch_len) { mz_uint dist, pos = lookahead_pos & TDEFL_LZ_DICT_SIZE_MASK, match_len = *pMatch_len, probe_pos = pos, next_probe_pos, probe_len; mz_uint num_probes_left = d->m_max_probes[match_len >= 32]; const mz_uint16 *s = (const mz_uint16*)(d->m_dict + pos), *p, *q; mz_uint16 c01 = TDEFL_READ_UNALIGNED_WORD(&d->m_dict[pos + match_len - 1]), s01 = TDEFL_READ_UNALIGNED_WORD(s); MZ_ASSERT(max_match_len <= TDEFL_MAX_MATCH_LEN); if (max_match_len <= match_len) return; for ( ; ; ) { for ( ; ; ) { if (--num_probes_left == 0) return; #define TDEFL_PROBE \ next_probe_pos = d->m_next[probe_pos]; \ if ((!next_probe_pos) || ((dist = (mz_uint16)(lookahead_pos - next_probe_pos)) > max_dist)) return; \ probe_pos = next_probe_pos & TDEFL_LZ_DICT_SIZE_MASK; \ if (TDEFL_READ_UNALIGNED_WORD(&d->m_dict[probe_pos + match_len - 1]) == c01) break; TDEFL_PROBE; TDEFL_PROBE; TDEFL_PROBE; } if (!dist) break; q = (const mz_uint16*)(d->m_dict + probe_pos); if (TDEFL_READ_UNALIGNED_WORD(q) != s01) continue; p = s; probe_len = 32; do { } while ( (TDEFL_READ_UNALIGNED_WORD(++p) == TDEFL_READ_UNALIGNED_WORD(++q)) && (TDEFL_READ_UNALIGNED_WORD(++p) == TDEFL_READ_UNALIGNED_WORD(++q)) && (TDEFL_READ_UNALIGNED_WORD(++p) == TDEFL_READ_UNALIGNED_WORD(++q)) && (TDEFL_READ_UNALIGNED_WORD(++p) == TDEFL_READ_UNALIGNED_WORD(++q)) && (--probe_len > 0) ); if (!probe_len) { *pMatch_dist = dist; *pMatch_len = MZ_MIN(max_match_len, TDEFL_MAX_MATCH_LEN); break; } else if ((probe_len = ((mz_uint)(p - s) * 2) + (mz_uint)(*(const mz_uint8*)p == *(const mz_uint8*)q)) > match_len) { *pMatch_dist = dist; if ((*pMatch_len = match_len = MZ_MIN(max_match_len, probe_len)) == max_match_len) break; c01 = TDEFL_READ_UNALIGNED_WORD(&d->m_dict[pos + match_len - 1]); } } } #else static MZ_FORCEINLINE void tdefl_find_match(tdefl_compressor *d, mz_uint lookahead_pos, mz_uint max_dist, mz_uint max_match_len, mz_uint *pMatch_dist, mz_uint *pMatch_len) { mz_uint dist, pos = lookahead_pos & TDEFL_LZ_DICT_SIZE_MASK, match_len = *pMatch_len, probe_pos = pos, next_probe_pos, probe_len; mz_uint num_probes_left = d->m_max_probes[match_len >= 32]; const mz_uint8 *s = d->m_dict + pos, *p, *q; mz_uint8 c0 = d->m_dict[pos + match_len], c1 = d->m_dict[pos + match_len - 1]; MZ_ASSERT(max_match_len <= TDEFL_MAX_MATCH_LEN); if (max_match_len <= match_len) return; for ( ; ; ) { for ( ; ; ) { if (--num_probes_left == 0) return; #define TDEFL_PROBE \ next_probe_pos = d->m_next[probe_pos]; \ if ((!next_probe_pos) || ((dist = (mz_uint16)(lookahead_pos - next_probe_pos)) > max_dist)) return; \ probe_pos = next_probe_pos & TDEFL_LZ_DICT_SIZE_MASK; \ if ((d->m_dict[probe_pos + match_len] == c0) && (d->m_dict[probe_pos + match_len - 1] == c1)) break; TDEFL_PROBE; TDEFL_PROBE; TDEFL_PROBE; } if (!dist) break; p = s; q = d->m_dict + probe_pos; for (probe_len = 0; probe_len < max_match_len; probe_len++) if (*p++ != *q++) break; if (probe_len > match_len) { *pMatch_dist = dist; if ((*pMatch_len = match_len = probe_len) == max_match_len) return; c0 = d->m_dict[pos + match_len]; c1 = d->m_dict[pos + match_len - 1]; } } } #endif // #if MINIZ_USE_UNALIGNED_LOADS_AND_STORES #if MINIZ_USE_UNALIGNED_LOADS_AND_STORES && MINIZ_LITTLE_ENDIAN static mz_bool tdefl_compress_fast(tdefl_compressor *d) { // Faster, minimally featured LZRW1-style match+parse loop with better register utilization. Intended for applications where raw throughput is valued more highly than ratio. mz_uint lookahead_pos = d->m_lookahead_pos, lookahead_size = d->m_lookahead_size, dict_size = d->m_dict_size, total_lz_bytes = d->m_total_lz_bytes, num_flags_left = d->m_num_flags_left; mz_uint8 *pLZ_code_buf = d->m_pLZ_code_buf, *pLZ_flags = d->m_pLZ_flags; mz_uint cur_pos = lookahead_pos & TDEFL_LZ_DICT_SIZE_MASK; while ((d->m_src_buf_left) || ((d->m_flush) && (lookahead_size))) { const mz_uint TDEFL_COMP_FAST_LOOKAHEAD_SIZE = 4096; mz_uint dst_pos = (lookahead_pos + lookahead_size) & TDEFL_LZ_DICT_SIZE_MASK; mz_uint num_bytes_to_process = (mz_uint)MZ_MIN(d->m_src_buf_left, TDEFL_COMP_FAST_LOOKAHEAD_SIZE - lookahead_size); d->m_src_buf_left -= num_bytes_to_process; lookahead_size += num_bytes_to_process; while (num_bytes_to_process) { mz_uint32 n = MZ_MIN(TDEFL_LZ_DICT_SIZE - dst_pos, num_bytes_to_process); memcpy(d->m_dict + dst_pos, d->m_pSrc, n); if (dst_pos < (TDEFL_MAX_MATCH_LEN - 1)) memcpy(d->m_dict + TDEFL_LZ_DICT_SIZE + dst_pos, d->m_pSrc, MZ_MIN(n, (TDEFL_MAX_MATCH_LEN - 1) - dst_pos)); d->m_pSrc += n; dst_pos = (dst_pos + n) & TDEFL_LZ_DICT_SIZE_MASK; num_bytes_to_process -= n; } dict_size = MZ_MIN(TDEFL_LZ_DICT_SIZE - lookahead_size, dict_size); if ((!d->m_flush) && (lookahead_size < TDEFL_COMP_FAST_LOOKAHEAD_SIZE)) break; while (lookahead_size >= 4) { mz_uint cur_match_dist, cur_match_len = 1; mz_uint8 *pCur_dict = d->m_dict + cur_pos; mz_uint first_trigram = (*(const mz_uint32 *)pCur_dict) & 0xFFFFFF; mz_uint hash = (first_trigram ^ (first_trigram >> (24 - (TDEFL_LZ_HASH_BITS - 8)))) & TDEFL_LEVEL1_HASH_SIZE_MASK; mz_uint probe_pos = d->m_hash[hash]; d->m_hash[hash] = (mz_uint16)lookahead_pos; if (((cur_match_dist = (mz_uint16)(lookahead_pos - probe_pos)) <= dict_size) && ((*(const mz_uint32 *)(d->m_dict + (probe_pos &= TDEFL_LZ_DICT_SIZE_MASK)) & 0xFFFFFF) == first_trigram)) { const mz_uint16 *p = (const mz_uint16 *)pCur_dict; const mz_uint16 *q = (const mz_uint16 *)(d->m_dict + probe_pos); mz_uint32 probe_len = 32; do { } while ( (TDEFL_READ_UNALIGNED_WORD(++p) == TDEFL_READ_UNALIGNED_WORD(++q)) && (TDEFL_READ_UNALIGNED_WORD(++p) == TDEFL_READ_UNALIGNED_WORD(++q)) && (TDEFL_READ_UNALIGNED_WORD(++p) == TDEFL_READ_UNALIGNED_WORD(++q)) && (TDEFL_READ_UNALIGNED_WORD(++p) == TDEFL_READ_UNALIGNED_WORD(++q)) && (--probe_len > 0) ); cur_match_len = ((mz_uint)(p - (const mz_uint16 *)pCur_dict) * 2) + (mz_uint)(*(const mz_uint8 *)p == *(const mz_uint8 *)q); if (!probe_len) cur_match_len = cur_match_dist ? TDEFL_MAX_MATCH_LEN : 0; if ((cur_match_len < TDEFL_MIN_MATCH_LEN) || ((cur_match_len == TDEFL_MIN_MATCH_LEN) && (cur_match_dist >= 8U*1024U))) { cur_match_len = 1; *pLZ_code_buf++ = (mz_uint8)first_trigram; *pLZ_flags = (mz_uint8)(*pLZ_flags >> 1); d->m_huff_count[0][(mz_uint8)first_trigram]++; } else { mz_uint32 s0, s1; cur_match_len = MZ_MIN(cur_match_len, lookahead_size); MZ_ASSERT((cur_match_len >= TDEFL_MIN_MATCH_LEN) && (cur_match_dist >= 1) && (cur_match_dist <= TDEFL_LZ_DICT_SIZE)); cur_match_dist--; pLZ_code_buf[0] = (mz_uint8)(cur_match_len - TDEFL_MIN_MATCH_LEN); *(mz_uint16 *)(&pLZ_code_buf[1]) = (mz_uint16)cur_match_dist; pLZ_code_buf += 3; *pLZ_flags = (mz_uint8)((*pLZ_flags >> 1) | 0x80); s0 = s_tdefl_small_dist_sym[cur_match_dist & 511]; s1 = s_tdefl_large_dist_sym[cur_match_dist >> 8]; d->m_huff_count[1][(cur_match_dist < 512) ? s0 : s1]++; d->m_huff_count[0][s_tdefl_len_sym[cur_match_len - TDEFL_MIN_MATCH_LEN]]++; } } else { *pLZ_code_buf++ = (mz_uint8)first_trigram; *pLZ_flags = (mz_uint8)(*pLZ_flags >> 1); d->m_huff_count[0][(mz_uint8)first_trigram]++; } if (--num_flags_left == 0) { num_flags_left = 8; pLZ_flags = pLZ_code_buf++; } total_lz_bytes += cur_match_len; lookahead_pos += cur_match_len; dict_size = MZ_MIN(dict_size + cur_match_len, TDEFL_LZ_DICT_SIZE); cur_pos = (cur_pos + cur_match_len) & TDEFL_LZ_DICT_SIZE_MASK; MZ_ASSERT(lookahead_size >= cur_match_len); lookahead_size -= cur_match_len; if (pLZ_code_buf > &d->m_lz_code_buf[TDEFL_LZ_CODE_BUF_SIZE - 8]) { int n; d->m_lookahead_pos = lookahead_pos; d->m_lookahead_size = lookahead_size; d->m_dict_size = dict_size; d->m_total_lz_bytes = total_lz_bytes; d->m_pLZ_code_buf = pLZ_code_buf; d->m_pLZ_flags = pLZ_flags; d->m_num_flags_left = num_flags_left; if ((n = tdefl_flush_block(d, 0)) != 0) return (n < 0) ? MZ_FALSE : MZ_TRUE; total_lz_bytes = d->m_total_lz_bytes; pLZ_code_buf = d->m_pLZ_code_buf; pLZ_flags = d->m_pLZ_flags; num_flags_left = d->m_num_flags_left; } } while (lookahead_size) { mz_uint8 lit = d->m_dict[cur_pos]; total_lz_bytes++; *pLZ_code_buf++ = lit; *pLZ_flags = (mz_uint8)(*pLZ_flags >> 1); if (--num_flags_left == 0) { num_flags_left = 8; pLZ_flags = pLZ_code_buf++; } d->m_huff_count[0][lit]++; lookahead_pos++; dict_size = MZ_MIN(dict_size + 1, TDEFL_LZ_DICT_SIZE); cur_pos = (cur_pos + 1) & TDEFL_LZ_DICT_SIZE_MASK; lookahead_size--; if (pLZ_code_buf > &d->m_lz_code_buf[TDEFL_LZ_CODE_BUF_SIZE - 8]) { int n; d->m_lookahead_pos = lookahead_pos; d->m_lookahead_size = lookahead_size; d->m_dict_size = dict_size; d->m_total_lz_bytes = total_lz_bytes; d->m_pLZ_code_buf = pLZ_code_buf; d->m_pLZ_flags = pLZ_flags; d->m_num_flags_left = num_flags_left; if ((n = tdefl_flush_block(d, 0)) != 0) return (n < 0) ? MZ_FALSE : MZ_TRUE; total_lz_bytes = d->m_total_lz_bytes; pLZ_code_buf = d->m_pLZ_code_buf; pLZ_flags = d->m_pLZ_flags; num_flags_left = d->m_num_flags_left; } } } d->m_lookahead_pos = lookahead_pos; d->m_lookahead_size = lookahead_size; d->m_dict_size = dict_size; d->m_total_lz_bytes = total_lz_bytes; d->m_pLZ_code_buf = pLZ_code_buf; d->m_pLZ_flags = pLZ_flags; d->m_num_flags_left = num_flags_left; return MZ_TRUE; } #endif // MINIZ_USE_UNALIGNED_LOADS_AND_STORES && MINIZ_LITTLE_ENDIAN static MZ_FORCEINLINE void tdefl_record_literal(tdefl_compressor *d, mz_uint8 lit) { d->m_total_lz_bytes++; *d->m_pLZ_code_buf++ = lit; *d->m_pLZ_flags = (mz_uint8)(*d->m_pLZ_flags >> 1); if (--d->m_num_flags_left == 0) { d->m_num_flags_left = 8; d->m_pLZ_flags = d->m_pLZ_code_buf++; } d->m_huff_count[0][lit]++; } static MZ_FORCEINLINE void tdefl_record_match(tdefl_compressor *d, mz_uint match_len, mz_uint match_dist) { mz_uint32 s0, s1; MZ_ASSERT((match_len >= TDEFL_MIN_MATCH_LEN) && (match_dist >= 1) && (match_dist <= TDEFL_LZ_DICT_SIZE)); d->m_total_lz_bytes += match_len; d->m_pLZ_code_buf[0] = (mz_uint8)(match_len - TDEFL_MIN_MATCH_LEN); match_dist -= 1; d->m_pLZ_code_buf[1] = (mz_uint8)(match_dist & 0xFF); d->m_pLZ_code_buf[2] = (mz_uint8)(match_dist >> 8); d->m_pLZ_code_buf += 3; *d->m_pLZ_flags = (mz_uint8)((*d->m_pLZ_flags >> 1) | 0x80); if (--d->m_num_flags_left == 0) { d->m_num_flags_left = 8; d->m_pLZ_flags = d->m_pLZ_code_buf++; } s0 = s_tdefl_small_dist_sym[match_dist & 511]; s1 = s_tdefl_large_dist_sym[(match_dist >> 8) & 127]; d->m_huff_count[1][(match_dist < 512) ? s0 : s1]++; if (match_len >= TDEFL_MIN_MATCH_LEN) d->m_huff_count[0][s_tdefl_len_sym[match_len - TDEFL_MIN_MATCH_LEN]]++; } static mz_bool tdefl_compress_normal(tdefl_compressor *d) { const mz_uint8 *pSrc = d->m_pSrc; size_t src_buf_left = d->m_src_buf_left; tdefl_flush flush = d->m_flush; while ((src_buf_left) || ((flush) && (d->m_lookahead_size))) { mz_uint len_to_move, cur_match_dist, cur_match_len, cur_pos; // Update dictionary and hash chains. Keeps the lookahead size equal to TDEFL_MAX_MATCH_LEN. if ((d->m_lookahead_size + d->m_dict_size) >= (TDEFL_MIN_MATCH_LEN - 1)) { mz_uint dst_pos = (d->m_lookahead_pos + d->m_lookahead_size) & TDEFL_LZ_DICT_SIZE_MASK, ins_pos = d->m_lookahead_pos + d->m_lookahead_size - 2; mz_uint hash = (d->m_dict[ins_pos & TDEFL_LZ_DICT_SIZE_MASK] << TDEFL_LZ_HASH_SHIFT) ^ d->m_dict[(ins_pos + 1) & TDEFL_LZ_DICT_SIZE_MASK]; mz_uint num_bytes_to_process = (mz_uint)MZ_MIN(src_buf_left, TDEFL_MAX_MATCH_LEN - d->m_lookahead_size); const mz_uint8 *pSrc_end = pSrc + num_bytes_to_process; src_buf_left -= num_bytes_to_process; d->m_lookahead_size += num_bytes_to_process; while (pSrc != pSrc_end) { mz_uint8 c = *pSrc++; d->m_dict[dst_pos] = c; if (dst_pos < (TDEFL_MAX_MATCH_LEN - 1)) d->m_dict[TDEFL_LZ_DICT_SIZE + dst_pos] = c; hash = ((hash << TDEFL_LZ_HASH_SHIFT) ^ c) & (TDEFL_LZ_HASH_SIZE - 1); d->m_next[ins_pos & TDEFL_LZ_DICT_SIZE_MASK] = d->m_hash[hash]; d->m_hash[hash] = (mz_uint16)(ins_pos); dst_pos = (dst_pos + 1) & TDEFL_LZ_DICT_SIZE_MASK; ins_pos++; } } else { while ((src_buf_left) && (d->m_lookahead_size < TDEFL_MAX_MATCH_LEN)) { mz_uint8 c = *pSrc++; mz_uint dst_pos = (d->m_lookahead_pos + d->m_lookahead_size) & TDEFL_LZ_DICT_SIZE_MASK; src_buf_left--; d->m_dict[dst_pos] = c; if (dst_pos < (TDEFL_MAX_MATCH_LEN - 1)) d->m_dict[TDEFL_LZ_DICT_SIZE + dst_pos] = c; if ((++d->m_lookahead_size + d->m_dict_size) >= TDEFL_MIN_MATCH_LEN) { mz_uint ins_pos = d->m_lookahead_pos + (d->m_lookahead_size - 1) - 2; mz_uint hash = ((d->m_dict[ins_pos & TDEFL_LZ_DICT_SIZE_MASK] << (TDEFL_LZ_HASH_SHIFT * 2)) ^ (d->m_dict[(ins_pos + 1) & TDEFL_LZ_DICT_SIZE_MASK] << TDEFL_LZ_HASH_SHIFT) ^ c) & (TDEFL_LZ_HASH_SIZE - 1); d->m_next[ins_pos & TDEFL_LZ_DICT_SIZE_MASK] = d->m_hash[hash]; d->m_hash[hash] = (mz_uint16)(ins_pos); } } } d->m_dict_size = MZ_MIN(TDEFL_LZ_DICT_SIZE - d->m_lookahead_size, d->m_dict_size); if ((!flush) && (d->m_lookahead_size < TDEFL_MAX_MATCH_LEN)) break; // Simple lazy/greedy parsing state machine. len_to_move = 1; cur_match_dist = 0; cur_match_len = d->m_saved_match_len ? d->m_saved_match_len : (TDEFL_MIN_MATCH_LEN - 1); cur_pos = d->m_lookahead_pos & TDEFL_LZ_DICT_SIZE_MASK; if (d->m_flags & (TDEFL_RLE_MATCHES | TDEFL_FORCE_ALL_RAW_BLOCKS)) { if ((d->m_dict_size) && (!(d->m_flags & TDEFL_FORCE_ALL_RAW_BLOCKS))) { mz_uint8 c = d->m_dict[(cur_pos - 1) & TDEFL_LZ_DICT_SIZE_MASK]; cur_match_len = 0; while (cur_match_len < d->m_lookahead_size) { if (d->m_dict[cur_pos + cur_match_len] != c) break; cur_match_len++; } if (cur_match_len < TDEFL_MIN_MATCH_LEN) cur_match_len = 0; else cur_match_dist = 1; } } else { tdefl_find_match(d, d->m_lookahead_pos, d->m_dict_size, d->m_lookahead_size, &cur_match_dist, &cur_match_len); } if (((cur_match_len == TDEFL_MIN_MATCH_LEN) && (cur_match_dist >= 8U*1024U)) || (cur_pos == cur_match_dist) || ((d->m_flags & TDEFL_FILTER_MATCHES) && (cur_match_len <= 5))) { cur_match_dist = cur_match_len = 0; } if (d->m_saved_match_len) { if (cur_match_len > d->m_saved_match_len) { tdefl_record_literal(d, (mz_uint8)d->m_saved_lit); if (cur_match_len >= 128) { tdefl_record_match(d, cur_match_len, cur_match_dist); d->m_saved_match_len = 0; len_to_move = cur_match_len; } else { d->m_saved_lit = d->m_dict[cur_pos]; d->m_saved_match_dist = cur_match_dist; d->m_saved_match_len = cur_match_len; } } else { tdefl_record_match(d, d->m_saved_match_len, d->m_saved_match_dist); len_to_move = d->m_saved_match_len - 1; d->m_saved_match_len = 0; } } else if (!cur_match_dist) tdefl_record_literal(d, d->m_dict[MZ_MIN(cur_pos, sizeof(d->m_dict) - 1)]); else if ((d->m_greedy_parsing) || (d->m_flags & TDEFL_RLE_MATCHES) || (cur_match_len >= 128)) { tdefl_record_match(d, cur_match_len, cur_match_dist); len_to_move = cur_match_len; } else { d->m_saved_lit = d->m_dict[MZ_MIN(cur_pos, sizeof(d->m_dict) - 1)]; d->m_saved_match_dist = cur_match_dist; d->m_saved_match_len = cur_match_len; } // Move the lookahead forward by len_to_move bytes. d->m_lookahead_pos += len_to_move; MZ_ASSERT(d->m_lookahead_size >= len_to_move); d->m_lookahead_size -= len_to_move; d->m_dict_size = MZ_MIN(d->m_dict_size + len_to_move, TDEFL_LZ_DICT_SIZE); // Check if it's time to flush the current LZ codes to the internal output buffer. if ( (d->m_pLZ_code_buf > &d->m_lz_code_buf[TDEFL_LZ_CODE_BUF_SIZE - 8]) || ( (d->m_total_lz_bytes > 31*1024) && (((((mz_uint)(d->m_pLZ_code_buf - d->m_lz_code_buf) * 115) >> 7) >= d->m_total_lz_bytes) || (d->m_flags & TDEFL_FORCE_ALL_RAW_BLOCKS))) ) { int n; d->m_pSrc = pSrc; d->m_src_buf_left = src_buf_left; if ((n = tdefl_flush_block(d, 0)) != 0) return (n < 0) ? MZ_FALSE : MZ_TRUE; } } d->m_pSrc = pSrc; d->m_src_buf_left = src_buf_left; return MZ_TRUE; } static tdefl_status tdefl_flush_output_buffer(tdefl_compressor *d) { if (d->m_pIn_buf_size) { *d->m_pIn_buf_size = d->m_pSrc - (const mz_uint8 *)d->m_pIn_buf; } if (d->m_pOut_buf_size) { size_t n = MZ_MIN(*d->m_pOut_buf_size - d->m_out_buf_ofs, d->m_output_flush_remaining); memcpy((mz_uint8 *)d->m_pOut_buf + d->m_out_buf_ofs, d->m_output_buf + d->m_output_flush_ofs, n); d->m_output_flush_ofs += (mz_uint)n; d->m_output_flush_remaining -= (mz_uint)n; d->m_out_buf_ofs += n; *d->m_pOut_buf_size = d->m_out_buf_ofs; } return (d->m_finished && !d->m_output_flush_remaining) ? TDEFL_STATUS_DONE : TDEFL_STATUS_OKAY; } tdefl_status tdefl_compress(tdefl_compressor *d, const void *pIn_buf, size_t *pIn_buf_size, void *pOut_buf, size_t *pOut_buf_size, tdefl_flush flush) { if (!d) { if (pIn_buf_size) *pIn_buf_size = 0; if (pOut_buf_size) *pOut_buf_size = 0; return TDEFL_STATUS_BAD_PARAM; } d->m_pIn_buf = pIn_buf; d->m_pIn_buf_size = pIn_buf_size; d->m_pOut_buf = pOut_buf; d->m_pOut_buf_size = pOut_buf_size; d->m_pSrc = (const mz_uint8 *)(pIn_buf); d->m_src_buf_left = pIn_buf_size ? *pIn_buf_size : 0; d->m_out_buf_ofs = 0; d->m_flush = flush; if ( ((d->m_pPut_buf_func != NULL) == ((pOut_buf != NULL) || (pOut_buf_size != NULL))) || (d->m_prev_return_status != TDEFL_STATUS_OKAY) || (d->m_wants_to_finish && (flush != TDEFL_FINISH)) || (pIn_buf_size && *pIn_buf_size && !pIn_buf) || (pOut_buf_size && *pOut_buf_size && !pOut_buf) ) { if (pIn_buf_size) *pIn_buf_size = 0; if (pOut_buf_size) *pOut_buf_size = 0; return (d->m_prev_return_status = TDEFL_STATUS_BAD_PARAM); } d->m_wants_to_finish |= (flush == TDEFL_FINISH); if ((d->m_output_flush_remaining) || (d->m_finished)) return (d->m_prev_return_status = tdefl_flush_output_buffer(d)); #if MINIZ_USE_UNALIGNED_LOADS_AND_STORES && MINIZ_LITTLE_ENDIAN if (((d->m_flags & TDEFL_MAX_PROBES_MASK) == 1) && ((d->m_flags & TDEFL_GREEDY_PARSING_FLAG) != 0) && ((d->m_flags & (TDEFL_FILTER_MATCHES | TDEFL_FORCE_ALL_RAW_BLOCKS | TDEFL_RLE_MATCHES)) == 0)) { if (!tdefl_compress_fast(d)) return d->m_prev_return_status; } else #endif // #if MINIZ_USE_UNALIGNED_LOADS_AND_STORES && MINIZ_LITTLE_ENDIAN { if (!tdefl_compress_normal(d)) return d->m_prev_return_status; } if ((d->m_flags & (TDEFL_WRITE_ZLIB_HEADER | TDEFL_COMPUTE_ADLER32)) && (pIn_buf)) d->m_adler32 = (mz_uint32)mz_adler32(d->m_adler32, (const mz_uint8 *)pIn_buf, d->m_pSrc - (const mz_uint8 *)pIn_buf); if ((flush) && (!d->m_lookahead_size) && (!d->m_src_buf_left) && (!d->m_output_flush_remaining)) { if (tdefl_flush_block(d, flush) < 0) return d->m_prev_return_status; d->m_finished = (flush == TDEFL_FINISH); if (flush == TDEFL_FULL_FLUSH) { MZ_CLEAR_OBJ(d->m_hash); MZ_CLEAR_OBJ(d->m_next); d->m_dict_size = 0; } } return (d->m_prev_return_status = tdefl_flush_output_buffer(d)); } tdefl_status tdefl_compress_buffer(tdefl_compressor *d, const void *pIn_buf, size_t in_buf_size, tdefl_flush flush) { MZ_ASSERT(d->m_pPut_buf_func); return tdefl_compress(d, pIn_buf, &in_buf_size, NULL, NULL, flush); } tdefl_status tdefl_init(tdefl_compressor *d, tdefl_put_buf_func_ptr pPut_buf_func, void *pPut_buf_user, int flags) { d->m_pPut_buf_func = pPut_buf_func; d->m_pPut_buf_user = pPut_buf_user; d->m_flags = (mz_uint)(flags); d->m_max_probes[0] = 1 + ((flags & 0xFFF) + 2) / 3; d->m_greedy_parsing = (flags & TDEFL_GREEDY_PARSING_FLAG) != 0; d->m_max_probes[1] = 1 + (((flags & 0xFFF) >> 2) + 2) / 3; if (!(flags & TDEFL_NONDETERMINISTIC_PARSING_FLAG)) MZ_CLEAR_OBJ(d->m_hash); d->m_lookahead_pos = d->m_lookahead_size = d->m_dict_size = d->m_total_lz_bytes = d->m_lz_code_buf_dict_pos = d->m_bits_in = 0; d->m_output_flush_ofs = d->m_output_flush_remaining = d->m_finished = d->m_block_index = d->m_bit_buffer = d->m_wants_to_finish = 0; d->m_pLZ_code_buf = d->m_lz_code_buf + 1; d->m_pLZ_flags = d->m_lz_code_buf; d->m_num_flags_left = 8; d->m_pOutput_buf = d->m_output_buf; d->m_pOutput_buf_end = d->m_output_buf; d->m_prev_return_status = TDEFL_STATUS_OKAY; d->m_saved_match_dist = d->m_saved_match_len = d->m_saved_lit = 0; d->m_adler32 = 1; d->m_pIn_buf = NULL; d->m_pOut_buf = NULL; d->m_pIn_buf_size = NULL; d->m_pOut_buf_size = NULL; d->m_flush = TDEFL_NO_FLUSH; d->m_pSrc = NULL; d->m_src_buf_left = 0; d->m_out_buf_ofs = 0; memset(&d->m_huff_count[0][0], 0, sizeof(d->m_huff_count[0][0]) * TDEFL_MAX_HUFF_SYMBOLS_0); memset(&d->m_huff_count[1][0], 0, sizeof(d->m_huff_count[1][0]) * TDEFL_MAX_HUFF_SYMBOLS_1); return TDEFL_STATUS_OKAY; } tdefl_status tdefl_get_prev_return_status(tdefl_compressor *d) { return d->m_prev_return_status; } mz_uint32 tdefl_get_adler32(tdefl_compressor *d) { return d->m_adler32; } mz_bool tdefl_compress_mem_to_output(const void *pBuf, size_t buf_len, tdefl_put_buf_func_ptr pPut_buf_func, void *pPut_buf_user, int flags) { tdefl_compressor *pComp; mz_bool succeeded; if (((buf_len) && (!pBuf)) || (!pPut_buf_func)) return MZ_FALSE; pComp = (tdefl_compressor*)MZ_MALLOC(sizeof(tdefl_compressor)); if (!pComp) return MZ_FALSE; succeeded = (tdefl_init(pComp, pPut_buf_func, pPut_buf_user, flags) == TDEFL_STATUS_OKAY); succeeded = succeeded && (tdefl_compress_buffer(pComp, pBuf, buf_len, TDEFL_FINISH) == TDEFL_STATUS_DONE); MZ_FREE(pComp); return succeeded; } typedef struct { size_t m_size, m_capacity; mz_uint8 *m_pBuf; mz_bool m_expandable; } tdefl_output_buffer; static mz_bool tdefl_output_buffer_putter(const void *pBuf, int len, void *pUser) { tdefl_output_buffer *p = (tdefl_output_buffer *)pUser; size_t new_size = p->m_size + len; if (new_size > p->m_capacity) { size_t new_capacity = p->m_capacity; mz_uint8 *pNew_buf; if (!p->m_expandable) return MZ_FALSE; do { new_capacity = MZ_MAX(128U, new_capacity << 1U); } while (new_size > new_capacity); pNew_buf = (mz_uint8*)MZ_REALLOC(p->m_pBuf, new_capacity); if (!pNew_buf) return MZ_FALSE; p->m_pBuf = pNew_buf; p->m_capacity = new_capacity; } memcpy((mz_uint8*)p->m_pBuf + p->m_size, pBuf, len); p->m_size = new_size; return MZ_TRUE; } void *tdefl_compress_mem_to_heap(const void *pSrc_buf, size_t src_buf_len, size_t *pOut_len, int flags) { tdefl_output_buffer out_buf; MZ_CLEAR_OBJ(out_buf); if (!pOut_len) return MZ_FALSE; else *pOut_len = 0; out_buf.m_expandable = MZ_TRUE; if (!tdefl_compress_mem_to_output(pSrc_buf, src_buf_len, tdefl_output_buffer_putter, &out_buf, flags)) return NULL; *pOut_len = out_buf.m_size; return out_buf.m_pBuf; } size_t tdefl_compress_mem_to_mem(void *pOut_buf, size_t out_buf_len, const void *pSrc_buf, size_t src_buf_len, int flags) { tdefl_output_buffer out_buf; MZ_CLEAR_OBJ(out_buf); if (!pOut_buf) return 0; out_buf.m_pBuf = (mz_uint8*)pOut_buf; out_buf.m_capacity = out_buf_len; if (!tdefl_compress_mem_to_output(pSrc_buf, src_buf_len, tdefl_output_buffer_putter, &out_buf, flags)) return 0; return out_buf.m_size; } #ifndef MINIZ_NO_ZLIB_APIS static const mz_uint s_tdefl_num_probes[11] = { 0, 1, 6, 32, 16, 32, 128, 256, 512, 768, 1500 }; // level may actually range from [0,10] (10 is a "hidden" max level, where we want a bit more compression and it's fine if throughput to fall off a cliff on some files). mz_uint tdefl_create_comp_flags_from_zip_params(int level, int window_bits, int strategy) { mz_uint comp_flags = s_tdefl_num_probes[(level >= 0) ? MZ_MIN(10, level) : MZ_DEFAULT_LEVEL] | ((level <= 3) ? TDEFL_GREEDY_PARSING_FLAG : 0); if (window_bits > 0) comp_flags |= TDEFL_WRITE_ZLIB_HEADER; if (!level) comp_flags |= TDEFL_FORCE_ALL_RAW_BLOCKS; else if (strategy == MZ_FILTERED) comp_flags |= TDEFL_FILTER_MATCHES; else if (strategy == MZ_HUFFMAN_ONLY) comp_flags &= ~TDEFL_MAX_PROBES_MASK; else if (strategy == MZ_FIXED) comp_flags |= TDEFL_FORCE_ALL_STATIC_BLOCKS; else if (strategy == MZ_RLE) comp_flags |= TDEFL_RLE_MATCHES; return comp_flags; } #endif //MINIZ_NO_ZLIB_APIS #ifdef _MSC_VER #pragma warning (push) #pragma warning (disable:4204) // nonstandard extension used : non-constant aggregate initializer (also supported by GNU C and C99, so no big deal) #endif // Simple PNG writer function by Alex Evans, 2011. Released into the public domain: https://gist.github.com/908299, more context at // http://altdevblogaday.org/2011/04/06/a-smaller-jpg-encoder/. // This is actually a modification of Alex's original code so PNG files generated by this function pass pngcheck. void *tdefl_write_image_to_png_file_in_memory_ex(const void *pImage, int w, int h, int num_chans, size_t *pLen_out, mz_uint level, mz_bool flip) { // Using a local copy of this array here in case MINIZ_NO_ZLIB_APIS was defined. static const mz_uint s_tdefl_png_num_probes[11] = { 0, 1, 6, 32, 16, 32, 128, 256, 512, 768, 1500 }; tdefl_compressor *pComp = (tdefl_compressor *)MZ_MALLOC(sizeof(tdefl_compressor)); tdefl_output_buffer out_buf; int i, bpl = w * num_chans, y, z; mz_uint32 c; *pLen_out = 0; if (!pComp) return NULL; MZ_CLEAR_OBJ(out_buf); out_buf.m_expandable = MZ_TRUE; out_buf.m_capacity = 57+MZ_MAX(64, (1+bpl)*h); if (NULL == (out_buf.m_pBuf = (mz_uint8*)MZ_MALLOC(out_buf.m_capacity))) { MZ_FREE(pComp); return NULL; } // write dummy header for (z = 41; z; --z) tdefl_output_buffer_putter(&z, 1, &out_buf); // compress image data tdefl_init(pComp, tdefl_output_buffer_putter, &out_buf, s_tdefl_png_num_probes[MZ_MIN(10, level)] | TDEFL_WRITE_ZLIB_HEADER); for (y = 0; y < h; ++y) { tdefl_compress_buffer(pComp, &z, 1, TDEFL_NO_FLUSH); tdefl_compress_buffer(pComp, (mz_uint8*)pImage + (flip ? (h - 1 - y) : y) * bpl, bpl, TDEFL_NO_FLUSH); } if (tdefl_compress_buffer(pComp, NULL, 0, TDEFL_FINISH) != TDEFL_STATUS_DONE) { MZ_FREE(pComp); MZ_FREE(out_buf.m_pBuf); return NULL; } // write real header *pLen_out = out_buf.m_size-41; { static const mz_uint8 chans[] = {0x00, 0x00, 0x04, 0x02, 0x06}; mz_uint8 pnghdr[41]={0x89,0x50,0x4e,0x47,0x0d,0x0a,0x1a,0x0a,0x00,0x00,0x00,0x0d,0x49,0x48,0x44,0x52, 0,0,(mz_uint8)(w>>8),(mz_uint8)w,0,0,(mz_uint8)(h>>8),(mz_uint8)h,8,chans[num_chans],0,0,0,0,0,0,0, (mz_uint8)(*pLen_out>>24),(mz_uint8)(*pLen_out>>16),(mz_uint8)(*pLen_out>>8),(mz_uint8)*pLen_out,0x49,0x44,0x41,0x54}; c=(mz_uint32)mz_crc32(MZ_CRC32_INIT,pnghdr+12,17); for (i=0; i<4; ++i, c<<=8) ((mz_uint8*)(pnghdr+29))[i]=(mz_uint8)(c>>24); memcpy(out_buf.m_pBuf, pnghdr, 41); } // write footer (IDAT CRC-32, followed by IEND chunk) if (!tdefl_output_buffer_putter("\0\0\0\0\0\0\0\0\x49\x45\x4e\x44\xae\x42\x60\x82", 16, &out_buf)) { *pLen_out = 0; MZ_FREE(pComp); MZ_FREE(out_buf.m_pBuf); return NULL; } c = (mz_uint32)mz_crc32(MZ_CRC32_INIT,out_buf.m_pBuf+41-4, *pLen_out+4); for (i=0; i<4; ++i, c<<=8) (out_buf.m_pBuf+out_buf.m_size-16)[i] = (mz_uint8)(c >> 24); // compute final size of file, grab compressed data buffer and return *pLen_out += 57; MZ_FREE(pComp); return out_buf.m_pBuf; } void *tdefl_write_image_to_png_file_in_memory(const void *pImage, int w, int h, int num_chans, size_t *pLen_out) { // Level 6 corresponds to TDEFL_DEFAULT_MAX_PROBES or MZ_DEFAULT_LEVEL (but we can't depend on MZ_DEFAULT_LEVEL being available in case the zlib API's where #defined out) return tdefl_write_image_to_png_file_in_memory_ex(pImage, w, h, num_chans, pLen_out, 6, MZ_FALSE); } #ifdef _MSC_VER #pragma warning (pop) #endif // ------------------- .ZIP archive reading #ifndef MINIZ_NO_ARCHIVE_APIS #ifdef MINIZ_NO_STDIO #define MZ_FILE void * #else #include #include #if defined(_MSC_VER) || defined(__MINGW64__) static FILE *mz_fopen(const char *pFilename, const char *pMode) { FILE* pFile = NULL; fopen_s(&pFile, pFilename, pMode); return pFile; } static FILE *mz_freopen(const char *pPath, const char *pMode, FILE *pStream) { FILE* pFile = NULL; if (freopen_s(&pFile, pPath, pMode, pStream)) return NULL; return pFile; } #ifndef MINIZ_NO_TIME #include #endif #define MZ_FILE FILE #define MZ_FOPEN mz_fopen #define MZ_FCLOSE fclose #define MZ_FREAD fread #define MZ_FWRITE fwrite #define MZ_FTELL64 _ftelli64 #define MZ_FSEEK64 _fseeki64 #define MZ_FILE_STAT_STRUCT _stat #define MZ_FILE_STAT _stat #define MZ_FFLUSH fflush #define MZ_FREOPEN mz_freopen #define MZ_DELETE_FILE remove #elif defined(__MINGW32__) #ifndef MINIZ_NO_TIME #include #endif #define MZ_FILE FILE #define MZ_FOPEN(f, m) fopen(f, m) #define MZ_FCLOSE fclose #define MZ_FREAD fread #define MZ_FWRITE fwrite #define MZ_FTELL64 ftello64 #define MZ_FSEEK64 fseeko64 #define MZ_FILE_STAT_STRUCT _stat #define MZ_FILE_STAT _stat #define MZ_FFLUSH fflush #define MZ_FREOPEN(f, m, s) freopen(f, m, s) #define MZ_DELETE_FILE remove #elif defined(__TINYC__) #ifndef MINIZ_NO_TIME #include #endif #define MZ_FILE FILE #define MZ_FOPEN(f, m) fopen(f, m) #define MZ_FCLOSE fclose #define MZ_FREAD fread #define MZ_FWRITE fwrite #define MZ_FTELL64 ftell #define MZ_FSEEK64 fseek #define MZ_FILE_STAT_STRUCT stat #define MZ_FILE_STAT stat #define MZ_FFLUSH fflush #define MZ_FREOPEN(f, m, s) freopen(f, m, s) #define MZ_DELETE_FILE remove #elif defined(__GNUC__) && _LARGEFILE64_SOURCE #ifndef MINIZ_NO_TIME #include #endif #define MZ_FILE FILE #define MZ_FOPEN(f, m) fopen64(f, m) #define MZ_FCLOSE fclose #define MZ_FREAD fread #define MZ_FWRITE fwrite #define MZ_FTELL64 ftello64 #define MZ_FSEEK64 fseeko64 #define MZ_FILE_STAT_STRUCT stat64 #define MZ_FILE_STAT stat64 #define MZ_FFLUSH fflush #define MZ_FREOPEN(p, m, s) freopen64(p, m, s) #define MZ_DELETE_FILE remove #else #ifndef MINIZ_NO_TIME #include #endif #define MZ_FILE FILE #define MZ_FOPEN(f, m) fopen(f, m) #define MZ_FCLOSE fclose #define MZ_FREAD fread #define MZ_FWRITE fwrite #define MZ_FTELL64 ftello #define MZ_FSEEK64 fseeko #define MZ_FILE_STAT_STRUCT stat #define MZ_FILE_STAT stat #define MZ_FFLUSH fflush #define MZ_FREOPEN(f, m, s) freopen(f, m, s) #define MZ_DELETE_FILE remove #endif // #ifdef _MSC_VER #endif // #ifdef MINIZ_NO_STDIO #define MZ_TOLOWER(c) ((((c) >= 'A') && ((c) <= 'Z')) ? ((c) - 'A' + 'a') : (c)) // Various ZIP archive enums. To completely avoid cross platform compiler alignment and platform endian issues, miniz.c doesn't use structs for any of this stuff. enum { // ZIP archive identifiers and record sizes MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIG = 0x06054b50, MZ_ZIP_CENTRAL_DIR_HEADER_SIG = 0x02014b50, MZ_ZIP_LOCAL_DIR_HEADER_SIG = 0x04034b50, MZ_ZIP_LOCAL_DIR_HEADER_SIZE = 30, MZ_ZIP_CENTRAL_DIR_HEADER_SIZE = 46, MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE = 22, // Central directory header record offsets MZ_ZIP_CDH_SIG_OFS = 0, MZ_ZIP_CDH_VERSION_MADE_BY_OFS = 4, MZ_ZIP_CDH_VERSION_NEEDED_OFS = 6, MZ_ZIP_CDH_BIT_FLAG_OFS = 8, MZ_ZIP_CDH_METHOD_OFS = 10, MZ_ZIP_CDH_FILE_TIME_OFS = 12, MZ_ZIP_CDH_FILE_DATE_OFS = 14, MZ_ZIP_CDH_CRC32_OFS = 16, MZ_ZIP_CDH_COMPRESSED_SIZE_OFS = 20, MZ_ZIP_CDH_DECOMPRESSED_SIZE_OFS = 24, MZ_ZIP_CDH_FILENAME_LEN_OFS = 28, MZ_ZIP_CDH_EXTRA_LEN_OFS = 30, MZ_ZIP_CDH_COMMENT_LEN_OFS = 32, MZ_ZIP_CDH_DISK_START_OFS = 34, MZ_ZIP_CDH_INTERNAL_ATTR_OFS = 36, MZ_ZIP_CDH_EXTERNAL_ATTR_OFS = 38, MZ_ZIP_CDH_LOCAL_HEADER_OFS = 42, // Local directory header offsets MZ_ZIP_LDH_SIG_OFS = 0, MZ_ZIP_LDH_VERSION_NEEDED_OFS = 4, MZ_ZIP_LDH_BIT_FLAG_OFS = 6, MZ_ZIP_LDH_METHOD_OFS = 8, MZ_ZIP_LDH_FILE_TIME_OFS = 10, MZ_ZIP_LDH_FILE_DATE_OFS = 12, MZ_ZIP_LDH_CRC32_OFS = 14, MZ_ZIP_LDH_COMPRESSED_SIZE_OFS = 18, MZ_ZIP_LDH_DECOMPRESSED_SIZE_OFS = 22, MZ_ZIP_LDH_FILENAME_LEN_OFS = 26, MZ_ZIP_LDH_EXTRA_LEN_OFS = 28, // End of central directory offsets MZ_ZIP_ECDH_SIG_OFS = 0, MZ_ZIP_ECDH_NUM_THIS_DISK_OFS = 4, MZ_ZIP_ECDH_NUM_DISK_CDIR_OFS = 6, MZ_ZIP_ECDH_CDIR_NUM_ENTRIES_ON_DISK_OFS = 8, MZ_ZIP_ECDH_CDIR_TOTAL_ENTRIES_OFS = 10, MZ_ZIP_ECDH_CDIR_SIZE_OFS = 12, MZ_ZIP_ECDH_CDIR_OFS_OFS = 16, MZ_ZIP_ECDH_COMMENT_SIZE_OFS = 20, }; typedef struct { void *m_p; size_t m_size, m_capacity; mz_uint m_element_size; } mz_zip_array; struct mz_zip_internal_state_tag { mz_zip_array m_central_dir; mz_zip_array m_central_dir_offsets; mz_zip_array m_sorted_central_dir_offsets; MZ_FILE *m_pFile; void *m_pMem; size_t m_mem_size; size_t m_mem_capacity; }; #define MZ_ZIP_ARRAY_SET_ELEMENT_SIZE(array_ptr, element_size) (array_ptr)->m_element_size = element_size #define MZ_ZIP_ARRAY_ELEMENT(array_ptr, element_type, index) ((element_type *)((array_ptr)->m_p))[index] static MZ_FORCEINLINE void mz_zip_array_clear(mz_zip_archive *pZip, mz_zip_array *pArray) { pZip->m_pFree(pZip->m_pAlloc_opaque, pArray->m_p); memset(pArray, 0, sizeof(mz_zip_array)); } static mz_bool mz_zip_array_ensure_capacity(mz_zip_archive *pZip, mz_zip_array *pArray, size_t min_new_capacity, mz_uint growing) { void *pNew_p; size_t new_capacity = min_new_capacity; MZ_ASSERT(pArray->m_element_size); if (pArray->m_capacity >= min_new_capacity) return MZ_TRUE; if (growing) { new_capacity = MZ_MAX(1, pArray->m_capacity); while (new_capacity < min_new_capacity) new_capacity *= 2; } if (NULL == (pNew_p = pZip->m_pRealloc(pZip->m_pAlloc_opaque, pArray->m_p, pArray->m_element_size, new_capacity))) return MZ_FALSE; pArray->m_p = pNew_p; pArray->m_capacity = new_capacity; return MZ_TRUE; } static MZ_FORCEINLINE mz_bool mz_zip_array_reserve(mz_zip_archive *pZip, mz_zip_array *pArray, size_t new_capacity, mz_uint growing) { if (new_capacity > pArray->m_capacity) { if (!mz_zip_array_ensure_capacity(pZip, pArray, new_capacity, growing)) return MZ_FALSE; } return MZ_TRUE; } static MZ_FORCEINLINE mz_bool mz_zip_array_resize(mz_zip_archive *pZip, mz_zip_array *pArray, size_t new_size, mz_uint growing) { if (new_size > pArray->m_capacity) { if (!mz_zip_array_ensure_capacity(pZip, pArray, new_size, growing)) return MZ_FALSE; } pArray->m_size = new_size; return MZ_TRUE; } static MZ_FORCEINLINE mz_bool mz_zip_array_ensure_room(mz_zip_archive *pZip, mz_zip_array *pArray, size_t n) { return mz_zip_array_reserve(pZip, pArray, pArray->m_size + n, MZ_TRUE); } static MZ_FORCEINLINE mz_bool mz_zip_array_push_back(mz_zip_archive *pZip, mz_zip_array *pArray, const void *pElements, size_t n) { size_t orig_size = pArray->m_size; if (!mz_zip_array_resize(pZip, pArray, orig_size + n, MZ_TRUE)) return MZ_FALSE; memcpy((mz_uint8*)pArray->m_p + orig_size * pArray->m_element_size, pElements, n * pArray->m_element_size); return MZ_TRUE; } #ifndef MINIZ_NO_TIME static time_t mz_zip_dos_to_time_t(int dos_time, int dos_date) { struct tm tm; memset(&tm, 0, sizeof(tm)); tm.tm_isdst = -1; tm.tm_year = ((dos_date >> 9) & 127) + 1980 - 1900; tm.tm_mon = ((dos_date >> 5) & 15) - 1; tm.tm_mday = dos_date & 31; tm.tm_hour = (dos_time >> 11) & 31; tm.tm_min = (dos_time >> 5) & 63; tm.tm_sec = (dos_time << 1) & 62; return mktime(&tm); } static void mz_zip_time_to_dos_time(time_t time, mz_uint16 *pDOS_time, mz_uint16 *pDOS_date) { #ifdef _MSC_VER struct tm tm_struct; struct tm *tm = &tm_struct; errno_t err = localtime_s(tm, &time); if (err) { *pDOS_date = 0; *pDOS_time = 0; return; } #else struct tm *tm = localtime(&time); #endif *pDOS_time = (mz_uint16)(((tm->tm_hour) << 11) + ((tm->tm_min) << 5) + ((tm->tm_sec) >> 1)); *pDOS_date = (mz_uint16)(((tm->tm_year + 1900 - 1980) << 9) + ((tm->tm_mon + 1) << 5) + tm->tm_mday); } #endif #ifndef MINIZ_NO_STDIO static mz_bool mz_zip_get_file_modified_time(const char *pFilename, mz_uint16 *pDOS_time, mz_uint16 *pDOS_date) { #ifdef MINIZ_NO_TIME (void)pFilename; *pDOS_date = *pDOS_time = 0; #else struct MZ_FILE_STAT_STRUCT file_stat; // On Linux with x86 glibc, this call will fail on large files (>= 0x80000000 bytes) unless you compiled with _LARGEFILE64_SOURCE. Argh. if (MZ_FILE_STAT(pFilename, &file_stat) != 0) return MZ_FALSE; mz_zip_time_to_dos_time(file_stat.st_mtime, pDOS_time, pDOS_date); #endif // #ifdef MINIZ_NO_TIME return MZ_TRUE; } #ifndef MINIZ_NO_TIME static mz_bool mz_zip_set_file_times(const char *pFilename, time_t access_time, time_t modified_time) { struct utimbuf t; t.actime = access_time; t.modtime = modified_time; return !utime(pFilename, &t); } #endif // #ifndef MINIZ_NO_TIME #endif // #ifndef MINIZ_NO_STDIO static mz_bool mz_zip_reader_init_internal(mz_zip_archive *pZip, mz_uint32 flags) { (void)flags; if ((!pZip) || (pZip->m_pState) || (pZip->m_zip_mode != MZ_ZIP_MODE_INVALID)) return MZ_FALSE; if (!pZip->m_pAlloc) pZip->m_pAlloc = def_alloc_func; if (!pZip->m_pFree) pZip->m_pFree = def_free_func; if (!pZip->m_pRealloc) pZip->m_pRealloc = def_realloc_func; pZip->m_zip_mode = MZ_ZIP_MODE_READING; pZip->m_archive_size = 0; pZip->m_central_directory_file_ofs = 0; pZip->m_total_files = 0; if (NULL == (pZip->m_pState = (mz_zip_internal_state *)pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, sizeof(mz_zip_internal_state)))) return MZ_FALSE; memset(pZip->m_pState, 0, sizeof(mz_zip_internal_state)); MZ_ZIP_ARRAY_SET_ELEMENT_SIZE(&pZip->m_pState->m_central_dir, sizeof(mz_uint8)); MZ_ZIP_ARRAY_SET_ELEMENT_SIZE(&pZip->m_pState->m_central_dir_offsets, sizeof(mz_uint32)); MZ_ZIP_ARRAY_SET_ELEMENT_SIZE(&pZip->m_pState->m_sorted_central_dir_offsets, sizeof(mz_uint32)); return MZ_TRUE; } static MZ_FORCEINLINE mz_bool mz_zip_reader_filename_less(const mz_zip_array *pCentral_dir_array, const mz_zip_array *pCentral_dir_offsets, mz_uint l_index, mz_uint r_index) { const mz_uint8 *pL = &MZ_ZIP_ARRAY_ELEMENT(pCentral_dir_array, mz_uint8, MZ_ZIP_ARRAY_ELEMENT(pCentral_dir_offsets, mz_uint32, l_index)), *pE; const mz_uint8 *pR = &MZ_ZIP_ARRAY_ELEMENT(pCentral_dir_array, mz_uint8, MZ_ZIP_ARRAY_ELEMENT(pCentral_dir_offsets, mz_uint32, r_index)); mz_uint l_len = MZ_READ_LE16(pL + MZ_ZIP_CDH_FILENAME_LEN_OFS), r_len = MZ_READ_LE16(pR + MZ_ZIP_CDH_FILENAME_LEN_OFS); mz_uint8 l = 0, r = 0; pL += MZ_ZIP_CENTRAL_DIR_HEADER_SIZE; pR += MZ_ZIP_CENTRAL_DIR_HEADER_SIZE; pE = pL + MZ_MIN(l_len, r_len); while (pL < pE) { if ((l = MZ_TOLOWER(*pL)) != (r = MZ_TOLOWER(*pR))) break; pL++; pR++; } return (pL == pE) ? (l_len < r_len) : (l < r); } #define MZ_SWAP_UINT32(a, b) do { mz_uint32 t = a; a = b; b = t; } MZ_MACRO_END // Heap sort of lowercased filenames, used to help accelerate plain central directory searches by mz_zip_reader_locate_file(). (Could also use qsort(), but it could allocate memory.) static void mz_zip_reader_sort_central_dir_offsets_by_filename(mz_zip_archive *pZip) { mz_zip_internal_state *pState = pZip->m_pState; const mz_zip_array *pCentral_dir_offsets = &pState->m_central_dir_offsets; const mz_zip_array *pCentral_dir = &pState->m_central_dir; mz_uint32 *pIndices = &MZ_ZIP_ARRAY_ELEMENT(&pState->m_sorted_central_dir_offsets, mz_uint32, 0); const int size = pZip->m_total_files; int start = (size - 2) >> 1, end; while (start >= 0) { int child, root = start; for ( ; ; ) { if ((child = (root << 1) + 1) >= size) break; child += (((child + 1) < size) && (mz_zip_reader_filename_less(pCentral_dir, pCentral_dir_offsets, pIndices[child], pIndices[child + 1]))); if (!mz_zip_reader_filename_less(pCentral_dir, pCentral_dir_offsets, pIndices[root], pIndices[child])) break; MZ_SWAP_UINT32(pIndices[root], pIndices[child]); root = child; } start--; } end = size - 1; while (end > 0) { int child, root = 0; MZ_SWAP_UINT32(pIndices[end], pIndices[0]); for ( ; ; ) { if ((child = (root << 1) + 1) >= end) break; child += (((child + 1) < end) && mz_zip_reader_filename_less(pCentral_dir, pCentral_dir_offsets, pIndices[child], pIndices[child + 1])); if (!mz_zip_reader_filename_less(pCentral_dir, pCentral_dir_offsets, pIndices[root], pIndices[child])) break; MZ_SWAP_UINT32(pIndices[root], pIndices[child]); root = child; } end--; } } static mz_bool mz_zip_reader_read_central_dir(mz_zip_archive *pZip, mz_uint32 flags) { mz_uint cdir_size, num_this_disk, cdir_disk_index; mz_uint64 cdir_ofs; mz_int64 cur_file_ofs; const mz_uint8 *p; mz_uint32 buf_u32[4096 / sizeof(mz_uint32)]; mz_uint8 *pBuf = (mz_uint8 *)buf_u32; mz_bool sort_central_dir = ((flags & MZ_ZIP_FLAG_DO_NOT_SORT_CENTRAL_DIRECTORY) == 0); + mz_bool zip_signature_found = 0; // Basic sanity checks - reject files which are too small, and check the first 4 bytes of the file to make sure a local header is there. if (pZip->m_archive_size < MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE) return MZ_FALSE; // Find the end of central directory record by scanning the file from the end towards the beginning. cur_file_ofs = MZ_MAX((mz_int64)pZip->m_archive_size - (mz_int64)sizeof(buf_u32), 0); for ( ; ; ) { - for ( ; ; ) + int i, n = (int)MZ_MIN(sizeof(buf_u32), pZip->m_archive_size - cur_file_ofs); + if (pZip->m_pRead(pZip->m_pIO_opaque, cur_file_ofs, pBuf, n) != (mz_uint)n) + return MZ_FALSE; + for (i = n - 4; i >= 0; --i) { - int i, n = (int)MZ_MIN(sizeof(buf_u32), pZip->m_archive_size - cur_file_ofs); - if (pZip->m_pRead(pZip->m_pIO_opaque, cur_file_ofs, pBuf, n) != (mz_uint)n) - return MZ_FALSE; - for (i = n - 4; i >= 0; --i) - if (MZ_READ_LE32(pBuf + i) == MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIG) - break; - if (i >= 0) + if (MZ_READ_LE32(pBuf + i) == MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIG) { - cur_file_ofs += i; + // Read and verify the end of central directory record. + if (pZip->m_pRead(pZip->m_pIO_opaque, cur_file_ofs + i, pBuf, MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE) != MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE) + continue; + if ((MZ_READ_LE32(pBuf + MZ_ZIP_ECDH_SIG_OFS) != MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIG) || + ((pZip->m_total_files = MZ_READ_LE16(pBuf + MZ_ZIP_ECDH_CDIR_TOTAL_ENTRIES_OFS)) != MZ_READ_LE16(pBuf + MZ_ZIP_ECDH_CDIR_NUM_ENTRIES_ON_DISK_OFS))) + continue; + zip_signature_found = 1; break; } - if ((!cur_file_ofs) || (cur_file_ofs < MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE)) - return MZ_FALSE; - cur_file_ofs = MZ_MAX(cur_file_ofs - (sizeof(buf_u32) - 3), 0); } - // Read and verify the end of central directory record. - if (pZip->m_pRead(pZip->m_pIO_opaque, cur_file_ofs, pBuf, MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE) != MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE) - continue; - if ((MZ_READ_LE32(pBuf + MZ_ZIP_ECDH_SIG_OFS) != MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIG) || - ((pZip->m_total_files = MZ_READ_LE16(pBuf + MZ_ZIP_ECDH_CDIR_TOTAL_ENTRIES_OFS)) != MZ_READ_LE16(pBuf + MZ_ZIP_ECDH_CDIR_NUM_ENTRIES_ON_DISK_OFS))) - continue; - break; + + if (zip_signature_found) + { + cur_file_ofs += i; + break; + } + if ((!cur_file_ofs) || (cur_file_ofs < MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE)) + return MZ_FALSE; + + cur_file_ofs = MZ_MAX(cur_file_ofs - (mz_int64)(sizeof(buf_u32) - 3), 0); } num_this_disk = MZ_READ_LE16(pBuf + MZ_ZIP_ECDH_NUM_THIS_DISK_OFS); cdir_disk_index = MZ_READ_LE16(pBuf + MZ_ZIP_ECDH_NUM_DISK_CDIR_OFS); if (((num_this_disk | cdir_disk_index) != 0) && ((num_this_disk != 1) || (cdir_disk_index != 1))) return MZ_FALSE; if ((cdir_size = MZ_READ_LE32(pBuf + MZ_ZIP_ECDH_CDIR_SIZE_OFS)) < pZip->m_total_files * MZ_ZIP_CENTRAL_DIR_HEADER_SIZE) return MZ_FALSE; cdir_ofs = cur_file_ofs - cdir_size; if ((cdir_ofs + (mz_uint64)cdir_size) > pZip->m_archive_size) return MZ_FALSE; pZip->m_central_directory_file_ofs = cdir_ofs; pZip->m_archive_file_ofs = cdir_ofs - MZ_READ_LE32(pBuf + MZ_ZIP_ECDH_CDIR_OFS_OFS); if (pZip->m_archive_file_ofs > pZip->m_archive_size) return MZ_FALSE; if (pZip->m_total_files) { mz_uint i, n; // Read the entire central directory into a heap block, and allocate another heap block to hold the unsorted central dir file record offsets, and another to hold the sorted indices. if ((!mz_zip_array_resize(pZip, &pZip->m_pState->m_central_dir, cdir_size, MZ_FALSE)) || (!mz_zip_array_resize(pZip, &pZip->m_pState->m_central_dir_offsets, pZip->m_total_files, MZ_FALSE))) return MZ_FALSE; if (sort_central_dir) { if (!mz_zip_array_resize(pZip, &pZip->m_pState->m_sorted_central_dir_offsets, pZip->m_total_files, MZ_FALSE)) return MZ_FALSE; } if (pZip->m_pRead(pZip->m_pIO_opaque, cdir_ofs, pZip->m_pState->m_central_dir.m_p, cdir_size) != cdir_size) return MZ_FALSE; // Now create an index into the central directory file records, do some basic sanity checking on each record, and check for zip64 entries (which are not yet supported). p = (const mz_uint8 *)pZip->m_pState->m_central_dir.m_p; for (n = cdir_size, i = 0; i < pZip->m_total_files; ++i) { mz_uint total_header_size, comp_size, decomp_size, disk_index; if ((n < MZ_ZIP_CENTRAL_DIR_HEADER_SIZE) || (MZ_READ_LE32(p) != MZ_ZIP_CENTRAL_DIR_HEADER_SIG)) return MZ_FALSE; MZ_ZIP_ARRAY_ELEMENT(&pZip->m_pState->m_central_dir_offsets, mz_uint32, i) = (mz_uint32)(p - (const mz_uint8 *)pZip->m_pState->m_central_dir.m_p); if (sort_central_dir) MZ_ZIP_ARRAY_ELEMENT(&pZip->m_pState->m_sorted_central_dir_offsets, mz_uint32, i) = i; comp_size = MZ_READ_LE32(p + MZ_ZIP_CDH_COMPRESSED_SIZE_OFS); decomp_size = MZ_READ_LE32(p + MZ_ZIP_CDH_DECOMPRESSED_SIZE_OFS); if (((!MZ_READ_LE32(p + MZ_ZIP_CDH_METHOD_OFS)) && (decomp_size != comp_size)) || (decomp_size && !comp_size) || (decomp_size == 0xFFFFFFFF) || (comp_size == 0xFFFFFFFF)) return MZ_FALSE; disk_index = MZ_READ_LE16(p + MZ_ZIP_CDH_DISK_START_OFS); if ((disk_index != num_this_disk) && (disk_index != 1)) return MZ_FALSE; if (((mz_uint64)MZ_READ_LE32(p + MZ_ZIP_CDH_LOCAL_HEADER_OFS) + MZ_ZIP_LOCAL_DIR_HEADER_SIZE + comp_size) > pZip->m_archive_size) return MZ_FALSE; if ((total_header_size = MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + MZ_READ_LE16(p + MZ_ZIP_CDH_FILENAME_LEN_OFS) + MZ_READ_LE16(p + MZ_ZIP_CDH_EXTRA_LEN_OFS) + MZ_READ_LE16(p + MZ_ZIP_CDH_COMMENT_LEN_OFS)) > n) return MZ_FALSE; n -= total_header_size; p += total_header_size; } } if (sort_central_dir) mz_zip_reader_sort_central_dir_offsets_by_filename(pZip); return MZ_TRUE; } mz_bool mz_zip_reader_init(mz_zip_archive *pZip, mz_uint64 size, mz_uint32 flags) { if ((!pZip) || (!pZip->m_pRead)) return MZ_FALSE; if (!mz_zip_reader_init_internal(pZip, flags)) return MZ_FALSE; pZip->m_archive_size = size; if (!mz_zip_reader_read_central_dir(pZip, flags)) { mz_zip_reader_end(pZip); return MZ_FALSE; } return MZ_TRUE; } static size_t mz_zip_mem_read_func(void *pOpaque, mz_uint64 file_ofs, void *pBuf, size_t n) { mz_zip_archive *pZip = (mz_zip_archive *)pOpaque; size_t s = (file_ofs >= pZip->m_archive_size) ? 0 : (size_t)MZ_MIN(pZip->m_archive_size - file_ofs, n); memcpy(pBuf, (const mz_uint8 *)pZip->m_pState->m_pMem + file_ofs, s); return s; } mz_bool mz_zip_reader_init_mem(mz_zip_archive *pZip, const void *pMem, size_t size, mz_uint32 flags) { if (!mz_zip_reader_init_internal(pZip, flags)) return MZ_FALSE; pZip->m_archive_size = size; pZip->m_pRead = mz_zip_mem_read_func; pZip->m_pIO_opaque = pZip; #ifdef __cplusplus pZip->m_pState->m_pMem = const_cast(pMem); #else pZip->m_pState->m_pMem = (void *)pMem; #endif pZip->m_pState->m_mem_size = size; if (!mz_zip_reader_read_central_dir(pZip, flags)) { mz_zip_reader_end(pZip); return MZ_FALSE; } return MZ_TRUE; } #ifndef MINIZ_NO_STDIO static size_t mz_zip_file_read_func(void *pOpaque, mz_uint64 file_ofs, void *pBuf, size_t n) { mz_zip_archive *pZip = (mz_zip_archive *)pOpaque; mz_int64 cur_ofs = MZ_FTELL64(pZip->m_pState->m_pFile); if (((mz_int64)file_ofs < 0) || (((cur_ofs != (mz_int64)file_ofs)) && (MZ_FSEEK64(pZip->m_pState->m_pFile, (mz_int64)file_ofs, SEEK_SET)))) return 0; return MZ_FREAD(pBuf, 1, n, pZip->m_pState->m_pFile); } mz_bool mz_zip_reader_init_file(mz_zip_archive *pZip, const char *pFilename, mz_uint32 flags) { mz_uint64 file_size; MZ_FILE *pFile = MZ_FOPEN(pFilename, "rb"); if (!pFile) return MZ_FALSE; if (MZ_FSEEK64(pFile, 0, SEEK_END)) { MZ_FCLOSE(pFile); return MZ_FALSE; } file_size = MZ_FTELL64(pFile); if (!mz_zip_reader_init_internal(pZip, flags)) { MZ_FCLOSE(pFile); return MZ_FALSE; } pZip->m_pRead = mz_zip_file_read_func; pZip->m_pIO_opaque = pZip; pZip->m_pState->m_pFile = pFile; pZip->m_archive_size = file_size; if (!mz_zip_reader_read_central_dir(pZip, flags)) { mz_zip_reader_end(pZip); return MZ_FALSE; } return MZ_TRUE; } #endif // #ifndef MINIZ_NO_STDIO mz_uint mz_zip_reader_get_num_files(mz_zip_archive *pZip) { return pZip ? pZip->m_total_files : 0; } static MZ_FORCEINLINE const mz_uint8 *mz_zip_reader_get_cdh(mz_zip_archive *pZip, mz_uint file_index) { if ((!pZip) || (!pZip->m_pState) || (file_index >= pZip->m_total_files) || (pZip->m_zip_mode != MZ_ZIP_MODE_READING)) return NULL; return &MZ_ZIP_ARRAY_ELEMENT(&pZip->m_pState->m_central_dir, mz_uint8, MZ_ZIP_ARRAY_ELEMENT(&pZip->m_pState->m_central_dir_offsets, mz_uint32, file_index)); } mz_bool mz_zip_reader_is_file_encrypted(mz_zip_archive *pZip, mz_uint file_index) { mz_uint m_bit_flag; const mz_uint8 *p = mz_zip_reader_get_cdh(pZip, file_index); if (!p) return MZ_FALSE; m_bit_flag = MZ_READ_LE16(p + MZ_ZIP_CDH_BIT_FLAG_OFS); return (m_bit_flag & 1); } mz_bool mz_zip_reader_is_file_a_directory(mz_zip_archive *pZip, mz_uint file_index) { mz_uint filename_len, external_attr; const mz_uint8 *p = mz_zip_reader_get_cdh(pZip, file_index); if (!p) return MZ_FALSE; // First see if the filename ends with a '/' character. filename_len = MZ_READ_LE16(p + MZ_ZIP_CDH_FILENAME_LEN_OFS); if (filename_len) { if (*(p + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + filename_len - 1) == '/') return MZ_TRUE; } // Bugfix: This code was also checking if the internal attribute was non-zero, which wasn't correct. // Most/all zip writers (hopefully) set DOS file/directory attributes in the low 16-bits, so check for the DOS directory flag and ignore the source OS ID in the created by field. // FIXME: Remove this check? Is it necessary - we already check the filename. external_attr = MZ_READ_LE32(p + MZ_ZIP_CDH_EXTERNAL_ATTR_OFS); if ((external_attr & 0x10) != 0) return MZ_TRUE; return MZ_FALSE; } mz_bool mz_zip_reader_file_stat(mz_zip_archive *pZip, mz_uint file_index, mz_zip_archive_file_stat *pStat) { mz_uint n; const mz_uint8 *p = mz_zip_reader_get_cdh(pZip, file_index); if ((!p) || (!pStat)) return MZ_FALSE; // Unpack the central directory record. pStat->m_file_index = file_index; pStat->m_central_dir_ofs = MZ_ZIP_ARRAY_ELEMENT(&pZip->m_pState->m_central_dir_offsets, mz_uint32, file_index); pStat->m_version_made_by = MZ_READ_LE16(p + MZ_ZIP_CDH_VERSION_MADE_BY_OFS); pStat->m_version_needed = MZ_READ_LE16(p + MZ_ZIP_CDH_VERSION_NEEDED_OFS); pStat->m_bit_flag = MZ_READ_LE16(p + MZ_ZIP_CDH_BIT_FLAG_OFS); pStat->m_method = MZ_READ_LE16(p + MZ_ZIP_CDH_METHOD_OFS); #ifndef MINIZ_NO_TIME pStat->m_time = mz_zip_dos_to_time_t(MZ_READ_LE16(p + MZ_ZIP_CDH_FILE_TIME_OFS), MZ_READ_LE16(p + MZ_ZIP_CDH_FILE_DATE_OFS)); #endif pStat->m_crc32 = MZ_READ_LE32(p + MZ_ZIP_CDH_CRC32_OFS); pStat->m_comp_size = MZ_READ_LE32(p + MZ_ZIP_CDH_COMPRESSED_SIZE_OFS); pStat->m_uncomp_size = MZ_READ_LE32(p + MZ_ZIP_CDH_DECOMPRESSED_SIZE_OFS); pStat->m_internal_attr = MZ_READ_LE16(p + MZ_ZIP_CDH_INTERNAL_ATTR_OFS); pStat->m_external_attr = MZ_READ_LE32(p + MZ_ZIP_CDH_EXTERNAL_ATTR_OFS); pStat->m_local_header_ofs = MZ_READ_LE32(p + MZ_ZIP_CDH_LOCAL_HEADER_OFS); // Copy as much of the filename and comment as possible. n = MZ_READ_LE16(p + MZ_ZIP_CDH_FILENAME_LEN_OFS); n = MZ_MIN(n, MZ_ZIP_MAX_ARCHIVE_FILENAME_SIZE - 1); memcpy(pStat->m_filename, p + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE, n); pStat->m_filename[n] = '\0'; n = MZ_READ_LE16(p + MZ_ZIP_CDH_COMMENT_LEN_OFS); n = MZ_MIN(n, MZ_ZIP_MAX_ARCHIVE_FILE_COMMENT_SIZE - 1); pStat->m_comment_size = n; memcpy(pStat->m_comment, p + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + MZ_READ_LE16(p + MZ_ZIP_CDH_FILENAME_LEN_OFS) + MZ_READ_LE16(p + MZ_ZIP_CDH_EXTRA_LEN_OFS), n); pStat->m_comment[n] = '\0'; return MZ_TRUE; } mz_uint mz_zip_reader_get_filename(mz_zip_archive *pZip, mz_uint file_index, char *pFilename, mz_uint filename_buf_size) { mz_uint n; const mz_uint8 *p = mz_zip_reader_get_cdh(pZip, file_index); if (!p) { if (filename_buf_size) pFilename[0] = '\0'; return 0; } n = MZ_READ_LE16(p + MZ_ZIP_CDH_FILENAME_LEN_OFS); if (filename_buf_size) { n = MZ_MIN(n, filename_buf_size - 1); memcpy(pFilename, p + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE, n); pFilename[n] = '\0'; } return n + 1; } static MZ_FORCEINLINE mz_bool mz_zip_reader_string_equal(const char *pA, const char *pB, mz_uint len, mz_uint flags) { mz_uint i; if (flags & MZ_ZIP_FLAG_CASE_SENSITIVE) return 0 == memcmp(pA, pB, len); for (i = 0; i < len; ++i) if (MZ_TOLOWER(pA[i]) != MZ_TOLOWER(pB[i])) return MZ_FALSE; return MZ_TRUE; } static MZ_FORCEINLINE int mz_zip_reader_filename_compare(const mz_zip_array *pCentral_dir_array, const mz_zip_array *pCentral_dir_offsets, mz_uint l_index, const char *pR, mz_uint r_len) { const mz_uint8 *pL = &MZ_ZIP_ARRAY_ELEMENT(pCentral_dir_array, mz_uint8, MZ_ZIP_ARRAY_ELEMENT(pCentral_dir_offsets, mz_uint32, l_index)), *pE; mz_uint l_len = MZ_READ_LE16(pL + MZ_ZIP_CDH_FILENAME_LEN_OFS); mz_uint8 l = 0, r = 0; pL += MZ_ZIP_CENTRAL_DIR_HEADER_SIZE; pE = pL + MZ_MIN(l_len, r_len); while (pL < pE) { if ((l = MZ_TOLOWER(*pL)) != (r = MZ_TOLOWER(*pR))) break; pL++; pR++; } return (pL == pE) ? (int)(l_len - r_len) : (l - r); } static int mz_zip_reader_locate_file_binary_search(mz_zip_archive *pZip, const char *pFilename) { mz_zip_internal_state *pState = pZip->m_pState; const mz_zip_array *pCentral_dir_offsets = &pState->m_central_dir_offsets; const mz_zip_array *pCentral_dir = &pState->m_central_dir; mz_uint32 *pIndices = &MZ_ZIP_ARRAY_ELEMENT(&pState->m_sorted_central_dir_offsets, mz_uint32, 0); const int size = pZip->m_total_files; const mz_uint filename_len = (mz_uint)strlen(pFilename); int l = 0, h = size - 1; while (l <= h) { int m = (l + h) >> 1, file_index = pIndices[m], comp = mz_zip_reader_filename_compare(pCentral_dir, pCentral_dir_offsets, file_index, pFilename, filename_len); if (!comp) return file_index; else if (comp < 0) l = m + 1; else h = m - 1; } return -1; } int mz_zip_reader_locate_file(mz_zip_archive *pZip, const char *pName, const char *pComment, mz_uint flags) { mz_uint file_index; size_t name_len, comment_len; if ((!pZip) || (!pZip->m_pState) || (!pName) || (pZip->m_zip_mode != MZ_ZIP_MODE_READING)) return -1; if (((flags & (MZ_ZIP_FLAG_IGNORE_PATH | MZ_ZIP_FLAG_CASE_SENSITIVE)) == 0) && (!pComment) && (pZip->m_pState->m_sorted_central_dir_offsets.m_size)) return mz_zip_reader_locate_file_binary_search(pZip, pName); name_len = strlen(pName); if (name_len > 0xFFFF) return -1; comment_len = pComment ? strlen(pComment) : 0; if (comment_len > 0xFFFF) return -1; for (file_index = 0; file_index < pZip->m_total_files; file_index++) { const mz_uint8 *pHeader = &MZ_ZIP_ARRAY_ELEMENT(&pZip->m_pState->m_central_dir, mz_uint8, MZ_ZIP_ARRAY_ELEMENT(&pZip->m_pState->m_central_dir_offsets, mz_uint32, file_index)); mz_uint filename_len = MZ_READ_LE16(pHeader + MZ_ZIP_CDH_FILENAME_LEN_OFS); const char *pFilename = (const char *)pHeader + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE; if (filename_len < name_len) continue; if (comment_len) { mz_uint file_extra_len = MZ_READ_LE16(pHeader + MZ_ZIP_CDH_EXTRA_LEN_OFS), file_comment_len = MZ_READ_LE16(pHeader + MZ_ZIP_CDH_COMMENT_LEN_OFS); const char *pFile_comment = pFilename + filename_len + file_extra_len; if ((file_comment_len != comment_len) || (!mz_zip_reader_string_equal(pComment, pFile_comment, file_comment_len, flags))) continue; } if ((flags & MZ_ZIP_FLAG_IGNORE_PATH) && (filename_len)) { int ofs = filename_len - 1; do { if ((pFilename[ofs] == '/') || (pFilename[ofs] == '\\') || (pFilename[ofs] == ':')) break; } while (--ofs >= 0); ofs++; pFilename += ofs; filename_len -= ofs; } if ((filename_len == name_len) && (mz_zip_reader_string_equal(pName, pFilename, filename_len, flags))) return file_index; } return -1; } mz_bool mz_zip_reader_extract_to_mem_no_alloc(mz_zip_archive *pZip, mz_uint file_index, void *pBuf, size_t buf_size, mz_uint flags, void *pUser_read_buf, size_t user_read_buf_size) { int status = TINFL_STATUS_DONE; mz_uint64 needed_size, cur_file_ofs, comp_remaining, out_buf_ofs = 0, read_buf_size, read_buf_ofs = 0, read_buf_avail; mz_zip_archive_file_stat file_stat; void *pRead_buf; mz_uint32 local_header_u32[(MZ_ZIP_LOCAL_DIR_HEADER_SIZE + sizeof(mz_uint32) - 1) / sizeof(mz_uint32)]; mz_uint8 *pLocal_header = (mz_uint8 *)local_header_u32; tinfl_decompressor inflator; if ((buf_size) && (!pBuf)) return MZ_FALSE; if (!mz_zip_reader_file_stat(pZip, file_index, &file_stat)) return MZ_FALSE; // Empty file, or a directory (but not always a directory - I've seen odd zips with directories that have compressed data which inflates to 0 bytes) if (!file_stat.m_comp_size) return MZ_TRUE; // Entry is a subdirectory (I've seen old zips with dir entries which have compressed deflate data which inflates to 0 bytes, but these entries claim to uncompress to 512 bytes in the headers). // I'm torn how to handle this case - should it fail instead? if (mz_zip_reader_is_file_a_directory(pZip, file_index)) return MZ_TRUE; // Encryption and patch files are not supported. if (file_stat.m_bit_flag & (1 | 32)) return MZ_FALSE; // This function only supports stored and deflate. if ((!(flags & MZ_ZIP_FLAG_COMPRESSED_DATA)) && (file_stat.m_method != 0) && (file_stat.m_method != MZ_DEFLATED)) return MZ_FALSE; // Ensure supplied output buffer is large enough. needed_size = (flags & MZ_ZIP_FLAG_COMPRESSED_DATA) ? file_stat.m_comp_size : file_stat.m_uncomp_size; if (buf_size < needed_size) return MZ_FALSE; // Read and parse the local directory entry. cur_file_ofs = pZip->m_archive_file_ofs + file_stat.m_local_header_ofs; if (pZip->m_pRead(pZip->m_pIO_opaque, cur_file_ofs, pLocal_header, MZ_ZIP_LOCAL_DIR_HEADER_SIZE) != MZ_ZIP_LOCAL_DIR_HEADER_SIZE) return MZ_FALSE; if (MZ_READ_LE32(pLocal_header) != MZ_ZIP_LOCAL_DIR_HEADER_SIG) return MZ_FALSE; cur_file_ofs += MZ_ZIP_LOCAL_DIR_HEADER_SIZE + MZ_READ_LE16(pLocal_header + MZ_ZIP_LDH_FILENAME_LEN_OFS) + MZ_READ_LE16(pLocal_header + MZ_ZIP_LDH_EXTRA_LEN_OFS); if ((cur_file_ofs + file_stat.m_comp_size) > pZip->m_archive_size) return MZ_FALSE; if ((flags & MZ_ZIP_FLAG_COMPRESSED_DATA) || (!file_stat.m_method)) { // The file is stored or the caller has requested the compressed data. if (pZip->m_pRead(pZip->m_pIO_opaque, cur_file_ofs, pBuf, (size_t)needed_size) != needed_size) return MZ_FALSE; return ((flags & MZ_ZIP_FLAG_COMPRESSED_DATA) != 0) || (mz_crc32(MZ_CRC32_INIT, (const mz_uint8 *)pBuf, (size_t)file_stat.m_uncomp_size) == file_stat.m_crc32); } // Decompress the file either directly from memory or from a file input buffer. tinfl_init(&inflator); if (pZip->m_pState->m_pMem) { // Read directly from the archive in memory. pRead_buf = (mz_uint8 *)pZip->m_pState->m_pMem + cur_file_ofs; read_buf_size = read_buf_avail = file_stat.m_comp_size; comp_remaining = 0; } else if (pUser_read_buf) { // Use a user provided read buffer. if (!user_read_buf_size) return MZ_FALSE; pRead_buf = (mz_uint8 *)pUser_read_buf; read_buf_size = user_read_buf_size; read_buf_avail = 0; comp_remaining = file_stat.m_comp_size; } else { // Temporarily allocate a read buffer. read_buf_size = MZ_MIN(file_stat.m_comp_size, MZ_ZIP_MAX_IO_BUF_SIZE); #ifdef _MSC_VER if (((0, sizeof(size_t) == sizeof(mz_uint32))) && (read_buf_size > 0x7FFFFFFF)) #else if (((sizeof(size_t) == sizeof(mz_uint32))) && (read_buf_size > 0x7FFFFFFF)) #endif return MZ_FALSE; if (NULL == (pRead_buf = pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, (size_t)read_buf_size))) return MZ_FALSE; read_buf_avail = 0; comp_remaining = file_stat.m_comp_size; } do { size_t in_buf_size, out_buf_size = (size_t)(file_stat.m_uncomp_size - out_buf_ofs); if ((!read_buf_avail) && (!pZip->m_pState->m_pMem)) { read_buf_avail = MZ_MIN(read_buf_size, comp_remaining); if (pZip->m_pRead(pZip->m_pIO_opaque, cur_file_ofs, pRead_buf, (size_t)read_buf_avail) != read_buf_avail) { status = TINFL_STATUS_FAILED; break; } cur_file_ofs += read_buf_avail; comp_remaining -= read_buf_avail; read_buf_ofs = 0; } in_buf_size = (size_t)read_buf_avail; status = tinfl_decompress(&inflator, (mz_uint8 *)pRead_buf + read_buf_ofs, &in_buf_size, (mz_uint8 *)pBuf, (mz_uint8 *)pBuf + out_buf_ofs, &out_buf_size, TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF | (comp_remaining ? TINFL_FLAG_HAS_MORE_INPUT : 0)); read_buf_avail -= in_buf_size; read_buf_ofs += in_buf_size; out_buf_ofs += out_buf_size; } while (status == TINFL_STATUS_NEEDS_MORE_INPUT); if (status == TINFL_STATUS_DONE) { // Make sure the entire file was decompressed, and check its CRC. if ((out_buf_ofs != file_stat.m_uncomp_size) || (mz_crc32(MZ_CRC32_INIT, (const mz_uint8 *)pBuf, (size_t)file_stat.m_uncomp_size) != file_stat.m_crc32)) status = TINFL_STATUS_FAILED; } if ((!pZip->m_pState->m_pMem) && (!pUser_read_buf)) pZip->m_pFree(pZip->m_pAlloc_opaque, pRead_buf); return status == TINFL_STATUS_DONE; } mz_bool mz_zip_reader_extract_file_to_mem_no_alloc(mz_zip_archive *pZip, const char *pFilename, void *pBuf, size_t buf_size, mz_uint flags, void *pUser_read_buf, size_t user_read_buf_size) { int file_index = mz_zip_reader_locate_file(pZip, pFilename, NULL, flags); if (file_index < 0) return MZ_FALSE; return mz_zip_reader_extract_to_mem_no_alloc(pZip, file_index, pBuf, buf_size, flags, pUser_read_buf, user_read_buf_size); } mz_bool mz_zip_reader_extract_to_mem(mz_zip_archive *pZip, mz_uint file_index, void *pBuf, size_t buf_size, mz_uint flags) { return mz_zip_reader_extract_to_mem_no_alloc(pZip, file_index, pBuf, buf_size, flags, NULL, 0); } mz_bool mz_zip_reader_extract_file_to_mem(mz_zip_archive *pZip, const char *pFilename, void *pBuf, size_t buf_size, mz_uint flags) { return mz_zip_reader_extract_file_to_mem_no_alloc(pZip, pFilename, pBuf, buf_size, flags, NULL, 0); } void *mz_zip_reader_extract_to_heap(mz_zip_archive *pZip, mz_uint file_index, size_t *pSize, mz_uint flags) { mz_uint64 comp_size, uncomp_size, alloc_size; const mz_uint8 *p = mz_zip_reader_get_cdh(pZip, file_index); void *pBuf; if (pSize) *pSize = 0; if (!p) return NULL; comp_size = MZ_READ_LE32(p + MZ_ZIP_CDH_COMPRESSED_SIZE_OFS); uncomp_size = MZ_READ_LE32(p + MZ_ZIP_CDH_DECOMPRESSED_SIZE_OFS); alloc_size = (flags & MZ_ZIP_FLAG_COMPRESSED_DATA) ? comp_size : uncomp_size; #ifdef _MSC_VER if (((0, sizeof(size_t) == sizeof(mz_uint32))) && (alloc_size > 0x7FFFFFFF)) #else if (((sizeof(size_t) == sizeof(mz_uint32))) && (alloc_size > 0x7FFFFFFF)) #endif return NULL; if (NULL == (pBuf = pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, (size_t)alloc_size))) return NULL; if (!mz_zip_reader_extract_to_mem(pZip, file_index, pBuf, (size_t)alloc_size, flags)) { pZip->m_pFree(pZip->m_pAlloc_opaque, pBuf); return NULL; } if (pSize) *pSize = (size_t)alloc_size; return pBuf; } void *mz_zip_reader_extract_file_to_heap(mz_zip_archive *pZip, const char *pFilename, size_t *pSize, mz_uint flags) { int file_index = mz_zip_reader_locate_file(pZip, pFilename, NULL, flags); if (file_index < 0) { if (pSize) *pSize = 0; return MZ_FALSE; } return mz_zip_reader_extract_to_heap(pZip, file_index, pSize, flags); } mz_bool mz_zip_reader_extract_to_callback(mz_zip_archive *pZip, mz_uint file_index, mz_file_write_func pCallback, void *pOpaque, mz_uint flags) { int status = TINFL_STATUS_DONE; mz_uint file_crc32 = MZ_CRC32_INIT; mz_uint64 read_buf_size, read_buf_ofs = 0, read_buf_avail, comp_remaining, out_buf_ofs = 0, cur_file_ofs; mz_zip_archive_file_stat file_stat; void *pRead_buf = NULL; void *pWrite_buf = NULL; mz_uint32 local_header_u32[(MZ_ZIP_LOCAL_DIR_HEADER_SIZE + sizeof(mz_uint32) - 1) / sizeof(mz_uint32)]; mz_uint8 *pLocal_header = (mz_uint8 *)local_header_u32; if (!mz_zip_reader_file_stat(pZip, file_index, &file_stat)) return MZ_FALSE; // Empty file, or a directory (but not always a directory - I've seen odd zips with directories that have compressed data which inflates to 0 bytes) if (!file_stat.m_comp_size) return MZ_TRUE; // Entry is a subdirectory (I've seen old zips with dir entries which have compressed deflate data which inflates to 0 bytes, but these entries claim to uncompress to 512 bytes in the headers). // I'm torn how to handle this case - should it fail instead? if (mz_zip_reader_is_file_a_directory(pZip, file_index)) return MZ_TRUE; // Encryption and patch files are not supported. if (file_stat.m_bit_flag & (1 | 32)) return MZ_FALSE; // This function only supports stored and deflate. if ((!(flags & MZ_ZIP_FLAG_COMPRESSED_DATA)) && (file_stat.m_method != 0) && (file_stat.m_method != MZ_DEFLATED)) return MZ_FALSE; // Read and parse the local directory entry. cur_file_ofs = file_stat.m_local_header_ofs; if (pZip->m_pRead(pZip->m_pIO_opaque, cur_file_ofs, pLocal_header, MZ_ZIP_LOCAL_DIR_HEADER_SIZE) != MZ_ZIP_LOCAL_DIR_HEADER_SIZE) return MZ_FALSE; if (MZ_READ_LE32(pLocal_header) != MZ_ZIP_LOCAL_DIR_HEADER_SIG) return MZ_FALSE; cur_file_ofs += MZ_ZIP_LOCAL_DIR_HEADER_SIZE + MZ_READ_LE16(pLocal_header + MZ_ZIP_LDH_FILENAME_LEN_OFS) + MZ_READ_LE16(pLocal_header + MZ_ZIP_LDH_EXTRA_LEN_OFS); if ((cur_file_ofs + file_stat.m_comp_size) > pZip->m_archive_size) return MZ_FALSE; // Decompress the file either directly from memory or from a file input buffer. if (pZip->m_pState->m_pMem) { pRead_buf = (mz_uint8 *)pZip->m_pState->m_pMem + cur_file_ofs; read_buf_size = read_buf_avail = file_stat.m_comp_size; comp_remaining = 0; } else { read_buf_size = MZ_MIN(file_stat.m_comp_size, MZ_ZIP_MAX_IO_BUF_SIZE); if (NULL == (pRead_buf = pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, (size_t)read_buf_size))) return MZ_FALSE; read_buf_avail = 0; comp_remaining = file_stat.m_comp_size; } if ((flags & MZ_ZIP_FLAG_COMPRESSED_DATA) || (!file_stat.m_method)) { // The file is stored or the caller has requested the compressed data. if (pZip->m_pState->m_pMem) { #ifdef _MSC_VER if (((0, sizeof(size_t) == sizeof(mz_uint32))) && (file_stat.m_comp_size > 0xFFFFFFFF)) #else if (((sizeof(size_t) == sizeof(mz_uint32))) && (file_stat.m_comp_size > 0xFFFFFFFF)) #endif return MZ_FALSE; if (pCallback(pOpaque, out_buf_ofs, pRead_buf, (size_t)file_stat.m_comp_size) != file_stat.m_comp_size) status = TINFL_STATUS_FAILED; else if (!(flags & MZ_ZIP_FLAG_COMPRESSED_DATA)) file_crc32 = (mz_uint32)mz_crc32(file_crc32, (const mz_uint8 *)pRead_buf, (size_t)file_stat.m_comp_size); cur_file_ofs += file_stat.m_comp_size; out_buf_ofs += file_stat.m_comp_size; comp_remaining = 0; } else { while (comp_remaining) { read_buf_avail = MZ_MIN(read_buf_size, comp_remaining); if (pZip->m_pRead(pZip->m_pIO_opaque, cur_file_ofs, pRead_buf, (size_t)read_buf_avail) != read_buf_avail) { status = TINFL_STATUS_FAILED; break; } if (!(flags & MZ_ZIP_FLAG_COMPRESSED_DATA)) file_crc32 = (mz_uint32)mz_crc32(file_crc32, (const mz_uint8 *)pRead_buf, (size_t)read_buf_avail); if (pCallback(pOpaque, out_buf_ofs, pRead_buf, (size_t)read_buf_avail) != read_buf_avail) { status = TINFL_STATUS_FAILED; break; } cur_file_ofs += read_buf_avail; out_buf_ofs += read_buf_avail; comp_remaining -= read_buf_avail; } } } else { tinfl_decompressor inflator; tinfl_init(&inflator); if (NULL == (pWrite_buf = pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, TINFL_LZ_DICT_SIZE))) status = TINFL_STATUS_FAILED; else { do { mz_uint8 *pWrite_buf_cur = (mz_uint8 *)pWrite_buf + (out_buf_ofs & (TINFL_LZ_DICT_SIZE - 1)); size_t in_buf_size, out_buf_size = TINFL_LZ_DICT_SIZE - (out_buf_ofs & (TINFL_LZ_DICT_SIZE - 1)); if ((!read_buf_avail) && (!pZip->m_pState->m_pMem)) { read_buf_avail = MZ_MIN(read_buf_size, comp_remaining); if (pZip->m_pRead(pZip->m_pIO_opaque, cur_file_ofs, pRead_buf, (size_t)read_buf_avail) != read_buf_avail) { status = TINFL_STATUS_FAILED; break; } cur_file_ofs += read_buf_avail; comp_remaining -= read_buf_avail; read_buf_ofs = 0; } in_buf_size = (size_t)read_buf_avail; status = tinfl_decompress(&inflator, (const mz_uint8 *)pRead_buf + read_buf_ofs, &in_buf_size, (mz_uint8 *)pWrite_buf, pWrite_buf_cur, &out_buf_size, comp_remaining ? TINFL_FLAG_HAS_MORE_INPUT : 0); read_buf_avail -= in_buf_size; read_buf_ofs += in_buf_size; if (out_buf_size) { if (pCallback(pOpaque, out_buf_ofs, pWrite_buf_cur, out_buf_size) != out_buf_size) { status = TINFL_STATUS_FAILED; break; } file_crc32 = (mz_uint32)mz_crc32(file_crc32, pWrite_buf_cur, out_buf_size); if ((out_buf_ofs += out_buf_size) > file_stat.m_uncomp_size) { status = TINFL_STATUS_FAILED; break; } } } while ((status == TINFL_STATUS_NEEDS_MORE_INPUT) || (status == TINFL_STATUS_HAS_MORE_OUTPUT)); } } if ((status == TINFL_STATUS_DONE) && (!(flags & MZ_ZIP_FLAG_COMPRESSED_DATA))) { // Make sure the entire file was decompressed, and check its CRC. if ((out_buf_ofs != file_stat.m_uncomp_size) || (file_crc32 != file_stat.m_crc32)) status = TINFL_STATUS_FAILED; } if (!pZip->m_pState->m_pMem) pZip->m_pFree(pZip->m_pAlloc_opaque, pRead_buf); if (pWrite_buf) pZip->m_pFree(pZip->m_pAlloc_opaque, pWrite_buf); return status == TINFL_STATUS_DONE; } mz_bool mz_zip_reader_extract_file_to_callback(mz_zip_archive *pZip, const char *pFilename, mz_file_write_func pCallback, void *pOpaque, mz_uint flags) { int file_index = mz_zip_reader_locate_file(pZip, pFilename, NULL, flags); if (file_index < 0) return MZ_FALSE; return mz_zip_reader_extract_to_callback(pZip, file_index, pCallback, pOpaque, flags); } #ifndef MINIZ_NO_STDIO static size_t mz_zip_file_write_callback(void *pOpaque, mz_uint64 ofs, const void *pBuf, size_t n) { (void)ofs; return MZ_FWRITE(pBuf, 1, n, (MZ_FILE*)pOpaque); } mz_bool mz_zip_reader_extract_to_file(mz_zip_archive *pZip, mz_uint file_index, const char *pDst_filename, mz_uint flags) { mz_bool status; mz_zip_archive_file_stat file_stat; MZ_FILE *pFile; if (!mz_zip_reader_file_stat(pZip, file_index, &file_stat)) return MZ_FALSE; pFile = MZ_FOPEN(pDst_filename, "wb"); if (!pFile) return MZ_FALSE; status = mz_zip_reader_extract_to_callback(pZip, file_index, mz_zip_file_write_callback, pFile, flags); if (MZ_FCLOSE(pFile) == EOF) return MZ_FALSE; #ifndef MINIZ_NO_TIME if (status) mz_zip_set_file_times(pDst_filename, file_stat.m_time, file_stat.m_time); #endif return status; } #endif // #ifndef MINIZ_NO_STDIO mz_bool mz_zip_reader_end(mz_zip_archive *pZip) { if ((!pZip) || (!pZip->m_pState) || (!pZip->m_pAlloc) || (!pZip->m_pFree) || (pZip->m_zip_mode != MZ_ZIP_MODE_READING)) return MZ_FALSE; if (pZip->m_pState) { mz_zip_internal_state *pState = pZip->m_pState; pZip->m_pState = NULL; mz_zip_array_clear(pZip, &pState->m_central_dir); mz_zip_array_clear(pZip, &pState->m_central_dir_offsets); mz_zip_array_clear(pZip, &pState->m_sorted_central_dir_offsets); #ifndef MINIZ_NO_STDIO if (pState->m_pFile) { MZ_FCLOSE(pState->m_pFile); pState->m_pFile = NULL; } #endif // #ifndef MINIZ_NO_STDIO pZip->m_pFree(pZip->m_pAlloc_opaque, pState); } pZip->m_zip_mode = MZ_ZIP_MODE_INVALID; return MZ_TRUE; } #ifndef MINIZ_NO_STDIO mz_bool mz_zip_reader_extract_file_to_file(mz_zip_archive *pZip, const char *pArchive_filename, const char *pDst_filename, mz_uint flags) { int file_index = mz_zip_reader_locate_file(pZip, pArchive_filename, NULL, flags); if (file_index < 0) return MZ_FALSE; return mz_zip_reader_extract_to_file(pZip, file_index, pDst_filename, flags); } #endif // ------------------- .ZIP archive writing #ifndef MINIZ_NO_ARCHIVE_WRITING_APIS static void mz_write_le16(mz_uint8 *p, mz_uint16 v) { p[0] = (mz_uint8)v; p[1] = (mz_uint8)(v >> 8); } static void mz_write_le32(mz_uint8 *p, mz_uint32 v) { p[0] = (mz_uint8)v; p[1] = (mz_uint8)(v >> 8); p[2] = (mz_uint8)(v >> 16); p[3] = (mz_uint8)(v >> 24); } #define MZ_WRITE_LE16(p, v) mz_write_le16((mz_uint8 *)(p), (mz_uint16)(v)) #define MZ_WRITE_LE32(p, v) mz_write_le32((mz_uint8 *)(p), (mz_uint32)(v)) mz_bool mz_zip_writer_init(mz_zip_archive *pZip, mz_uint64 existing_size) { if ((!pZip) || (pZip->m_pState) || (!pZip->m_pWrite) || (pZip->m_zip_mode != MZ_ZIP_MODE_INVALID)) return MZ_FALSE; if (pZip->m_file_offset_alignment) { // Ensure user specified file offset alignment is a power of 2. if (pZip->m_file_offset_alignment & (pZip->m_file_offset_alignment - 1)) return MZ_FALSE; } if (!pZip->m_pAlloc) pZip->m_pAlloc = def_alloc_func; if (!pZip->m_pFree) pZip->m_pFree = def_free_func; if (!pZip->m_pRealloc) pZip->m_pRealloc = def_realloc_func; pZip->m_zip_mode = MZ_ZIP_MODE_WRITING; pZip->m_archive_size = existing_size; pZip->m_central_directory_file_ofs = 0; pZip->m_total_files = 0; if (NULL == (pZip->m_pState = (mz_zip_internal_state *)pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, sizeof(mz_zip_internal_state)))) return MZ_FALSE; memset(pZip->m_pState, 0, sizeof(mz_zip_internal_state)); MZ_ZIP_ARRAY_SET_ELEMENT_SIZE(&pZip->m_pState->m_central_dir, sizeof(mz_uint8)); MZ_ZIP_ARRAY_SET_ELEMENT_SIZE(&pZip->m_pState->m_central_dir_offsets, sizeof(mz_uint32)); MZ_ZIP_ARRAY_SET_ELEMENT_SIZE(&pZip->m_pState->m_sorted_central_dir_offsets, sizeof(mz_uint32)); return MZ_TRUE; } static size_t mz_zip_heap_write_func(void *pOpaque, mz_uint64 file_ofs, const void *pBuf, size_t n) { mz_zip_archive *pZip = (mz_zip_archive *)pOpaque; mz_zip_internal_state *pState = pZip->m_pState; mz_uint64 new_size = MZ_MAX(file_ofs + n, pState->m_mem_size); #ifdef _MSC_VER if ((!n) || ((0, sizeof(size_t) == sizeof(mz_uint32)) && (new_size > 0x7FFFFFFF))) #else if ((!n) || ((sizeof(size_t) == sizeof(mz_uint32)) && (new_size > 0x7FFFFFFF))) #endif return 0; if (new_size > pState->m_mem_capacity) { void *pNew_block; size_t new_capacity = MZ_MAX(64, pState->m_mem_capacity); while (new_capacity < new_size) new_capacity *= 2; if (NULL == (pNew_block = pZip->m_pRealloc(pZip->m_pAlloc_opaque, pState->m_pMem, 1, new_capacity))) return 0; pState->m_pMem = pNew_block; pState->m_mem_capacity = new_capacity; } memcpy((mz_uint8 *)pState->m_pMem + file_ofs, pBuf, n); pState->m_mem_size = (size_t)new_size; return n; } mz_bool mz_zip_writer_init_heap(mz_zip_archive *pZip, size_t size_to_reserve_at_beginning, size_t initial_allocation_size) { pZip->m_pWrite = mz_zip_heap_write_func; pZip->m_pIO_opaque = pZip; if (!mz_zip_writer_init(pZip, size_to_reserve_at_beginning)) return MZ_FALSE; if (0 != (initial_allocation_size = MZ_MAX(initial_allocation_size, size_to_reserve_at_beginning))) { if (NULL == (pZip->m_pState->m_pMem = pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, initial_allocation_size))) { mz_zip_writer_end(pZip); return MZ_FALSE; } pZip->m_pState->m_mem_capacity = initial_allocation_size; } return MZ_TRUE; } #ifndef MINIZ_NO_STDIO static size_t mz_zip_file_write_func(void *pOpaque, mz_uint64 file_ofs, const void *pBuf, size_t n) { mz_zip_archive *pZip = (mz_zip_archive *)pOpaque; mz_int64 cur_ofs = MZ_FTELL64(pZip->m_pState->m_pFile); if (((mz_int64)file_ofs < 0) || (((cur_ofs != (mz_int64)file_ofs)) && (MZ_FSEEK64(pZip->m_pState->m_pFile, (mz_int64)file_ofs, SEEK_SET)))) return 0; return MZ_FWRITE(pBuf, 1, n, pZip->m_pState->m_pFile); } mz_bool mz_zip_writer_init_file(mz_zip_archive *pZip, const char *pFilename, mz_uint64 size_to_reserve_at_beginning) { MZ_FILE *pFile; pZip->m_pWrite = mz_zip_file_write_func; pZip->m_pIO_opaque = pZip; if (!mz_zip_writer_init(pZip, size_to_reserve_at_beginning)) return MZ_FALSE; if (NULL == (pFile = MZ_FOPEN(pFilename, "wb"))) { mz_zip_writer_end(pZip); return MZ_FALSE; } pZip->m_pState->m_pFile = pFile; if (size_to_reserve_at_beginning) { mz_uint64 cur_ofs = 0; char buf[4096]; MZ_CLEAR_OBJ(buf); do { size_t n = (size_t)MZ_MIN(sizeof(buf), size_to_reserve_at_beginning); if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_ofs, buf, n) != n) { mz_zip_writer_end(pZip); return MZ_FALSE; } cur_ofs += n; size_to_reserve_at_beginning -= n; } while (size_to_reserve_at_beginning); } return MZ_TRUE; } #endif // #ifndef MINIZ_NO_STDIO mz_bool mz_zip_writer_init_from_reader(mz_zip_archive *pZip, const char *pFilename) { mz_zip_internal_state *pState; if ((!pZip) || (!pZip->m_pState) || (pZip->m_zip_mode != MZ_ZIP_MODE_READING)) return MZ_FALSE; // No sense in trying to write to an archive that's already at the support max size if ((pZip->m_total_files == 0xFFFF) || ((pZip->m_archive_size + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + MZ_ZIP_LOCAL_DIR_HEADER_SIZE) > 0xFFFFFFFF)) return MZ_FALSE; pState = pZip->m_pState; if (pState->m_pFile) { #ifdef MINIZ_NO_STDIO pFilename; return MZ_FALSE; #else // Archive is being read from stdio - try to reopen as writable. if (pZip->m_pIO_opaque != pZip) return MZ_FALSE; if (!pFilename) return MZ_FALSE; pZip->m_pWrite = mz_zip_file_write_func; if (NULL == (pState->m_pFile = MZ_FREOPEN(pFilename, "r+b", pState->m_pFile))) { // The mz_zip_archive is now in a bogus state because pState->m_pFile is NULL, so just close it. mz_zip_reader_end(pZip); return MZ_FALSE; } #endif // #ifdef MINIZ_NO_STDIO } else if (pState->m_pMem) { // Archive lives in a memory block. Assume it's from the heap that we can resize using the realloc callback. if (pZip->m_pIO_opaque != pZip) return MZ_FALSE; pState->m_mem_capacity = pState->m_mem_size; pZip->m_pWrite = mz_zip_heap_write_func; } // Archive is being read via a user provided read function - make sure the user has specified a write function too. else if (!pZip->m_pWrite) return MZ_FALSE; // Start writing new files at the archive's current central directory location. pZip->m_archive_size = pZip->m_central_directory_file_ofs; pZip->m_zip_mode = MZ_ZIP_MODE_WRITING; pZip->m_central_directory_file_ofs = 0; return MZ_TRUE; } mz_bool mz_zip_writer_add_mem(mz_zip_archive *pZip, const char *pArchive_name, const void *pBuf, size_t buf_size, mz_uint level_and_flags) { return mz_zip_writer_add_mem_ex(pZip, pArchive_name, pBuf, buf_size, NULL, 0, level_and_flags, 0, 0); } typedef struct { mz_zip_archive *m_pZip; mz_uint64 m_cur_archive_file_ofs; mz_uint64 m_comp_size; } mz_zip_writer_add_state; static mz_bool mz_zip_writer_add_put_buf_callback(const void* pBuf, int len, void *pUser) { mz_zip_writer_add_state *pState = (mz_zip_writer_add_state *)pUser; if ((int)pState->m_pZip->m_pWrite(pState->m_pZip->m_pIO_opaque, pState->m_cur_archive_file_ofs, pBuf, len) != len) return MZ_FALSE; pState->m_cur_archive_file_ofs += len; pState->m_comp_size += len; return MZ_TRUE; } static mz_bool mz_zip_writer_create_local_dir_header(mz_zip_archive *pZip, mz_uint8 *pDst, mz_uint16 filename_size, mz_uint16 extra_size, mz_uint64 uncomp_size, mz_uint64 comp_size, mz_uint32 uncomp_crc32, mz_uint16 method, mz_uint16 bit_flags, mz_uint16 dos_time, mz_uint16 dos_date) { (void)pZip; memset(pDst, 0, MZ_ZIP_LOCAL_DIR_HEADER_SIZE); MZ_WRITE_LE32(pDst + MZ_ZIP_LDH_SIG_OFS, MZ_ZIP_LOCAL_DIR_HEADER_SIG); MZ_WRITE_LE16(pDst + MZ_ZIP_LDH_VERSION_NEEDED_OFS, method ? 20 : 0); MZ_WRITE_LE16(pDst + MZ_ZIP_LDH_BIT_FLAG_OFS, bit_flags); MZ_WRITE_LE16(pDst + MZ_ZIP_LDH_METHOD_OFS, method); MZ_WRITE_LE16(pDst + MZ_ZIP_LDH_FILE_TIME_OFS, dos_time); MZ_WRITE_LE16(pDst + MZ_ZIP_LDH_FILE_DATE_OFS, dos_date); MZ_WRITE_LE32(pDst + MZ_ZIP_LDH_CRC32_OFS, uncomp_crc32); MZ_WRITE_LE32(pDst + MZ_ZIP_LDH_COMPRESSED_SIZE_OFS, comp_size); MZ_WRITE_LE32(pDst + MZ_ZIP_LDH_DECOMPRESSED_SIZE_OFS, uncomp_size); MZ_WRITE_LE16(pDst + MZ_ZIP_LDH_FILENAME_LEN_OFS, filename_size); MZ_WRITE_LE16(pDst + MZ_ZIP_LDH_EXTRA_LEN_OFS, extra_size); return MZ_TRUE; } static mz_bool mz_zip_writer_create_central_dir_header(mz_zip_archive *pZip, mz_uint8 *pDst, mz_uint16 filename_size, mz_uint16 extra_size, mz_uint16 comment_size, mz_uint64 uncomp_size, mz_uint64 comp_size, mz_uint32 uncomp_crc32, mz_uint16 method, mz_uint16 bit_flags, mz_uint16 dos_time, mz_uint16 dos_date, mz_uint64 local_header_ofs, mz_uint32 ext_attributes) { (void)pZip; memset(pDst, 0, MZ_ZIP_CENTRAL_DIR_HEADER_SIZE); MZ_WRITE_LE32(pDst + MZ_ZIP_CDH_SIG_OFS, MZ_ZIP_CENTRAL_DIR_HEADER_SIG); MZ_WRITE_LE16(pDst + MZ_ZIP_CDH_VERSION_NEEDED_OFS, method ? 20 : 0); MZ_WRITE_LE16(pDst + MZ_ZIP_CDH_BIT_FLAG_OFS, bit_flags); MZ_WRITE_LE16(pDst + MZ_ZIP_CDH_METHOD_OFS, method); MZ_WRITE_LE16(pDst + MZ_ZIP_CDH_FILE_TIME_OFS, dos_time); MZ_WRITE_LE16(pDst + MZ_ZIP_CDH_FILE_DATE_OFS, dos_date); MZ_WRITE_LE32(pDst + MZ_ZIP_CDH_CRC32_OFS, uncomp_crc32); MZ_WRITE_LE32(pDst + MZ_ZIP_CDH_COMPRESSED_SIZE_OFS, comp_size); MZ_WRITE_LE32(pDst + MZ_ZIP_CDH_DECOMPRESSED_SIZE_OFS, uncomp_size); MZ_WRITE_LE16(pDst + MZ_ZIP_CDH_FILENAME_LEN_OFS, filename_size); MZ_WRITE_LE16(pDst + MZ_ZIP_CDH_EXTRA_LEN_OFS, extra_size); MZ_WRITE_LE16(pDst + MZ_ZIP_CDH_COMMENT_LEN_OFS, comment_size); MZ_WRITE_LE32(pDst + MZ_ZIP_CDH_EXTERNAL_ATTR_OFS, ext_attributes); MZ_WRITE_LE32(pDst + MZ_ZIP_CDH_LOCAL_HEADER_OFS, local_header_ofs); return MZ_TRUE; } static mz_bool mz_zip_writer_add_to_central_dir(mz_zip_archive *pZip, const char *pFilename, mz_uint16 filename_size, const void *pExtra, mz_uint16 extra_size, const void *pComment, mz_uint16 comment_size, mz_uint64 uncomp_size, mz_uint64 comp_size, mz_uint32 uncomp_crc32, mz_uint16 method, mz_uint16 bit_flags, mz_uint16 dos_time, mz_uint16 dos_date, mz_uint64 local_header_ofs, mz_uint32 ext_attributes) { mz_zip_internal_state *pState = pZip->m_pState; mz_uint32 central_dir_ofs = (mz_uint32)pState->m_central_dir.m_size; size_t orig_central_dir_size = pState->m_central_dir.m_size; mz_uint8 central_dir_header[MZ_ZIP_CENTRAL_DIR_HEADER_SIZE]; // No zip64 support yet if ((local_header_ofs > 0xFFFFFFFF) || (((mz_uint64)pState->m_central_dir.m_size + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + filename_size + extra_size + comment_size) > 0xFFFFFFFF)) return MZ_FALSE; if (!mz_zip_writer_create_central_dir_header(pZip, central_dir_header, filename_size, extra_size, comment_size, uncomp_size, comp_size, uncomp_crc32, method, bit_flags, dos_time, dos_date, local_header_ofs, ext_attributes)) return MZ_FALSE; if ((!mz_zip_array_push_back(pZip, &pState->m_central_dir, central_dir_header, MZ_ZIP_CENTRAL_DIR_HEADER_SIZE)) || (!mz_zip_array_push_back(pZip, &pState->m_central_dir, pFilename, filename_size)) || (!mz_zip_array_push_back(pZip, &pState->m_central_dir, pExtra, extra_size)) || (!mz_zip_array_push_back(pZip, &pState->m_central_dir, pComment, comment_size)) || (!mz_zip_array_push_back(pZip, &pState->m_central_dir_offsets, ¢ral_dir_ofs, 1))) { // Try to push the central directory array back into its original state. mz_zip_array_resize(pZip, &pState->m_central_dir, orig_central_dir_size, MZ_FALSE); return MZ_FALSE; } return MZ_TRUE; } static mz_bool mz_zip_writer_validate_archive_name(const char *pArchive_name) { // Basic ZIP archive filename validity checks: Valid filenames cannot start with a forward slash, cannot contain a drive letter, and cannot use DOS-style backward slashes. if (*pArchive_name == '/') return MZ_FALSE; while (*pArchive_name) { if ((*pArchive_name == '\\') || (*pArchive_name == ':')) return MZ_FALSE; pArchive_name++; } return MZ_TRUE; } static mz_uint mz_zip_writer_compute_padding_needed_for_file_alignment(mz_zip_archive *pZip) { mz_uint32 n; if (!pZip->m_file_offset_alignment) return 0; n = (mz_uint32)(pZip->m_archive_size & (pZip->m_file_offset_alignment - 1)); return (pZip->m_file_offset_alignment - n) & (pZip->m_file_offset_alignment - 1); } static mz_bool mz_zip_writer_write_zeros(mz_zip_archive *pZip, mz_uint64 cur_file_ofs, mz_uint32 n) { char buf[4096]; memset(buf, 0, MZ_MIN(sizeof(buf), n)); while (n) { mz_uint32 s = MZ_MIN(sizeof(buf), n); if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_file_ofs, buf, s) != s) return MZ_FALSE; cur_file_ofs += s; n -= s; } return MZ_TRUE; } mz_bool mz_zip_writer_add_mem_ex(mz_zip_archive *pZip, const char *pArchive_name, const void *pBuf, size_t buf_size, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags, mz_uint64 uncomp_size, mz_uint32 uncomp_crc32) { mz_uint16 method = 0, dos_time = 0, dos_date = 0; mz_uint level, ext_attributes = 0, num_alignment_padding_bytes; mz_uint64 local_dir_header_ofs = pZip->m_archive_size, cur_archive_file_ofs = pZip->m_archive_size, comp_size = 0; size_t archive_name_size; mz_uint8 local_dir_header[MZ_ZIP_LOCAL_DIR_HEADER_SIZE]; tdefl_compressor *pComp = NULL; mz_bool store_data_uncompressed; mz_zip_internal_state *pState; if ((int)level_and_flags < 0) level_and_flags = MZ_DEFAULT_LEVEL; level = level_and_flags & 0xF; store_data_uncompressed = ((!level) || (level_and_flags & MZ_ZIP_FLAG_COMPRESSED_DATA)); if ((!pZip) || (!pZip->m_pState) || (pZip->m_zip_mode != MZ_ZIP_MODE_WRITING) || ((buf_size) && (!pBuf)) || (!pArchive_name) || ((comment_size) && (!pComment)) || (pZip->m_total_files == 0xFFFF) || (level > MZ_UBER_COMPRESSION)) return MZ_FALSE; pState = pZip->m_pState; if ((!(level_and_flags & MZ_ZIP_FLAG_COMPRESSED_DATA)) && (uncomp_size)) return MZ_FALSE; // No zip64 support yet if ((buf_size > 0xFFFFFFFF) || (uncomp_size > 0xFFFFFFFF)) return MZ_FALSE; if (!mz_zip_writer_validate_archive_name(pArchive_name)) return MZ_FALSE; #ifndef MINIZ_NO_TIME { time_t cur_time; time(&cur_time); mz_zip_time_to_dos_time(cur_time, &dos_time, &dos_date); } #endif // #ifndef MINIZ_NO_TIME archive_name_size = strlen(pArchive_name); if (archive_name_size > 0xFFFF) return MZ_FALSE; num_alignment_padding_bytes = mz_zip_writer_compute_padding_needed_for_file_alignment(pZip); // no zip64 support yet if ((pZip->m_total_files == 0xFFFF) || ((pZip->m_archive_size + num_alignment_padding_bytes + MZ_ZIP_LOCAL_DIR_HEADER_SIZE + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + comment_size + archive_name_size) > 0xFFFFFFFF)) return MZ_FALSE; if ((archive_name_size) && (pArchive_name[archive_name_size - 1] == '/')) { // Set DOS Subdirectory attribute bit. ext_attributes |= 0x10; // Subdirectories cannot contain data. if ((buf_size) || (uncomp_size)) return MZ_FALSE; } // Try to do any allocations before writing to the archive, so if an allocation fails the file remains unmodified. (A good idea if we're doing an in-place modification.) if ((!mz_zip_array_ensure_room(pZip, &pState->m_central_dir, MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + archive_name_size + comment_size)) || (!mz_zip_array_ensure_room(pZip, &pState->m_central_dir_offsets, 1))) return MZ_FALSE; if ((!store_data_uncompressed) && (buf_size)) { if (NULL == (pComp = (tdefl_compressor *)pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, sizeof(tdefl_compressor)))) return MZ_FALSE; } if (!mz_zip_writer_write_zeros(pZip, cur_archive_file_ofs, num_alignment_padding_bytes + sizeof(local_dir_header))) { pZip->m_pFree(pZip->m_pAlloc_opaque, pComp); return MZ_FALSE; } local_dir_header_ofs += num_alignment_padding_bytes; if (pZip->m_file_offset_alignment) { MZ_ASSERT((local_dir_header_ofs & (pZip->m_file_offset_alignment - 1)) == 0); } cur_archive_file_ofs += num_alignment_padding_bytes + sizeof(local_dir_header); MZ_CLEAR_OBJ(local_dir_header); if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, pArchive_name, archive_name_size) != archive_name_size) { pZip->m_pFree(pZip->m_pAlloc_opaque, pComp); return MZ_FALSE; } cur_archive_file_ofs += archive_name_size; if (!(level_and_flags & MZ_ZIP_FLAG_COMPRESSED_DATA)) { uncomp_crc32 = (mz_uint32)mz_crc32(MZ_CRC32_INIT, (const mz_uint8*)pBuf, buf_size); uncomp_size = buf_size; if (uncomp_size <= 3) { level = 0; store_data_uncompressed = MZ_TRUE; } } if (store_data_uncompressed) { if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, pBuf, buf_size) != buf_size) { pZip->m_pFree(pZip->m_pAlloc_opaque, pComp); return MZ_FALSE; } cur_archive_file_ofs += buf_size; comp_size = buf_size; if (level_and_flags & MZ_ZIP_FLAG_COMPRESSED_DATA) method = MZ_DEFLATED; } else if (buf_size) { mz_zip_writer_add_state state; state.m_pZip = pZip; state.m_cur_archive_file_ofs = cur_archive_file_ofs; state.m_comp_size = 0; if ((tdefl_init(pComp, mz_zip_writer_add_put_buf_callback, &state, tdefl_create_comp_flags_from_zip_params(level, -15, MZ_DEFAULT_STRATEGY)) != TDEFL_STATUS_OKAY) || (tdefl_compress_buffer(pComp, pBuf, buf_size, TDEFL_FINISH) != TDEFL_STATUS_DONE)) { pZip->m_pFree(pZip->m_pAlloc_opaque, pComp); return MZ_FALSE; } comp_size = state.m_comp_size; cur_archive_file_ofs = state.m_cur_archive_file_ofs; method = MZ_DEFLATED; } pZip->m_pFree(pZip->m_pAlloc_opaque, pComp); pComp = NULL; // no zip64 support yet if ((comp_size > 0xFFFFFFFF) || (cur_archive_file_ofs > 0xFFFFFFFF)) return MZ_FALSE; if (!mz_zip_writer_create_local_dir_header(pZip, local_dir_header, (mz_uint16)archive_name_size, 0, uncomp_size, comp_size, uncomp_crc32, method, 0, dos_time, dos_date)) return MZ_FALSE; if (pZip->m_pWrite(pZip->m_pIO_opaque, local_dir_header_ofs, local_dir_header, sizeof(local_dir_header)) != sizeof(local_dir_header)) return MZ_FALSE; if (!mz_zip_writer_add_to_central_dir(pZip, pArchive_name, (mz_uint16)archive_name_size, NULL, 0, pComment, comment_size, uncomp_size, comp_size, uncomp_crc32, method, 0, dos_time, dos_date, local_dir_header_ofs, ext_attributes)) return MZ_FALSE; pZip->m_total_files++; pZip->m_archive_size = cur_archive_file_ofs; return MZ_TRUE; } #ifndef MINIZ_NO_STDIO mz_bool mz_zip_writer_add_file(mz_zip_archive *pZip, const char *pArchive_name, const char *pSrc_filename, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags) { mz_uint uncomp_crc32 = MZ_CRC32_INIT, level, num_alignment_padding_bytes; mz_uint16 method = 0, dos_time = 0, dos_date = 0, ext_attributes = 0; mz_uint64 local_dir_header_ofs = pZip->m_archive_size, cur_archive_file_ofs = pZip->m_archive_size, uncomp_size = 0, comp_size = 0; size_t archive_name_size; mz_uint8 local_dir_header[MZ_ZIP_LOCAL_DIR_HEADER_SIZE]; MZ_FILE *pSrc_file = NULL; if ((int)level_and_flags < 0) level_and_flags = MZ_DEFAULT_LEVEL; level = level_and_flags & 0xF; if ((!pZip) || (!pZip->m_pState) || (pZip->m_zip_mode != MZ_ZIP_MODE_WRITING) || (!pArchive_name) || ((comment_size) && (!pComment)) || (level > MZ_UBER_COMPRESSION)) return MZ_FALSE; if (level_and_flags & MZ_ZIP_FLAG_COMPRESSED_DATA) return MZ_FALSE; if (!mz_zip_writer_validate_archive_name(pArchive_name)) return MZ_FALSE; archive_name_size = strlen(pArchive_name); if (archive_name_size > 0xFFFF) return MZ_FALSE; num_alignment_padding_bytes = mz_zip_writer_compute_padding_needed_for_file_alignment(pZip); // no zip64 support yet if ((pZip->m_total_files == 0xFFFF) || ((pZip->m_archive_size + num_alignment_padding_bytes + MZ_ZIP_LOCAL_DIR_HEADER_SIZE + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + comment_size + archive_name_size) > 0xFFFFFFFF)) return MZ_FALSE; if (!mz_zip_get_file_modified_time(pSrc_filename, &dos_time, &dos_date)) return MZ_FALSE; pSrc_file = MZ_FOPEN(pSrc_filename, "rb"); if (!pSrc_file) return MZ_FALSE; MZ_FSEEK64(pSrc_file, 0, SEEK_END); uncomp_size = MZ_FTELL64(pSrc_file); MZ_FSEEK64(pSrc_file, 0, SEEK_SET); if (uncomp_size > 0xFFFFFFFF) { // No zip64 support yet MZ_FCLOSE(pSrc_file); return MZ_FALSE; } if (uncomp_size <= 3) level = 0; if (!mz_zip_writer_write_zeros(pZip, cur_archive_file_ofs, num_alignment_padding_bytes + sizeof(local_dir_header))) { MZ_FCLOSE(pSrc_file); return MZ_FALSE; } local_dir_header_ofs += num_alignment_padding_bytes; if (pZip->m_file_offset_alignment) { MZ_ASSERT((local_dir_header_ofs & (pZip->m_file_offset_alignment - 1)) == 0); } cur_archive_file_ofs += num_alignment_padding_bytes + sizeof(local_dir_header); MZ_CLEAR_OBJ(local_dir_header); if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, pArchive_name, archive_name_size) != archive_name_size) { MZ_FCLOSE(pSrc_file); return MZ_FALSE; } cur_archive_file_ofs += archive_name_size; if (uncomp_size) { mz_uint64 uncomp_remaining = uncomp_size; void *pRead_buf = pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, MZ_ZIP_MAX_IO_BUF_SIZE); if (!pRead_buf) { MZ_FCLOSE(pSrc_file); return MZ_FALSE; } if (!level) { while (uncomp_remaining) { mz_uint n = (mz_uint)MZ_MIN(MZ_ZIP_MAX_IO_BUF_SIZE, uncomp_remaining); if ((MZ_FREAD(pRead_buf, 1, n, pSrc_file) != n) || (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, pRead_buf, n) != n)) { pZip->m_pFree(pZip->m_pAlloc_opaque, pRead_buf); MZ_FCLOSE(pSrc_file); return MZ_FALSE; } uncomp_crc32 = (mz_uint32)mz_crc32(uncomp_crc32, (const mz_uint8 *)pRead_buf, n); uncomp_remaining -= n; cur_archive_file_ofs += n; } comp_size = uncomp_size; } else { mz_bool result = MZ_FALSE; mz_zip_writer_add_state state; tdefl_compressor *pComp = (tdefl_compressor *)pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, sizeof(tdefl_compressor)); if (!pComp) { pZip->m_pFree(pZip->m_pAlloc_opaque, pRead_buf); MZ_FCLOSE(pSrc_file); return MZ_FALSE; } state.m_pZip = pZip; state.m_cur_archive_file_ofs = cur_archive_file_ofs; state.m_comp_size = 0; if (tdefl_init(pComp, mz_zip_writer_add_put_buf_callback, &state, tdefl_create_comp_flags_from_zip_params(level, -15, MZ_DEFAULT_STRATEGY)) != TDEFL_STATUS_OKAY) { pZip->m_pFree(pZip->m_pAlloc_opaque, pComp); pZip->m_pFree(pZip->m_pAlloc_opaque, pRead_buf); MZ_FCLOSE(pSrc_file); return MZ_FALSE; } for ( ; ; ) { size_t in_buf_size = (mz_uint32)MZ_MIN(uncomp_remaining, MZ_ZIP_MAX_IO_BUF_SIZE); tdefl_status status; if (MZ_FREAD(pRead_buf, 1, in_buf_size, pSrc_file) != in_buf_size) break; uncomp_crc32 = (mz_uint32)mz_crc32(uncomp_crc32, (const mz_uint8 *)pRead_buf, in_buf_size); uncomp_remaining -= in_buf_size; status = tdefl_compress_buffer(pComp, pRead_buf, in_buf_size, uncomp_remaining ? TDEFL_NO_FLUSH : TDEFL_FINISH); if (status == TDEFL_STATUS_DONE) { result = MZ_TRUE; break; } else if (status != TDEFL_STATUS_OKAY) break; } pZip->m_pFree(pZip->m_pAlloc_opaque, pComp); if (!result) { pZip->m_pFree(pZip->m_pAlloc_opaque, pRead_buf); MZ_FCLOSE(pSrc_file); return MZ_FALSE; } comp_size = state.m_comp_size; cur_archive_file_ofs = state.m_cur_archive_file_ofs; method = MZ_DEFLATED; } pZip->m_pFree(pZip->m_pAlloc_opaque, pRead_buf); } MZ_FCLOSE(pSrc_file); pSrc_file = NULL; // no zip64 support yet if ((comp_size > 0xFFFFFFFF) || (cur_archive_file_ofs > 0xFFFFFFFF)) return MZ_FALSE; if (!mz_zip_writer_create_local_dir_header(pZip, local_dir_header, (mz_uint16)archive_name_size, 0, uncomp_size, comp_size, uncomp_crc32, method, 0, dos_time, dos_date)) return MZ_FALSE; if (pZip->m_pWrite(pZip->m_pIO_opaque, local_dir_header_ofs, local_dir_header, sizeof(local_dir_header)) != sizeof(local_dir_header)) return MZ_FALSE; if (!mz_zip_writer_add_to_central_dir(pZip, pArchive_name, (mz_uint16)archive_name_size, NULL, 0, pComment, comment_size, uncomp_size, comp_size, uncomp_crc32, method, 0, dos_time, dos_date, local_dir_header_ofs, ext_attributes)) return MZ_FALSE; pZip->m_total_files++; pZip->m_archive_size = cur_archive_file_ofs; return MZ_TRUE; } #endif // #ifndef MINIZ_NO_STDIO mz_bool mz_zip_writer_add_from_zip_reader(mz_zip_archive *pZip, mz_zip_archive *pSource_zip, mz_uint file_index) { mz_uint n, bit_flags, num_alignment_padding_bytes; mz_uint64 comp_bytes_remaining, local_dir_header_ofs; mz_uint64 cur_src_file_ofs, cur_dst_file_ofs; mz_uint32 local_header_u32[(MZ_ZIP_LOCAL_DIR_HEADER_SIZE + sizeof(mz_uint32) - 1) / sizeof(mz_uint32)]; mz_uint8 *pLocal_header = (mz_uint8 *)local_header_u32; mz_uint8 central_header[MZ_ZIP_CENTRAL_DIR_HEADER_SIZE]; size_t orig_central_dir_size; mz_zip_internal_state *pState; void *pBuf; const mz_uint8 *pSrc_central_header; if ((!pZip) || (!pZip->m_pState) || (pZip->m_zip_mode != MZ_ZIP_MODE_WRITING)) return MZ_FALSE; if (NULL == (pSrc_central_header = mz_zip_reader_get_cdh(pSource_zip, file_index))) return MZ_FALSE; pState = pZip->m_pState; num_alignment_padding_bytes = mz_zip_writer_compute_padding_needed_for_file_alignment(pZip); // no zip64 support yet if ((pZip->m_total_files == 0xFFFF) || ((pZip->m_archive_size + num_alignment_padding_bytes + MZ_ZIP_LOCAL_DIR_HEADER_SIZE + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE) > 0xFFFFFFFF)) return MZ_FALSE; cur_src_file_ofs = pSource_zip->m_archive_file_ofs + MZ_READ_LE32(pSrc_central_header + MZ_ZIP_CDH_LOCAL_HEADER_OFS); cur_dst_file_ofs = pZip->m_archive_size; if (pSource_zip->m_pRead(pSource_zip->m_pIO_opaque, cur_src_file_ofs, pLocal_header, MZ_ZIP_LOCAL_DIR_HEADER_SIZE) != MZ_ZIP_LOCAL_DIR_HEADER_SIZE) return MZ_FALSE; if (MZ_READ_LE32(pLocal_header) != MZ_ZIP_LOCAL_DIR_HEADER_SIG) return MZ_FALSE; cur_src_file_ofs += MZ_ZIP_LOCAL_DIR_HEADER_SIZE; if (!mz_zip_writer_write_zeros(pZip, cur_dst_file_ofs, num_alignment_padding_bytes)) return MZ_FALSE; cur_dst_file_ofs += num_alignment_padding_bytes; local_dir_header_ofs = cur_dst_file_ofs; if (pZip->m_file_offset_alignment) { MZ_ASSERT((local_dir_header_ofs & (pZip->m_file_offset_alignment - 1)) == 0); } if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_dst_file_ofs, pLocal_header, MZ_ZIP_LOCAL_DIR_HEADER_SIZE) != MZ_ZIP_LOCAL_DIR_HEADER_SIZE) return MZ_FALSE; cur_dst_file_ofs += MZ_ZIP_LOCAL_DIR_HEADER_SIZE; n = MZ_READ_LE16(pLocal_header + MZ_ZIP_LDH_FILENAME_LEN_OFS) + MZ_READ_LE16(pLocal_header + MZ_ZIP_LDH_EXTRA_LEN_OFS); comp_bytes_remaining = n + MZ_READ_LE32(pSrc_central_header + MZ_ZIP_CDH_COMPRESSED_SIZE_OFS); if (NULL == (pBuf = pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, (size_t)MZ_MAX(sizeof(mz_uint32) * 4, MZ_MIN(MZ_ZIP_MAX_IO_BUF_SIZE, comp_bytes_remaining))))) return MZ_FALSE; while (comp_bytes_remaining) { n = (mz_uint)MZ_MIN(MZ_ZIP_MAX_IO_BUF_SIZE, comp_bytes_remaining); if (pSource_zip->m_pRead(pSource_zip->m_pIO_opaque, cur_src_file_ofs, pBuf, n) != n) { pZip->m_pFree(pZip->m_pAlloc_opaque, pBuf); return MZ_FALSE; } cur_src_file_ofs += n; if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_dst_file_ofs, pBuf, n) != n) { pZip->m_pFree(pZip->m_pAlloc_opaque, pBuf); return MZ_FALSE; } cur_dst_file_ofs += n; comp_bytes_remaining -= n; } bit_flags = MZ_READ_LE16(pLocal_header + MZ_ZIP_LDH_BIT_FLAG_OFS); if (bit_flags & 8) { // Copy data descriptor if (pSource_zip->m_pRead(pSource_zip->m_pIO_opaque, cur_src_file_ofs, pBuf, sizeof(mz_uint32) * 4) != sizeof(mz_uint32) * 4) { pZip->m_pFree(pZip->m_pAlloc_opaque, pBuf); return MZ_FALSE; } n = sizeof(mz_uint32) * ((MZ_READ_LE32(pBuf) == 0x08074b50) ? 4 : 3); if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_dst_file_ofs, pBuf, n) != n) { pZip->m_pFree(pZip->m_pAlloc_opaque, pBuf); return MZ_FALSE; } cur_src_file_ofs += n; cur_dst_file_ofs += n; } pZip->m_pFree(pZip->m_pAlloc_opaque, pBuf); // no zip64 support yet if (cur_dst_file_ofs > 0xFFFFFFFF) return MZ_FALSE; orig_central_dir_size = pState->m_central_dir.m_size; memcpy(central_header, pSrc_central_header, MZ_ZIP_CENTRAL_DIR_HEADER_SIZE); MZ_WRITE_LE32(central_header + MZ_ZIP_CDH_LOCAL_HEADER_OFS, local_dir_header_ofs); if (!mz_zip_array_push_back(pZip, &pState->m_central_dir, central_header, MZ_ZIP_CENTRAL_DIR_HEADER_SIZE)) return MZ_FALSE; n = MZ_READ_LE16(pSrc_central_header + MZ_ZIP_CDH_FILENAME_LEN_OFS) + MZ_READ_LE16(pSrc_central_header + MZ_ZIP_CDH_EXTRA_LEN_OFS) + MZ_READ_LE16(pSrc_central_header + MZ_ZIP_CDH_COMMENT_LEN_OFS); if (!mz_zip_array_push_back(pZip, &pState->m_central_dir, pSrc_central_header + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE, n)) { mz_zip_array_resize(pZip, &pState->m_central_dir, orig_central_dir_size, MZ_FALSE); return MZ_FALSE; } if (pState->m_central_dir.m_size > 0xFFFFFFFF) return MZ_FALSE; n = (mz_uint32)orig_central_dir_size; if (!mz_zip_array_push_back(pZip, &pState->m_central_dir_offsets, &n, 1)) { mz_zip_array_resize(pZip, &pState->m_central_dir, orig_central_dir_size, MZ_FALSE); return MZ_FALSE; } pZip->m_total_files++; pZip->m_archive_size = cur_dst_file_ofs; return MZ_TRUE; } mz_bool mz_zip_writer_finalize_archive(mz_zip_archive *pZip) { mz_zip_internal_state *pState; mz_uint64 central_dir_ofs, central_dir_size; mz_uint8 hdr[MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE]; if ((!pZip) || (!pZip->m_pState) || (pZip->m_zip_mode != MZ_ZIP_MODE_WRITING)) return MZ_FALSE; pState = pZip->m_pState; // no zip64 support yet if ((pZip->m_total_files > 0xFFFF) || ((pZip->m_archive_size + pState->m_central_dir.m_size + MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE) > 0xFFFFFFFF)) return MZ_FALSE; central_dir_ofs = 0; central_dir_size = 0; if (pZip->m_total_files) { // Write central directory central_dir_ofs = pZip->m_archive_size; central_dir_size = pState->m_central_dir.m_size; pZip->m_central_directory_file_ofs = central_dir_ofs; if (pZip->m_pWrite(pZip->m_pIO_opaque, central_dir_ofs, pState->m_central_dir.m_p, (size_t)central_dir_size) != central_dir_size) return MZ_FALSE; pZip->m_archive_size += central_dir_size; } // Write end of central directory record MZ_CLEAR_OBJ(hdr); MZ_WRITE_LE32(hdr + MZ_ZIP_ECDH_SIG_OFS, MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIG); MZ_WRITE_LE16(hdr + MZ_ZIP_ECDH_CDIR_NUM_ENTRIES_ON_DISK_OFS, pZip->m_total_files); MZ_WRITE_LE16(hdr + MZ_ZIP_ECDH_CDIR_TOTAL_ENTRIES_OFS, pZip->m_total_files); MZ_WRITE_LE32(hdr + MZ_ZIP_ECDH_CDIR_SIZE_OFS, central_dir_size); MZ_WRITE_LE32(hdr + MZ_ZIP_ECDH_CDIR_OFS_OFS, central_dir_ofs); if (pZip->m_pWrite(pZip->m_pIO_opaque, pZip->m_archive_size, hdr, sizeof(hdr)) != sizeof(hdr)) return MZ_FALSE; #ifndef MINIZ_NO_STDIO if ((pState->m_pFile) && (MZ_FFLUSH(pState->m_pFile) == EOF)) return MZ_FALSE; #endif // #ifndef MINIZ_NO_STDIO pZip->m_archive_size += sizeof(hdr); pZip->m_zip_mode = MZ_ZIP_MODE_WRITING_HAS_BEEN_FINALIZED; return MZ_TRUE; } mz_bool mz_zip_writer_finalize_heap_archive(mz_zip_archive *pZip, void **pBuf, size_t *pSize) { if ((!pZip) || (!pZip->m_pState) || (!pBuf) || (!pSize)) return MZ_FALSE; if (pZip->m_pWrite != mz_zip_heap_write_func) return MZ_FALSE; if (!mz_zip_writer_finalize_archive(pZip)) return MZ_FALSE; *pBuf = pZip->m_pState->m_pMem; *pSize = pZip->m_pState->m_mem_size; pZip->m_pState->m_pMem = NULL; pZip->m_pState->m_mem_size = pZip->m_pState->m_mem_capacity = 0; return MZ_TRUE; } mz_bool mz_zip_writer_end(mz_zip_archive *pZip) { mz_zip_internal_state *pState; mz_bool status = MZ_TRUE; if ((!pZip) || (!pZip->m_pState) || (!pZip->m_pAlloc) || (!pZip->m_pFree) || ((pZip->m_zip_mode != MZ_ZIP_MODE_WRITING) && (pZip->m_zip_mode != MZ_ZIP_MODE_WRITING_HAS_BEEN_FINALIZED))) return MZ_FALSE; pState = pZip->m_pState; pZip->m_pState = NULL; mz_zip_array_clear(pZip, &pState->m_central_dir); mz_zip_array_clear(pZip, &pState->m_central_dir_offsets); mz_zip_array_clear(pZip, &pState->m_sorted_central_dir_offsets); #ifndef MINIZ_NO_STDIO if (pState->m_pFile) { MZ_FCLOSE(pState->m_pFile); pState->m_pFile = NULL; } #endif // #ifndef MINIZ_NO_STDIO if ((pZip->m_pWrite == mz_zip_heap_write_func) && (pState->m_pMem)) { pZip->m_pFree(pZip->m_pAlloc_opaque, pState->m_pMem); pState->m_pMem = NULL; } pZip->m_pFree(pZip->m_pAlloc_opaque, pState); pZip->m_zip_mode = MZ_ZIP_MODE_INVALID; return status; } #ifndef MINIZ_NO_STDIO mz_bool mz_zip_add_mem_to_archive_file_in_place(const char *pZip_filename, const char *pArchive_name, const void *pBuf, size_t buf_size, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags) { mz_bool status, created_new_archive = MZ_FALSE; mz_zip_archive zip_archive; struct MZ_FILE_STAT_STRUCT file_stat; MZ_CLEAR_OBJ(zip_archive); if ((int)level_and_flags < 0) level_and_flags = MZ_DEFAULT_LEVEL; if ((!pZip_filename) || (!pArchive_name) || ((buf_size) && (!pBuf)) || ((comment_size) && (!pComment)) || ((level_and_flags & 0xF) > MZ_UBER_COMPRESSION)) return MZ_FALSE; if (!mz_zip_writer_validate_archive_name(pArchive_name)) return MZ_FALSE; if (MZ_FILE_STAT(pZip_filename, &file_stat) != 0) { // Create a new archive. if (!mz_zip_writer_init_file(&zip_archive, pZip_filename, 0)) return MZ_FALSE; created_new_archive = MZ_TRUE; } else { // Append to an existing archive. if (!mz_zip_reader_init_file(&zip_archive, pZip_filename, level_and_flags | MZ_ZIP_FLAG_DO_NOT_SORT_CENTRAL_DIRECTORY)) return MZ_FALSE; if (!mz_zip_writer_init_from_reader(&zip_archive, pZip_filename)) { mz_zip_reader_end(&zip_archive); return MZ_FALSE; } } status = mz_zip_writer_add_mem_ex(&zip_archive, pArchive_name, pBuf, buf_size, pComment, comment_size, level_and_flags, 0, 0); // Always finalize, even if adding failed for some reason, so we have a valid central directory. (This may not always succeed, but we can try.) if (!mz_zip_writer_finalize_archive(&zip_archive)) status = MZ_FALSE; if (!mz_zip_writer_end(&zip_archive)) status = MZ_FALSE; if ((!status) && (created_new_archive)) { // It's a new archive and something went wrong, so just delete it. int ignoredStatus = MZ_DELETE_FILE(pZip_filename); (void)ignoredStatus; } return status; } void *mz_zip_extract_archive_file_to_heap(const char *pZip_filename, const char *pArchive_name, size_t *pSize, mz_uint flags) { int file_index; mz_zip_archive zip_archive; void *p = NULL; if (pSize) *pSize = 0; if ((!pZip_filename) || (!pArchive_name)) return NULL; MZ_CLEAR_OBJ(zip_archive); if (!mz_zip_reader_init_file(&zip_archive, pZip_filename, flags | MZ_ZIP_FLAG_DO_NOT_SORT_CENTRAL_DIRECTORY)) return NULL; if ((file_index = mz_zip_reader_locate_file(&zip_archive, pArchive_name, NULL, flags)) >= 0) p = mz_zip_reader_extract_to_heap(&zip_archive, file_index, pSize, flags); mz_zip_reader_end(&zip_archive); return p; } #endif // #ifndef MINIZ_NO_STDIO #endif // #ifndef MINIZ_NO_ARCHIVE_WRITING_APIS #endif // #ifndef MINIZ_NO_ARCHIVE_APIS #ifdef __cplusplus } #endif #endif // MINIZ_HEADER_FILE_ONLY /* This is free and unencumbered software released into the public domain. Anyone is free to copy, modify, publish, use, compile, sell, or distribute this software, either in source code form or as a compiled binary, for any purpose, commercial or non-commercial, and by any means. In jurisdictions that recognize copyright laws, the author or authors of this software dedicate any and all copyright interest in the software to the public domain. We make this dedication for the benefit of the public at large and to the detriment of our heirs and successors. We intend this dedication to be an overt act of relinquishment in perpetuity of all present and future rights to this software under copyright law. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. For more information, please refer to */ diff --git a/Core/CppMicroServices/third_party/miniz_v115_r4.patch b/Core/CppMicroServices/third_party/miniz_v115_r4.patch index 0ec308cd79..7fba1f9627 100644 --- a/Core/CppMicroServices/third_party/miniz_v115_r4.patch +++ b/Core/CppMicroServices/third_party/miniz_v115_r4.patch @@ -1,77 +1,94 @@ ---- a/miniz.c 2013-10-14 04:02:24.000000000 +0200 -+++ b/miniz.c 2014-10-28 14:08:19.668529223 +0100 +--- /home/sascha/miniz.c 2013-10-14 04:02:24.000000000 +0200 ++++ miniz.c 2014-11-19 23:10:15.744583538 +0100 @@ -535,6 +535,7 @@ typedef struct mz_zip_archive_tag { mz_uint64 m_archive_size; + mz_uint64 m_archive_file_ofs; mz_uint64 m_central_directory_file_ofs; mz_uint m_total_files; mz_zip_mode m_zip_mode; -@@ -3180,6 +3181,8 @@ - cur_file_ofs = MZ_MAX((mz_int64)pZip->m_archive_size - (mz_int64)sizeof(buf_u32), 0); - for ( ; ; ) - { -+ for ( ; ; ) -+ { - int i, n = (int)MZ_MIN(sizeof(buf_u32), pZip->m_archive_size - cur_file_ofs); +@@ -3173,6 +3174,7 @@ + const mz_uint8 *p; + mz_uint32 buf_u32[4096 / sizeof(mz_uint32)]; mz_uint8 *pBuf = (mz_uint8 *)buf_u32; + mz_bool sort_central_dir = ((flags & MZ_ZIP_FLAG_DO_NOT_SORT_CENTRAL_DIRECTORY) == 0); ++ mz_bool zip_signature_found = 0; + // Basic sanity checks - reject files which are too small, and check the first 4 bytes of the file to make sure a local header is there. + if (pZip->m_archive_size < MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE) + return MZ_FALSE; +@@ -3184,23 +3186,30 @@ if (pZip->m_pRead(pZip->m_pIO_opaque, cur_file_ofs, pBuf, n) != (mz_uint)n) return MZ_FALSE; -@@ -3191,16 +3194,18 @@ + for (i = n - 4; i >= 0; --i) ++ { + if (MZ_READ_LE32(pBuf + i) == MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIG) ++ { ++ // Read and verify the end of central directory record. ++ if (pZip->m_pRead(pZip->m_pIO_opaque, cur_file_ofs + i, pBuf, MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE) != MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE) ++ continue; ++ if ((MZ_READ_LE32(pBuf + MZ_ZIP_ECDH_SIG_OFS) != MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIG) || ++ ((pZip->m_total_files = MZ_READ_LE16(pBuf + MZ_ZIP_ECDH_CDIR_TOTAL_ENTRIES_OFS)) != MZ_READ_LE16(pBuf + MZ_ZIP_ECDH_CDIR_NUM_ENTRIES_ON_DISK_OFS))) ++ continue; ++ zip_signature_found = 1; + break; +- if (i >= 0) ++ } ++ } ++ ++ if (zip_signature_found) + { cur_file_ofs += i; break; } - if ((!cur_file_ofs) || ((pZip->m_archive_size - cur_file_ofs) >= (0xFFFF + MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE))) -+ if ((!cur_file_ofs) || (cur_file_ofs < MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE)) ++ if ((!cur_file_ofs) || (cur_file_ofs < MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE)) return MZ_FALSE; - cur_file_ofs = MZ_MAX(cur_file_ofs - (sizeof(buf_u32) - 3), 0); +- cur_file_ofs = MZ_MAX(cur_file_ofs - (sizeof(buf_u32) - 3), 0); ++ ++ cur_file_ofs = MZ_MAX(cur_file_ofs - (mz_int64)(sizeof(buf_u32) - 3), 0); } - // Read and verify the end of central directory record. - if (pZip->m_pRead(pZip->m_pIO_opaque, cur_file_ofs, pBuf, MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE) != MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE) +- // Read and verify the end of central directory record. +- if (pZip->m_pRead(pZip->m_pIO_opaque, cur_file_ofs, pBuf, MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE) != MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE) - return MZ_FALSE; -+ continue; - if ((MZ_READ_LE32(pBuf + MZ_ZIP_ECDH_SIG_OFS) != MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIG) || - ((pZip->m_total_files = MZ_READ_LE16(pBuf + MZ_ZIP_ECDH_CDIR_TOTAL_ENTRIES_OFS)) != MZ_READ_LE16(pBuf + MZ_ZIP_ECDH_CDIR_NUM_ENTRIES_ON_DISK_OFS))) +- if ((MZ_READ_LE32(pBuf + MZ_ZIP_ECDH_SIG_OFS) != MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIG) || +- ((pZip->m_total_files = MZ_READ_LE16(pBuf + MZ_ZIP_ECDH_CDIR_TOTAL_ENTRIES_OFS)) != MZ_READ_LE16(pBuf + MZ_ZIP_ECDH_CDIR_NUM_ENTRIES_ON_DISK_OFS))) - return MZ_FALSE; -+ continue; -+ break; -+ } num_this_disk = MZ_READ_LE16(pBuf + MZ_ZIP_ECDH_NUM_THIS_DISK_OFS); cdir_disk_index = MZ_READ_LE16(pBuf + MZ_ZIP_ECDH_NUM_DISK_CDIR_OFS); -@@ -3210,12 +3215,16 @@ +@@ -3210,12 +3219,16 @@ if ((cdir_size = MZ_READ_LE32(pBuf + MZ_ZIP_ECDH_CDIR_SIZE_OFS)) < pZip->m_total_files * MZ_ZIP_CENTRAL_DIR_HEADER_SIZE) return MZ_FALSE; - cdir_ofs = MZ_READ_LE32(pBuf + MZ_ZIP_ECDH_CDIR_OFS_OFS); + cdir_ofs = cur_file_ofs - cdir_size; if ((cdir_ofs + (mz_uint64)cdir_size) > pZip->m_archive_size) return MZ_FALSE; pZip->m_central_directory_file_ofs = cdir_ofs; + pZip->m_archive_file_ofs = cdir_ofs - MZ_READ_LE32(pBuf + MZ_ZIP_ECDH_CDIR_OFS_OFS); + if (pZip->m_archive_file_ofs > pZip->m_archive_size) + return MZ_FALSE; + if (pZip->m_total_files) { mz_uint i, n; -@@ -3573,7 +3582,7 @@ +@@ -3573,7 +3586,7 @@ return MZ_FALSE; // Read and parse the local directory entry. - cur_file_ofs = file_stat.m_local_header_ofs; + cur_file_ofs = pZip->m_archive_file_ofs + file_stat.m_local_header_ofs; if (pZip->m_pRead(pZip->m_pIO_opaque, cur_file_ofs, pLocal_header, MZ_ZIP_LOCAL_DIR_HEADER_SIZE) != MZ_ZIP_LOCAL_DIR_HEADER_SIZE) return MZ_FALSE; if (MZ_READ_LE32(pLocal_header) != MZ_ZIP_LOCAL_DIR_HEADER_SIG) -@@ -4610,7 +4619,7 @@ +@@ -4610,7 +4623,7 @@ if ((pZip->m_total_files == 0xFFFF) || ((pZip->m_archive_size + num_alignment_padding_bytes + MZ_ZIP_LOCAL_DIR_HEADER_SIZE + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE) > 0xFFFFFFFF)) return MZ_FALSE; - cur_src_file_ofs = MZ_READ_LE32(pSrc_central_header + MZ_ZIP_CDH_LOCAL_HEADER_OFS); + cur_src_file_ofs = pSource_zip->m_archive_file_ofs + MZ_READ_LE32(pSrc_central_header + MZ_ZIP_CDH_LOCAL_HEADER_OFS); cur_dst_file_ofs = pZip->m_archive_size; if (pSource_zip->m_pRead(pSource_zip->m_pIO_opaque, cur_src_file_ofs, pLocal_header, MZ_ZIP_LOCAL_DIR_HEADER_SIZE) != MZ_ZIP_LOCAL_DIR_HEADER_SIZE) diff --git a/Documentation/Doxygen/UserManual/MITKPluginManualsList.dox b/Documentation/Doxygen/UserManual/MITKPluginManualsList.dox index be03f2ba30..1b70e25a7f 100644 --- a/Documentation/Doxygen/UserManual/MITKPluginManualsList.dox +++ b/Documentation/Doxygen/UserManual/MITKPluginManualsList.dox @@ -1,46 +1,45 @@ /** \page PluginListPage MITK Plugin Manuals \section PluginListPageOverview Overview The plugins and bundles provide much of the extended functionality of MITK. Each encapsulates a solution to a problem and associated features. This way one can easily assemble the necessary capabilites for a workflow without adding a lot of bloat, by combining plugins as needed. The distinction between developer and end user use is for convenience only and mainly distinguishes which group a plugin is primarily aimed at. \section PluginListPageEndUserPluginList List of Plugins for End User Use \li \subpage org_blueberry_ui_qt_log \li \subpage org_mitk_views_basicimageprocessing \li \subpage org_mitk_views_cmdlinemodules \li \subpage org_mitk_views_datamanager \li \subpage org_mitk_gui_qt_dicom \li \subpage org_mitk_gui_qt_diffusionimaging \li \subpage org_mitk_views_imagecropper \li \subpage org_mitk_views_imagenavigator \li \subpage org_mitk_gui_qt_measurementtoolbox - \li \subpage org_mitk_views_meshdecimation \li \subpage org_mitk_views_moviemaker \li \subpage org_mitk_views_screenshotmaker \li \subpage org_mitk_views_pointsetinteraction \li \subpage org_mitk_gui_qt_python \li \subpage org_mitk_gui_qt_registration \li \subpage org_mitk_gui_qt_remeshing \li \subpage org_mitk_views_segmentation \li \subpage org_mitk_gui_qt_ultrasound \li \subpage org_mitk_gui_qt_viewnavigator \li \subpage org_mitk_views_volumevisualization \li \subpage org_mitk_gui_qt_xnat \section PluginListPageDevPluginList List of Plugins for Developer Use and Examples \li \subpage org_surfacematerialeditor \li \subpage org_toftutorial \li \subpage org_mitk_gui_qt_examples \li \subpage org_mitkexamplesopencv \li \subpage org_mitk_gui_qt_igtexample \li \subpage org_mitk_gui_qt_igttracking \li \subpage org_blueberry_ui_qt_objectinspector \li \subpage org_mitk_gui_qt_eventrecorder */ diff --git a/Examples/BlueBerryExampleLauncher/CMakeLists.txt b/Examples/BlueBerryExampleLauncher/CMakeLists.txt index 2cd2b7188d..3ce31cf4e1 100644 --- a/Examples/BlueBerryExampleLauncher/CMakeLists.txt +++ b/Examples/BlueBerryExampleLauncher/CMakeLists.txt @@ -1,85 +1,93 @@ project(BlueBerryExampleLauncher) set(_source_files BlueBerryExampleLauncher.cpp BlueBerryExampleLauncherDialog.cpp ) set(_source_moc_h_files BlueBerryExampleLauncherDialog.h ) set(_source_ui_files BlueBerryExampleLauncherDialog.ui ) # this is a workaround for Visual Studio. The relative include paths in the generated # moc files can get very long and can't be resolved by the MSVC compiler. foreach(_moc_src ${_source_moc_h_files}) - qt4_wrap_cpp(_source_files ${_moc_src} OPTIONS -f${_moc_src}) + if (DESIRED_QT_VERSION MATCHES "5") + qt5_wrap_cpp(_source_files ${_moc_src} OPTIONS -f${_moc_src}) + else() + qt4_wrap_cpp(_source_files ${_moc_src} OPTIONS -f${_moc_src}) + endif() endforeach() -qt4_wrap_ui(_source_files ${_source_ui_files}) +if (DESIRED_QT_VERSION MATCHES "5") + qt5_wrap_ui(_source_files ${_source_ui_files}) +else() + qt4_wrap_ui(_source_files ${_source_ui_files}) +endif() include_directories(${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR} ) #----------------------------------------------------------------------------- # Create provisioning files #----------------------------------------------------------------------------- set(_plugins_for_all_demos org.blueberry.compat ) file(GLOB _demo_configurations Configurations/*.cmake) set(ALL_REQUIRED_PLUGINS ${_plugins_for_all_demos}) foreach(_demo_config_file ${_demo_configurations}) set(REQUIRED_PLUGINS ) set(DESCRIPTION ) include(${_demo_config_file}) get_filename_component(_name ${_demo_config_file} NAME_WE) FunctionCreateProvisioningFile(FILE ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${PROJECT_NAME}_${_name}.provisioning PLUGINS ${REQUIRED_PLUGINS} ${_plugins_for_all_demos} NO_INSTALL ) if(DESCRIPTION) configure_file(${CMAKE_CURRENT_SOURCE_DIR}/BlueBerryExampleDescription.txt ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${PROJECT_NAME}_${_name}.txt @ONLY) endif() list(APPEND ALL_REQUIRED_PLUGINS ${REQUIRED_PLUGINS}) endforeach() list(REMOVE_DUPLICATES ALL_REQUIRED_PLUGINS) set(ALL_REQUIRED_PLUGIN_TARGETS ) foreach(req_plugin ${ALL_REQUIRED_PLUGINS}) string(REPLACE "." "_" _plugin_target ${req_plugin}) if(TARGET ${_plugin_target}) list(APPEND ALL_REQUIRED_PLUGIN_TARGETS ${_plugin_target}) endif() endforeach() #----------------------------------------------------------------------------- # Create the example launcher #----------------------------------------------------------------------------- FunctionCreateBlueBerryApplication( NAME ${PROJECT_NAME} DESCRIPTION "MITK Application Framework Demo" SOURCES ${_source_files} # PLUGINS ${ALL_REQUIRED_PLUGIN_TARGETS} NO_PROVISIONING NO_INSTALL SHOW_CONSOLE ) -mitk_use_modules(TARGET ${PROJECT_NAME} PACKAGES Qt4|QtGui) +mitk_use_modules(TARGET ${PROJECT_NAME} PACKAGES Qt4|QtGui Qt5|Widgets) add_dependencies(${PROJECT_NAME} ${ALL_REQUIRED_PLUGIN_TARGETS}) # subproject support set_property(TARGET ${PROJECT_NAME} PROPERTY LABELS ${MITK_DEFAULT_SUBPROJECTS}) foreach(subproject ${MITK_DEFAULT_SUBPROJECTS}) add_dependencies(${subproject} ${PROJECT_NAME}) endforeach() diff --git a/Examples/Plugins/org.mitk.example.gui.customviewer.views/src/internal/org_mitk_example_gui_customviewer_views_Activator.cpp b/Examples/Plugins/org.mitk.example.gui.customviewer.views/src/internal/org_mitk_example_gui_customviewer_views_Activator.cpp index dc35d5ddc5..4eda975a56 100644 --- a/Examples/Plugins/org.mitk.example.gui.customviewer.views/src/internal/org_mitk_example_gui_customviewer_views_Activator.cpp +++ b/Examples/Plugins/org.mitk.example.gui.customviewer.views/src/internal/org_mitk_example_gui_customviewer_views_Activator.cpp @@ -1,48 +1,49 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "org_mitk_example_gui_customviewer_views_Activator.h" #include "DicomView.h" #include "SimpleRenderWindowView.h" #include ctkPluginContext* org_mitk_example_gui_customviewer_views_Activator::PluginContext = 0; void org_mitk_example_gui_customviewer_views_Activator::start(ctkPluginContext* context) { BERRY_REGISTER_EXTENSION_CLASS(DicomView, context) BERRY_REGISTER_EXTENSION_CLASS(SimpleRenderWindowView, context) PluginContext = context; } void org_mitk_example_gui_customviewer_views_Activator::stop(ctkPluginContext* context) { Q_UNUSED(context) PluginContext = 0; } ctkPluginContext* org_mitk_example_gui_customviewer_views_Activator::GetPluginContext() { return PluginContext; } -Q_EXPORT_PLUGIN2(org_mitk_example_gui_customviewer_views, org_mitk_example_gui_customviewer_views_Activator) - +#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) + Q_EXPORT_PLUGIN2(org_mitk_example_gui_customviewer_views, org_mitk_example_gui_customviewer_views_Activator) +#endif diff --git a/Examples/Plugins/org.mitk.example.gui.customviewer.views/src/internal/org_mitk_example_gui_customviewer_views_Activator.h b/Examples/Plugins/org.mitk.example.gui.customviewer.views/src/internal/org_mitk_example_gui_customviewer_views_Activator.h index 5f84e99346..576c37adcf 100644 --- a/Examples/Plugins/org.mitk.example.gui.customviewer.views/src/internal/org_mitk_example_gui_customviewer_views_Activator.h +++ b/Examples/Plugins/org.mitk.example.gui.customviewer.views/src/internal/org_mitk_example_gui_customviewer_views_Activator.h @@ -1,44 +1,47 @@ /*=================================================================== 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 org_mitk_example_gui_customviewer_views_Activator_H #define org_mitk_example_gui_customviewer_views_Activator_H #include class ctkPluginContext; class org_mitk_example_gui_customviewer_views_Activator : public QObject, public ctkPluginActivator { Q_OBJECT +#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) + Q_PLUGIN_METADATA(IID "org_mitk_example_gui_customviewer_views") +#endif Q_INTERFACES(ctkPluginActivator) public: void start(ctkPluginContext* context); void stop(ctkPluginContext* context); static ctkPluginContext* GetPluginContext(); private: static ctkPluginContext* PluginContext; }; #endif // org_mitk_example_gui_customviewer_views_Activator_H diff --git a/Examples/Plugins/org.mitk.example.gui.customviewer/src/internal/org_mitk_example_gui_customviewer_Activator.cpp b/Examples/Plugins/org.mitk.example.gui.customviewer/src/internal/org_mitk_example_gui_customviewer_Activator.cpp index 518103ebb2..2a48532fa0 100644 --- a/Examples/Plugins/org.mitk.example.gui.customviewer/src/internal/org_mitk_example_gui_customviewer_Activator.cpp +++ b/Examples/Plugins/org.mitk.example.gui.customviewer/src/internal/org_mitk_example_gui_customviewer_Activator.cpp @@ -1,50 +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. ===================================================================*/ #include "org_mitk_example_gui_customviewer_Activator.h" #include "CustomViewer.h" #include "ViewerPerspective.h" #include "DicomPerspective.h" #include ctkPluginContext* org_mitk_example_gui_customviewer_Activator::PluginContext = 0; void org_mitk_example_gui_customviewer_Activator::start(ctkPluginContext* context) { BERRY_REGISTER_EXTENSION_CLASS(CustomViewer, context) BERRY_REGISTER_EXTENSION_CLASS(ViewerPerspective, context) BERRY_REGISTER_EXTENSION_CLASS(DicomPerspective, context) PluginContext = context; } void org_mitk_example_gui_customviewer_Activator::stop(ctkPluginContext* context) { Q_UNUSED(context) PluginContext = 0; } ctkPluginContext* org_mitk_example_gui_customviewer_Activator::GetPluginContext() { return PluginContext; } -Q_EXPORT_PLUGIN2(org_mitk_example_gui_customviewer, org_mitk_example_gui_customviewer_Activator) - +#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) + Q_EXPORT_PLUGIN2(org_mitk_example_gui_customviewer, org_mitk_example_gui_customviewer_Activator) +#endif diff --git a/Examples/Plugins/org.mitk.example.gui.customviewer/src/internal/org_mitk_example_gui_customviewer_Activator.h b/Examples/Plugins/org.mitk.example.gui.customviewer/src/internal/org_mitk_example_gui_customviewer_Activator.h index 22dd6970c1..27a2b0e9c8 100644 --- a/Examples/Plugins/org.mitk.example.gui.customviewer/src/internal/org_mitk_example_gui_customviewer_Activator.h +++ b/Examples/Plugins/org.mitk.example.gui.customviewer/src/internal/org_mitk_example_gui_customviewer_Activator.h @@ -1,44 +1,47 @@ /*=================================================================== 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 org_mitk_example_gui_customviewer_Activator_H #define org_mitk_example_gui_customviewer_Activator_H #include class ctkPluginContext; // //! [PluginActivatorHeader] class org_mitk_example_gui_customviewer_Activator : public QObject, public ctkPluginActivator { Q_OBJECT +#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) + Q_PLUGIN_METADATA(IID "org_mitk_example_gui_customviewer") +#endif Q_INTERFACES(ctkPluginActivator) public: void start(ctkPluginContext* context); void stop(ctkPluginContext* context); static ctkPluginContext* GetPluginContext(); private: static ctkPluginContext* PluginContext; }; // //! [PluginActivatorHeader] #endif // org_mitk_example_gui_customviewer_Activator_H diff --git a/Examples/Plugins/org.mitk.example.gui.extensionpointcontribution/src/internal/org_mitk_example_gui_extensionpointcontribution_Activator.cpp b/Examples/Plugins/org.mitk.example.gui.extensionpointcontribution/src/internal/org_mitk_example_gui_extensionpointcontribution_Activator.cpp index e44ad74007..1c8b726083 100644 --- a/Examples/Plugins/org.mitk.example.gui.extensionpointcontribution/src/internal/org_mitk_example_gui_extensionpointcontribution_Activator.cpp +++ b/Examples/Plugins/org.mitk.example.gui.extensionpointcontribution/src/internal/org_mitk_example_gui_extensionpointcontribution_Activator.cpp @@ -1,35 +1,38 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "org_mitk_example_gui_extensionpointcontribution_Activator.h" #include "ChangeTextToLowerCase.h" #include "ChangeTextToUpperCase.h" #include void org_mitk_example_gui_extensionpointcontribution_Activator::start(ctkPluginContext* context) { BERRY_REGISTER_EXTENSION_CLASS(ChangeTextToLowerCase, context) BERRY_REGISTER_EXTENSION_CLASS(ChangeTextToUpperCase, context) } void org_mitk_example_gui_extensionpointcontribution_Activator::stop(ctkPluginContext* context) { Q_UNUSED(context) } -Q_EXPORT_PLUGIN2(org_mitk_example_gui_extensionpointcontribution, org_mitk_example_gui_extensionpointcontribution_Activator) +#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) + Q_EXPORT_PLUGIN2(org_mitk_example_gui_extensionpointcontribution, org_mitk_example_gui_extensionpointcontribution_Activator) +#endif + diff --git a/Examples/Plugins/org.mitk.example.gui.extensionpointcontribution/src/internal/org_mitk_example_gui_extensionpointcontribution_Activator.h b/Examples/Plugins/org.mitk.example.gui.extensionpointcontribution/src/internal/org_mitk_example_gui_extensionpointcontribution_Activator.h index 6cd46f0ada..263fb1264b 100644 --- a/Examples/Plugins/org.mitk.example.gui.extensionpointcontribution/src/internal/org_mitk_example_gui_extensionpointcontribution_Activator.h +++ b/Examples/Plugins/org.mitk.example.gui.extensionpointcontribution/src/internal/org_mitk_example_gui_extensionpointcontribution_Activator.h @@ -1,36 +1,39 @@ /*=================================================================== 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 org_mitk_example_gui_extensionpointcontribution_Activator_H #define org_mitk_example_gui_extensionpointcontribution_Activator_H #include class org_mitk_example_gui_extensionpointcontribution_Activator : public QObject, public ctkPluginActivator { Q_OBJECT +#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) + Q_PLUGIN_METADATA(IID "org_mitk_example_gui_extensionpointcontribution") +#endif Q_INTERFACES(ctkPluginActivator) public: void start(ctkPluginContext* context); void stop(ctkPluginContext* context); }; #endif // org_mitk_example_gui_extensionpointcontribution_Activator_H diff --git a/Examples/Plugins/org.mitk.example.gui.extensionpointdefinition/src/internal/org_mitk_example_gui_extensionpointdefinition_Activator.cpp b/Examples/Plugins/org.mitk.example.gui.extensionpointdefinition/src/internal/org_mitk_example_gui_extensionpointdefinition_Activator.cpp index f9edf73097..b28cd9175a 100644 --- a/Examples/Plugins/org.mitk.example.gui.extensionpointdefinition/src/internal/org_mitk_example_gui_extensionpointdefinition_Activator.cpp +++ b/Examples/Plugins/org.mitk.example.gui.extensionpointdefinition/src/internal/org_mitk_example_gui_extensionpointdefinition_Activator.cpp @@ -1,44 +1,46 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "org_mitk_example_gui_extensionpointdefinition_Activator.h" #include "ExtensionPointDefinition.h" #include "MinimalPerspective.h" #include "MinimalView.h" #include void org_mitk_example_gui_extensionpointdefinition_Activator::start(ctkPluginContext* context) { BERRY_REGISTER_EXTENSION_CLASS(ExtensionPointDefinition, context) BERRY_REGISTER_EXTENSION_CLASS(MinimalPerspective, context) BERRY_REGISTER_EXTENSION_CLASS(MinimalView, context) } void org_mitk_example_gui_extensionpointdefinition_Activator::stop(ctkPluginContext* context) { Q_UNUSED(context) } ChangeTextRegistry* org_mitk_example_gui_extensionpointdefinition_Activator::getChangeTextRegistry() { static ChangeTextRegistry registry; return ®istry; } -Q_EXPORT_PLUGIN2(org_mitk_example_gui_extensionpointdefinition, org_mitk_example_gui_extensionpointdefinition_Activator) +#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) + Q_EXPORT_PLUGIN2(org_mitk_example_gui_extensionpointdefinition, org_mitk_example_gui_extensionpointdefinition_Activator) +#endif diff --git a/Examples/Plugins/org.mitk.example.gui.extensionpointdefinition/src/internal/org_mitk_example_gui_extensionpointdefinition_Activator.h b/Examples/Plugins/org.mitk.example.gui.extensionpointdefinition/src/internal/org_mitk_example_gui_extensionpointdefinition_Activator.h index 52a9660365..0cf1942db2 100644 --- a/Examples/Plugins/org.mitk.example.gui.extensionpointdefinition/src/internal/org_mitk_example_gui_extensionpointdefinition_Activator.h +++ b/Examples/Plugins/org.mitk.example.gui.extensionpointdefinition/src/internal/org_mitk_example_gui_extensionpointdefinition_Activator.h @@ -1,43 +1,46 @@ /*=================================================================== 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 org_mitk_example_gui_extensionpointdefinition_Activator_H #define org_mitk_example_gui_extensionpointdefinition_Activator_H #include #include "ChangeTextRegistry.h" class org_mitk_example_gui_extensionpointdefinition_Activator : public QObject, public ctkPluginActivator { Q_OBJECT +#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) + Q_PLUGIN_METADATA(IID "org_mitk_example_gui_extensionpointdefinition") +#endif Q_INTERFACES(ctkPluginActivator) public: void start(ctkPluginContext* context); void stop(ctkPluginContext* context); /** * Get the Registry (for extensions). */ static ChangeTextRegistry* getChangeTextRegistry(); }; #endif // org_mitk_example_gui_extensionpointdefinition_Activator_H diff --git a/Examples/Plugins/org.mitk.example.gui.imaging/src/internal/mitkPluginActivator.cpp b/Examples/Plugins/org.mitk.example.gui.imaging/src/internal/mitkPluginActivator.cpp index 7c4b40697a..42c32ff086 100644 --- a/Examples/Plugins/org.mitk.example.gui.imaging/src/internal/mitkPluginActivator.cpp +++ b/Examples/Plugins/org.mitk.example.gui.imaging/src/internal/mitkPluginActivator.cpp @@ -1,50 +1,52 @@ /*=================================================================== 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 "mitkPluginActivator.h" #include #include "src/internal/colourimageprocessing/QmitkColourImageProcessingView.h" #include "src/internal/isosurface/QmitkIsoSurface.h" #include "src/internal/simpleexample/QmitkSimpleExampleView.h" #include "src/internal/simplemeasurement/QmitkSimpleMeasurement.h" #include "src/internal/viewinitialization/QmitkViewInitializationView.h" #include "src/internal/volumetry/QmitkVolumetryView.h" #include "src/internal/surfaceutilities/QmitkSurfaceUtilities.h" namespace mitk { void PluginActivator::start(ctkPluginContext* context) { BERRY_REGISTER_EXTENSION_CLASS(QmitkColourImageProcessingView, context) BERRY_REGISTER_EXTENSION_CLASS(QmitkIsoSurface, context) BERRY_REGISTER_EXTENSION_CLASS(QmitkSimpleExampleView, context) BERRY_REGISTER_EXTENSION_CLASS(QmitkSimpleMeasurement, context) BERRY_REGISTER_EXTENSION_CLASS(QmitkViewInitializationView, context) BERRY_REGISTER_EXTENSION_CLASS(QmitkVolumetryView, context) BERRY_REGISTER_EXTENSION_CLASS(QmitkSurfaceUtilities, context) } void PluginActivator::stop(ctkPluginContext* context) { Q_UNUSED(context) } } -Q_EXPORT_PLUGIN2(org_mitk_gui_qt_examples, mitk::PluginActivator) +#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) + Q_EXPORT_PLUGIN2(org_mitk_gui_qt_examples, mitk::PluginActivator) +#endif diff --git a/Examples/Plugins/org.mitk.example.gui.imaging/src/internal/mitkPluginActivator.h b/Examples/Plugins/org.mitk.example.gui.imaging/src/internal/mitkPluginActivator.h index 489bd853ca..5dd5940465 100644 --- a/Examples/Plugins/org.mitk.example.gui.imaging/src/internal/mitkPluginActivator.h +++ b/Examples/Plugins/org.mitk.example.gui.imaging/src/internal/mitkPluginActivator.h @@ -1,40 +1,43 @@ /*=================================================================== 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 MITKPLUGINACTIVATOR_H #define MITKPLUGINACTIVATOR_H #include #include namespace mitk { class MITK_LOCAL PluginActivator : public QObject, public ctkPluginActivator { Q_OBJECT +#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) + Q_PLUGIN_METADATA(IID "org_mitk_gui_qt_examples") +#endif Q_INTERFACES(ctkPluginActivator) public: void start(ctkPluginContext* context); void stop(ctkPluginContext* context); }; // PluginActivator } #endif // MITKPLUGINACTIVATOR_H diff --git a/Examples/Plugins/org.mitk.example.gui.minimalapplication/src/internal/org_mitk_example_gui_minimalapplication_Activator.cpp b/Examples/Plugins/org.mitk.example.gui.minimalapplication/src/internal/org_mitk_example_gui_minimalapplication_Activator.cpp index 1ffd94fc04..016215472c 100644 --- a/Examples/Plugins/org.mitk.example.gui.minimalapplication/src/internal/org_mitk_example_gui_minimalapplication_Activator.cpp +++ b/Examples/Plugins/org.mitk.example.gui.minimalapplication/src/internal/org_mitk_example_gui_minimalapplication_Activator.cpp @@ -1,36 +1,38 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "org_mitk_example_gui_minimalapplication_Activator.h" #include "MinimalApplication.h" #include "MinimalPerspective.h" #include void org_mitk_example_gui_minimalapplication_Activator::start(ctkPluginContext* context) { BERRY_REGISTER_EXTENSION_CLASS(MinimalApplication, context) BERRY_REGISTER_EXTENSION_CLASS(MinimalPerspective, context) } void org_mitk_example_gui_minimalapplication_Activator::stop(ctkPluginContext* context) { Q_UNUSED(context) } -Q_EXPORT_PLUGIN2(org_mitk_example_gui_minimalapplication, org_mitk_example_gui_minimalapplication_Activator) +#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) + Q_EXPORT_PLUGIN2(org_mitk_example_gui_minimalapplication, org_mitk_example_gui_minimalapplication_Activator) +#endif diff --git a/Examples/Plugins/org.mitk.example.gui.minimalapplication/src/internal/org_mitk_example_gui_minimalapplication_Activator.h b/Examples/Plugins/org.mitk.example.gui.minimalapplication/src/internal/org_mitk_example_gui_minimalapplication_Activator.h index d1e5c6ce75..4ce677fcd2 100644 --- a/Examples/Plugins/org.mitk.example.gui.minimalapplication/src/internal/org_mitk_example_gui_minimalapplication_Activator.h +++ b/Examples/Plugins/org.mitk.example.gui.minimalapplication/src/internal/org_mitk_example_gui_minimalapplication_Activator.h @@ -1,36 +1,39 @@ /*=================================================================== 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 org_mitk_example_gui_minimalapplication_Activator_H #define org_mitk_example_gui_minimalapplication_Activator_H #include class org_mitk_example_gui_minimalapplication_Activator : public QObject, public ctkPluginActivator { Q_OBJECT +#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) + Q_PLUGIN_METADATA(IID "org_mitk_example_gui_minimalapplication") +#endif Q_INTERFACES(ctkPluginActivator) public: void start(ctkPluginContext* context); void stop(ctkPluginContext* context); }; #endif // org_mitk_example_gui_minimalapplication_Activator_H diff --git a/Examples/Plugins/org.mitk.example.gui.multipleperspectives/src/internal/org_mitk_example_gui_multipleperspectives_Activator.cpp b/Examples/Plugins/org.mitk.example.gui.multipleperspectives/src/internal/org_mitk_example_gui_multipleperspectives_Activator.cpp index a071e49572..a1b6e034ff 100644 --- a/Examples/Plugins/org.mitk.example.gui.multipleperspectives/src/internal/org_mitk_example_gui_multipleperspectives_Activator.cpp +++ b/Examples/Plugins/org.mitk.example.gui.multipleperspectives/src/internal/org_mitk_example_gui_multipleperspectives_Activator.cpp @@ -1,42 +1,44 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "org_mitk_example_gui_multipleperspectives_Activator.h" #include "MultiplePerspectives.h" #include "MinimalPerspective.h" #include "ExtendedPerspective.h" #include "EmptyView1.h" #include "EmptyView2.h" #include void org_mitk_example_gui_multipleperspectives_Activator::start(ctkPluginContext* context) { BERRY_REGISTER_EXTENSION_CLASS(MultiplePerspectives, context) BERRY_REGISTER_EXTENSION_CLASS(MinimalPerspective, context) BERRY_REGISTER_EXTENSION_CLASS(ExtendedPerspective, context) BERRY_REGISTER_EXTENSION_CLASS(EmptyView1, context) BERRY_REGISTER_EXTENSION_CLASS(EmptyView2, context) } void org_mitk_example_gui_multipleperspectives_Activator::stop(ctkPluginContext* context) { Q_UNUSED(context) } -Q_EXPORT_PLUGIN2(org_mitk_example_gui_multipleperspectives, org_mitk_example_gui_multipleperspectives_Activator) +#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) + Q_EXPORT_PLUGIN2(org_mitk_example_gui_multipleperspectives, org_mitk_example_gui_multipleperspectives_Activator) +#endif diff --git a/Examples/Plugins/org.mitk.example.gui.multipleperspectives/src/internal/org_mitk_example_gui_multipleperspectives_Activator.h b/Examples/Plugins/org.mitk.example.gui.multipleperspectives/src/internal/org_mitk_example_gui_multipleperspectives_Activator.h index ed1f4df078..7ee1d5272b 100644 --- a/Examples/Plugins/org.mitk.example.gui.multipleperspectives/src/internal/org_mitk_example_gui_multipleperspectives_Activator.h +++ b/Examples/Plugins/org.mitk.example.gui.multipleperspectives/src/internal/org_mitk_example_gui_multipleperspectives_Activator.h @@ -1,36 +1,39 @@ /*=================================================================== 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 org_mitk_example_gui_multipleperspectives_Activator_H #define org_mitk_example_gui_multipleperspectives_Activator_H #include class org_mitk_example_gui_multipleperspectives_Activator : public QObject, public ctkPluginActivator { Q_OBJECT +#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) + Q_PLUGIN_METADATA(IID "org_mitk_example_gui_multipleperspectives") +#endif Q_INTERFACES(ctkPluginActivator) public: void start(ctkPluginContext* context); void stop(ctkPluginContext* context); }; #endif // org_mitk_example_gui_multipleperspectives_Activator_H diff --git a/Examples/Plugins/org.mitk.example.gui.opencv/src/internal/mitkPluginActivator.cpp b/Examples/Plugins/org.mitk.example.gui.opencv/src/internal/mitkPluginActivator.cpp index 86724180cb..bb64d5ec02 100644 --- a/Examples/Plugins/org.mitk.example.gui.opencv/src/internal/mitkPluginActivator.cpp +++ b/Examples/Plugins/org.mitk.example.gui.opencv/src/internal/mitkPluginActivator.cpp @@ -1,36 +1,38 @@ /*=================================================================== 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 "mitkPluginActivator.h" #include "src/internal/videoplayer/QmitkVideoPlayer.h" #include namespace mitk { void PluginActivator::start(ctkPluginContext* context) { BERRY_REGISTER_EXTENSION_CLASS(QmitkVideoPlayer, context) } void PluginActivator::stop(ctkPluginContext* context) { Q_UNUSED(context) } } -Q_EXPORT_PLUGIN2(org_mitk_gui_qt_examplesopencv, mitk::PluginActivator) +#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) + Q_EXPORT_PLUGIN2(org_mitk_gui_qt_examplesopencv, mitk::PluginActivator) +#endif diff --git a/Examples/Plugins/org.mitk.example.gui.opencv/src/internal/mitkPluginActivator.h b/Examples/Plugins/org.mitk.example.gui.opencv/src/internal/mitkPluginActivator.h index b96fd0fb6e..bb961625ce 100644 --- a/Examples/Plugins/org.mitk.example.gui.opencv/src/internal/mitkPluginActivator.h +++ b/Examples/Plugins/org.mitk.example.gui.opencv/src/internal/mitkPluginActivator.h @@ -1,40 +1,43 @@ /*=================================================================== 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 MITKPLUGINACTIVATOR_H #define MITKPLUGINACTIVATOR_H #include #include namespace mitk { class MITK_LOCAL PluginActivator : public QObject, public ctkPluginActivator { Q_OBJECT - Q_INTERFACES(ctkPluginActivator) +#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) + Q_PLUGIN_METADATA(IID "org_mitk_gui_qt_examplesopencv") +#endif + Q_INTERFACES(ctkPluginActivator) public: void start(ctkPluginContext* context); void stop(ctkPluginContext* context); }; // PluginActivator } #endif // MITKPLUGINACTIVATOR_H diff --git a/Examples/Plugins/org.mitk.example.gui.regiongrowing/src/internal/org_mitk_example_gui_regiongrowing_Activator.cpp b/Examples/Plugins/org.mitk.example.gui.regiongrowing/src/internal/org_mitk_example_gui_regiongrowing_Activator.cpp index a0d3863e2e..d7bd9aae63 100644 --- a/Examples/Plugins/org.mitk.example.gui.regiongrowing/src/internal/org_mitk_example_gui_regiongrowing_Activator.cpp +++ b/Examples/Plugins/org.mitk.example.gui.regiongrowing/src/internal/org_mitk_example_gui_regiongrowing_Activator.cpp @@ -1,38 +1,40 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "org_mitk_example_gui_regiongrowing_Activator.h" #include #include "QmitkRegionGrowingView.h" namespace mitk { void org_mitk_example_gui_regiongrowing_Activator::start(ctkPluginContext* context) { BERRY_REGISTER_EXTENSION_CLASS(QmitkRegionGrowingView, context) } void org_mitk_example_gui_regiongrowing_Activator::stop(ctkPluginContext* context) { Q_UNUSED(context) } } -Q_EXPORT_PLUGIN2(org_mitk_example_gui_regiongrowing, mitk::org_mitk_example_gui_regiongrowing_Activator) +#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) + Q_EXPORT_PLUGIN2(org_mitk_example_gui_regiongrowing, mitk::org_mitk_example_gui_regiongrowing_Activator) +#endif diff --git a/Examples/Plugins/org.mitk.example.gui.regiongrowing/src/internal/org_mitk_example_gui_regiongrowing_Activator.h b/Examples/Plugins/org.mitk.example.gui.regiongrowing/src/internal/org_mitk_example_gui_regiongrowing_Activator.h index 29d561d6f5..37f5aeef32 100644 --- a/Examples/Plugins/org.mitk.example.gui.regiongrowing/src/internal/org_mitk_example_gui_regiongrowing_Activator.h +++ b/Examples/Plugins/org.mitk.example.gui.regiongrowing/src/internal/org_mitk_example_gui_regiongrowing_Activator.h @@ -1,40 +1,43 @@ /*=================================================================== 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 org_mitk_example_gui_regiongrowing_Activator_h #define org_mitk_example_gui_regiongrowing_Activator_h #include namespace mitk { class org_mitk_example_gui_regiongrowing_Activator : public QObject, public ctkPluginActivator { Q_OBJECT +#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) + Q_PLUGIN_METADATA(IID "org_mitk_example_gui_regiongrowing") +#endif Q_INTERFACES(ctkPluginActivator) public: void start(ctkPluginContext* context); void stop(ctkPluginContext* context); }; // org_mitk_example_gui_regiongrowing_Activator } #endif // org_mitk_example_gui_regiongrowing_Activator_h diff --git a/Examples/Plugins/org.mitk.example.gui.selectionservicemitk.views/src/internal/org_mitk_example_gui_selectionservicemitk_views_Activator.cpp b/Examples/Plugins/org.mitk.example.gui.selectionservicemitk.views/src/internal/org_mitk_example_gui_selectionservicemitk_views_Activator.cpp index 6dbb8b0ae1..65547f0103 100644 --- a/Examples/Plugins/org.mitk.example.gui.selectionservicemitk.views/src/internal/org_mitk_example_gui_selectionservicemitk_views_Activator.cpp +++ b/Examples/Plugins/org.mitk.example.gui.selectionservicemitk.views/src/internal/org_mitk_example_gui_selectionservicemitk_views_Activator.cpp @@ -1,38 +1,40 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "org_mitk_example_gui_selectionservicemitk_views_Activator.h" #include "ListenerViewMitk.h" #include "SelectionViewMitk.h" #include void org_mitk_example_gui_selectionservicemitk_views_Activator::start(ctkPluginContext* context) { BERRY_REGISTER_EXTENSION_CLASS(ListenerViewMitk, context) BERRY_REGISTER_EXTENSION_CLASS(SelectionViewMitk, context) } void org_mitk_example_gui_selectionservicemitk_views_Activator::stop(ctkPluginContext* context) { Q_UNUSED(context) } -Q_EXPORT_PLUGIN2(org_mitk_example_gui_selectionservicemitk_views, org_mitk_example_gui_selectionservicemitk_views_Activator) +#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) + Q_EXPORT_PLUGIN2(org_mitk_example_gui_selectionservicemitk_views, org_mitk_example_gui_selectionservicemitk_views_Activator) +#endif diff --git a/Examples/Plugins/org.mitk.example.gui.selectionservicemitk.views/src/internal/org_mitk_example_gui_selectionservicemitk_views_Activator.h b/Examples/Plugins/org.mitk.example.gui.selectionservicemitk.views/src/internal/org_mitk_example_gui_selectionservicemitk_views_Activator.h index fc8d45039c..ad4f34297b 100644 --- a/Examples/Plugins/org.mitk.example.gui.selectionservicemitk.views/src/internal/org_mitk_example_gui_selectionservicemitk_views_Activator.h +++ b/Examples/Plugins/org.mitk.example.gui.selectionservicemitk.views/src/internal/org_mitk_example_gui_selectionservicemitk_views_Activator.h @@ -1,36 +1,39 @@ /*=================================================================== 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 org_mitk_example_gui_selectionservicemitk_views_Activator_H #define org_mitk_example_gui_selectionservicemitk_views_Activator_H #include class org_mitk_example_gui_selectionservicemitk_views_Activator : public QObject, public ctkPluginActivator { Q_OBJECT +#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) + Q_PLUGIN_METADATA(IID "org_mitk_example_gui_selectionservicemitk_views") +#endif Q_INTERFACES(ctkPluginActivator) public: void start(ctkPluginContext* context); void stop(ctkPluginContext* context); }; #endif // org_mitk_example_gui_selectionservicemitk_views_Activator_H diff --git a/Examples/Plugins/org.mitk.example.gui.selectionservicemitk/src/internal/org_mitk_example_gui_selectionservicemitk_Activator.cpp b/Examples/Plugins/org.mitk.example.gui.selectionservicemitk/src/internal/org_mitk_example_gui_selectionservicemitk_Activator.cpp index dd9ce20696..1c25e30bce 100644 --- a/Examples/Plugins/org.mitk.example.gui.selectionservicemitk/src/internal/org_mitk_example_gui_selectionservicemitk_Activator.cpp +++ b/Examples/Plugins/org.mitk.example.gui.selectionservicemitk/src/internal/org_mitk_example_gui_selectionservicemitk_Activator.cpp @@ -1,38 +1,40 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "org_mitk_example_gui_selectionservicemitk_Activator.h" #include "SelectionServiceMitk.h" #include "ExtendedPerspective.h" #include void org_mitk_example_gui_selectionservicemitk_Activator::start(ctkPluginContext* context) { BERRY_REGISTER_EXTENSION_CLASS(SelectionServiceMitk, context) BERRY_REGISTER_EXTENSION_CLASS(ExtendedPerspective, context) } void org_mitk_example_gui_selectionservicemitk_Activator::stop(ctkPluginContext* context) { Q_UNUSED(context) } -Q_EXPORT_PLUGIN2(org_mitk_example_gui_selectionservicemitk, org_mitk_example_gui_selectionservicemitk_Activator) +#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) + Q_EXPORT_PLUGIN2(org_mitk_example_gui_selectionservicemitk, org_mitk_example_gui_selectionservicemitk_Activator) +#endif diff --git a/Examples/Plugins/org.mitk.example.gui.selectionservicemitk/src/internal/org_mitk_example_gui_selectionservicemitk_Activator.h b/Examples/Plugins/org.mitk.example.gui.selectionservicemitk/src/internal/org_mitk_example_gui_selectionservicemitk_Activator.h index e1f807d2ee..eeea2518ca 100644 --- a/Examples/Plugins/org.mitk.example.gui.selectionservicemitk/src/internal/org_mitk_example_gui_selectionservicemitk_Activator.h +++ b/Examples/Plugins/org.mitk.example.gui.selectionservicemitk/src/internal/org_mitk_example_gui_selectionservicemitk_Activator.h @@ -1,36 +1,39 @@ /*=================================================================== 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 org_mitk_example_gui_selectionservicemitk_Activator_H #define org_mitk_example_gui_selectionservicemitk_Activator_H #include class org_mitk_example_gui_selectionservicemitk_Activator : public QObject, public ctkPluginActivator { Q_OBJECT +#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) + Q_PLUGIN_METADATA(IID "org_mitk_example_gui_selectionservicemitk") +#endif Q_INTERFACES(ctkPluginActivator) public: void start(ctkPluginContext* context); void stop(ctkPluginContext* context); }; #endif // org_mitk_example_gui_selectionservicemitk_Activator_H diff --git a/Examples/Plugins/org.mitk.example.gui.selectionserviceqt/src/internal/org_mitk_example_gui_selectionserviceqt_Activator.cpp b/Examples/Plugins/org.mitk.example.gui.selectionserviceqt/src/internal/org_mitk_example_gui_selectionserviceqt_Activator.cpp index 440edb3ab4..33ac2db633 100644 --- a/Examples/Plugins/org.mitk.example.gui.selectionserviceqt/src/internal/org_mitk_example_gui_selectionserviceqt_Activator.cpp +++ b/Examples/Plugins/org.mitk.example.gui.selectionserviceqt/src/internal/org_mitk_example_gui_selectionserviceqt_Activator.cpp @@ -1,41 +1,43 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "org_mitk_example_gui_selectionserviceqt_Activator.h" #include "SelectionServiceQt.h" #include "ExtendedPerspective.h" #include "ListenerView.h" #include "SelectionView.h" #include void org_mitk_example_gui_selectionserviceqt_Activator::start(ctkPluginContext* context) { BERRY_REGISTER_EXTENSION_CLASS(SelectionServiceQt, context) BERRY_REGISTER_EXTENSION_CLASS(ExtendedPerspective, context) BERRY_REGISTER_EXTENSION_CLASS(ListenerView, context) BERRY_REGISTER_EXTENSION_CLASS(SelectionView, context) } void org_mitk_example_gui_selectionserviceqt_Activator::stop(ctkPluginContext* context) { Q_UNUSED(context) } -Q_EXPORT_PLUGIN2(org_mitk_example_gui_selectionserviceqt, org_mitk_example_gui_selectionserviceqt_Activator) +#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) + Q_EXPORT_PLUGIN2(org_mitk_example_gui_selectionserviceqt, org_mitk_example_gui_selectionserviceqt_Activator) +#endif diff --git a/Examples/Plugins/org.mitk.example.gui.selectionserviceqt/src/internal/org_mitk_example_gui_selectionserviceqt_Activator.h b/Examples/Plugins/org.mitk.example.gui.selectionserviceqt/src/internal/org_mitk_example_gui_selectionserviceqt_Activator.h index 63661b8979..a4a00cf7cb 100644 --- a/Examples/Plugins/org.mitk.example.gui.selectionserviceqt/src/internal/org_mitk_example_gui_selectionserviceqt_Activator.h +++ b/Examples/Plugins/org.mitk.example.gui.selectionserviceqt/src/internal/org_mitk_example_gui_selectionserviceqt_Activator.h @@ -1,36 +1,39 @@ /*=================================================================== 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 org_mitk_example_gui_selectionserviceqt_Activator_H #define org_mitk_example_gui_selectionserviceqt_Activator_H #include class org_mitk_example_gui_selectionserviceqt_Activator : public QObject, public ctkPluginActivator { Q_OBJECT +#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) + Q_PLUGIN_METADATA(IID "org_mitk_example_gui_selectionserviceqt") +#endif Q_INTERFACES(ctkPluginActivator) public: void start(ctkPluginContext* context); void stop(ctkPluginContext* context); }; #endif // org_mitk_example_gui_selectionserviceqt_Activator_H diff --git a/Examples/QuickRender/CMakeLists.txt b/Examples/QuickRender/CMakeLists.txt index 0bc5f675a0..ab2111efc6 100644 --- a/Examples/QuickRender/CMakeLists.txt +++ b/Examples/QuickRender/CMakeLists.txt @@ -1,4 +1,4 @@ project(QuickRender) find_package(MITK REQUIRED) -mitk_create_executable(DEPENDS MitkQmlItems) +mitk_create_executable(DEPENDS MitkQmlItems MitkLegacyIO) diff --git a/Modules/AlgorithmsExt/Testing/files.cmake b/Modules/AlgorithmsExt/Testing/files.cmake index 9a9b325349..4423805431 100644 --- a/Modules/AlgorithmsExt/Testing/files.cmake +++ b/Modules/AlgorithmsExt/Testing/files.cmake @@ -1,9 +1,10 @@ set(MODULE_TESTS mitkAutoCropImageFilterTest.cpp mitkBoundingObjectCutterTest.cpp + mitkImageToUnstructuredGridFilterTest.cpp mitkSimpleHistogramTest.cpp ) set(MODULE_CUSTOM_TESTS mitkLabeledImageToSurfaceFilterTest.cpp ) diff --git a/Modules/AlgorithmsExt/Testing/mitkImageToUnstructuredGridFilterTest.cpp b/Modules/AlgorithmsExt/Testing/mitkImageToUnstructuredGridFilterTest.cpp new file mode 100644 index 0000000000..fc27e7a298 --- /dev/null +++ b/Modules/AlgorithmsExt/Testing/mitkImageToUnstructuredGridFilterTest.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 "mitkTestingMacros.h" +#include +#include + +#include + +class mitkImageToUnstructuredGridFilterTestSuite : public mitk::TestFixture +{ + CPPUNIT_TEST_SUITE(mitkImageToUnstructuredGridFilterTestSuite); + MITK_TEST(testImageToUnstructuredGridFilterInitialization); + MITK_TEST(testInput); + MITK_TEST(testUnstructuredGridGeneration); + MITK_TEST(testThreshold); + CPPUNIT_TEST_SUITE_END(); + +private: + + /** Members used inside the different test methods. All members are initialized via setUp().*/ + mitk::Image::Pointer m_BallImage; + +public: + + /** + * @brief Setup Always call this method before each Test-case to ensure correct and new intialization of the used members for a new test case. (If the members are not used in a test, the method does not need to be called). + */ + void setUp() + { + m_BallImage = mitk::IOUtil::LoadImage(GetTestDataFilePath("BallBinary30x30x30.nrrd")); + } + + void testImageToUnstructuredGridFilterInitialization() + { + mitk::ImageToUnstructuredGridFilter::Pointer testFilter = mitk::ImageToUnstructuredGridFilter::New(); + CPPUNIT_ASSERT_MESSAGE("Testing instantiation of test object", testFilter.IsNotNull()); + CPPUNIT_ASSERT_MESSAGE("Testing initialization of threshold member variable",testFilter->GetThreshold() == -0.1); + } + + void testInput() + { + mitk::ImageToUnstructuredGridFilter::Pointer testFilter = mitk::ImageToUnstructuredGridFilter::New(); + testFilter->SetInput(m_BallImage); + CPPUNIT_ASSERT_MESSAGE("Testing set / get input!", testFilter->GetInput() == m_BallImage); + } + + void testUnstructuredGridGeneration() + { + mitk::ImageToUnstructuredGridFilter::Pointer testFilter = mitk::ImageToUnstructuredGridFilter::New(); + testFilter->SetInput(m_BallImage); + testFilter->Update(); + CPPUNIT_ASSERT_MESSAGE("Testing surface generation!", testFilter->GetOutput() != NULL); + } + + void testThreshold() + { + mitk::ImageToUnstructuredGridFilter::Pointer testFilter1 = mitk::ImageToUnstructuredGridFilter::New(); + testFilter1->SetInput(m_BallImage); + testFilter1->Update(); + + int numberOfPoints1 = testFilter1->GetNumberOfExtractedPoints(); + + mitk::ImageToUnstructuredGridFilter::Pointer testFilter2 = mitk::ImageToUnstructuredGridFilter::New(); + testFilter2->SetInput(m_BallImage); + testFilter2->SetThreshold(1.0); + testFilter2->Update(); + + int numberOfPoints2 = testFilter2->GetNumberOfExtractedPoints(); + + CPPUNIT_ASSERT_MESSAGE("Testing Threshold", numberOfPoints1 > numberOfPoints2); + } + +}; + +MITK_TEST_SUITE_REGISTRATION(mitkImageToUnstructuredGridFilter) diff --git a/Modules/AlgorithmsExt/files.cmake b/Modules/AlgorithmsExt/files.cmake index 62667e34bc..b94468babe 100644 --- a/Modules/AlgorithmsExt/files.cmake +++ b/Modules/AlgorithmsExt/files.cmake @@ -1,23 +1,24 @@ set(CPP_FILES mitkAutoCropImageFilter.cpp mitkBoundingObjectCutter.cpp mitkBoundingObjectToSegmentationFilter.cpp mitkGeometryClipImageFilter.cpp mitkHeightFieldSurfaceClipImageFilter.cpp + mitkImageToUnstructuredGridFilter.cpp mitkLabeledImageToSurfaceFilter.cpp mitkMaskAndCutRoiImageFilter.cpp mitkMaskImageFilter.cpp mitkMovieGenerator.cpp mitkNonBlockingAlgorithm.cpp mitkPadImageFilter.cpp mitkPlaneLandmarkProjector.cpp mitkPointLocator.cpp mitkSimpleHistogram.cpp mitkSimpleUnstructuredGridHistogram.cpp ) if(WIN32 AND NOT MINGW) list(APPEND CPP_FILES mitkMovieGeneratorWin32.cpp ) endif() diff --git a/Modules/AlgorithmsExt/mitkImageToUnstructuredGridFilter.cpp b/Modules/AlgorithmsExt/mitkImageToUnstructuredGridFilter.cpp new file mode 100644 index 0000000000..70dd0d8c6f --- /dev/null +++ b/Modules/AlgorithmsExt/mitkImageToUnstructuredGridFilter.cpp @@ -0,0 +1,127 @@ +/*=================================================================== + +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 + +#include +#include +#include + +#include + +#include + + +mitk::ImageToUnstructuredGridFilter::ImageToUnstructuredGridFilter(): +m_NumberOfExtractedPoints(0), +m_Threshold(-0.1) +{ + this->m_UnstructGrid = mitk::UnstructuredGrid::New(); +} + +mitk::ImageToUnstructuredGridFilter::~ImageToUnstructuredGridFilter(){} + +void mitk::ImageToUnstructuredGridFilter::GenerateData() +{ + mitk::UnstructuredGrid::Pointer unstructGrid = this->GetOutput(); + const mitk::Image* image = this->GetInput(); + + if(image == NULL || !image->IsInitialized()) + { + MITK_ERROR << "Wrong input image set" << std::endl; + return; + } + + m_Geometry = image->GetGeometry(); + + m_NumberOfExtractedPoints = 0; + + AccessByItk(image, ExtractPoints) +} + +void mitk::ImageToUnstructuredGridFilter::SetInput(const mitk::Image* image) +{ + this->ProcessObject::SetNthInput(0, const_cast< mitk::Image* >( image ) ); +} + + +const mitk::Image* mitk::ImageToUnstructuredGridFilter::GetInput(void) +{ + if (this->GetNumberOfInputs() < 1) + { + MITK_ERROR << "No input set" << std::endl; + return 0; + } + + return static_cast( this->ProcessObject::GetInput(0) ); +} + +template +void mitk::ImageToUnstructuredGridFilter:: + ExtractPoints(const itk::Image* image) +{ + typedef itk::Image InputImageType; + typename itk::ImageRegionConstIterator it(image, image->GetRequestedRegion()); + + vtkSmartPointer points = vtkSmartPointer::New(); + + it.GoToBegin(); + while( !it.IsAtEnd() ) + { + if(it.Get() > m_Threshold) + { + mitk::Point3D imagePoint; + mitk::Point3D worldPoint; + + imagePoint[0] = it.GetIndex()[0]; + imagePoint[1] = it.GetIndex()[1]; + imagePoint[2] = it.GetIndex()[2]; + + m_Geometry->IndexToWorld(imagePoint, worldPoint); + + points->InsertNextPoint(worldPoint[0],worldPoint[1],worldPoint[2]); + m_NumberOfExtractedPoints++; + } + ++it; + } + + vtkSmartPointer vtkUnstructGrid = vtkSmartPointer::New(); + vtkUnstructGrid->SetPoints(points); + + m_UnstructGrid->SetVtkUnstructuredGrid(vtkUnstructGrid); +} + +void mitk::ImageToUnstructuredGridFilter::SetThreshold(double threshold) +{ + this->m_Threshold = threshold; +} + +double mitk::ImageToUnstructuredGridFilter::GetThreshold() +{ + return this->m_Threshold; +} + + +void mitk::ImageToUnstructuredGridFilter::GenerateOutputInformation() +{ + mitk::Image::ConstPointer inputImage = this->GetInput(); + + m_UnstructGrid = this->GetOutput(); + + itkDebugMacro(<<"GenerateOutputInformation()"); + + if(inputImage.IsNull()) return; +} diff --git a/Modules/AlgorithmsExt/mitkImageToUnstructuredGridFilter.h b/Modules/AlgorithmsExt/mitkImageToUnstructuredGridFilter.h new file mode 100644 index 0000000000..0d1ef51316 --- /dev/null +++ b/Modules/AlgorithmsExt/mitkImageToUnstructuredGridFilter.h @@ -0,0 +1,107 @@ +/*=================================================================== + +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 _MITKIMAGETOUNSTRUCTUREDGRIDFILTER_h__ +#define _MITKIMAGETOUNSTRUCTUREDGRIDFILTER_h__ + +#include + +#include + +#include +#include +#include + + +namespace mitk { + /** + * @brief Converts an Image into an UnstructuredGrid represented by Points. + * The filter uses a Threshold to extract every pixel, with value higher than + * the threshold, as point. + * If no threshold is set, every pixel is extracted as a point. + */ + + class MitkAlgorithmsExt_EXPORT ImageToUnstructuredGridFilter + : public UnstructuredGridSource + { + public: + + mitkClassMacro(ImageToUnstructuredGridFilter, UnstructuredGridSource) + itkFactorylessNewMacro(Self) + itkCloneMacro(Self) + + /** This method is called by Update(). */ + virtual void GenerateData(); + + /** Initializes the output information */ + virtual void GenerateOutputInformation(); + + /** Returns a const reference to the input image */ + const mitk::Image* GetInput(void); + + /** Set the source image. As input every mitk 3D image can be used. */ + using itk::ProcessObject::SetInput; + virtual void SetInput(const mitk::Image *image); + + /** + * Set the threshold for extracting points. Every pixel, which value + * is higher than this value, will be a point. + */ + void SetThreshold(double threshold); + + /** Returns the threshold */ + double GetThreshold(); + + itkGetMacro(NumberOfExtractedPoints, int) + + protected: + + /** Constructor */ + ImageToUnstructuredGridFilter(); + + /** Destructor */ + virtual ~ImageToUnstructuredGridFilter(); + + /** + * Access method for extracting the points from the input image + */ + template + void ExtractPoints(const itk::Image* image); + + private: + + /** + * Geometry of the input image, needed to tranform the image points + * into world points + */ + mitk::BaseGeometry* m_Geometry; + + /** The number of points extracted by the filter */ + int m_NumberOfExtractedPoints; + + /** Threshold for extracting the points */ + double m_Threshold; + + /** The output of the filter, which contains the extracted points */ + mitk::UnstructuredGrid::Pointer m_UnstructGrid; + + }; + +} // namespace mitk + +#endif //_MITKIMAGETOUNSTRUCTUREDGRIDFILTER_h__ + + diff --git a/Modules/DeformableRegistrationUI/QmitkBSplineRegistrationView.cpp b/Modules/DeformableRegistrationUI/QmitkBSplineRegistrationView.cpp index 4b9674049c..f0b4e45efb 100644 --- a/Modules/DeformableRegistrationUI/QmitkBSplineRegistrationView.cpp +++ b/Modules/DeformableRegistrationUI/QmitkBSplineRegistrationView.cpp @@ -1,216 +1,216 @@ /*=================================================================== 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 #include #include #include #include #include #include "itkRegularStepGradientDescentOptimizer.h" #include #include #include "QmitkBSplineRegistrationView.h" #include "ui_QmitkBSplineRegistrationViewControls.h" #include "mitkBSplineRegistration.h" #include "itkImageFileReader.h" typedef itk::Vector< float, 3 > VectorType; typedef itk::Image< VectorType, 3 > DeformationFieldType; typedef itk::ImageFileReader< DeformationFieldType > ImageReaderType; QmitkBSplineRegistrationView::QmitkBSplineRegistrationView(QWidget* parent, Qt::WindowFlags f ) : QWidget( parent, f ), m_FixedNode(NULL), m_MovingNode(NULL) { m_Controls.setupUi(parent); QObject::connect( (QObject*)(m_Controls.m_PrintDeformField), SIGNAL(clicked()), (QObject*) this, SLOT(PrintDeformationField()) ); QObject::connect( (QObject*)(m_Controls.m_BrowseDeformationField), SIGNAL(clicked()), (QObject*) this, SLOT(SelectDeformationField()) ); connect( m_Controls.m_OptimizerSelector, SIGNAL(activated(int)), m_Controls.m_OptimizerWidgetStack, SLOT(setCurrentIndex(int))); connect( m_Controls.m_OptimizerSelector, SIGNAL(activated(int)), this, SLOT(OptimizerSelected(int))); } QmitkBSplineRegistrationView::~QmitkBSplineRegistrationView() { } void QmitkBSplineRegistrationView::OptimizerSelected(int optimizer) { HideAllOptimizerFrames(); if(optimizer == 0) { m_Controls.m_LBFGSFrame->show(); } else if(optimizer == 1) { m_Controls.m_GradientDescentFrame->show(); } } void QmitkBSplineRegistrationView::HideAllOptimizerFrames() { m_Controls.m_LBFGSFrame->hide(); m_Controls.m_GradientDescentFrame->hide(); } void QmitkBSplineRegistrationView::SelectDeformationField() { // SELECT FOLDER DIALOG QFileDialog* w = new QFileDialog( this, "Select Deformation Field" ); w->setFileMode( QFileDialog::ExistingFiles ); - w->setFilter( "Images (*.mhd)" ); + w->setNameFilter( "Images (*.mhd)" ); w->setDirectory("G:\\home\\vanbrugg\\testimages\\deformable"); // RETRIEVE SELECTION if ( w->exec() != QDialog::Accepted ) { return; cout << "Failed to load" << endl; } QStringList filenames = w->selectedFiles(); QStringList::Iterator it = filenames.begin(); if( it != filenames.end() ) { std::string filename = ( *it ).toStdString(); ++it; QString qStr = QString( filename.c_str() ); m_Controls.m_DeformationField->setText(qStr); } } void QmitkBSplineRegistrationView::PrintDeformationField() { ImageReaderType::Pointer reader = ImageReaderType::New(); reader->SetFileName( m_Controls.m_DeformationField->text().toStdString() ); reader->Update(); DeformationFieldType::Pointer deformationField = reader->GetOutput(); typedef itk::ImageRegionIterator IteratorType; IteratorType deformIter(deformationField, deformationField->GetRequestedRegion()); for(deformIter.GoToBegin(); !deformIter.IsAtEnd(); ++deformIter) { std::cout << deformIter.Get() << std::endl; } } void QmitkBSplineRegistrationView::CalculateTransformation() { if (m_FixedNode != NULL && m_MovingNode != NULL) { mitk::Image::Pointer fimage = dynamic_cast(m_FixedNode->GetData()); mitk::Image::Pointer mimage = dynamic_cast(m_MovingNode->GetData()); mitk::BSplineRegistration::Pointer registration = mitk::BSplineRegistration::New(); registration->SetSaveResult(false); registration->SetReferenceImage(fimage); registration->SetInput(mimage); // Read out optimizer parameters from the interface setOptimizerParameters(); registration->SetNumberOfGridPoints( m_Controls.m_NumberOfGridNodes->text().toInt() ); registration->SetOptimizerParameters(m_OptimizerParameters); registration->SetUpdateInputImage(true); if(m_Controls.m_SaveDeformFieldCheck->isChecked()) { // Set some parameters to save the deformation field registration->SetSaveDeformationField(true); registration->SetDeformationFileName( m_Controls.m_DeformationField->text().toStdString() ); } try { registration->Update(); } catch (itk::ExceptionObject& excpt) { QMessageBox::information( this, "Registration exception", excpt.GetDescription(), QMessageBox::Ok ); } mitk::Image::Pointer image = registration->GetOutput(); if (image.IsNotNull()) { m_MovingNode->SetData(image); mitk::LevelWindowProperty::Pointer levWinProp = mitk::LevelWindowProperty::New(); mitk::LevelWindow levelWindow; levelWindow.SetAuto( image ); levWinProp->SetLevelWindow(levelWindow); m_MovingNode->GetPropertyList()->SetProperty("levelwindow",levWinProp); } mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } } void QmitkBSplineRegistrationView::setOptimizerParameters() { m_OptimizerParameters = mitk::OptimizerParameters::New(); if(m_Controls.m_OptimizerSelector->currentText() == "LBFGSOptimizer") { m_OptimizerParameters->SetOptimizer(mitk::OptimizerParameters::LBFGSOPTIMIZER); m_OptimizerParameters->SetGradientConvergenceToleranceLBFGS( m_Controls.m_GradConvTolerance->text().toFloat() ); m_OptimizerParameters->SetLineSearchAccuracyLBFGS( m_Controls.m_LineSearchAccuracy->text().toFloat() ); m_OptimizerParameters->SetDefaultStepLengthLBFGS( m_Controls.m_DefaultStepLength->text().toFloat() ); m_OptimizerParameters->SetNumberOfIterationsLBFGS( m_Controls.m_FunctionEvaluations->text().toInt() ); } else if(m_Controls.m_OptimizerSelector->currentText() == "Gradient Descent") { m_OptimizerParameters->SetOptimizer(mitk::OptimizerParameters::GRADIENTDESCENTOPTIMIZER); m_OptimizerParameters->SetLearningRateGradientDescent( m_Controls.m_LearningRateGradientDescent->text().toFloat() ); m_OptimizerParameters->SetNumberOfIterationsGradientDescent (m_Controls.m_NumberOfIterationsGradientDescent->text().toInt() ); } } void QmitkBSplineRegistrationView::SetFixedNode( mitk::DataNode * fixedNode ) { m_FixedNode = fixedNode; } void QmitkBSplineRegistrationView::SetMovingNode( mitk::DataNode * movingNode ) { m_MovingNode = movingNode; } diff --git a/Modules/DicomUI/CMakeLists.txt b/Modules/DicomUI/CMakeLists.txt index fac3a66d09..e0fcbef18f 100644 --- a/Modules/DicomUI/CMakeLists.txt +++ b/Modules/DicomUI/CMakeLists.txt @@ -1,7 +1,7 @@ include_directories(${CTK_INCLUDE_DIRS}) MITK_CREATE_MODULE( DEPENDS MitkCore - PACKAGE_DEPENDS CTK|CTKDICOMWidgets Qt4|QtGui+QtSql + PACKAGE_DEPENDS CTK|CTKDICOMWidgets Qt4|QtGui+QtSql Qt5|OpenGL+Sql+Widgets+Xml EXPORT_DEFINE MITK_DICOMUI_EXPORT ) diff --git a/Modules/DiffusionImaging/DiffusionCore/CMakeLists.txt b/Modules/DiffusionImaging/DiffusionCore/CMakeLists.txt index c6bbc6b951..b0ee596bbe 100644 --- a/Modules/DiffusionImaging/DiffusionCore/CMakeLists.txt +++ b/Modules/DiffusionImaging/DiffusionCore/CMakeLists.txt @@ -1,15 +1,19 @@ # With apple gcc 4.2.1 the following waring leads to an build error if boost is enabled if(APPLE) mitkFunctionCheckCAndCXXCompilerFlags("-Wno-error=empty-body" CMAKE_C_FLAGS CMAKE_CXX_FLAGS) endif() MITK_CREATE_MODULE( SUBPROJECTS MITK-DTI INCLUDE_DIRS Algorithms Algorithms/Reconstruction Algorithms/Registration Algorithms/Reconstruction/MultishellProcessing DicomImport IODataStructures/DiffusionWeightedImages IODataStructures/QBallImages IODataStructures/TensorImages IODataStructures Rendering ${CMAKE_CURRENT_BINARY_DIR} DEPENDS MitkMapperExt MitkPlanarFigure MitkImageExtraction MitkSceneSerializationBase MitkDICOMReader PACKAGE_DEPENDS VTK|vtkFiltersProgrammable ITK|ITKDistanceMap+ITKRegistrationCommon+ITKLabelVoting+ITKVTK Boost ITK|ITKMetricsv4+ITKRegistrationMethodsv4 WARNINGS_AS_ERRORS ) +if(MSVC) + mitkFunctionCheckCAndCXXCompilerFlags("/wd4005" CMAKE_C_FLAGS CMAKE_CXX_FLAGS) +endif() + add_subdirectory(Testing) diff --git a/Modules/GPGPU/CMakeLists.txt b/Modules/GPGPU/CMakeLists.txt index 77e7253458..794102e1e4 100644 --- a/Modules/GPGPU/CMakeLists.txt +++ b/Modules/GPGPU/CMakeLists.txt @@ -1,19 +1,19 @@ if(APPLE) message(STATUS "Module GPGPU is not ported to MacOS yet") else(APPLE) set(package_deps) if(UNIX) list(APPEND package_deps X11) endif() MITK_CREATE_MODULE( # INCLUDE_DIRS . DEPENDS MitkCore - PACKAGE_DEPENDS ${package_deps} GLEW Qt4|QtGui + PACKAGE_DEPENDS ${package_deps} GLEW Qt4|QtGui Qt5|Widgets EXPORT_DEFINE GPGPU_DLL_API WARNINGS_AS_ERRORS ) endif(APPLE) diff --git a/Modules/GPGPU/mitkGPGPU.cpp b/Modules/GPGPU/mitkGPGPU.cpp index 56de055027..abb8c2320c 100644 --- a/Modules/GPGPU/mitkGPGPU.cpp +++ b/Modules/GPGPU/mitkGPGPU.cpp @@ -1,627 +1,627 @@ /*=================================================================== 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 #include #include "mitkGPGPU.h" #include #define GPGPU_INFO MITK_INFO("mitk.gpgpu") #define GPGPU_ERROR MITK_ERROR("mitk.gpgpu") #define GPGPU_CHECKGLERR MITK_ERROR(glGetError()!=GL_NO_ERROR)("mitk.gpgpu") << "GL ERROR @ " #define OPERATING_TEXTURE GL_TEXTURE15 static GLint convertTextureFormatToInternalFormatGL(mitk::GPGPU::TextureFormat format) { switch(format) { case mitk::GPGPU::FLOAT32_LUMINANCE: return GL_LUMINANCE_FLOAT32_ATI; case mitk::GPGPU::FLOAT32_LUMINANCE_ALPHA: return GL_LUMINANCE_ALPHA_FLOAT32_ATI; case mitk::GPGPU::FLOAT32_RGBA: return GL_RGBA32F_ARB; case mitk::GPGPU::UINT8_RGBA: return GL_RGBA8; } return 0; } static GLint convertTextureFormatToFormatGL(mitk::GPGPU::TextureFormat format) { switch(format) { case mitk::GPGPU::FLOAT32_LUMINANCE: return GL_LUMINANCE; case mitk::GPGPU::FLOAT32_LUMINANCE_ALPHA: return GL_LUMINANCE_ALPHA; case mitk::GPGPU::FLOAT32_RGBA: return GL_RGBA; case mitk::GPGPU::UINT8_RGBA: return GL_RGBA; } return 0; } static GLint convertTextureFormatToTypeGL(mitk::GPGPU::TextureFormat format) { switch(format) { case mitk::GPGPU::FLOAT32_LUMINANCE: return GL_FLOAT; case mitk::GPGPU::FLOAT32_LUMINANCE_ALPHA: return GL_FLOAT; case mitk::GPGPU::FLOAT32_RGBA: return GL_FLOAT; case mitk::GPGPU::UINT8_RGBA: return GL_UNSIGNED_BYTE; } return 0; } int mitk::GPGPU::Texture::GetWidth(){return myWidth;} int mitk::GPGPU::Texture::GetHeigth(){return myHeight;} int mitk::GPGPU::Texture::GetDepth(){return myDepth;} mitk::GPGPU::Texture::Texture(mitk::GPGPU::TextureFormat format,int width,int height,int depth) { if(depth==0) glTarget=GL_TEXTURE_2D; else glTarget=GL_TEXTURE_3D; myFormat=format; myWidth=width; myHeight=height; myDepth=depth; GLuint handle; glGenTextures(1,&handle); glTextureHandle = handle; glActiveTexture(OPERATING_TEXTURE); glBindTexture(glTarget,glTextureHandle); GPGPU_CHECKGLERR << "allocating texture handle"; if(glTarget==GL_TEXTURE_2D) { glTexImage2D(GL_TEXTURE_2D,0,convertTextureFormatToInternalFormatGL(myFormat),width,height,0,GL_RGBA,GL_UNSIGNED_BYTE,0); // glGenerateMipmap(GL_TEXTURE_2D); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_R,GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST); } else { glTexImage3D(GL_TEXTURE_3D,0,convertTextureFormatToInternalFormatGL(myFormat),width,height,depth,0,GL_RGBA,GL_UNSIGNED_BYTE,0); // glGenerateMipmap(GL_TEXTURE_3D); glTexParameteri(GL_TEXTURE_3D,GL_TEXTURE_WRAP_R,GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_3D,GL_TEXTURE_WRAP_S,GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_3D,GL_TEXTURE_WRAP_T,GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_3D,GL_TEXTURE_MIN_FILTER,GL_NEAREST); glTexParameteri(GL_TEXTURE_3D,GL_TEXTURE_MAG_FILTER,GL_NEAREST); } GPGPU_CHECKGLERR << "declaring texture format&dimensions"; glGenFramebuffers(1,&handle); glFBOHandle = handle; GPGPU_CHECKGLERR << "allocating framebuffer object"; } mitk::GPGPU::Texture::~Texture() { GLuint handle; handle=glFBOHandle; glDeleteFramebuffers(1,&handle); GPGPU_CHECKGLERR << "deleting framebufferobject"; handle=glTextureHandle; glDeleteTextures(1,&handle); GPGPU_CHECKGLERR << "deleting texture handle"; } void mitk::GPGPU::Texture::ActivateAsSource(int unit) { glActiveTexture(GL_TEXTURE0 + unit); glBindTexture(glTarget,glTextureHandle); GPGPU_CHECKGLERR << "binding texture to unit"; } void mitk::GPGPU::Texture::ActivateAsDestination() { static GLenum buffers[5][4] = { { GL_NONE, GL_NONE, GL_NONE, GL_NONE }, { GL_COLOR_ATTACHMENT0, GL_NONE, GL_NONE, GL_NONE }, { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, GL_NONE, GL_NONE }, { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2, GL_NONE }, { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2, GL_COLOR_ATTACHMENT3 }, }; glBindFramebuffer( GL_FRAMEBUFFER, glFBOHandle ); glDrawBuffers(4, buffers[1]); glFramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, glTarget,glTextureHandle,0); GPGPU_CHECKGLERR << "associating texture to framebufferobject"; int error = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); switch(error) { case GL_FRAMEBUFFER_COMPLETE_EXT: break; case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT: GPGPU_ERROR << "Incomplete attachment\n";break; case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT: GPGPU_ERROR << "Missing attachment\n";break; case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT: GPGPU_ERROR << "Incomplete dimensions\n";break; case GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT: GPGPU_ERROR << "Incomplete formats\n";break; case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT: GPGPU_ERROR << "Incomplete draw buffer\n";break; case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT: GPGPU_ERROR << "Incomplete read buffer\n";break; case GL_FRAMEBUFFER_UNSUPPORTED_EXT: GPGPU_ERROR << "Framebufferobjects unsupported\n";break; default: GPGPU_ERROR << "unknown framebuffer status\n";break; } glViewport(0,0,myWidth,myHeight); GPGPU_CHECKGLERR << "setting viewport"; } void mitk::GPGPU::Texture::Upload(TextureFormat inputformat,const void *src) { glActiveTexture(OPERATING_TEXTURE); glBindTexture(glTarget,glTextureHandle); if(glTarget==GL_TEXTURE_2D) { glTexSubImage2D(GL_TEXTURE_2D,0,0,0,myWidth,myHeight,convertTextureFormatToFormatGL(inputformat),convertTextureFormatToTypeGL(inputformat),src); } else { glTexSubImage3D(GL_TEXTURE_3D,0,0,0,0,myWidth,myHeight,myDepth,convertTextureFormatToFormatGL(inputformat),convertTextureFormatToTypeGL(inputformat),src); } GPGPU_CHECKGLERR << "texture upload to gpu"; } void mitk::GPGPU::Texture::Download(TextureFormat inputformat,void *dst) { glActiveTexture(OPERATING_TEXTURE); glBindTexture(glTarget,glTextureHandle); if(glTarget==GL_TEXTURE_2D) { glGetTexImage( GL_TEXTURE_2D,0,convertTextureFormatToFormatGL(inputformat),convertTextureFormatToTypeGL(inputformat),dst); GPGPU_CHECKGLERR << "texture download to cpu"; } else { } } static char stubVertexShader[] = "void main() { gl_Position = vec4( 2*gl_Vertex.xy-1,0,1 ); }\n"; mitk::GPGPU::Shader::Shader(char *source) { //std::cout << "compiling shader:\n" << source << std::endl; glHandleVertex = glCreateShader(GL_VERTEX_SHADER); glHandleFragment = glCreateShader(GL_FRAGMENT_SHADER); glHandleProgram = glCreateProgram(); GLchar *src[2]; src[0] = stubVertexShader; src[1] = 0; glShaderSource(glHandleVertex,1,(const GLchar **)src,0); src[0] = source; src[1] = 0; glShaderSource(glHandleFragment,1,(const GLchar **)src,0); bool failed=false; GLint _sv,_sf,_sl; glCompileShader( glHandleVertex ); GPGPU_CHECKGLERR << "compiling vertex shader"; glGetShaderiv( glHandleVertex, GL_COMPILE_STATUS, &_sv); if( !_sv) { GPGPU_ERROR << "vertex shader compilation failed\n"; failed=true; } glCompileShader( glHandleFragment ); GPGPU_CHECKGLERR << "compiling fragment shader"; glGetShaderiv( glHandleFragment, GL_COMPILE_STATUS, &_sf); if( !_sf) { GPGPU_ERROR << "fragment shader compilation failed\n"; failed=true; } glAttachShader( glHandleProgram,glHandleVertex ); glAttachShader( glHandleProgram,glHandleFragment ); glLinkProgram( glHandleProgram ); GPGPU_CHECKGLERR << "linking shader program"; glGetProgramiv( glHandleProgram, GL_LINK_STATUS, &_sl); if( !_sl) { GPGPU_ERROR << "shader linkage failed\n"; failed=true; } if(failed) { int infologLength = 0; int charsWritten = 0; char *infoLog; glGetProgramiv(glHandleProgram, GL_INFO_LOG_LENGTH,&infologLength); if (infologLength > 0) { infoLog = (char *)malloc(infologLength); glGetProgramInfoLog(glHandleProgram, infologLength, &charsWritten, infoLog); GPGPU_ERROR << "SHADER CREATION FAILED INFOLOG:\n" << infoLog; free(infoLog); } } } mitk::GPGPU::Shader::~Shader() { glDeleteProgram( glHandleProgram); glDeleteShader( glHandleVertex ); glDeleteShader( glHandleFragment ); } void mitk::GPGPU::Shader::Activate() { glUseProgram( glHandleProgram ); GPGPU_CHECKGLERR << "activating shader"; } int mitk::GPGPU::Shader::GetUniformLocation(char *name) { return glGetUniformLocation(glHandleProgram,name); } void mitk::GPGPU::Shader::SetUniform(char *name,int i0) { glUniform1i( GetUniformLocation(name) , i0); GPGPU_CHECKGLERR << "setting uniform"; } void mitk::GPGPU::Shader::SetUniform(char *name,int i0,int i1) { GLint i[2]; i[0]=i0; i[1]=i1; glUniform2iv( GetUniformLocation(name) , 1 , i ); GPGPU_CHECKGLERR << "setting uniform"; } void mitk::GPGPU::Shader::SetUniform(char *name,int i0,int i1,int i2) { GLint i[3]; i[0]=i0; i[1]=i1; i[2]=i2; glUniform3iv( GetUniformLocation(name) , 1 , i ); GPGPU_CHECKGLERR << "setting uniform"; } void mitk::GPGPU::Shader::SetUniform(char *name,int i0,int i1,int i2,int i3) { GLint i[4]; i[0]=i0; i[1]=i1; i[2]=i2; i[3]=i3; glUniform4iv( GetUniformLocation(name) , 1 , i ); GPGPU_CHECKGLERR << "setting uniform"; } void mitk::GPGPU::Shader::SetUniform(char *name,float i0) { GLint location = GetUniformLocation(name); glUniform1f(location,i0); GPGPU_CHECKGLERR << "setting uniform"; } void mitk::GPGPU::Shader::SetUniform(char *name,float i0,float i1) { GLfloat i[2]; i[0]=i0; i[1]=i1; glUniform2fv(GetUniformLocation(name),1,i); GPGPU_CHECKGLERR << "setting uniform"; } void mitk::GPGPU::Shader::SetUniform(char *name,float i0,float i1,float i2) { GLfloat i[3]; i[0]=i0; i[1]=i1; i[2]=i2; glUniform3fv(GetUniformLocation(name),1,i); GPGPU_CHECKGLERR << "setting uniform"; } void mitk::GPGPU::Shader::SetUniform(char *name,float i0,float i1,float i2,float i3) { GLfloat i[4]; i[0]=i0; i[1]=i1; i[2]=i2; i[3]=i3; glUniform4fv(GetUniformLocation(name),1,i); GPGPU_CHECKGLERR << "setting uniform"; } #ifdef _WIN32 LRESULT CALLBACK MainWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { switch(msg) { case WM_CLOSE: DestroyWindow(hwnd); break; case WM_DESTROY: PostQuitMessage(0); break; default: return DefWindowProc(hwnd, msg, wParam, lParam); } return 0; } #endif mitk::GPGPU::GPGPU() { #ifdef _WIN32 /* WNDCLASSEX wcx; // Fill in the window class structure with parameters // that describe the main window. wcx.cbSize = sizeof(wcx); // size of structure wcx.style = CS_HREDRAW | CS_VREDRAW; // redraw if size changes wcx.lpfnWndProc = MainWndProc; // points to window procedure wcx.cbClsExtra = 0; // no extra class memory wcx.cbWndExtra = 0; // no extra window memory wcx.hInstance = GetModuleHandle(NULL); // handle to inst ance wcx.hIcon = LoadIcon(NULL, IDI_APPLICATION); // predefined app. icon wcx.hCursor = LoadCursor(NULL, IDC_ARROW); // predefined arrow wcx.hbrBackground = NULL; // white background brush wcx.lpszMenuName = (LPCSTR) "MainMenu"; // name of menu resource wcx.lpszClassName = (LPCSTR) "MainWClass"; // name of window class wcx.hIconSm = LoadIcon(NULL, IDI_APPLICATION); // Register the window class. if(!RegisterClassEx(&wcx)) std::cout << "failed registering window class\n"; HWND desktopWindow=CreateWindowEx( WS_EX_CLIENTEDGE, (LPCSTR)"MainWClass", (LPCSTR)"Anatomy of a Window", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 240, 120, NULL, NULL, GetModuleHandle(NULL), NULL); windowHandle = desktopWindow; ShowWindow(desktopWindow, SW_RESTORE); if(desktopWindow==0) std::cout << "failed creating window\n"; */ - HWND desktopWindow=QApplication::topLevelWidgets().at(0)->winId(); + HWND desktopWindow= (HWND)QApplication::topLevelWidgets().at(0)->winId(); windowsContext = GetDC(desktopWindow); if(windowsContext==0) std::cout << "failed getting window device context\n"; static PIXELFORMATDESCRIPTOR pfd =// pfd Tells Windows How We Want Things To Be { sizeof(PIXELFORMATDESCRIPTOR), // Size Of This Pixel Format Descriptor 1, // Version Number PFD_DRAW_TO_WINDOW | // Format Must Support Window PFD_SUPPORT_OPENGL | // Format Must Support OpenGL PFD_DOUBLEBUFFER | PFD_SWAP_EXCHANGE , // Must Support Double Buffering PFD_TYPE_RGBA, // Request An RGBA Format 24, // Select Our Color Depth 0, 0, 0, 0, 0, 0, // Color Bits Ignored if(openGLContext==0) 0, // No Alpha Buffer 0, // Shift Bit Ignored 0, // No Accumulation Buffer 0, 0, 0, 0, // Accumulation Bits Ignored 0, // 16Bit Z-Buffer (Depth Buffer) 0, // No Stencil Buffer 0, // No Auxiliary Buffer PFD_MAIN_PLANE, // Main Drawing Layer 0, // Reserved 0, 0, 0 // Layer Masks Ignored }; // Sonstiges einstellen int iFormat = ChoosePixelFormat(windowsContext,&pfd); SetPixelFormat(windowsContext,iFormat,&pfd); openGLContext = wglCreateContext(windowsContext); int errw=GetLastError(); if(openGLContext==0) std::cout << "failed creating openGL context "<winId(); GPGPU_ERROR( !GLX_drawable ) << "cant get toplevel widget from QT"; static int visAttributes[] = { GLX_RGBA, GLX_RED_SIZE, 1, GLX_GREEN_SIZE, 1, GLX_BLUE_SIZE, 1, GLX_DOUBLEBUFFER, None }; XVisualInfo *visinfo = glXChooseVisual(X_display, 0, visAttributes); GPGPU_ERROR(!visinfo) << "Unable to choose specified visual!"; openGLContext = glXCreateContext(X_display, visinfo, 0, true); if(visinfo) XFree(visinfo); GPGPU_ERROR(!openGLContext) << "cant create GLX context"; #endif Activate(); GPGPU_INFO << "initializing glew"; int err=glewInit(); GPGPU_CHECKGLERR << "initializing glew"; GPGPU_ERROR(GLEW_OK != err) << "glewInit() fails with " << err << " as text: " << glewGetErrorString(err); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(0,1,0,1,-1,1); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); GPGPU_CHECKGLERR << "intializing projection&modelview matrix"; glDisable(GL_CULL_FACE); glShadeModel(GL_SMOOTH); // Enable Smooth Shading glClearColor(0.0f, 0.0f, 0.0f, 0.0f); // Black Background glClearDepth(1.0f); // Depth Buffer Setup glDisable(GL_DEPTH_TEST); // Enables Depth Testing glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // Really Nice Perspective Calculations glHint(GL_TEXTURE_COMPRESSION_HINT, GL_NICEST); glDepthMask(false); GPGPU_CHECKGLERR << "setting up openGL context"; } mitk::GPGPU::~GPGPU() { #ifdef _WIN32 wglDeleteContext( openGLContext ); #else if(openGLContext) glXDestroyContext(X_display,openGLContext); if(X_display) XCloseDisplay(X_display); #endif } void mitk::GPGPU::Activate() { #ifdef _WIN32 wglMakeCurrent(windowsContext,openGLContext); #else glXMakeCurrent(X_display, GLX_drawable, openGLContext); #endif GPGPU_CHECKGLERR << "activating openGL context"; } void mitk::GPGPU::Deactivate() { } void mitk::GPGPU::Run() { glBegin( GL_TRIANGLE_STRIP ); glVertex2f( 0,0 ); glVertex2f( 0,1 ); glVertex2f( 1,0 ); glVertex2f( 1,1 ); glEnd(); GPGPU_CHECKGLERR << "running a shader"; } void mitk::GPGPU::Run(float start,float end) { glBegin( GL_TRIANGLE_STRIP ); glVertex2f( 0,start ); glVertex2f( 0,end ); glVertex2f( 1,start ); glVertex2f( 1,end ); glEnd(); GPGPU_CHECKGLERR << "running a shader"; } diff --git a/Modules/IGTUI/Qmitk/QmitkNDIToolDelegate.cpp b/Modules/IGTUI/Qmitk/QmitkNDIToolDelegate.cpp index 6c04598e97..f6ca846c21 100644 --- a/Modules/IGTUI/Qmitk/QmitkNDIToolDelegate.cpp +++ b/Modules/IGTUI/Qmitk/QmitkNDIToolDelegate.cpp @@ -1,214 +1,214 @@ /*=================================================================== 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 "QmitkNDIToolDelegate.h" #include #include #include #include #include "QmitkEnums.h" #include "QmitkDataStorageComboBox.h" #include "QmitkCustomVariants.h" #include "mitkDataStorage.h" #include "mitkNodePredicateBase.h" #include "QmitkDataStorageComboBox.h" #include "mitkNDIPassiveTool.h" Q_DECLARE_METATYPE(mitk::NDIPassiveTool*) QmitkNDIToolDelegate::QmitkNDIToolDelegate(QObject * parent) : QStyledItemDelegate(parent), m_Types(), m_DataStorage(NULL), m_Predicate(NULL), m_TagProperty(NULL), m_TagPropertyName() { } QWidget* QmitkNDIToolDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const { if (index.isValid() == false) return QStyledItemDelegate::createEditor(parent, option, index); switch (index.column()) { case SROMCol: { return new QLabel("", parent); } case TypeCol: { QComboBox* c = new QComboBox(parent); c->addItems(m_Types); return c; } case NodeCol: { return new QmitkDataStorageComboBox(m_DataStorage, m_Predicate, parent); } case IndexCol: case NameCol: case StatusCol: default: return QStyledItemDelegate::createEditor(parent, option, index); } } void QmitkNDIToolDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const { if (index.isValid() == false) return; switch (index.column()) { case SROMCol: { QLabel* l = qobject_cast(editor); if (l->text().isEmpty()) { - QString fileName = qVariantValue(index.data(/*mitk::FileNameRole*/)); + QString fileName = index.data(/*mitk::FileNameRole*/).value(); fileName = QFileDialog::getOpenFileName(editor, "Open SROM file", fileName, "SROM files (*.rom)"); QLabel* l = qobject_cast(editor); l->setText(fileName); } return; } case TypeCol: { - QString type = qVariantValue(index.data(/*mitk::TypeRole*/)); + QString type = index.data(/*mitk::TypeRole*/).value(); QComboBox* c = qobject_cast(editor); c->setCurrentIndex(c->findText(type)); connect(c, SIGNAL(currentIndexChanged(int)), this, SLOT(ComboBoxCurrentIndexChanged(int))); return; } case NodeCol: { - mitk::DataNode::Pointer n = qVariantValue(index.data(/*mitk::OrganNodeRole*/)); + mitk::DataNode::Pointer n = index.data(/*mitk::OrganNodeRole*/).value(); if (n.IsNotNull()) { QmitkDataStorageComboBox* dsc = qobject_cast(editor); dsc->setCurrentIndex(dsc->findText(QString::fromStdString(n->GetName()))); connect(dsc, SIGNAL(currentIndexChanged(int)), this, SLOT(ComboBoxCurrentIndexChanged(int))); } return; } case IndexCol: case NameCol: case StatusCol: default: QStyledItemDelegate::setEditorData(editor, index); } } void QmitkNDIToolDelegate::setModelData(QWidget *editor, QAbstractItemModel* model, const QModelIndex &index) const { if (index.isValid() == false) return; switch (index.column()) { case SROMCol: { QLabel* l = qobject_cast(editor); //model->setData(index, l->text(), mitk::FileNameRole); //model->setData(index, l->text(), Qt::DisplayRole); // use for display too model->setData(index, l->text()); // use for display too return; } case TypeCol: { QComboBox* c = qobject_cast(editor); //model->setData(index, c->currentText(), mitk::TypeRole); model->setData(index, c->currentText(), Qt::DisplayRole); return; } case NodeCol: { QmitkDataStorageComboBox* dsc = qobject_cast(editor); if (dsc->GetSelectedNode().IsNotNull()) { model->setData(index, qVariantFromValue(dsc->GetSelectedNode()), OrganNodeRole); //model->setData(index, QString::fromStdString(dsc->GetSelectedNode()->GetName()), Qt::DisplayRole); model->setData(index, QString::fromStdString(dsc->GetSelectedNode()->GetName())); if ((m_TagProperty.IsNotNull()) && (m_TagPropertyName.empty() == false)) // tag this node as selected dsc->GetSelectedNode()->SetProperty(m_TagPropertyName.c_str(), m_TagProperty); } } return; case IndexCol: case NameCol: case StatusCol: default: QStyledItemDelegate::setModelData(editor, model, index); } } void QmitkNDIToolDelegate::commitAndCloseEditor() { //QWidget* editor = 0; //if(QPushButton *pushBtn = qobject_cast(sender())) //{ //} //if(editor) //{ //emit commitData(editor); //emit closeEditor(editor); //} } void QmitkNDIToolDelegate::ComboBoxCurrentIndexChanged( int /*index*/ ) { if(QComboBox *comboBox = qobject_cast(sender())) { emit commitData(comboBox); emit closeEditor(comboBox); } } void QmitkNDIToolDelegate::SetTypes( const QStringList& types ) { m_Types = types; } void QmitkNDIToolDelegate::SetDataStorage(mitk::DataStorage* ds) { m_DataStorage = ds; } void QmitkNDIToolDelegate::SetPredicate(mitk::NodePredicateBase::Pointer p) { m_Predicate = p; } void QmitkNDIToolDelegate::SetTagProperty(mitk::BaseProperty::Pointer prop) { m_TagProperty = prop; } void QmitkNDIToolDelegate::SetTagPropertyName( const std::string& name ) { m_TagPropertyName = name; } diff --git a/Modules/IGTUI/Qmitk/QmitkNavigationToolCreationWidget.cpp b/Modules/IGTUI/Qmitk/QmitkNavigationToolCreationWidget.cpp index 6293a244d6..5b65583c4b 100644 --- a/Modules/IGTUI/Qmitk/QmitkNavigationToolCreationWidget.cpp +++ b/Modules/IGTUI/Qmitk/QmitkNavigationToolCreationWidget.cpp @@ -1,341 +1,341 @@ /*=================================================================== 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 "QmitkNavigationToolCreationWidget.h" //mitk headers #include "mitkTrackingTypes.h" #include #include #include "mitkNavigationData.h" #include "mitkRenderingManager.h" //qt headers #include #include #include //poco headers #include // vtk #include #include "vtkConeSource.h" const std::string QmitkNavigationToolCreationWidget::VIEW_ID = "org.mitk.views.navigationtoolcreationwizardwidget"; QmitkNavigationToolCreationWidget::QmitkNavigationToolCreationWidget(QWidget* parent, Qt::WindowFlags f) : QWidget(parent, f) { m_Controls = NULL; m_AdvancedWidget = new QmitkNavigationToolCreationAdvancedWidget(this); m_AdvancedWidget->setWindowFlags(Qt::Tool | Qt::WindowStaysOnTopHint); m_AdvancedWidget->setWindowTitle("Tool Creation Advanced Options"); m_AdvancedWidget->setModal(false); CreateQtPartControl(this); CreateConnections(); } QmitkNavigationToolCreationWidget::~QmitkNavigationToolCreationWidget() { m_Controls->m_CalibrationLandmarksList->SetPointSetNode(NULL); m_Controls->m_RegistrationLandmarksList->SetPointSetNode(NULL); delete m_AdvancedWidget; } void QmitkNavigationToolCreationWidget::CreateQtPartControl(QWidget *parent) { if (!m_Controls) { // create GUI widgets m_Controls = new Ui::QmitkNavigationToolCreationWidgetControls; m_Controls->setupUi(parent); } } void QmitkNavigationToolCreationWidget::CreateConnections() { if ( m_Controls ) { connect( (QObject*)(m_Controls->m_cancel), SIGNAL(clicked()), this, SLOT(OnCancel()) ); connect( (QObject*)(m_Controls->m_finished), SIGNAL(clicked()), this, SLOT(OnFinished()) ); connect( (QObject*)(m_Controls->m_LoadSurface), SIGNAL(clicked()), this, SLOT(OnLoadSurface()) ); connect( (QObject*)(m_Controls->m_LoadCalibrationFile), SIGNAL(clicked()), this, SLOT(OnLoadCalibrationFile()) ); connect( (QObject*)(m_Controls->m_ShowAdvancedOptionsPB), SIGNAL(toggled(bool)), this, SLOT(OnShowAdvancedOptions(bool)) ); connect( (QObject*)(m_AdvancedWidget), SIGNAL(DialogCloseRequested()), this, SLOT(OnProcessDialogCloseRequest()) ); connect( (QObject*)(m_AdvancedWidget), SIGNAL(RetrieveDataForManualToolTipManipulation()), this, SLOT(OnRetrieveDataForManualTooltipManipulation()) ); connect( m_Controls->m_Surface_Use_Other, SIGNAL(toggled(bool)), this, SLOT(OnSurfaceUseOtherToggled(bool))); } } void QmitkNavigationToolCreationWidget::Initialize(mitk::DataStorage* dataStorage, std::string supposedIdentifier, std::string supposedName) { m_DataStorage = dataStorage; //initialize UI components m_Controls->m_SurfaceChooser->SetDataStorage(m_DataStorage); m_Controls->m_SurfaceChooser->SetAutoSelectNewItems(true); m_Controls->m_SurfaceChooser->SetPredicate(mitk::NodePredicateDataType::New("Surface")); //set default data m_Controls->m_ToolNameEdit->setText(supposedName.c_str()); m_Controls->m_CalibrationFileName->setText("none"); m_Controls->m_Surface_Use_Sphere->setChecked(true); m_AdvancedWidget->SetDataStorage(m_DataStorage); m_Controls->m_IdentifierEdit->setText(supposedIdentifier.c_str()); this->InitializeUIToolLandmarkLists(); m_Controls->m_CalibrationLandmarksList->EnableEditButton(false); m_Controls->m_RegistrationLandmarksList->EnableEditButton(false); } void QmitkNavigationToolCreationWidget::SetTrackingDeviceType(mitk::TrackingDeviceType type, bool changeable) { switch(type) { case mitk::NDIAurora: m_Controls->m_TrackingDeviceTypeChooser->setCurrentIndex(0);break; case mitk::NDIPolaris: m_Controls->m_TrackingDeviceTypeChooser->setCurrentIndex(1);break; case mitk::ClaronMicron: m_Controls->m_TrackingDeviceTypeChooser->setCurrentIndex(2);break; case mitk::NPOptitrack: m_Controls->m_TrackingDeviceTypeChooser->setCurrentIndex(3);break; default: m_Controls->m_TrackingDeviceTypeChooser->setCurrentIndex(0); } m_Controls->m_TrackingDeviceTypeChooser->setEnabled(changeable); } mitk::NavigationTool::Pointer QmitkNavigationToolCreationWidget::GetCreatedTool() { return m_CreatedTool; } //################################################################################## //############################## slots ############################ //################################################################################## void QmitkNavigationToolCreationWidget::OnFinished() { //here we create a new tool m_CreatedTool = mitk::NavigationTool::New(); //create DataNode... mitk::DataNode::Pointer newNode = mitk::DataNode::New(); if(m_Controls->m_Surface_Use_Sphere->isChecked()) { //create small sphere and use it as surface mitk::Surface::Pointer mySphere = mitk::Surface::New(); vtkConeSource *vtkData = vtkConeSource::New(); vtkData->SetAngle(5.0); vtkData->SetResolution(50); vtkData->SetHeight(6.0f); vtkData->SetRadius(2.0f); vtkData->SetCenter(0.0, 0.0, 0.0); vtkData->Update(); mySphere->SetVtkPolyData(vtkData->GetOutput()); vtkData->Delete(); newNode->SetData(mySphere); } else { newNode->SetData(m_Controls->m_SurfaceChooser->GetSelectedNode()->GetData()); } newNode->SetName(m_Controls->m_ToolNameEdit->text().toLatin1()); m_CreatedTool->SetDataNode(newNode); //fill NavigationTool object -m_CreatedTool->SetCalibrationFile(m_Controls->m_CalibrationFileName->text().toAscii().data()); -m_CreatedTool->SetIdentifier(m_Controls->m_IdentifierEdit->text().toAscii().data()); -m_CreatedTool->SetSerialNumber(m_Controls->m_SerialNumberEdit->text().toAscii().data()); +m_CreatedTool->SetCalibrationFile(m_Controls->m_CalibrationFileName->text().toLatin1().data()); +m_CreatedTool->SetIdentifier(m_Controls->m_IdentifierEdit->text().toLatin1().data()); +m_CreatedTool->SetSerialNumber(m_Controls->m_SerialNumberEdit->text().toLatin1().data()); //Tracking Device if (m_Controls->m_TrackingDeviceTypeChooser->currentText()=="NDI Aurora") m_CreatedTool->SetTrackingDeviceType(mitk::NDIAurora); else if (m_Controls->m_TrackingDeviceTypeChooser->currentText()=="NDI Polaris") m_CreatedTool->SetTrackingDeviceType(mitk::NDIPolaris); else if (m_Controls->m_TrackingDeviceTypeChooser->currentText()=="Claron Technology Micron Tracker") m_CreatedTool->SetTrackingDeviceType(mitk::ClaronMicron); else if (m_Controls->m_TrackingDeviceTypeChooser->currentText()=="NP Optitrack") m_CreatedTool->SetTrackingDeviceType(mitk::NPOptitrack); else m_CreatedTool->SetTrackingDeviceType(mitk::TrackingSystemNotSpecified); //ToolType if (m_Controls->m_ToolTypeChooser->currentText()=="Instrument") m_CreatedTool->SetType(mitk::NavigationTool::Instrument); else if (m_Controls->m_ToolTypeChooser->currentText()=="Fiducial") m_CreatedTool->SetType(mitk::NavigationTool::Fiducial); else if (m_Controls->m_ToolTypeChooser->currentText()=="Skinmarker") m_CreatedTool->SetType(mitk::NavigationTool::Skinmarker); else m_CreatedTool->SetType(mitk::NavigationTool::Unknown); //Tool Tip mitk::NavigationData::Pointer tempND = mitk::NavigationData::New(m_AdvancedWidget->GetManipulatedToolTip()); m_CreatedTool->SetToolTipOrientation(tempND->GetOrientation()); m_CreatedTool->SetToolTipPosition(tempND->GetPosition()); //Tool Landmarks mitk::PointSet::Pointer toolCalLandmarks, toolRegLandmarks; GetUIToolLandmarksLists(toolCalLandmarks,toolRegLandmarks); m_CreatedTool->SetToolCalibrationLandmarks(toolCalLandmarks); m_CreatedTool->SetToolRegistrationLandmarks(toolRegLandmarks); emit NavigationToolFinished(); } void QmitkNavigationToolCreationWidget::OnCancel() { m_CreatedTool = NULL; emit Canceled(); } void QmitkNavigationToolCreationWidget::OnLoadSurface() { std::string filename = QFileDialog::getOpenFileName(NULL,tr("Open Surface"), "/", tr("STL (*.stl)")).toLatin1().data(); mitk::STLFileReader::Pointer stlReader = mitk::STLFileReader::New(); try { stlReader->SetFileName( filename.c_str() ); stlReader->Update(); } catch (...) { } if ( stlReader->GetOutput() == NULL ); else { mitk::DataNode::Pointer newNode = mitk::DataNode::New(); newNode->SetName(filename); newNode->SetData(stlReader->GetOutput()); m_DataStorage->Add(newNode); } } void QmitkNavigationToolCreationWidget::OnLoadCalibrationFile() { m_Controls->m_CalibrationFileName->setText(QFileDialog::getOpenFileName(NULL,tr("Open Calibration File"), "/", "*.*")); } void QmitkNavigationToolCreationWidget::SetDefaultData(mitk::NavigationTool::Pointer DefaultTool) { m_Controls->m_ToolNameEdit->setText(QString(DefaultTool->GetDataNode()->GetName().c_str())); m_Controls->m_IdentifierEdit->setText(QString(DefaultTool->GetIdentifier().c_str())); m_Controls->m_SerialNumberEdit->setText(QString(DefaultTool->GetSerialNumber().c_str())); m_AdvancedWidget->SetDefaultTooltip( DefaultTool->GetToolTipTransform() ); switch(DefaultTool->GetTrackingDeviceType()) { case mitk::NDIAurora: m_Controls->m_TrackingDeviceTypeChooser->setCurrentIndex(0);break; case mitk::NDIPolaris: m_Controls->m_TrackingDeviceTypeChooser->setCurrentIndex(1);break; case mitk::ClaronMicron: m_Controls->m_TrackingDeviceTypeChooser->setCurrentIndex(2);break; case mitk::NPOptitrack: m_Controls->m_TrackingDeviceTypeChooser->setCurrentIndex(3);break; default: m_Controls->m_TrackingDeviceTypeChooser->setCurrentIndex(0); } m_Controls->m_CalibrationFileName->setText(QString(DefaultTool->GetCalibrationFile().c_str())); m_Controls->m_Surface_Use_Other->setChecked(true); switch(DefaultTool->GetType()) { case mitk::NavigationTool::Instrument: m_Controls->m_ToolTypeChooser->setCurrentIndex(0); break; case mitk::NavigationTool::Fiducial: m_Controls->m_ToolTypeChooser->setCurrentIndex(1); break; case mitk::NavigationTool::Skinmarker: m_Controls->m_ToolTypeChooser->setCurrentIndex(2); break; case mitk::NavigationTool::Unknown: m_Controls->m_ToolTypeChooser->setCurrentIndex(3); break; } m_Controls->m_SurfaceChooser->SetSelectedNode(DefaultTool->GetDataNode()); FillUIToolLandmarkLists(DefaultTool->GetToolCalibrationLandmarks(),DefaultTool->GetToolRegistrationLandmarks()); } //################################################################################## //############################## internal help methods ############################# //################################################################################## void QmitkNavigationToolCreationWidget::MessageBox(std::string s) { QMessageBox msgBox; msgBox.setText(s.c_str()); msgBox.exec(); } void QmitkNavigationToolCreationWidget::OnShowAdvancedOptions(bool state) { if(state) { m_AdvancedWidget->show(); m_AdvancedWidget->SetDefaultTooltip(m_AdvancedWidget->GetManipulatedToolTip()); //use the last one, if there is one m_AdvancedWidget->ReInitialize(); // reinit the views with the new nodes mitk::DataStorage::SetOfObjects::ConstPointer rs = m_DataStorage->GetAll(); mitk::TimeGeometry::Pointer bounds = m_DataStorage->ComputeBoundingGeometry3D(rs, "visible"); // initialize the views to the bounding geometry mitk::RenderingManager::GetInstance()->InitializeViews(bounds); } else { m_AdvancedWidget->hide(); } } void QmitkNavigationToolCreationWidget::OnProcessDialogCloseRequest() { m_AdvancedWidget->hide(); m_Controls->m_ShowAdvancedOptionsPB->setChecked(false); } void QmitkNavigationToolCreationWidget::OnRetrieveDataForManualTooltipManipulation() { if(m_Controls->m_Surface_Use_Sphere->isChecked()) { m_AdvancedWidget->SetToolTipSurface(true); } else { m_AdvancedWidget->SetToolTipSurface(false, dynamic_cast(m_Controls->m_SurfaceChooser->GetSelectedNode().GetPointer())); } } void QmitkNavigationToolCreationWidget::OnSurfaceUseOtherToggled(bool checked) { m_Controls->m_LoadSurface->setEnabled(checked); } void QmitkNavigationToolCreationWidget::FillUIToolLandmarkLists(mitk::PointSet::Pointer calLandmarks, mitk::PointSet::Pointer regLandmarks) { m_calLandmarkNode->SetData(calLandmarks); m_regLandmarkNode->SetData(regLandmarks); m_Controls->m_CalibrationLandmarksList->SetPointSetNode(m_calLandmarkNode); m_Controls->m_RegistrationLandmarksList->SetPointSetNode(m_regLandmarkNode); } void QmitkNavigationToolCreationWidget::GetUIToolLandmarksLists(mitk::PointSet::Pointer& calLandmarks, mitk::PointSet::Pointer& regLandmarks) { calLandmarks = dynamic_cast(m_calLandmarkNode->GetData()); regLandmarks = dynamic_cast(m_regLandmarkNode->GetData()); } void QmitkNavigationToolCreationWidget::InitializeUIToolLandmarkLists() { m_calLandmarkNode = mitk::DataNode::New(); m_regLandmarkNode = mitk::DataNode::New(); FillUIToolLandmarkLists(mitk::PointSet::New(),mitk::PointSet::New()); } diff --git a/Modules/IGTUI/Qmitk/QmitkNavigationToolManagementWidget.cpp b/Modules/IGTUI/Qmitk/QmitkNavigationToolManagementWidget.cpp index da956f9c9b..f35c1781bb 100644 --- a/Modules/IGTUI/Qmitk/QmitkNavigationToolManagementWidget.cpp +++ b/Modules/IGTUI/Qmitk/QmitkNavigationToolManagementWidget.cpp @@ -1,357 +1,357 @@ /*=================================================================== 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 "QmitkNavigationToolManagementWidget.h" //mitk headers #include "mitkTrackingTypes.h" #include #include #include #include #include #include #include //qt headers #include #include #include //poco headers #include const std::string QmitkNavigationToolManagementWidget::VIEW_ID = "org.mitk.views.navigationtoolmanagementwidget"; QmitkNavigationToolManagementWidget::QmitkNavigationToolManagementWidget(QWidget* parent, Qt::WindowFlags f) : QWidget(parent, f) { m_Controls = NULL; CreateQtPartControl(this); CreateConnections(); } QmitkNavigationToolManagementWidget::~QmitkNavigationToolManagementWidget() { } void QmitkNavigationToolManagementWidget::CreateQtPartControl(QWidget *parent) { if (!m_Controls) { // create GUI widgets m_Controls = new Ui::QmitkNavigationToolManagementWidgetControls; m_Controls->setupUi(parent); } //Disable StorageControls in the beginning, because there is no storage to edit DisableStorageControls(); } void QmitkNavigationToolManagementWidget::OnLoadTool() { if(m_NavigationToolStorage->isLocked()) { MessageBox("Storage is locked, cannot modify it. Maybe the tracking device which uses this storage is connected. If you want to modify the storage please disconnect the device first."); return; } mitk::NavigationToolReader::Pointer myReader = mitk::NavigationToolReader::New(); - std::string filename = QFileDialog::getOpenFileName(NULL,tr("Add Navigation Tool"), "/", "*.IGTTool").toAscii().data(); + std::string filename = QFileDialog::getOpenFileName(NULL,tr("Add Navigation Tool"), "/", "*.IGTTool").toLatin1().data(); if (filename == "") return; mitk::NavigationTool::Pointer readTool = myReader->DoRead(filename); if (readTool.IsNull()) MessageBox("Error: " + myReader->GetErrorMessage()); else { if (!m_NavigationToolStorage->AddTool(readTool)) { MessageBox("Error: Can't add tool!"); m_DataStorage->Remove(readTool->GetDataNode()); } UpdateToolTable(); } } void QmitkNavigationToolManagementWidget::OnSaveTool() { //if no item is selected, show error message: if (m_Controls->m_ToolList->currentItem() == NULL) {MessageBox("Error: Please select tool first!");return;} mitk::NavigationToolWriter::Pointer myWriter = mitk::NavigationToolWriter::New(); - std::string filename = QFileDialog::getSaveFileName(NULL,tr("Save Navigation Tool"), "/", "*.IGTTool").toAscii().data(); + std::string filename = QFileDialog::getSaveFileName(NULL,tr("Save Navigation Tool"), "/", "*.IGTTool").toLatin1().data(); if (filename == "") return; if (!myWriter->DoWrite(filename,m_NavigationToolStorage->GetTool(m_Controls->m_ToolList->currentIndex().row()))) MessageBox("Error: "+ myWriter->GetErrorMessage()); } void QmitkNavigationToolManagementWidget::CreateConnections() { if ( m_Controls ) { //main widget page: connect( (QObject*)(m_Controls->m_AddTool), SIGNAL(clicked()), this, SLOT(OnAddTool()) ); connect( (QObject*)(m_Controls->m_DeleteTool), SIGNAL(clicked()), this, SLOT(OnDeleteTool()) ); connect( (QObject*)(m_Controls->m_EditTool), SIGNAL(clicked()), this, SLOT(OnEditTool()) ); connect( (QObject*)(m_Controls->m_LoadStorage), SIGNAL(clicked()), this, SLOT(OnLoadStorage()) ); connect( (QObject*)(m_Controls->m_SaveStorage), SIGNAL(clicked()), this, SLOT(OnSaveStorage()) ); connect( (QObject*)(m_Controls->m_LoadTool), SIGNAL(clicked()), this, SLOT(OnLoadTool()) ); connect( (QObject*)(m_Controls->m_SaveTool), SIGNAL(clicked()), this, SLOT(OnSaveTool()) ); connect( (QObject*)(m_Controls->m_CreateNewStorage), SIGNAL(clicked()), this, SLOT(OnCreateStorage()) ); //widget page "add tool": connect( (QObject*)(m_Controls->m_ToolCreationWidget), SIGNAL(Canceled()), this, SLOT(OnAddToolCancel()) ); connect( (QObject*)(m_Controls->m_ToolCreationWidget), SIGNAL(NavigationToolFinished()), this, SLOT(OnAddToolSave()) ); } } void QmitkNavigationToolManagementWidget::Initialize(mitk::DataStorage* dataStorage) { m_DataStorage = dataStorage; m_Controls->m_ToolCreationWidget->Initialize(m_DataStorage,"Tool0"); } void QmitkNavigationToolManagementWidget::LoadStorage(mitk::NavigationToolStorage::Pointer storageToLoad) { if(storageToLoad.IsNotNull()) { m_NavigationToolStorage = storageToLoad; m_Controls->m_StorageName->setText(m_NavigationToolStorage->GetName().c_str()); EnableStorageControls(); } else { m_NavigationToolStorage = NULL; DisableStorageControls(); } UpdateToolTable(); } //################################################################################## //############################## slots: main widget ################################ //################################################################################## void QmitkNavigationToolManagementWidget::OnAddTool() { if(m_NavigationToolStorage->isLocked()) { MessageBox("Storage is locked, cannot modify it. Maybe the tracking device which uses this storage is connected. If you want to modify the storage please disconnect the device first."); return; } QString defaultIdentifier = "NavigationTool#"+QString::number(m_NavigationToolStorage->GetToolCount()); m_Controls->m_ToolCreationWidget->Initialize(m_DataStorage,defaultIdentifier.toStdString()); m_edit = false; m_Controls->m_MainWidgets->setCurrentIndex(1); } void QmitkNavigationToolManagementWidget::OnDeleteTool() { //first: some checks if(m_NavigationToolStorage->isLocked()) { MessageBox("Storage is locked, cannot modify it. Maybe the tracking device which uses this storage is connected. If you want to modify the storage please disconnect the device first."); return; } else if (m_Controls->m_ToolList->currentItem() == NULL) //if no item is selected, show error message: { MessageBox("Error: Please select tool first!"); return; } m_DataStorage->Remove(m_NavigationToolStorage->GetTool(m_Controls->m_ToolList->currentIndex().row())->GetDataNode()); m_NavigationToolStorage->DeleteTool(m_Controls->m_ToolList->currentIndex().row()); UpdateToolTable(); } void QmitkNavigationToolManagementWidget::OnEditTool() { if(m_NavigationToolStorage->isLocked()) { MessageBox("Storage is locked, cannot modify it. Maybe the tracking device which uses this storage is connected. If you want to modify the storage please disconnect the device first."); return; } else if (m_Controls->m_ToolList->currentItem() == NULL) //if no item is selected, show error message: { MessageBox("Error: Please select tool first!"); return; } mitk::NavigationTool::Pointer selectedTool = m_NavigationToolStorage->GetTool(m_Controls->m_ToolList->currentIndex().row()); m_Controls->m_ToolCreationWidget->SetDefaultData(selectedTool); m_edit = true; m_Controls->m_MainWidgets->setCurrentIndex(1); } void QmitkNavigationToolManagementWidget::OnCreateStorage() { QString storageName = QInputDialog::getText(NULL,"Storage Name","Name of the new tool storage:"); if (storageName.isNull()) return; m_NavigationToolStorage = mitk::NavigationToolStorage::New(this->m_DataStorage); m_NavigationToolStorage->SetName(storageName.toStdString()); m_Controls->m_StorageName->setText(m_NavigationToolStorage->GetName().c_str()); EnableStorageControls(); emit NewStorageAdded(m_NavigationToolStorage, storageName.toStdString()); } void QmitkNavigationToolManagementWidget::OnLoadStorage() { mitk::NavigationToolStorageDeserializer::Pointer myDeserializer = mitk::NavigationToolStorageDeserializer::New(m_DataStorage); std::string filename = QFileDialog::getOpenFileName(NULL, tr("Open Navigation Tool Storage"), "/", tr("IGT Tool Storage (*.IGTToolStorage)")).toStdString(); if (filename == "") return; try { mitk::NavigationToolStorage::Pointer tempStorage = myDeserializer->Deserialize(filename); if (tempStorage.IsNull()) MessageBox("Error" + myDeserializer->GetErrorMessage()); else { Poco::Path myPath = Poco::Path(filename.c_str()); tempStorage->SetName(myPath.getFileName()); //set the filename as name for the storage, so the user can identify it this->LoadStorage(tempStorage); emit NewStorageAdded(m_NavigationToolStorage,myPath.getFileName()); } } catch (const mitk::Exception& exception) { MessageBox(exception.GetDescription()); } } void QmitkNavigationToolManagementWidget::OnSaveStorage() { //read in filename QString filename = QFileDialog::getSaveFileName(NULL, tr("Save Navigation Tool Storage"), "/", tr("IGT Tool Storage (*.IGTToolStorage)")); if (filename.isEmpty()) return; //canceled by the user // add file extension if it wasn't added by the file dialog if ( filename.right(15) != ".IGTToolStorage" ) { filename += ".IGTToolStorage"; } //serialize tool storage mitk::NavigationToolStorageSerializer::Pointer mySerializer = mitk::NavigationToolStorageSerializer::New(); if (!mySerializer->Serialize(filename.toStdString(),m_NavigationToolStorage)) { MessageBox("Error: " + mySerializer->GetErrorMessage()); return; } Poco::Path myPath = Poco::Path(filename.toStdString()); m_Controls->m_StorageName->setText(QString::fromStdString(myPath.getFileName())); } //################################################################################## //############################## slots: add tool widget ############################ //################################################################################## void QmitkNavigationToolManagementWidget::OnAddToolSave() { mitk::NavigationTool::Pointer newTool = m_Controls->m_ToolCreationWidget->GetCreatedTool(); if (m_edit) //here we edit a existing tool { mitk::NavigationTool::Pointer editedTool = m_NavigationToolStorage->GetTool(m_Controls->m_ToolList->currentIndex().row()); editedTool->Graft(newTool); } else //here we create a new tool { m_NavigationToolStorage->AddTool(newTool); } UpdateToolTable(); m_Controls->m_MainWidgets->setCurrentIndex(0); } void QmitkNavigationToolManagementWidget::OnAddToolCancel() { m_Controls->m_MainWidgets->setCurrentIndex(0); } //################################################################################## //############################## private help methods ############################## //################################################################################## void QmitkNavigationToolManagementWidget::UpdateToolTable() { m_Controls->m_ToolList->clear(); if(m_NavigationToolStorage.IsNull()) return; for(int i=0; iGetToolCount(); i++) { QString currentTool = "Tool" + QString::number(i) + ": " + QString(m_NavigationToolStorage->GetTool(i)->GetDataNode()->GetName().c_str())+ " "; switch (m_NavigationToolStorage->GetTool(i)->GetTrackingDeviceType()) { case mitk::ClaronMicron: currentTool += "(MicronTracker/"; break; case mitk::NDIAurora: currentTool += "(NDI Aurora/"; break; case mitk::NDIPolaris: currentTool += "(NDI Polaris/"; break; case mitk::NPOptitrack: currentTool += "(NP Optitrack/"; break; default: currentTool += "(unknown tracking system/"; break; } switch (m_NavigationToolStorage->GetTool(i)->GetType()) { case mitk::NavigationTool::Instrument: currentTool += "Instrument)"; break; case mitk::NavigationTool::Fiducial: currentTool += "Fiducial)"; break; case mitk::NavigationTool::Skinmarker: currentTool += "Skinmarker)"; break; default: currentTool += "Unknown)"; } m_Controls->m_ToolList->addItem(currentTool); } } void QmitkNavigationToolManagementWidget::MessageBox(std::string s) { QMessageBox msgBox; msgBox.setText(s.c_str()); msgBox.exec(); } void QmitkNavigationToolManagementWidget::DisableStorageControls() { m_Controls->m_StorageName->setText(""); m_Controls->m_AddTool->setEnabled(false); m_Controls->m_LoadTool->setEnabled(false); m_Controls->m_selectedLabel->setEnabled(false); m_Controls->m_DeleteTool->setEnabled(false); m_Controls->m_EditTool->setEnabled(false); m_Controls->m_SaveTool->setEnabled(false); m_Controls->m_ToolList->setEnabled(false); m_Controls->m_SaveStorage->setEnabled(false); m_Controls->m_ToolLabel->setEnabled(false); } void QmitkNavigationToolManagementWidget::EnableStorageControls() { m_Controls->m_AddTool->setEnabled(true); m_Controls->m_LoadTool->setEnabled(true); m_Controls->m_selectedLabel->setEnabled(true); m_Controls->m_DeleteTool->setEnabled(true); m_Controls->m_EditTool->setEnabled(true); m_Controls->m_SaveTool->setEnabled(true); m_Controls->m_ToolList->setEnabled(true); m_Controls->m_SaveStorage->setEnabled(true); m_Controls->m_ToolLabel->setEnabled(true); } diff --git a/Modules/IGTUI/Qmitk/QmitkTrackingDeviceConfigurationWidget.cpp b/Modules/IGTUI/Qmitk/QmitkTrackingDeviceConfigurationWidget.cpp index 028bb29069..f5cb6899d9 100644 --- a/Modules/IGTUI/Qmitk/QmitkTrackingDeviceConfigurationWidget.cpp +++ b/Modules/IGTUI/Qmitk/QmitkTrackingDeviceConfigurationWidget.cpp @@ -1,728 +1,728 @@ /*=================================================================== 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 "QmitkTrackingDeviceConfigurationWidget.h" #include #include #include #include #include #include #include #include #include #include #include #include #include const std::string QmitkTrackingDeviceConfigurationWidget::VIEW_ID = "org.mitk.views.trackingdeviceconfigurationwidget"; QmitkTrackingDeviceConfigurationWidget::QmitkTrackingDeviceConfigurationWidget(QWidget* parent, Qt::WindowFlags f) : QWidget(parent, f) { //initialize worker thread m_TestConnectionWorker = new QmitkTrackingDeviceConfigurationWidgetConnectionWorker(); m_ScanPortsWorker = new QmitkTrackingDeviceConfigurationWidgetScanPortsWorker(); m_ScanPortsWorkerThread = new QThread(); m_TestConnectionWorkerThread = new QThread(); //initializations m_Controls = NULL; CreateQtPartControl(this); CreateConnections(); m_MTCalibrationFile = ""; m_AdvancedUserControl = true; //initialize a few UI elements this->m_TrackingDeviceConfigurated = false; AddOutput("
NDI Polaris selected"); //Polaris is selected by default m_Controls->m_trackingDeviceChooser->setCurrentIndex(0); m_Controls->m_TrackingSystemWidget->setCurrentIndex(0); //reset a few things ResetOutput(); //restore old UI settings LoadUISettings(); } void QmitkTrackingDeviceConfigurationWidget::SetGUIStyle(QmitkTrackingDeviceConfigurationWidget::Style style) { switch(style) { case QmitkTrackingDeviceConfigurationWidget::SIMPLE: //move all UI elements to an empty dummy layout //m_Controls->dummyLayout->addItem(m_Controls->mainLayout); m_Controls->dummyLayout->addWidget(m_Controls->widget_title_label); m_Controls->dummyLayout->addWidget(m_Controls->choose_tracking_device_label); m_Controls->dummyLayout->addWidget(m_Controls->polaris_label); m_Controls->dummyLayout->addWidget(m_Controls->aurora_label); //m_Controls->dummyLayout->addWidget(m_Controls->aurora_label); m_Controls->dummyLayout->addWidget(m_Controls->microntracker_label); m_Controls->dummyLayout->addWidget(m_Controls->m_testConnectionMicronTracker); m_Controls->dummyLayout->addWidget(m_Controls->m_outputTextMicronTracker); m_Controls->dummyLayout->addWidget(m_Controls->m_outputTextAurora); m_Controls->dummyLayout->addWidget(m_Controls->m_testConnectionAurora); m_Controls->dummyLayout->addWidget(m_Controls->m_outputTextPolaris); m_Controls->dummyLayout->addWidget(m_Controls->m_testConnectionPolaris); m_Controls->dummyLayout->addWidget(m_Controls->m_polarisTrackingModeBox); m_Controls->dummyLayout->addWidget(m_Controls->m_testConnectionOptitrack); m_Controls->dummyLayout->addWidget(m_Controls->m_outputTextOptitrack); m_Controls->dummyLayout->addWidget(m_Controls->m_OptitrackExp); m_Controls->dummyLayout->addWidget(m_Controls->m_OptitrackThr); m_Controls->dummyLayout->addWidget(m_Controls->m_OptitrackLed); m_Controls->dummyLayout->addWidget(m_Controls->Optitrack_label); m_Controls->dummyLayout->addWidget(m_Controls->m_finishedLine); m_Controls->dummyLayout->addWidget(m_Controls->line); m_Controls->dummyLayout->addWidget(m_Controls->configuration_finished_label); m_Controls->dummyLayout->addItem(m_Controls->horizontalLayout_4); m_Controls->mainLayout->removeItem(m_Controls->horizontalLayout_4); m_Controls->dummyLayout->addWidget(m_Controls->configuration_finished_label); m_Controls->dummyLayout->addItem(m_Controls->verticalSpacer_2); m_Controls->verticalLayout_3->removeItem(m_Controls->verticalSpacer_2); m_Controls->dummyLayout->addItem(m_Controls->horizontalSpacer_9); m_Controls->horizontalLayout_9->removeItem(m_Controls->horizontalSpacer_9); m_Controls->dummyLayout->addItem(m_Controls->horizontalSpacer_3); m_Controls->horizontalLayout_11->removeItem(m_Controls->horizontalSpacer_3); m_Controls->dummyLayout->addItem(m_Controls->verticalSpacer_3); m_Controls->verticalLayout_7->removeItem(m_Controls->verticalSpacer_3); m_Controls->dummyLayout->addItem(m_Controls->verticalSpacer_4); m_Controls->verticalLayout_10->removeItem(m_Controls->verticalSpacer_4); m_Controls->dummyLayout->addItem(m_Controls->horizontalSpacer_10); m_Controls->verticalLayout_10->removeItem(m_Controls->horizontalSpacer_10); //set height to min m_Controls->m_outputTextPolaris->setMinimumHeight(0); m_Controls->m_outputTextPolaris->setMaximumHeight(0); m_Controls->m_outputTextMicronTracker->setMinimumHeight(0); m_Controls->m_outputTextMicronTracker->setMaximumHeight(0); m_Controls->m_outputTextAurora->setMinimumHeight(0); m_Controls->m_outputTextAurora->setMaximumHeight(0); m_Controls->m_finishedButton->setMinimumHeight(0); m_Controls->m_finishedButton->setMaximumHeight(0); m_Controls->m_resetButton->setMinimumHeight(0); m_Controls->m_resetButton->setMaximumHeight(0); //set the height of the tracking device combo box m_Controls->m_trackingDeviceChooser->setMinimumHeight(50); //move back the used elemets to the main layout m_Controls->simpleLayout->addWidget(m_Controls->m_trackingDeviceChooser); m_Controls->simpleLayout->addWidget(m_Controls->m_TrackingSystemWidget); m_Controls->mainWidget->setCurrentIndex(1); this->setMaximumHeight(150); this->EnableAdvancedUserControl(false); break; case QmitkTrackingDeviceConfigurationWidget::ADVANCED: //default at the moment => start settings are advanced break; } } QmitkTrackingDeviceConfigurationWidget::~QmitkTrackingDeviceConfigurationWidget() { StoreUISettings(); if (m_ScanPortsWorker) delete m_ScanPortsWorker; if (m_TestConnectionWorker) delete m_TestConnectionWorker; if (m_ScanPortsWorkerThread) delete m_ScanPortsWorkerThread; if (m_TestConnectionWorkerThread) delete m_TestConnectionWorkerThread; } void QmitkTrackingDeviceConfigurationWidget::CreateQtPartControl(QWidget *parent) { if (!m_Controls) { // create GUI widgets m_Controls = new Ui::QmitkTrackingDeviceConfigurationWidgetControls; m_Controls->setupUi(parent); } } void QmitkTrackingDeviceConfigurationWidget::CreateConnections() { if ( m_Controls ) { connect( (QObject*)(m_Controls->m_trackingDeviceChooser), SIGNAL(currentIndexChanged(int)), this, SLOT(TrackingDeviceChanged()) ); connect( (QObject*)(m_Controls->m_testConnectionPolaris), SIGNAL(clicked()), this, SLOT(TestConnection()) ); connect( (QObject*)(m_Controls->m_testConnectionAurora), SIGNAL(clicked()), this, SLOT(TestConnection()) ); connect( (QObject*)(m_Controls->m_testConnectionMicronTracker), SIGNAL(clicked()), this, SLOT(TestConnection()) ); connect( (QObject*)(m_Controls->m_testConnectionOptitrack), SIGNAL(clicked()), this, SLOT(TestConnection()) ); connect( (QObject*)(m_Controls->m_resetButton), SIGNAL(clicked()), this, SLOT(ResetByUser()) ); connect( (QObject*)(m_Controls->m_finishedButton), SIGNAL(clicked()), this, SLOT(Finished()) ); connect( (QObject*)(m_Controls->m_AutoScanPolaris), SIGNAL(clicked()), this, SLOT(AutoScanPorts()) ); connect( (QObject*)(m_Controls->m_AutoScanAurora), SIGNAL(clicked()), this, SLOT(AutoScanPorts()) ); connect( (QObject*)(m_Controls->m_SetMTCalibrationFile), SIGNAL(clicked()), this, SLOT(SetMTCalibrationFileClicked()) ); connect( (QObject*)(m_Controls->m_SetOptitrackCalibrationFile), SIGNAL(clicked()), this, SLOT(SetOptitrackCalibrationFileClicked()) ); //slots for the worker thread connect(m_ScanPortsWorker, SIGNAL(PortsScanned(int,int,QString,int,int)), this, SLOT(AutoScanPortsFinished(int,int,QString,int,int)) ); connect(m_TestConnectionWorker, SIGNAL(ConnectionTested(bool,QString)), this, SLOT(TestConnectionFinished(bool,QString)) ); connect(m_ScanPortsWorkerThread,SIGNAL(started()), m_ScanPortsWorker, SLOT(ScanPortsThreadFunc()) ); connect(m_TestConnectionWorkerThread,SIGNAL(started()), m_TestConnectionWorker, SLOT(TestConnectionThreadFunc()) ); //move the worker to the thread m_ScanPortsWorker->moveToThread(m_ScanPortsWorkerThread); m_TestConnectionWorker->moveToThread(m_TestConnectionWorkerThread); //set a few UI components depending on Windows / Linux #ifdef WIN32 m_Controls->portTypeLabelPolaris->setVisible(false); m_Controls->portTypePolaris->setVisible(false); m_Controls->portTypeLabelAurora->setVisible(false); m_Controls->portTypeAurora->setVisible(false); #else m_Controls->comPortLabelAurora->setText("Port Nr:"); m_Controls->m_comPortLabelPolaris->setText("Port Nr:"); m_Controls->m_portSpinBoxAurora->setPrefix(""); m_Controls->m_portSpinBoxPolaris->setPrefix(""); #endif //disable unused UI component m_Controls->m_polarisTrackingModeBox->setVisible(false); //don't delete this component, because it is used in the MBI part of MITK } } void QmitkTrackingDeviceConfigurationWidget::TrackingDeviceChanged() { //show the correspondig widget m_Controls->m_TrackingSystemWidget->setCurrentIndex(m_Controls->m_trackingDeviceChooser->currentIndex()); //the new trackingdevice is not configurated yet m_TrackingDeviceConfigurated = false; //reset output ResetOutput(); //print output and do further initializations if (m_Controls->m_trackingDeviceChooser->currentIndex()==0)//NDI Polaris { AddOutput("
NDI Polaris selected"); } else if (m_Controls->m_trackingDeviceChooser->currentIndex()==1) //NDI Aurora { AddOutput("
NDI Aurora selected"); } else if (m_Controls->m_trackingDeviceChooser->currentIndex()==2) //ClaronTechnology MicronTracker 2 { AddOutput("
Microntracker selected"); if (!mitk::ClaronTrackingDevice::New()->IsDeviceInstalled()) { AddOutput("
ERROR: not installed!"); } else if (this->m_MTCalibrationFile == "") //if configuration file for MicronTracker is empty: load default { mitk::ClaronTrackingDevice::Pointer tempDevice = mitk::ClaronTrackingDevice::New(); m_MTCalibrationFile = tempDevice->GetCalibrationDir(); Poco::Path myPath = Poco::Path(m_MTCalibrationFile.c_str()); m_Controls->m_MTCalibrationFile->setText("Calibration File: " + QString(myPath.getFileName().c_str())); } } else if (m_Controls->m_trackingDeviceChooser->currentIndex()==3) { AddOutput("
Optitrack selected"); if (!mitk::OptitrackTrackingDevice::New()->IsDeviceInstalled()) { AddOutput("
ERROR: not installed!"); } } emit TrackingDeviceSelectionChanged(); } void QmitkTrackingDeviceConfigurationWidget::EnableUserReset(bool enable) { if (enable) m_Controls->m_resetButton->setVisible(true); else m_Controls->m_resetButton->setVisible(false); } void QmitkTrackingDeviceConfigurationWidget::TestConnection() { this->setEnabled(false); //construct a tracking device: mitk::TrackingDevice::Pointer testTrackingDevice = ConstructTrackingDevice(); m_TestConnectionWorker->SetTrackingDevice(testTrackingDevice); m_TestConnectionWorkerThread->start(); emit ProgressStarted(); } void QmitkTrackingDeviceConfigurationWidget::TestConnectionFinished(bool connected, QString output) { m_TestConnectionWorkerThread->quit(); AddOutput(output.toStdString()); MITK_INFO << "Test connection: " << connected; this->setEnabled(true); emit ProgressFinished(); } void QmitkTrackingDeviceConfigurationWidget::Finished() { m_TrackingDevice = ConstructTrackingDevice(); m_Controls->m_TrackingSystemWidget->setEnabled(false); m_Controls->m_trackingDeviceChooser->setEnabled(false); m_Controls->choose_tracking_device_label->setEnabled(false); m_Controls->configuration_finished_label->setText("\n\n

Configuration finished

"); this->m_TrackingDeviceConfigurated = true; emit TrackingDeviceConfigurationFinished(); } void QmitkTrackingDeviceConfigurationWidget::Reset() { m_TrackingDevice = NULL; m_Controls->m_TrackingSystemWidget->setEnabled(true); m_Controls->m_trackingDeviceChooser->setEnabled(true); m_Controls->choose_tracking_device_label->setEnabled(true); m_Controls->configuration_finished_label->setText("\n\n

Press \"Finished\" to confirm configuration

"); this->m_TrackingDeviceConfigurated = false; emit TrackingDeviceConfigurationReseted(); } void QmitkTrackingDeviceConfigurationWidget::ResetByUser() { Reset(); } void QmitkTrackingDeviceConfigurationWidget::AutoScanPorts() { this->setEnabled(false); AddOutput("
Scanning..."); m_ScanPortsWorkerThread->start(); emit ProgressStarted(); } void QmitkTrackingDeviceConfigurationWidget::AutoScanPortsFinished(int PolarisPort, int AuroraPort, QString result, int PortTypePolaris, int PortTypeAurora) { m_ScanPortsWorkerThread->quit(); #ifdef WIN32 if((PortTypePolaris!=-1)||(PortTypeAurora!=-1)) {MITK_WARN << "Port type is specified although this should not be the case for Windows. Ignoring port type.";} #else //linux systems if (PortTypePolaris!=-1) {m_Controls->portTypePolaris->setCurrentIndex(PortTypePolaris);} if (PortTypeAurora!=-1) {m_Controls->portTypeAurora->setCurrentIndex(PortTypeAurora);} #endif m_Controls->m_portSpinBoxPolaris->setValue(PolarisPort); m_Controls->m_portSpinBoxAurora->setValue(AuroraPort); AddOutput(result.toStdString()); this->setEnabled(true); emit ProgressFinished(); } void QmitkTrackingDeviceConfigurationWidget::SetMTCalibrationFileClicked() { - std::string filename = QFileDialog::getOpenFileName(NULL,tr("Open Calibration File"), "/", "*.*").toAscii().data(); + std::string filename = QFileDialog::getOpenFileName(NULL,tr("Open Calibration File"), "/", "*.*").toLatin1().data(); if (filename=="") {return;} else { m_MTCalibrationFile = filename; Poco::Path myPath = Poco::Path(m_MTCalibrationFile.c_str()); m_Controls->m_MTCalibrationFile->setText("Calibration File: " + QString(myPath.getFileName().c_str())); } } void QmitkTrackingDeviceConfigurationWidget::SetOptitrackCalibrationFileClicked() { - std::string filename = QFileDialog::getOpenFileName(NULL,tr("Open Calibration File"), "/", "*.*").toAscii().data(); + std::string filename = QFileDialog::getOpenFileName(NULL,tr("Open Calibration File"), "/", "*.*").toLatin1().data(); if (filename=="") {return;} else { m_OptitrackCalibrationFile = filename; Poco::Path myPath = Poco::Path(m_OptitrackCalibrationFile.c_str()); m_Controls->m_OptitrackCalibrationFile->setText("Calibration File: " + QString(myPath.getFileName().c_str())); } } //######################### internal help methods ####################################### void QmitkTrackingDeviceConfigurationWidget::ResetOutput() { m_output.str(""); m_output <<"output:"; m_Controls->m_outputTextAurora->setHtml(QString(m_output.str().c_str())); m_Controls->m_outputTextPolaris->setHtml(QString(m_output.str().c_str())); m_Controls->m_outputTextMicronTracker->setHtml(QString(m_output.str().c_str())); } void QmitkTrackingDeviceConfigurationWidget::AddOutput(std::string s) { //print output m_output << s; m_Controls->m_outputTextAurora->setHtml(QString(m_output.str().c_str())); m_Controls->m_outputTextPolaris->setHtml(QString(m_output.str().c_str())); m_Controls->m_outputTextMicronTracker->setHtml(QString(m_output.str().c_str())); m_Controls->m_outputTextOptitrack->setHtml(QString(m_output.str().c_str())); m_Controls->m_outputTextPolaris->verticalScrollBar()->setValue(m_Controls->m_outputTextPolaris->verticalScrollBar()->maximum()); m_Controls->m_outputTextAurora->verticalScrollBar()->setValue(m_Controls->m_outputTextAurora->verticalScrollBar()->maximum()); m_Controls->m_outputTextMicronTracker->verticalScrollBar()->setValue(m_Controls->m_outputTextMicronTracker->verticalScrollBar()->maximum()); m_Controls->m_outputTextOptitrack->verticalScrollBar()->setValue(m_Controls->m_outputTextOptitrack->verticalScrollBar()->maximum()); repaint(); } mitk::TrackingDevice::Pointer QmitkTrackingDeviceConfigurationWidget::ConstructTrackingDevice() { mitk::TrackingDevice::Pointer returnValue; //#### Step 1: configure tracking device: MITK_INFO << "Current Index: " << m_Controls->m_trackingDeviceChooser->currentIndex(); if (m_Controls->m_trackingDeviceChooser->currentIndex()==0)//NDI Polaris { if(m_Controls->m_radioPolaris5D->isChecked()) //5D Tracking { //not yet in the open source part so we'll only get NULL here. returnValue = ConfigureNDI5DTrackingDevice(); } else //6D Tracking { returnValue = ConfigureNDI6DTrackingDevice(); returnValue->SetType(mitk::NDIPolaris); } } else if (m_Controls->m_trackingDeviceChooser->currentIndex()==1)//NDI Aurora { returnValue = ConfigureNDI6DTrackingDevice(); returnValue->SetType(mitk::NDIAurora); } else if (m_Controls->m_trackingDeviceChooser->currentIndex()==2)//ClaronTechnology MicronTracker 2 { mitk::ClaronTrackingDevice::Pointer newDevice = mitk::ClaronTrackingDevice::New(); if(this->m_MTCalibrationFile=="") AddOutput("
Warning: Calibration file is not set!"); else { //extract path from calibration file and set the calibration dir of the device std::string path = itksys::SystemTools::GetFilenamePath(m_MTCalibrationFile); newDevice->SetCalibrationDir(path); } returnValue = newDevice; } else if (m_Controls->m_trackingDeviceChooser->currentIndex()==3) { // Create the Tracking Device this->m_OptitrackDevice = mitk::OptitrackTrackingDevice::New(); returnValue = ConfigureOptitrackTrackingDevice(); returnValue->SetType(mitk::NPOptitrack); } return returnValue; } mitk::TrackingDevice::Pointer QmitkTrackingDeviceConfigurationWidget::ConfigureNDI5DTrackingDevice() { return NULL; } mitk::TrackingDevice::Pointer QmitkTrackingDeviceConfigurationWidget::ConfigureOptitrackTrackingDevice() { mitk::OptitrackTrackingDevice::Pointer tempTrackingDevice = mitk::OptitrackTrackingDevice::New(); // Set the calibration File tempTrackingDevice->SetCalibrationPath(m_OptitrackCalibrationFile); //Set the camera parameters tempTrackingDevice->SetExp(m_Controls->m_OptitrackExp->value()); tempTrackingDevice->SetLed(m_Controls->m_OptitrackLed->value()); tempTrackingDevice->SetThr(m_Controls->m_OptitrackThr->value()); mitk::TrackingDevice::Pointer returnValue = static_cast(tempTrackingDevice); return returnValue; } mitk::TrackingDevice::Pointer QmitkTrackingDeviceConfigurationWidget::ConfigureNDI6DTrackingDevice() { mitk::NDITrackingDevice::Pointer tempTrackingDevice = mitk::NDITrackingDevice::New(); //get port int port = 0; if (m_Controls->m_trackingDeviceChooser->currentIndex()==1) port = m_Controls->m_portSpinBoxAurora->value(); else port = m_Controls->m_portSpinBoxPolaris->value(); //build prefix (depends on linux/win) QString prefix = ""; #ifdef WIN32 prefix ="COM"; tempTrackingDevice->SetPortNumber(static_cast(port)); //also set the com port for compatibility #else if (m_Controls->m_trackingDeviceChooser->currentIndex()==1) //Aurora prefix = m_Controls->portTypeAurora->currentText(); else //Polaris prefix = m_Controls->portTypePolaris->currentText(); #endif //build port name string QString portName = prefix + QString::number(port); tempTrackingDevice->SetDeviceName(portName.toStdString()); //set the port name tempTrackingDevice->SetBaudRate(mitk::SerialCommunication::BaudRate115200);//set baud rate mitk::TrackingDevice::Pointer returnValue = static_cast(tempTrackingDevice); return returnValue; } mitk::TrackingDevice::Pointer QmitkTrackingDeviceConfigurationWidget::GetTrackingDevice() { if (!m_AdvancedUserControl) m_TrackingDevice = ConstructTrackingDevice(); if (m_TrackingDevice.IsNull() || !m_TrackingDevice->IsDeviceInstalled()) return NULL; else return this->m_TrackingDevice; } bool QmitkTrackingDeviceConfigurationWidget::GetTrackingDeviceConfigured() { return this->m_TrackingDeviceConfigurated; } void QmitkTrackingDeviceConfigurationWidget::ConfigurationFinished() { Finished(); } void QmitkTrackingDeviceConfigurationWidget::EnableAdvancedUserControl(bool enable) { m_AdvancedUserControl = enable; m_Controls->configuration_finished_label->setVisible(enable); m_Controls->m_finishedLine->setVisible(enable); m_Controls->m_resetButton->setVisible(enable); m_Controls->m_finishedButton->setVisible(enable); } void QmitkTrackingDeviceConfigurationWidget::StoreUISettings() { std::string id = "org.mitk.modules.igt.ui.trackingdeviceconfigurationwidget"; int selectedDevice = m_Controls->m_trackingDeviceChooser->currentIndex(); if ( this->GetPeristenceService() ) // now save the settings using the persistence service { mitk::PropertyList::Pointer propList = this->GetPeristenceService()->GetPropertyList(id); propList->Set("PolarisPortWin",m_Controls->m_portSpinBoxPolaris->value()); propList->Set("AuroraPortWin",m_Controls->m_portSpinBoxAurora->value()); propList->Set("PortTypePolaris", m_Controls->portTypePolaris->currentIndex()); propList->Set("PortTypeAurora", m_Controls->portTypeAurora->currentIndex()); propList->Set("MTCalibrationFile",m_MTCalibrationFile); propList->Set("SelectedDevice",selectedDevice); } else // QSettings as a fallback if the persistence service is not available { QSettings settings; settings.beginGroup(QString::fromStdString(id)); settings.setValue("trackingDeviceChooser", QVariant(selectedDevice)); settings.setValue("portSpinBoxAurora", QVariant(m_Controls->m_portSpinBoxAurora->value())); settings.setValue("portSpinBoxPolaris", QVariant(m_Controls->m_portSpinBoxPolaris->value())); settings.setValue("portTypePolaris", QVariant(m_Controls->portTypePolaris->currentIndex())); settings.setValue("portTypeAurora", QVariant(m_Controls->portTypeAurora->currentIndex())); settings.setValue("mTCalibrationFile", QVariant(QString::fromStdString(m_MTCalibrationFile))); settings.endGroup(); } } void QmitkTrackingDeviceConfigurationWidget::LoadUISettings() { std::string id = "org.mitk.modules.igt.ui.trackingdeviceconfigurationwidget"; int SelectedDevice = 0; if ( this->GetPeristenceService() ) { mitk::PropertyList::Pointer propList = this->GetPeristenceService()->GetPropertyList(id); if (propList.IsNull()) {MITK_ERROR << "Property list for this UI (" << id <<") is not available, could not load UI settings!"; return;} int portPolarisWin,portAuroraWin,portTypePolaris,portTypeAurora; propList->Get("PolarisPortWin",portPolarisWin); propList->Get("AuroraPortWin",portAuroraWin); propList->Get("PortTypePolaris", portTypePolaris); propList->Get("PortTypeAurora", portTypeAurora); propList->Get("MTCalibrationFile",m_MTCalibrationFile); propList->Get("SelectedDevice",SelectedDevice); if (SelectedDevice<0) { MITK_ERROR << "Loaded data from persistence service is invalid (SelectedDevice:" <m_portSpinBoxPolaris->setValue(portPolarisWin); m_Controls->m_portSpinBoxAurora->setValue(portAuroraWin); m_Controls->portTypePolaris->setCurrentIndex(portTypePolaris); m_Controls->portTypeAurora->setCurrentIndex(portTypeAurora); MITK_INFO << "Sucessfully restored UI settings"; } else { // QSettings as a fallback if the persistence service is not available QSettings settings; settings.beginGroup(QString::fromStdString(id)); SelectedDevice = settings.value("trackingDeviceChooser", 0).toInt(); m_Controls->m_portSpinBoxAurora->setValue(settings.value("portSpinBoxAurora", 0).toInt()); m_Controls->m_portSpinBoxPolaris->setValue(settings.value("portSpinBoxPolaris", 0).toInt()); m_Controls->portTypePolaris->setCurrentIndex(settings.value("portTypePolaris", 0).toInt()); m_Controls->portTypeAurora->setCurrentIndex(settings.value("portTypeAurora", 0).toInt()); m_MTCalibrationFile = settings.value("mTCalibrationFile", "").toString().toStdString(); settings.endGroup(); } //the selected device requires some checks because a device that is not installed should not be restored to avoids bugs int selectedDeviceChecked = SelectedDevice; if (SelectedDevice==2 && !mitk::ClaronTrackingDevice::New()->IsDeviceInstalled()) {selectedDeviceChecked = 0;} //0 = Polaris (default) else if (SelectedDevice==3 && !mitk::OptitrackTrackingDevice::New()->IsDeviceInstalled()) {selectedDeviceChecked = 0;} MITK_INFO << "SelectedDeviceChecked: " << selectedDeviceChecked; m_Controls->m_TrackingSystemWidget->setCurrentIndex(selectedDeviceChecked); m_Controls->m_trackingDeviceChooser->setCurrentIndex(selectedDeviceChecked); m_Controls->m_MTCalibrationFile->setText("Calibration File: " + QString::fromStdString(m_MTCalibrationFile)); } void QmitkTrackingDeviceConfigurationWidgetConnectionWorker::TestConnectionThreadFunc() { MITK_INFO << "Testing Connection!"; QString output; bool connected = false; mitk::ProgressBar::GetInstance()->AddStepsToDo(4); try { if (!m_TrackingDevice->IsDeviceInstalled()) { output = "ERROR: Device is not installed!"; } else { //test connection and start tracking, generate output output = "
testing connection
..."; m_TrackingDevice->OpenConnection(); output += "OK"; mitk::ProgressBar::GetInstance()->Progress(); //try start/stop tracking output += "
testing tracking
..."; m_TrackingDevice->StartTracking(); mitk::ProgressBar::GetInstance()->Progress(); m_TrackingDevice->StopTracking(); mitk::ProgressBar::GetInstance()->Progress(); //try close connection m_TrackingDevice->CloseConnection(); mitk::ProgressBar::GetInstance()->Progress(); output += "OK"; connected = true; } } catch(mitk::IGTException &e) { output += "ERROR!"; MITK_WARN << "Error while testing connection / start tracking of the device: " << e.GetDescription(); } mitk::ProgressBar::GetInstance()->Progress(4); emit ConnectionTested(connected,output); } void QmitkTrackingDeviceConfigurationWidgetScanPortsWorker::ScanPortsThreadFunc() { int PolarisPort = -1; int AuroraPort = -1; int PortTypePolaris = -1; int PortTypeAurora = -1; QString result = "
Found Devices:"; int resultSize = result.size(); //remember size of result: if it stays the same no device were found #ifdef WIN32 mitk::ProgressBar::GetInstance()->AddStepsToDo(19); QString devName; for (unsigned int i = 1; i < 20; ++i) { QString statusOutput = "Scanning Port #" + QString::number(i); MITK_INFO << statusOutput.toStdString().c_str(); if (i<10) devName = QString("COM%1").arg(i); else devName = QString("\\\\.\\COM%1").arg(i); // prepend "\\.\ to COM ports >9, to be able to allow connection" mitk::TrackingDeviceType scannedPort = ScanPort(devName); switch (scannedPort) { case mitk::NDIPolaris: result += "
" + devName + ": " + "NDI Polaris"; PolarisPort = i; break; case mitk::NDIAurora: result += "
" + devName + ": " + "NDI Aurora"; AuroraPort = i; break; } mitk::ProgressBar::GetInstance()->Progress(); } #else //linux systems for(unsigned int i = 1; i < 6; ++i) { QString devName = QString("/dev/ttyS%1").arg(i); mitk::TrackingDeviceType scannedPort = ScanPort(devName); switch (scannedPort) { case mitk::NDIPolaris: result += "
" + devName + ": " + "NDI Polaris"; PolarisPort = i; PortTypePolaris = 1; break; case mitk::NDIAurora: result += "
" + devName + ": " + "NDI Aurora"; AuroraPort = i; PortTypeAurora = 1; break; } } for(unsigned int i = 0; i <7; ++i) { QString devName = QString("/dev/ttyUSB%1").arg(i); mitk::TrackingDeviceType scannedPort = ScanPort(devName); switch (scannedPort) { case mitk::NDIPolaris: result += "
" + devName + ": " + "NDI Polaris"; PolarisPort = i; PortTypePolaris = 0; break; case mitk::NDIAurora: result += "
" + devName + ": " + "NDI Aurora"; AuroraPort = i; PortTypeAurora = 0; break; } } #endif if ( result.size() == resultSize) result += "
none"; emit PortsScanned(PolarisPort,AuroraPort,result,PortTypePolaris,PortTypeAurora); } mitk::TrackingDeviceType QmitkTrackingDeviceConfigurationWidgetScanPortsWorker::ScanPort(QString port) { mitk::NDITrackingDevice::Pointer tracker = mitk::NDITrackingDevice::New(); tracker->SetDeviceName(port.toStdString()); mitk::TrackingDeviceType returnValue = mitk::TrackingSystemInvalid; try {returnValue = tracker->TestConnection();} catch (mitk::IGTException) {}//do nothing: there is simply no device on this port return returnValue; } void QmitkTrackingDeviceConfigurationWidgetConnectionWorker::SetTrackingDevice(mitk::TrackingDevice::Pointer t) { m_TrackingDevice = t; } diff --git a/Modules/ImageStatistics/CMakeLists.txt b/Modules/ImageStatistics/CMakeLists.txt index fe177d3216..f4c68ee64b 100644 --- a/Modules/ImageStatistics/CMakeLists.txt +++ b/Modules/ImageStatistics/CMakeLists.txt @@ -1,11 +1,11 @@ MITK_CREATE_MODULE( DEPENDS MitkImageExtraction MitkPlanarFigure PACKAGE_DEPENDS ITK|ITKVTK+ITKConvolution+ITKIOXML - WARNINGS_AS_ERRORS + # WARNINGS_AS_ERRORS ) if(BUILD_TESTING) add_subdirectory(Testing) endif(BUILD_TESTING) diff --git a/Modules/Python/CMakeLists.txt b/Modules/Python/CMakeLists.txt index ec064837e1..3c96e67f95 100644 --- a/Modules/Python/CMakeLists.txt +++ b/Modules/Python/CMakeLists.txt @@ -1,26 +1,26 @@ if( MITK_USE_Python ) if(NOT MITK_USE_SYSTEM_PYTHON) add_definitions( -DUSE_MITK_BUILTIN_PYTHON ) endif() set(OpenCV_DEP ) if(MITK_USE_OpenCV) set(OpenCV_DEP OpenCV) endif() # workaround until testing has a package depends set(SimpleITK_DEP ) if(BUILD_TESTING AND NOT APPLE) set(SimpleITK_DEP SimpleITK) endif() MITK_CREATE_MODULE( DEPENDS MitkCore MitkQtWidgets EXPORT_DEFINE MITK_PYTHON_EXPORT - PACKAGE_DEPENDS Qt4|QtGui CTK|CTKScriptingPythonCore+CTKScriptingPythonWidgets PythonLibs VTK|vtkPython+vtkWrappingPythonCore Numpy ${SimpleITK_DEP} ${OpenCV_DEP} + PACKAGE_DEPENDS Qt4|QtGui Qt5|Widgets CTK|CTKScriptingPythonCore+CTKScriptingPythonWidgets PythonLibs VTK|vtkPython+vtkWrappingPythonCore Numpy ${SimpleITK_DEP} ${OpenCV_DEP} ) configure_file(PythonPath.h.in "${CMAKE_CURRENT_BINARY_DIR}/PythonPath.h" @ONLY) add_subdirectory(Testing) endif() diff --git a/Modules/Python/QmitkPythonVariableStackTableModel.cpp b/Modules/Python/QmitkPythonVariableStackTableModel.cpp index 38ecedaf89..f213bf8641 100755 --- a/Modules/Python/QmitkPythonVariableStackTableModel.cpp +++ b/Modules/Python/QmitkPythonVariableStackTableModel.cpp @@ -1,225 +1,226 @@ /*=================================================================== 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 "QmitkPythonVariableStackTableModel.h" #include #include #include #include #include #include #include "QmitkMimeTypes.h" const QString QmitkPythonVariableStackTableModel::MITK_IMAGE_VAR_NAME = "mitkImage"; const QString QmitkPythonVariableStackTableModel::MITK_SURFACE_VAR_NAME = "mitkSurface"; QmitkPythonVariableStackTableModel::QmitkPythonVariableStackTableModel(QObject *parent) :QAbstractTableModel(parent) { us::ModuleContext* context = us::GetModuleContext(); m_PythonServiceRef = context->GetServiceReference(); m_PythonService = context->GetService(m_PythonServiceRef); m_PythonService->AddPythonCommandObserver( this ); } QmitkPythonVariableStackTableModel::~QmitkPythonVariableStackTableModel() { us::ModuleContext* context = us::GetModuleContext(); context->UngetService( m_PythonServiceRef ); m_PythonService->RemovePythonCommandObserver( this ); } bool QmitkPythonVariableStackTableModel::dropMimeData ( const QMimeData * data, Qt::DropAction action, int row, int column, const QModelIndex & parent ) { // Early exit, returning true, but not actually doing anything (ignoring data). if (action == Qt::IgnoreAction) return true; // Note, we are returning true if we handled it, and false otherwise bool returnValue = false; if(data->hasFormat(QmitkMimeTypes::DataNodePtrs)) { MITK_DEBUG("QmitkPythonVariableStackTableModel") << "dropped MITK DataNode"; returnValue = true; int i = 0; QList dataNodeList = QmitkMimeTypes::ToDataNodePtrList(data); mitk::DataNode* node = NULL; foreach(node, dataNodeList) { mitk::Image* mitkImage = dynamic_cast(node->GetData()); MITK_DEBUG("QmitkPythonVariableStackTableModel") << "mitkImage is not null " << (mitkImage != 0? "true": "false"); QRegExp rx("^\\d"); QString varName(node->GetName().c_str()); // regex replace every character that is not allowed in a python variable varName = varName.replace(QRegExp("[.\\+\\-*\\s\\/\\n\\t\\r]"),QString("_")); if( mitkImage ) { if ( varName.isEmpty() ) varName = MITK_IMAGE_VAR_NAME; if ( rx.indexIn(varName) == 0) varName.prepend("_").prepend(MITK_IMAGE_VAR_NAME); if( i > 0 ) varName = QString("%1%2").arg(varName).arg(i); MITK_DEBUG("QmitkPythonVariableStackTableModel") << "varName" << varName.toStdString(); bool exportAsCvImage = mitkImage->GetDimension() == 2 && m_PythonService->IsOpenCvPythonWrappingAvailable(); if( exportAsCvImage ) { int ret = QMessageBox::question(NULL, "Export option", "2D image detected. Export as OpenCV image to Python instead of an SimpleITK image?", QMessageBox::Yes | QMessageBox::No, QMessageBox::No); exportAsCvImage = ret == QMessageBox::Yes; if(exportAsCvImage) { varName = MITK_IMAGE_VAR_NAME; m_PythonService->CopyToPythonAsCvImage( mitkImage, varName.toStdString() ); ++i; } } if( !exportAsCvImage ) { if( m_PythonService->IsSimpleItkPythonWrappingAvailable() ) { m_PythonService->CopyToPythonAsSimpleItkImage( mitkImage, varName.toStdString() ); ++i; } else { MITK_ERROR << "SimpleITK Python wrapping not available. Skipping export for image " << node->GetName(); } } } else { mitk::Surface* surface = dynamic_cast(node->GetData()); MITK_DEBUG("QmitkPythonVariableStackTableModel") << "found surface"; if( surface ) { if (varName.isEmpty() ) varName = MITK_SURFACE_VAR_NAME; if ( rx.indexIn(varName) == 0) varName.prepend("_").prepend(MITK_SURFACE_VAR_NAME); MITK_DEBUG("QmitkPythonVariableStackTableModel") << "varName" << varName; if( m_PythonService->IsVtkPythonWrappingAvailable() ) { m_PythonService->CopyToPythonAsVtkPolyData( surface, varName.toStdString() ); } else { MITK_ERROR << "VTK Python wrapping not available. Skipping export for surface " << node->GetName(); } } } } } return returnValue; } QVariant QmitkPythonVariableStackTableModel::headerData(int section, Qt::Orientation orientation, int role) const { QVariant headerData; // show only horizontal header if ( role == Qt::DisplayRole ) { if( orientation == Qt::Horizontal ) { // first column: "Attribute" if(section == 0) headerData = "Attribute"; else if(section == 1) headerData = "Type"; else if(section == 2) headerData = "Value"; } } return headerData; } Qt::ItemFlags QmitkPythonVariableStackTableModel::flags(const QModelIndex &index) const { Qt::ItemFlags flags = QAbstractItemModel::flags(index); if(index.isValid()) return Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled | flags; else return Qt::ItemIsDropEnabled | flags; } int QmitkPythonVariableStackTableModel::rowCount(const QModelIndex &) const { return m_VariableStack.size(); } int QmitkPythonVariableStackTableModel::columnCount(const QModelIndex &) const { return 3; } QVariant QmitkPythonVariableStackTableModel::data(const QModelIndex &index, int role) const { if (index.isValid() && !m_VariableStack.empty()) { if(role == Qt::DisplayRole) { mitk::PythonVariable item = m_VariableStack.at(index.row()); if(index.column() == 0) return QString::fromStdString(item.m_Name); if(index.column() == 1) return QString::fromStdString(item.m_Type); if(index.column() == 2) return QString::fromStdString(item.m_Value); } } return QVariant(); } QStringList QmitkPythonVariableStackTableModel::mimeTypes() const { return QAbstractTableModel::mimeTypes(); QStringList types; types << "application/x-mitk-datanodes"; types << "application/x-qabstractitemmodeldatalist"; return types; } Qt::DropActions QmitkPythonVariableStackTableModel::supportedDropActions() const { return Qt::CopyAction | Qt::MoveAction; } void QmitkPythonVariableStackTableModel::CommandExecuted(const std::string& pythonCommand) { MITK_DEBUG("QmitkPythonVariableStackTableModel") << "command was executed " << pythonCommand; m_VariableStack = m_PythonService->GetVariableStack(); - QAbstractTableModel::reset(); + QAbstractTableModel::beginResetModel(); + QAbstractTableModel::endResetModel(); } std::vector QmitkPythonVariableStackTableModel::GetVariableStack() const { return m_VariableStack; } diff --git a/Modules/QtWidgets/CMakeLists.txt b/Modules/QtWidgets/CMakeLists.txt index c55beb2393..408fe878c0 100644 --- a/Modules/QtWidgets/CMakeLists.txt +++ b/Modules/QtWidgets/CMakeLists.txt @@ -1,8 +1,8 @@ MITK_CREATE_MODULE( DEPENDS MitkPlanarFigure MitkOverlays - PACKAGE_DEPENDS VTK|vtkGUISupportQt Qt4|QtGui + PACKAGE_DEPENDS VTK|vtkGUISupportQt Qt4|QtGui Qt5|Widgets SUBPROJECTS MITK-CoreUI EXPORT_DEFINE QMITK_EXPORT ) add_subdirectory(Testing) diff --git a/Modules/QtWidgets/QmitkDataStorageListModel.cpp b/Modules/QtWidgets/QmitkDataStorageListModel.cpp index fe19d6f41c..aff3248a25 100755 --- a/Modules/QtWidgets/QmitkDataStorageListModel.cpp +++ b/Modules/QtWidgets/QmitkDataStorageListModel.cpp @@ -1,273 +1,274 @@ /*=================================================================== 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 "QmitkDataStorageListModel.h" //# Own includes // mitk #include "mitkStringProperty.h" //# Toolkit includes // itk #include "itkCommand.h" QmitkDataStorageListModel::QmitkDataStorageListModel(mitk::DataStorage::Pointer dataStorage , mitk::NodePredicateBase* pred, QObject* parent) : QAbstractListModel(parent), m_NodePredicate(0), m_DataStorage(0), m_BlockEvents(false) { this->SetPredicate(pred); this->SetDataStorage(dataStorage); } QmitkDataStorageListModel::~QmitkDataStorageListModel() { // set data storage to 0 so that event listener get removed this->SetDataStorage(0); if (m_NodePredicate) delete m_NodePredicate; } void QmitkDataStorageListModel::SetDataStorage(mitk::DataStorage::Pointer dataStorage) { if( m_DataStorage != dataStorage) { // remove old listeners if(m_DataStorage != 0) { this->m_DataStorage->AddNodeEvent.RemoveListener( mitk::MessageDelegate1( this, &QmitkDataStorageListModel::NodeAdded ) ); this->m_DataStorage->RemoveNodeEvent.RemoveListener( mitk::MessageDelegate1( this, &QmitkDataStorageListModel::NodeRemoved ) ); // remove delete observer m_DataStorage->RemoveObserver(m_DataStorageDeleteObserverTag); // this is good coding style ! reset variables whenever they are not used anymore. m_DataStorageDeleteObserverTag = 0; } m_DataStorage = dataStorage; // remove event listeners if(m_DataStorage != 0) { // subscribe for node added/removed events this->m_DataStorage->AddNodeEvent.AddListener( mitk::MessageDelegate1( this, &QmitkDataStorageListModel::NodeAdded ) ); this->m_DataStorage->RemoveNodeEvent.AddListener( mitk::MessageDelegate1( this, &QmitkDataStorageListModel::NodeRemoved ) ); // add itk delete listener on datastorage itk::MemberCommand::Pointer deleteCommand = itk::MemberCommand::New(); deleteCommand->SetCallbackFunction(this, &QmitkDataStorageListModel::OnDelete); // add observer m_DataStorageDeleteObserverTag = m_DataStorage->AddObserver(itk::DeleteEvent(), deleteCommand); } // reset model reset(); } } Qt::ItemFlags QmitkDataStorageListModel::flags(const QModelIndex&) const { return Qt::ItemIsEnabled | Qt::ItemIsSelectable; } QVariant QmitkDataStorageListModel::data(const QModelIndex& index, int role) const { if(index.isValid()) { switch ( role ) { case Qt::DisplayRole: { const mitk::DataNode* node = m_DataNodes.at(index.row()); std::string name = node->GetName(); return QVariant(QString::fromStdString(name)); } break; } } // index.isValid() return QVariant(); } QVariant QmitkDataStorageListModel::headerData(int /*section*/, Qt::Orientation /*orientation*/, int /*role*/) const { return QVariant("Nodes"); } int QmitkDataStorageListModel::rowCount(const QModelIndex& /*parent*/) const { return m_DataNodes.size(); } std::vector QmitkDataStorageListModel::GetDataNodes() const { return m_DataNodes; } mitk::DataStorage::Pointer QmitkDataStorageListModel::GetDataStorage() const { return m_DataStorage; } void QmitkDataStorageListModel::SetPredicate(mitk::NodePredicateBase* pred) { m_NodePredicate = pred; reset(); - QAbstractListModel::reset(); + QAbstractListModel::beginResetModel(); + QAbstractListModel::endResetModel(); } mitk::NodePredicateBase* QmitkDataStorageListModel::GetPredicate() const { return m_NodePredicate; } void QmitkDataStorageListModel::reset() { if(m_DataStorage != 0) { mitk::DataStorage::SetOfObjects::ConstPointer setOfObjects; if (m_NodePredicate) setOfObjects = m_DataStorage->GetSubset(m_NodePredicate); else setOfObjects = m_DataStorage->GetAll(); // remove all observes unsigned int i = 0; for(std::vector::iterator it=m_DataNodes.begin() ; it!=m_DataNodes.end() ; ++it, ++i) { (*it)->RemoveObserver(m_DataNodesModifiedObserversTags[i]); } // clear vector with nodes m_DataNodesModifiedObserversTags.clear(); m_DataNodes.clear(); itk::MemberCommand::Pointer modifiedCommand; // copy all selected nodes the vector for (mitk::DataStorage::SetOfObjects::ConstIterator nodeIt = setOfObjects->Begin() ; nodeIt != setOfObjects->End(); ++nodeIt, ++i) // for each node { // add modified observer modifiedCommand = itk::MemberCommand::New(); modifiedCommand->SetCallbackFunction(this, &QmitkDataStorageListModel::OnModified); m_DataNodesModifiedObserversTags.push_back( m_DataStorage->AddObserver(itk::ModifiedEvent(), modifiedCommand) ); m_DataNodes.push_back( nodeIt.Value().GetPointer()); } // for } // m_DataStorage != 0 } // reset() void QmitkDataStorageListModel::NodeAdded( const mitk::DataNode* node ) { // garantuee no recursions when a new node event is thrown if(!m_BlockEvents) { m_BlockEvents = true; // check if node should be added to the model bool addNode = true; if(m_NodePredicate && !m_NodePredicate->CheckNode(node)) addNode = false; if(addNode) { beginInsertRows(QModelIndex(), m_DataNodes.size(), m_DataNodes.size()); //reset(); m_DataNodes.push_back(const_cast(node)); endInsertRows(); } m_BlockEvents = false; } } void QmitkDataStorageListModel::NodeRemoved( const mitk::DataNode* node ) { // garantuee no recursions when a new node event is thrown if(!m_BlockEvents) { m_BlockEvents = true; int row = -1; //bool removeNode = false; // check if node is contained in current list, if yes: reset model for (std::vector::const_iterator nodeIt = m_DataNodes.begin() ; nodeIt != m_DataNodes.end(); nodeIt++) // for each node { row++; if( (*nodeIt) == node ) { // node found, remove it beginRemoveRows(QModelIndex(), row, row); m_DataNodes.erase(std::find(m_DataNodes.begin(), m_DataNodes.end(), (*nodeIt))); endRemoveRows(); break; } } m_BlockEvents = false; } } void QmitkDataStorageListModel::OnModified( const itk::Object *caller, const itk::EventObject & /*event*/ ) { if(m_BlockEvents) return; const mitk::DataNode* modifiedNode = dynamic_cast(caller); if(modifiedNode) { int row = std::distance(std::find(m_DataNodes.begin(), m_DataNodes.end(), modifiedNode), m_DataNodes.end()); QModelIndex indexOfChangedProperty = index(row, 1); emit dataChanged(indexOfChangedProperty, indexOfChangedProperty); } } void QmitkDataStorageListModel::OnDelete( const itk::Object *caller, const itk::EventObject & /*event*/ ) { if(m_BlockEvents) return; const mitk::DataStorage* dataStorage = dynamic_cast(caller); if(dataStorage) { // set datastorage to 0 -> empty model this->SetDataStorage(0); } } mitk::DataNode::Pointer QmitkDataStorageListModel::getNode( const QModelIndex &index ) const { mitk::DataNode::Pointer node; if(index.isValid()) { node = m_DataNodes.at(index.row()); } return node; } diff --git a/Modules/QtWidgets/QmitkDataStorageTableModel.cpp b/Modules/QtWidgets/QmitkDataStorageTableModel.cpp index dbedb4b827..648b893e8c 100644 --- a/Modules/QtWidgets/QmitkDataStorageTableModel.cpp +++ b/Modules/QtWidgets/QmitkDataStorageTableModel.cpp @@ -1,525 +1,526 @@ /*=================================================================== 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 "QmitkDataStorageTableModel.h" //# Own includes #include "mitkNodePredicateBase.h" #include "mitkProperties.h" #include "mitkRenderingManager.h" #include "QmitkEnums.h" #include "QmitkCustomVariants.h" #include //# Toolkit includes #include #include #include //#CTORS/DTOR QmitkDataStorageTableModel::QmitkDataStorageTableModel(mitk::DataStorage::Pointer _DataStorage , mitk::NodePredicateBase* _Predicate , QObject* parent ) : QAbstractTableModel(parent) , m_DataStorage(0) , m_Predicate(0) , m_BlockEvents(false) , m_SortDescending(false) { this->SetPredicate(_Predicate); this->SetDataStorage(_DataStorage); } QmitkDataStorageTableModel::~QmitkDataStorageTableModel() { // set data storage 0 to remove event listeners this->SetDataStorage(0); } //# Public GETTER const mitk::DataStorage::Pointer QmitkDataStorageTableModel::GetDataStorage() const { return m_DataStorage.GetPointer(); } mitk::NodePredicateBase::Pointer QmitkDataStorageTableModel::GetPredicate() const { return m_Predicate; } mitk::DataNode::Pointer QmitkDataStorageTableModel::GetNode( const QModelIndex &index ) const { mitk::DataNode::Pointer node; if(index.isValid()) { node = m_NodeSet.at(index.row()); } return node; } QVariant QmitkDataStorageTableModel::headerData(int section, Qt::Orientation orientation, int role) const { QVariant headerData; // show only horizontal header if ( role == Qt::DisplayRole ) { if( orientation == Qt::Horizontal ) { // first column: "Name" if(section == 0) headerData = "Name"; else if(section == 1) headerData = "Data Type"; else if(section == 2) headerData = "Visibility"; } else if( orientation == Qt::Vertical ) { // show numbers for rows headerData = section+1; } } return headerData; } Qt::ItemFlags QmitkDataStorageTableModel::flags(const QModelIndex &index) const { Qt::ItemFlags flags = QAbstractItemModel::flags(index); // name & visibility is editable if (index.column() == 0) { flags |= Qt::ItemIsEditable; } else if (index.column() == 2) { flags |= Qt::ItemIsUserCheckable; } return flags; } int QmitkDataStorageTableModel::rowCount(const QModelIndex &) const { return m_NodeSet.size(); } int QmitkDataStorageTableModel::columnCount(const QModelIndex &) const { // show name, type and visible columnn int columns = 3; return columns; } QVariant QmitkDataStorageTableModel::data(const QModelIndex &index, int role) const { QVariant data; if (index.isValid() && !m_NodeSet.empty()) { mitk::DataNode::Pointer node = m_NodeSet.at(index.row()); std::string nodeName = node->GetName(); if(nodeName.empty()) nodeName = "unnamed"; // get name if(index.column() == 0) { // get name of node (may also be edited) if (role == Qt::DisplayRole || role == Qt::EditRole) { data = QFile::encodeName(nodeName.c_str()); } else if (role == QmitkDataNodeRole) { data = QVariant::fromValue(node); } } else if (index.column() == 1) { QmitkNodeDescriptor* nodeDescriptor = QmitkNodeDescriptorManager::GetInstance()->GetDescriptor(node); // get type property of mitk::BaseData if (role == Qt::DisplayRole) { data = nodeDescriptor->GetClassName(); } // show some nice icons for datatype else if(role == Qt::DecorationRole) { data = nodeDescriptor->GetIcon(); } } else if (index.column() == 2) { // get visible property of mitk::BaseData bool visibility = false; if(node->GetVisibility(visibility, 0) && role == Qt::CheckStateRole) { data = (visibility ? Qt::Checked : Qt::Unchecked); } // node->GetVisibility(visibility, 0) && role == Qt::CheckStateRole } // index.column() == 2 } // index.isValid() && !m_NodeSet.empty() return data; } //# Public SETTERS void QmitkDataStorageTableModel::SetPredicate( mitk::NodePredicateBase* _Predicate ) { // ensure that a new predicate is set in order to avoid unnecessary changed events if(m_Predicate != _Predicate) { m_Predicate = _Predicate; this->Reset(); } } void QmitkDataStorageTableModel::SetDataStorage( mitk::DataStorage::Pointer _DataStorage ) { // only proceed if we have a new datastorage if(m_DataStorage.GetPointer() != _DataStorage.GetPointer()) { // if a data storage was set before remove old event listeners if(m_DataStorage.IsNotNull()) { this->m_DataStorage->AddNodeEvent.RemoveListener( mitk::MessageDelegate1( this, &QmitkDataStorageTableModel::AddNode ) ); this->m_DataStorage->RemoveNodeEvent.RemoveListener( mitk::MessageDelegate1( this, &QmitkDataStorageTableModel::RemoveNode ) ); } // set new data storage m_DataStorage = _DataStorage.GetPointer(); // if new storage is not 0 subscribe for events if(m_DataStorage.IsNotNull()) { // subscribe for node added/removed events this->m_DataStorage->AddNodeEvent.AddListener( mitk::MessageDelegate1( this, &QmitkDataStorageTableModel::AddNode ) ); this->m_DataStorage->RemoveNodeEvent.AddListener( mitk::MessageDelegate1( this, &QmitkDataStorageTableModel::RemoveNode ) ); } // Reset model (even if datastorage is 0->will be checked in Reset()) this->Reset(); } } void QmitkDataStorageTableModel::AddNode( const mitk::DataNode* node ) { // garantuee no recursions when a new node event is thrown if(!m_BlockEvents) { // if we have a predicate, check node against predicate first if(m_Predicate.IsNotNull() && !m_Predicate->CheckNode(node)) return; // dont add nodes without data (formerly known as helper objects) if(node->GetData() == 0) return; // create listener commands to listen to changes in the name or the visibility of the node itk::MemberCommand::Pointer propertyModifiedCommand = itk::MemberCommand::New(); propertyModifiedCommand->SetCallbackFunction(this, &QmitkDataStorageTableModel::PropertyModified); mitk::BaseProperty* tempProperty = 0; // add listener for properties tempProperty = node->GetProperty("visible"); if(tempProperty) m_VisiblePropertyModifiedObserverTags[tempProperty] = tempProperty->AddObserver(itk::ModifiedEvent(), propertyModifiedCommand); tempProperty = node->GetProperty("name"); if(tempProperty) m_NamePropertyModifiedObserverTags[tempProperty] = tempProperty->AddObserver(itk::ModifiedEvent(), propertyModifiedCommand); // emit beginInsertRows event beginInsertRows(QModelIndex(), m_NodeSet.size(), m_NodeSet.size()); // add node m_NodeSet.push_back(const_cast(node)); // emit endInsertRows event endInsertRows(); } } void QmitkDataStorageTableModel::RemoveNode( const mitk::DataNode* node ) { // garantuee no recursions when a new node event is thrown if(!m_BlockEvents) { // find corresponding node std::vector::iterator nodeIt = std::find(m_NodeSet.begin(), m_NodeSet.end(), node); if(nodeIt != m_NodeSet.end()) { // now: remove listeners for name property ... mitk::BaseProperty* tempProperty = 0; tempProperty = (*nodeIt)->GetProperty("visible"); if(tempProperty) tempProperty->RemoveObserver(m_VisiblePropertyModifiedObserverTags[tempProperty]); m_VisiblePropertyModifiedObserverTags.erase(tempProperty); // ... and visibility property tempProperty = (*nodeIt)->GetProperty("name"); if(tempProperty) tempProperty->RemoveObserver(m_NamePropertyModifiedObserverTags[tempProperty]); m_NamePropertyModifiedObserverTags.erase(tempProperty); // get an index from iterator int row = std::distance(m_NodeSet.begin(), nodeIt); // emit beginRemoveRows event (QModelIndex is empty because we dont have a tree model) this->beginRemoveRows(QModelIndex(), row, row); // remove node m_NodeSet.erase(nodeIt); // emit endRemoveRows event endRemoveRows(); } } } void QmitkDataStorageTableModel::PropertyModified( const itk::Object *caller, const itk::EventObject & ) { if(!m_BlockEvents) { // get modified property const mitk::BaseProperty* modifiedProperty = dynamic_cast(caller); if(modifiedProperty) { // find node that holds the modified property int row = -1; int column = -1; std::vector::iterator it; mitk::BaseProperty* visibilityProperty = 0; mitk::BaseProperty* nameProperty = 0; // search for property that changed and emit datachanged on the corresponding ModelIndex for(it=m_NodeSet.begin(); it!=m_NodeSet.end(); it++) { // check for the visible property or the name property visibilityProperty = (*it)->GetProperty("visible"); if(modifiedProperty == visibilityProperty) { column = 2; break; } nameProperty = (*it)->GetProperty("name"); if(modifiedProperty == nameProperty) { column = 0; break; } } // if we have the property we have a valid iterator if( it != m_NodeSet.end() ) row = std::distance(m_NodeSet.begin(), it); // now emit the dataChanged signal QModelIndex indexOfChangedProperty = index(row, column); emit dataChanged(indexOfChangedProperty, indexOfChangedProperty); } } } bool QmitkDataStorageTableModel::setData(const QModelIndex &index, const QVariant &value, int role) { bool noErr = false; if (index.isValid() && (role == Qt::EditRole || role == Qt::CheckStateRole)) { // any change events produced here should not be caught in this class // --> set m_BlockEvents to true m_BlockEvents = true; mitk::DataNode::Pointer node = m_NodeSet.at(index.row()); if(index.column() == 0) { node->SetStringProperty("name", value.toString().toStdString().c_str()); } else if(index.column() == 2) { node->SetBoolProperty("visible", (value.toInt() == Qt::Checked ? true : false)); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } // inform listeners about changes emit dataChanged(index, index); m_BlockEvents = false; noErr = true; } return noErr; } //#Protected SETTER void QmitkDataStorageTableModel::Reset() { mitk::DataStorage::SetOfObjects::ConstPointer _NodeSet; // remove all nodes now (dont use iterators because removing elements // would invalidate the iterator) // start at the last element: first in, last out unsigned int i = m_NodeSet.size(); while(!m_NodeSet.empty()) { --i; this->RemoveNode(m_NodeSet.at(i)); } // normally now everything should be empty->just to be sure // erase all arrays again m_NamePropertyModifiedObserverTags.clear(); m_VisiblePropertyModifiedObserverTags.clear(); m_NodeSet.clear(); // the whole reset depends on the fact if a data storage is set or not if(m_DataStorage.IsNotNull()) { if(m_Predicate.IsNotNull()) // get subset _NodeSet = m_DataStorage->GetSubset(m_Predicate); // if predicate is NULL, select all nodes else { _NodeSet = m_DataStorage->GetAll(); // remove ghost root node } // finally add all nodes to the model for(mitk::DataStorage::SetOfObjects::const_iterator it=_NodeSet->begin(); it!=_NodeSet->end() ; it++) { // save node this->AddNode(*it); } } } void QmitkDataStorageTableModel::sort( int column, Qt::SortOrder order /*= Qt::AscendingOrder */ ) { bool sortDescending = (order == Qt::DescendingOrder) ? true: false; // do not sort twice !!! (dont know why, but qt calls this func twice. STUPID!) /* if(sortDescending != m_SortDescending) {*/ //m_SortDescending = sortDescending; DataNodeCompareFunction::CompareCriteria _CompareCriteria = DataNodeCompareFunction::CompareByName; DataNodeCompareFunction::CompareOperator _CompareOperator = sortDescending ? DataNodeCompareFunction::Greater: DataNodeCompareFunction::Less; if(column == 1) _CompareCriteria = DataNodeCompareFunction::CompareByClassName; else if(column == 2) _CompareCriteria = DataNodeCompareFunction::CompareByVisibility; DataNodeCompareFunction compareFunc(_CompareCriteria, _CompareOperator); std::sort(m_NodeSet.begin(), m_NodeSet.end(), compareFunc); - QAbstractTableModel::reset(); + QAbstractTableModel::beginResetModel(); + QAbstractTableModel::endResetModel(); //} } std::vector QmitkDataStorageTableModel::GetNodeSet() const { return m_NodeSet; } QmitkDataStorageTableModel::DataNodeCompareFunction::DataNodeCompareFunction( CompareCriteria _CompareCriteria , CompareOperator _CompareOperator ) : m_CompareCriteria(_CompareCriteria) , m_CompareOperator(_CompareOperator) { } bool QmitkDataStorageTableModel::DataNodeCompareFunction::operator() ( const mitk::DataNode::Pointer& _Left , const mitk::DataNode::Pointer& _Right ) const { switch(m_CompareCriteria) { case CompareByClassName: if(m_CompareOperator == Less) return (_Left->GetData()->GetNameOfClass() < _Right->GetData()->GetNameOfClass() ); else return (_Left->GetData()->GetNameOfClass() > _Right->GetData()->GetNameOfClass() ); break; case CompareByVisibility: { bool _LeftVisibility = false; bool _RightVisibility = false; _Left->GetVisibility(_LeftVisibility, 0); _Right->GetVisibility(_RightVisibility, 0); if(m_CompareOperator == Less) return (_LeftVisibility < _RightVisibility); else return (_LeftVisibility > _RightVisibility); } break; // CompareByName: default: if(m_CompareOperator == Less) return (_Left->GetName() < _Right->GetName()); else return (_Left->GetName() > _Right->GetName()); break; } } diff --git a/Modules/QtWidgets/QmitkDataStorageTreeModel.cpp b/Modules/QtWidgets/QmitkDataStorageTreeModel.cpp index e5c540b57a..09be20d85c 100644 --- a/Modules/QtWidgets/QmitkDataStorageTreeModel.cpp +++ b/Modules/QtWidgets/QmitkDataStorageTreeModel.cpp @@ -1,858 +1,860 @@ /*=================================================================== 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 #include #include #include #include #include #include #include #include #include #include "QmitkDataStorageTreeModel.h" #include "QmitkNodeDescriptorManager.h" #include #include #include #include #include #include #include #include QmitkDataStorageTreeModel::QmitkDataStorageTreeModel( mitk::DataStorage* _DataStorage , bool _PlaceNewNodesOnTop , QObject* parent ) : QAbstractItemModel(parent) , m_DataStorage(0) , m_PlaceNewNodesOnTop(_PlaceNewNodesOnTop) , m_Root(0) { this->SetDataStorage(_DataStorage); } QmitkDataStorageTreeModel::~QmitkDataStorageTreeModel() { // set data storage to 0 = remove all listeners this->SetDataStorage(0); m_Root->Delete(); m_Root = 0; } mitk::DataNode::Pointer QmitkDataStorageTreeModel::GetNode( const QModelIndex &index ) const { return this->TreeItemFromIndex(index)->GetDataNode(); } const mitk::DataStorage::Pointer QmitkDataStorageTreeModel::GetDataStorage() const { return m_DataStorage.GetPointer(); } QModelIndex QmitkDataStorageTreeModel::index( int row, int column, const QModelIndex & parent ) const { TreeItem* parentItem; if (!parent.isValid()) parentItem = m_Root; else parentItem = static_cast(parent.internalPointer()); TreeItem *childItem = parentItem->GetChild(row); if (childItem) return createIndex(row, column, childItem); else return QModelIndex(); } int QmitkDataStorageTreeModel::rowCount(const QModelIndex &parent) const { TreeItem *parentTreeItem = this->TreeItemFromIndex(parent); return parentTreeItem->GetChildCount(); } Qt::ItemFlags QmitkDataStorageTreeModel::flags( const QModelIndex& index ) const { mitk::DataNode* dataNode = this->TreeItemFromIndex(index)->GetDataNode(); if (index.isValid()) { if(DicomPropertiesExists(*dataNode)) { return Qt::ItemIsUserCheckable | Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled; } return Qt::ItemIsUserCheckable | Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsEditable | Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled; }else{ return Qt::ItemIsDropEnabled; } } int QmitkDataStorageTreeModel::columnCount( const QModelIndex& /* parent = QModelIndex() */ ) const { return 1; } QModelIndex QmitkDataStorageTreeModel::parent(const QModelIndex &index) const { if (!index.isValid()) return QModelIndex(); TreeItem *childItem = this->TreeItemFromIndex(index); TreeItem *parentItem = childItem->GetParent(); if (parentItem == m_Root) return QModelIndex(); return this->createIndex(parentItem->GetIndex(), 0, parentItem); } QmitkDataStorageTreeModel::TreeItem* QmitkDataStorageTreeModel::TreeItemFromIndex( const QModelIndex &index ) const { if (index.isValid()) return static_cast(index.internalPointer()); else return m_Root; } Qt::DropActions QmitkDataStorageTreeModel::supportedDropActions() const { return Qt::CopyAction | Qt::MoveAction; } Qt::DropActions QmitkDataStorageTreeModel::supportedDragActions() const { return Qt::CopyAction | Qt::MoveAction; } bool QmitkDataStorageTreeModel::dropMimeData(const QMimeData *data, Qt::DropAction action, int /*row*/, int /*column*/, const QModelIndex &parent) { // Early exit, returning true, but not actually doing anything (ignoring data). if (action == Qt::IgnoreAction) { return true; } // Note, we are returning true if we handled it, and false otherwise bool returnValue = false; if(data->hasFormat("application/x-qabstractitemmodeldatalist")) { returnValue = true; // First we extract a Qlist of TreeItem* pointers. QList listOfItemsToDrop = ToTreeItemPtrList(data); // Retrieve the TreeItem* where we are dropping stuff, and its parent. TreeItem* dropItem = this->TreeItemFromIndex(parent); TreeItem* parentItem = dropItem->GetParent(); // If item was dropped onto empty space, we select the root node if(dropItem == m_Root) { parentItem = m_Root; } // Dragging and Dropping is only allowed within the same parent, so use the first item in list to validate. // (otherwise, you could have a derived image such as a segmentation, and assign it to another image). // NOTE: We are assuming the input list is valid... i.e. when it was dragged, all the items had the same parent. if(listOfItemsToDrop[0] != dropItem && listOfItemsToDrop[0]->GetParent() == parentItem) { // Retrieve the index of where we are dropping stuff. QModelIndex dropItemModelIndex = this->IndexFromTreeItem(dropItem); QModelIndex parentModelIndex = this->IndexFromTreeItem(parentItem); // Iterate through the list of TreeItem (which may be at non-consecutive indexes). QList::iterator diIter; for (diIter = listOfItemsToDrop.begin(); diIter != listOfItemsToDrop.end(); diIter++) { // Here we assume that as you remove items, one at a time, that GetIndex() will be valid. this->beginRemoveRows(parentModelIndex, (*diIter)->GetIndex(), (*diIter)->GetIndex()); parentItem->RemoveChild(*diIter); this->endRemoveRows(); } // Select the target index position, or put it at the end of the list. int dropIndex = dropItemModelIndex.row(); if (dropIndex == -1) { dropIndex = parentItem->GetChildCount(); } // Now insert items again at the drop item position this->beginInsertRows(parentModelIndex, dropIndex, dropIndex + listOfItemsToDrop.size() - 1); for (diIter = listOfItemsToDrop.begin(); diIter != listOfItemsToDrop.end(); diIter++) { parentItem->InsertChild( (*diIter), dropIndex ); dropIndex++; } this->endInsertRows(); // Change Layers to match. this->AdjustLayerProperty(); } } else if(data->hasFormat("application/x-mitk-datanodes")) { returnValue = true; int numberOfNodesDropped = 0; QList dataNodeList = QmitkMimeTypes::ToDataNodePtrList(data); mitk::DataNode* node = NULL; foreach(node, dataNodeList) { if(node && m_DataStorage.IsNotNull() && !m_DataStorage->Exists(node)) { m_DataStorage->Add( node ); mitk::BaseData::Pointer basedata = node->GetData(); if (basedata.IsNotNull()) { mitk::RenderingManager::GetInstance()->InitializeViews( basedata->GetTimeGeometry(), mitk::RenderingManager::REQUEST_UPDATE_ALL, true ); numberOfNodesDropped++; } } } // Only do a rendering update, if we actually dropped anything. if (numberOfNodesDropped > 0) { mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } } return returnValue; } QStringList QmitkDataStorageTreeModel::mimeTypes() const { QStringList types = QAbstractItemModel::mimeTypes(); types << "application/x-qabstractitemmodeldatalist"; types << "application/x-mitk-datanodes"; return types; } QMimeData * QmitkDataStorageTreeModel::mimeData(const QModelIndexList & indexes) const { return mimeDataFromModelIndexList(indexes); } QMimeData *QmitkDataStorageTreeModel::mimeDataFromModelIndexList(const QModelIndexList &indexes) { QMimeData * ret = new QMimeData; QString treeItemAddresses(""); QString dataNodeAddresses(""); QByteArray baTreeItemPtrs; QByteArray baDataNodePtrs; QDataStream dsTreeItemPtrs(&baTreeItemPtrs, QIODevice::WriteOnly); QDataStream dsDataNodePtrs(&baDataNodePtrs, QIODevice::WriteOnly); for (int i = 0; i < indexes.size(); i++) { TreeItem* treeItem = static_cast(indexes.at(i).internalPointer()); dsTreeItemPtrs << reinterpret_cast(treeItem); dsDataNodePtrs << reinterpret_cast(treeItem->GetDataNode().GetPointer()); // --------------- deprecated ----------------- unsigned long long treeItemAddress = reinterpret_cast(treeItem); unsigned long long dataNodeAddress = reinterpret_cast(treeItem->GetDataNode().GetPointer()); QTextStream(&treeItemAddresses) << treeItemAddress; QTextStream(&dataNodeAddresses) << dataNodeAddress; if (i != indexes.size() - 1) { QTextStream(&treeItemAddresses) << ","; QTextStream(&dataNodeAddresses) << ","; } // -------------- end deprecated ------------- } // ------------------ deprecated ----------------- - ret->setData("application/x-qabstractitemmodeldatalist", QByteArray(treeItemAddresses.toAscii())); - ret->setData("application/x-mitk-datanodes", QByteArray(dataNodeAddresses.toAscii())); + ret->setData("application/x-qabstractitemmodeldatalist", QByteArray(treeItemAddresses.toLatin1())); + ret->setData("application/x-mitk-datanodes", QByteArray(dataNodeAddresses.toLatin1())); // --------------- end deprecated ----------------- ret->setData(QmitkMimeTypes::DataStorageTreeItemPtrs, baTreeItemPtrs); ret->setData(QmitkMimeTypes::DataNodePtrs, baDataNodePtrs); return ret; } QVariant QmitkDataStorageTreeModel::data( const QModelIndex & index, int role ) const { mitk::DataNode* dataNode = this->TreeItemFromIndex(index)->GetDataNode(); // get name of treeItem (may also be edited) QString nodeName; if(DicomPropertiesExists(*dataNode)) { mitk::BaseProperty* seriesDescription = (dataNode->GetProperty("dicom.series.SeriesDescription")); mitk::BaseProperty* studyDescription = (dataNode->GetProperty("dicom.study.StudyDescription")); mitk::BaseProperty* patientsName = (dataNode->GetProperty("dicom.patient.PatientsName")); nodeName += QFile::encodeName(patientsName->GetValueAsString().c_str()) + "\n"; nodeName += QFile::encodeName(studyDescription->GetValueAsString().c_str()) + "\n"; nodeName += QFile::encodeName(seriesDescription->GetValueAsString().c_str()); } else { nodeName = QFile::encodeName(dataNode->GetName().c_str()); } if(nodeName.isEmpty()) { nodeName = "unnamed"; } if (role == Qt::DisplayRole) return nodeName; else if(role == Qt::ToolTipRole) return nodeName; else if(role == Qt::DecorationRole) { QmitkNodeDescriptor* nodeDescriptor = QmitkNodeDescriptorManager::GetInstance()->GetDescriptor(dataNode); return nodeDescriptor->GetIcon(); } else if(role == Qt::CheckStateRole) { return dataNode->IsVisible(0); } else if(role == QmitkDataNodeRole) { return QVariant::fromValue(mitk::DataNode::Pointer(dataNode)); } else if(role == QmitkDataNodeRawPointerRole) { return QVariant::fromValue(dataNode); } return QVariant(); } bool QmitkDataStorageTreeModel::DicomPropertiesExists(const mitk::DataNode& node) const { bool propertiesExists = false; mitk::BaseProperty* seriesDescription = (node.GetProperty("dicom.series.SeriesDescription")); mitk::BaseProperty* studyDescription = (node.GetProperty("dicom.study.StudyDescription")); mitk::BaseProperty* patientsName = (node.GetProperty("dicom.patient.PatientsName")); if(patientsName!=NULL && studyDescription!=NULL && seriesDescription!=NULL) { if((!patientsName->GetValueAsString().empty())&& (!studyDescription->GetValueAsString().empty())&& (!seriesDescription->GetValueAsString().empty())) { propertiesExists = true; } } return propertiesExists; } QVariant QmitkDataStorageTreeModel::headerData(int /*section*/, Qt::Orientation orientation, int role) const { if (orientation == Qt::Horizontal && role == Qt::DisplayRole && m_Root) return QString::fromStdString(m_Root->GetDataNode()->GetName()); return QVariant(); } void QmitkDataStorageTreeModel::SetDataStorage( mitk::DataStorage* _DataStorage ) { if(m_DataStorage != _DataStorage) // dont take the same again { if(m_DataStorage.IsNotNull()) { // remove Listener for the data storage itself m_DataStorage.ObjectDelete.RemoveListener( mitk::MessageDelegate1( this, &QmitkDataStorageTreeModel::SetDataStorageDeleted ) ); // remove listeners for the nodes m_DataStorage->AddNodeEvent.RemoveListener( mitk::MessageDelegate1( this, &QmitkDataStorageTreeModel::AddNode ) ); m_DataStorage->ChangedNodeEvent.RemoveListener( mitk::MessageDelegate1( this, &QmitkDataStorageTreeModel::SetNodeModified ) ); m_DataStorage->RemoveNodeEvent.RemoveListener( mitk::MessageDelegate1( this, &QmitkDataStorageTreeModel::RemoveNode ) ); } // take over the new data storage m_DataStorage = _DataStorage; // delete the old root (if necessary, create new) if(m_Root) m_Root->Delete(); mitk::DataNode::Pointer rootDataNode = mitk::DataNode::New(); rootDataNode->SetName("Data Manager"); m_Root = new TreeItem(rootDataNode, 0); - this->reset(); + this->beginResetModel(); + this->endResetModel(); if(m_DataStorage.IsNotNull()) { // add Listener for the data storage itself m_DataStorage.ObjectDelete.AddListener( mitk::MessageDelegate1( this, &QmitkDataStorageTreeModel::SetDataStorageDeleted ) ); // add listeners for the nodes m_DataStorage->AddNodeEvent.AddListener( mitk::MessageDelegate1( this, &QmitkDataStorageTreeModel::AddNode ) ); m_DataStorage->ChangedNodeEvent.AddListener( mitk::MessageDelegate1( this, &QmitkDataStorageTreeModel::SetNodeModified ) ); m_DataStorage->RemoveNodeEvent.AddListener( mitk::MessageDelegate1( this, &QmitkDataStorageTreeModel::RemoveNode ) ); mitk::DataStorage::SetOfObjects::ConstPointer _NodeSet = m_DataStorage->GetSubset(m_Predicate); // finally add all nodes to the model this->Update(); } } } void QmitkDataStorageTreeModel::SetDataStorageDeleted( const itk::Object* /*_DataStorage*/ ) { this->SetDataStorage(0); } void QmitkDataStorageTreeModel::AddNodeInternal(const mitk::DataNode *node) { if(node == 0 || m_DataStorage.IsNull() || !m_DataStorage->Exists(node) || m_Root->Find(node) != 0) return; // find out if we have a root node TreeItem* parentTreeItem = m_Root; QModelIndex index; mitk::DataNode* parentDataNode = this->GetParentNode(node); if(parentDataNode) // no top level data node { parentTreeItem = m_Root->Find(parentDataNode); // find the corresponding tree item if(!parentTreeItem) { this->AddNode(parentDataNode); parentTreeItem = m_Root->Find(parentDataNode); if(!parentTreeItem) return; } // get the index of this parent with the help of the grand parent index = this->createIndex(parentTreeItem->GetIndex(), 0, parentTreeItem); } // add node if(m_PlaceNewNodesOnTop) { // emit beginInsertRows event beginInsertRows(index, 0, 0); parentTreeItem->InsertChild(new TreeItem( const_cast(node)), 0); } else { beginInsertRows(index, parentTreeItem->GetChildCount() , parentTreeItem->GetChildCount()); new TreeItem(const_cast(node), parentTreeItem); } // emit endInsertRows event endInsertRows(); this->AdjustLayerProperty(); } void QmitkDataStorageTreeModel::AddNode( const mitk::DataNode* node ) { if(node == 0 || m_DataStorage.IsNull() || !m_DataStorage->Exists(node) || m_Root->Find(node) != 0) return; this->AddNodeInternal(node); } void QmitkDataStorageTreeModel::SetPlaceNewNodesOnTop(bool _PlaceNewNodesOnTop) { m_PlaceNewNodesOnTop = _PlaceNewNodesOnTop; } void QmitkDataStorageTreeModel::RemoveNodeInternal( const mitk::DataNode* node ) { if(!m_Root) return; TreeItem* treeItem = m_Root->Find(node); if(!treeItem) return; // return because there is no treeitem containing this node TreeItem* parentTreeItem = treeItem->GetParent(); QModelIndex parentIndex = this->IndexFromTreeItem(parentTreeItem); // emit beginRemoveRows event (QModelIndex is empty because we dont have a tree model) this->beginRemoveRows(parentIndex, treeItem->GetIndex(), treeItem->GetIndex()); // remove node std::vector children = treeItem->GetChildren(); delete treeItem; // emit endRemoveRows event endRemoveRows(); // move all children of deleted node into its parent for ( std::vector::iterator it = children.begin() ; it != children.end(); it++) { // emit beginInsertRows event beginInsertRows(parentIndex, parentTreeItem->GetChildCount(), parentTreeItem->GetChildCount()); // add nodes again parentTreeItem->AddChild(*it); // emit endInsertRows event endInsertRows(); } this->AdjustLayerProperty(); } void QmitkDataStorageTreeModel::RemoveNode( const mitk::DataNode* node ) { if (node == 0) return; this->RemoveNodeInternal(node); } void QmitkDataStorageTreeModel::SetNodeModified( const mitk::DataNode* node ) { TreeItem* treeItem = m_Root->Find(node); if(treeItem) { TreeItem* parentTreeItem = treeItem->GetParent(); // as the root node should not be removed one should always have a parent item if(!parentTreeItem) return; QModelIndex index = this->createIndex(treeItem->GetIndex(), 0, treeItem); // now emit the dataChanged signal emit dataChanged(index, index); } } mitk::DataNode* QmitkDataStorageTreeModel::GetParentNode( const mitk::DataNode* node ) const { mitk::DataNode* dataNode = 0; mitk::DataStorage::SetOfObjects::ConstPointer _Sources = m_DataStorage->GetSources(node); if(_Sources->Size() > 0) dataNode = _Sources->front(); return dataNode; } bool QmitkDataStorageTreeModel::setData( const QModelIndex &index, const QVariant &value, int role ) { mitk::DataNode* dataNode = this->TreeItemFromIndex(index)->GetDataNode(); if(!dataNode) return false; if(role == Qt::EditRole && !value.toString().isEmpty()) { dataNode->SetStringProperty("name", value.toString().toStdString().c_str()); mitk::PlanarFigure* planarFigure = dynamic_cast(dataNode->GetData()); if (planarFigure != NULL) mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } else if(role == Qt::CheckStateRole) { // Please note: value.toInt() returns 2, independentely from the actual checkstate of the index element. // Therefore the checkstate is being estimated again here. QVariant qcheckstate = index.data(Qt::CheckStateRole); int checkstate = qcheckstate.toInt(); bool isVisible = bool(checkstate); dataNode->SetVisibility(!isVisible); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } // inform listeners about changes emit dataChanged(index, index); return true; } bool QmitkDataStorageTreeModel::setHeaderData( int /*section*/, Qt::Orientation /*orientation*/, const QVariant& /* value */, int /*role = Qt::EditRole*/ ) { return false; } void QmitkDataStorageTreeModel::AdjustLayerProperty() { /// transform the tree into an array and set the layer property descending std::vector vec; this->TreeToVector(m_Root, vec); int i = vec.size()-1; for(std::vector::const_iterator it = vec.begin(); it != vec.end(); ++it) { mitk::DataNode::Pointer dataNode = (*it)->GetDataNode(); bool fixedLayer = false; if (!(dataNode->GetBoolProperty("fixedLayer", fixedLayer) && fixedLayer)) dataNode->SetIntProperty("layer", i); --i; } mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } void QmitkDataStorageTreeModel::TreeToVector(TreeItem* parent, std::vector& vec) const { TreeItem* current; for(int i = 0; iGetChildCount(); ++i) { current = parent->GetChild(i); this->TreeToVector(current, vec); vec.push_back(current); } } QModelIndex QmitkDataStorageTreeModel::IndexFromTreeItem( TreeItem* item ) const { if(item == m_Root) return QModelIndex(); else return this->createIndex(item->GetIndex(), 0, item); } QList QmitkDataStorageTreeModel::GetNodeSet() const { QList res; if(m_Root) this->TreeToNodeSet(m_Root, res); return res; } void QmitkDataStorageTreeModel::TreeToNodeSet( TreeItem* parent, QList& vec ) const { TreeItem* current; for(int i = 0; iGetChildCount(); ++i) { current = parent->GetChild(i); vec.push_back(current->GetDataNode()); this->TreeToNodeSet(current, vec); } } QModelIndex QmitkDataStorageTreeModel::GetIndex( const mitk::DataNode* node ) const { if(m_Root) { TreeItem* item = m_Root->Find(node); if(item) return this->IndexFromTreeItem(item); } return QModelIndex(); } QList QmitkDataStorageTreeModel::ToTreeItemPtrList(const QMimeData* mimeData) { if (mimeData == NULL || !mimeData->hasFormat(QmitkMimeTypes::DataStorageTreeItemPtrs)) { return QList(); } return ToTreeItemPtrList(mimeData->data(QmitkMimeTypes::DataStorageTreeItemPtrs)); } QList QmitkDataStorageTreeModel::ToTreeItemPtrList(const QByteArray& ba) { QList result; QDataStream ds(ba); while(!ds.atEnd()) { quintptr treeItemPtr; ds >> treeItemPtr; result.push_back(reinterpret_cast(treeItemPtr)); } return result; } QmitkDataStorageTreeModel::TreeItem::TreeItem( mitk::DataNode* _DataNode, TreeItem* _Parent ) : m_Parent(_Parent) , m_DataNode(_DataNode) { if(m_Parent) m_Parent->AddChild(this); } QmitkDataStorageTreeModel::TreeItem::~TreeItem() { if(m_Parent) m_Parent->RemoveChild(this); } void QmitkDataStorageTreeModel::TreeItem::Delete() { while(m_Children.size() > 0) delete m_Children.back(); delete this; } QmitkDataStorageTreeModel::TreeItem* QmitkDataStorageTreeModel::TreeItem::Find( const mitk::DataNode* _DataNode ) const { QmitkDataStorageTreeModel::TreeItem* item = 0; if(_DataNode) { if(m_DataNode == _DataNode) item = const_cast(this); else { for(std::vector::const_iterator it = m_Children.begin(); it != m_Children.end(); ++it) { if(item) break; item = (*it)->Find(_DataNode); } } } return item; } int QmitkDataStorageTreeModel::TreeItem::IndexOfChild( const TreeItem* item ) const { std::vector::const_iterator it = std::find(m_Children.begin(), m_Children.end(), item); return it != m_Children.end() ? std::distance(m_Children.begin(), it): -1; } QmitkDataStorageTreeModel::TreeItem* QmitkDataStorageTreeModel::TreeItem::GetChild( int index ) const { return (m_Children.size() > 0 && index >= 0 && index < (int)m_Children.size())? m_Children.at(index): 0; } void QmitkDataStorageTreeModel::TreeItem::AddChild( TreeItem* item ) { this->InsertChild(item); } void QmitkDataStorageTreeModel::TreeItem::RemoveChild( TreeItem* item ) { std::vector::iterator it = std::find(m_Children.begin(), m_Children.end(), item); if(it != m_Children.end()) { m_Children.erase(it); item->SetParent(0); } } int QmitkDataStorageTreeModel::TreeItem::GetChildCount() const { return m_Children.size(); } int QmitkDataStorageTreeModel::TreeItem::GetIndex() const { if (m_Parent) return m_Parent->IndexOfChild(this); return 0; } QmitkDataStorageTreeModel::TreeItem* QmitkDataStorageTreeModel::TreeItem::GetParent() const { return m_Parent; } mitk::DataNode::Pointer QmitkDataStorageTreeModel::TreeItem::GetDataNode() const { return m_DataNode; } void QmitkDataStorageTreeModel::TreeItem::InsertChild( TreeItem* item, int index ) { std::vector::iterator it = std::find(m_Children.begin(), m_Children.end(), item); if(it == m_Children.end()) { if(m_Children.size() > 0 && index >= 0 && index < (int)m_Children.size()) { it = m_Children.begin(); std::advance(it, index); m_Children.insert(it, item); } else m_Children.push_back(item); // add parent if necessary if(item->GetParent() != this) item->SetParent(this); } } std::vector QmitkDataStorageTreeModel::TreeItem::GetChildren() const { return m_Children; } void QmitkDataStorageTreeModel::TreeItem::SetParent( TreeItem* _Parent ) { m_Parent = _Parent; if(m_Parent) m_Parent->AddChild(this); } void QmitkDataStorageTreeModel::Update() { if (m_DataStorage.IsNotNull()) { - this->reset(); + this->beginResetModel(); + this->endResetModel(); mitk::DataStorage::SetOfObjects::ConstPointer _NodeSet = m_DataStorage->GetAll(); for (mitk::DataStorage::SetOfObjects::const_iterator it = _NodeSet->begin(); it != _NodeSet->end(); it++) { // save node this->AddNodeInternal(*it); } } } diff --git a/Modules/QtWidgets/QmitkFileReaderOptionsDialog.ui b/Modules/QtWidgets/QmitkFileReaderOptionsDialog.ui index 3ee173c788..5e5e9d6748 100644 --- a/Modules/QtWidgets/QmitkFileReaderOptionsDialog.ui +++ b/Modules/QtWidgets/QmitkFileReaderOptionsDialog.ui @@ -1,147 +1,131 @@ QmitkFileReaderOptionsDialog 0 0 - 458 - 343 + 272 + 186 Dialog - true + false true + + QLayout::SetFixedSize + Choose file reader true - - - 0 - 0 - - Options false - - - - Qt::Vertical - - - - 20 - 10 - - - - - Remember settings for all remaining files of the same type + Apply to the next files with same type Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Ok buttonBox accepted() QmitkFileReaderOptionsDialog accept() 248 254 157 274 buttonBox rejected() QmitkFileReaderOptionsDialog reject() 316 260 286 274 m_ReaderComboBox currentIndexChanged(int) m_StackedOptionsWidget setCurrentIndex(int) 199 44 203 167 diff --git a/Modules/QtWidgets/QmitkFileWriterOptionsDialog.ui b/Modules/QtWidgets/QmitkFileWriterOptionsDialog.ui index a86d37ed1a..dd38619b01 100644 --- a/Modules/QtWidgets/QmitkFileWriterOptionsDialog.ui +++ b/Modules/QtWidgets/QmitkFileWriterOptionsDialog.ui @@ -1,147 +1,131 @@ QmitkFileWriterOptionsDialog 0 0 - 458 - 343 + 272 + 186 Dialog - true + false true + + QLayout::SetFixedSize + Choose file writer true - - - 0 - 0 - - Options false - - - - Qt::Vertical - - - - 20 - 10 - - - - - Remember settings for all remaining files of the same type + Apply to the next files with same type Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Ok buttonBox accepted() QmitkFileWriterOptionsDialog accept() 248 254 157 274 buttonBox rejected() QmitkFileWriterOptionsDialog reject() 316 260 286 274 m_WriterComboBox currentIndexChanged(int) m_StackedOptionsWidget setCurrentIndex(int) 199 44 203 167 diff --git a/Modules/QtWidgets/QmitkIOUtil.cpp b/Modules/QtWidgets/QmitkIOUtil.cpp index 8f2576dd14..8d170d27cb 100644 --- a/Modules/QtWidgets/QmitkIOUtil.cpp +++ b/Modules/QtWidgets/QmitkIOUtil.cpp @@ -1,528 +1,548 @@ /*=================================================================== 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 "QmitkIOUtil.h" #include #include #include #include "mitkCoreServices.h" #include "mitkIMimeTypeProvider.h" #include "mitkMimeType.h" #include "mitkCustomMimeType.h" #include "mitkFileReaderRegistry.h" #include "mitkFileWriterRegistry.h" #include "QmitkFileReaderOptionsDialog.h" #include "QmitkFileWriterOptionsDialog.h" // QT #include #include #include #include //ITK #include #include struct QmitkIOUtil::Impl { struct ReaderOptionsDialogFunctor : public ReaderOptionsFunctorBase { virtual bool operator()(LoadInfo& loadInfo) { QmitkFileReaderOptionsDialog dialog(loadInfo); if (dialog.exec() == QDialog::Accepted) { return !dialog.ReuseOptions(); } else { loadInfo.m_Cancel = true; return true; } } }; struct WriterOptionsDialogFunctor : public WriterOptionsFunctorBase { virtual bool operator()(SaveInfo& saveInfo) { QmitkFileWriterOptionsDialog dialog(saveInfo); if (dialog.exec() == QDialog::Accepted) { return !dialog.ReuseOptions(); } else { saveInfo.m_Cancel = true; return true; } } }; }; struct MimeTypeComparison : public std::unary_function { MimeTypeComparison(const std::string& mimeTypeName) : m_Name(mimeTypeName) {} bool operator()(const mitk::MimeType& mimeType) const { return mimeType.GetName() == m_Name; } const std::string m_Name; }; QString QmitkIOUtil::GetFileOpenFilterString() { QString filters; mitk::CoreServicePointer mimeTypeProvider(mitk::CoreServices::GetMimeTypeProvider()); std::vector categories = mimeTypeProvider->GetCategories(); for (std::vector::iterator cat = categories.begin(); cat != categories.end(); ++cat) { QSet filterExtensions; std::vector mimeTypes = mimeTypeProvider->GetMimeTypesForCategory(*cat); for (std::vector::iterator mt = mimeTypes.begin(); mt != mimeTypes.end(); ++mt) { std::vector extensions = mt->GetExtensions(); for (std::vector::iterator ext = extensions.begin(); ext != extensions.end(); ++ext) { filterExtensions << QString::fromStdString(*ext); } } QString filter = QString::fromStdString(*cat) + " ("; foreach(const QString& extension, filterExtensions) { filter += "*." + extension + " "; } filter = filter.replace(filter.size()-1, 1, ')'); filters += ";;" + filter; } - filters.prepend("All (*.*)"); + filters.prepend("All (*)"); return filters; } QList QmitkIOUtil::Load(const QStringList& paths, QWidget* parent) { std::vector loadInfos; foreach(const QString& file, paths) { loadInfos.push_back(LoadInfo(file.toStdString())); } Impl::ReaderOptionsDialogFunctor optionsCallback; std::string errMsg = Load(loadInfos, NULL, NULL, &optionsCallback); if (!errMsg.empty()) { QMessageBox::warning(parent, "Error reading files", QString::fromStdString(errMsg)); mitkThrow() << errMsg; } QList qResult; for(std::vector::const_iterator iter = loadInfos.begin(), iterEnd = loadInfos.end(); iter != iterEnd; ++iter) { for (std::vector::const_iterator dataIter = iter->m_Output.begin(), dataIterEnd = iter->m_Output.end(); dataIter != dataIterEnd; ++dataIter) { qResult << *dataIter; } } return qResult; } mitk::DataStorage::SetOfObjects::Pointer QmitkIOUtil::Load(const QStringList& paths, mitk::DataStorage& storage, QWidget* parent) { std::vector loadInfos; foreach(const QString& file, paths) { loadInfos.push_back(LoadInfo(QFile::encodeName(file).constData())); } mitk::DataStorage::SetOfObjects::Pointer nodeResult = mitk::DataStorage::SetOfObjects::New(); Impl::ReaderOptionsDialogFunctor optionsCallback; std::string errMsg = Load(loadInfos, nodeResult, &storage, &optionsCallback); if (!errMsg.empty()) { QMessageBox::warning(parent, "Error reading files", QString::fromStdString(errMsg)); mitkThrow() << errMsg; } return nodeResult; } QList QmitkIOUtil::Load(const QString& path, QWidget* parent) { QStringList paths; paths << path; return Load(paths, parent); } mitk::DataStorage::SetOfObjects::Pointer QmitkIOUtil::Load(const QString& path, mitk::DataStorage& storage, QWidget* parent) { QStringList paths; paths << path; return Load(paths, storage, parent); } QString QmitkIOUtil::Save(const mitk::BaseData* data, const QString& defaultBaseName, const QString& defaultPath, QWidget* parent) { std::vector dataVector; dataVector.push_back(data); QStringList defaultBaseNames; defaultBaseNames.push_back(defaultBaseName); return Save(dataVector, defaultBaseNames, defaultPath, parent).back(); } QStringList QmitkIOUtil::Save(const std::vector& data, const QStringList& defaultBaseNames, const QString& defaultPath, QWidget* parent) { QStringList fileNames; QString currentPath = defaultPath; std::vector saveInfos; int counter = 0; for(std::vector::const_iterator dataIter = data.begin(), dataIterEnd = data.end(); dataIter != dataIterEnd; ++dataIter, ++counter) { SaveInfo saveInfo(*dataIter, mitk::MimeType(), std::string()); SaveFilter filters(saveInfo); // If there is only the "__all__" filter string, it means there is no writer for this base data if (filters.Size() < 2) { QMessageBox::warning(parent, "Saving not possible", QString("No writer available for type \"%1\"").arg( QString::fromStdString((*dataIter)->GetNameOfClass()))); continue; } // Construct a default path and file name QString filterString = filters.ToString(); QString selectedFilter = filters.GetDefaultFilter(); QString fileName = currentPath; QString dialogTitle = "Save " + QString::fromStdString((*dataIter)->GetNameOfClass()); if (counter < defaultBaseNames.size()) { dialogTitle += " \"" + defaultBaseNames[counter] + "\""; fileName += QDir::separator() + defaultBaseNames[counter]; // We do not append an extension to the file name by default. The extension // is chosen by the user by either selecting a filter or writing the // extension in the file name himself (in the file save dialog). /* QString defaultExt = filters.GetDefaultExtension(); if (!defaultExt.isEmpty()) { fileName += "." + defaultExt; } */ } // Ask the user for a file name QString nextName = QFileDialog::getSaveFileName(parent, dialogTitle, fileName, filterString, &selectedFilter); if (nextName.isEmpty()) { // We stop asking for further file names, but we still save the // data where the user already confirmed the save dialog. break; } fileName = nextName; std::string stdFileName = QFile::encodeName(fileName).constData(); QFileInfo fileInfo(fileName); currentPath = fileInfo.absolutePath(); QString suffix = fileInfo.completeSuffix(); - mitk::MimeType mimeType = filters.GetMimeTypeForFilter(selectedFilter); + mitk::MimeType filterMimeType = filters.GetMimeTypeForFilter(selectedFilter); + mitk::MimeType selectedMimeType; - mitk::CoreServicePointer mimeTypeProvider(mitk::CoreServices::GetMimeTypeProvider()); - // If the filename contains a suffix, use it but check if it is valid - if (!suffix.isEmpty()) + if (fileInfo.exists() && !fileInfo.isFile()) { - std::vector availableTypes = mimeTypeProvider->GetMimeTypesForFile(stdFileName); - - // Check if the selected mime-type is related to the specified suffix (file extension). - // If not, get the best matching mime-type for the suffix. - if (std::find(availableTypes.begin(), availableTypes.end(), mimeType) == availableTypes.end()) - { - mimeType = mitk::MimeType(); - for (std::vector::const_iterator availIter = availableTypes.begin(), - availIterEnd = availableTypes.end(); availIter != availIterEnd; ++availIter) - { - if (filters.ContainsMimeType(availIter->GetName())) - { - mimeType = *availIter; - break; - } - } - } + QMessageBox::warning(parent, "Saving not possible", QString("The path \"%1\" is not a file").arg(fileName)); + continue; + } - if (!mimeType.IsValid()) + // Check if one of the available mime-types match the filename + std::vector filterMimeTypes = filters.GetMimeTypes(); + for (std::vector::const_iterator mimeTypeIter = filterMimeTypes.begin(), + mimeTypeIterEnd = filterMimeTypes.end(); mimeTypeIter != mimeTypeIterEnd; ++mimeTypeIter) + { + if (mimeTypeIter->AppliesTo(stdFileName)) { - // The extension is not valid (no mime-type found), bail out - QMessageBox::warning(parent, - "Saving not possible", - QString("Extension \"%1\" unknown for type \"%2\"") - .arg(suffix) - .arg(QString::fromStdString((*dataIter)->GetNameOfClass()))); - continue; + selectedMimeType = *mimeTypeIter; + break; } } - else + + if (!selectedMimeType.IsValid()) { - // Create a default suffix, unless the file already exists and the user - // already confirmed to overwrite it (without using a suffix) - if (mimeType == SaveFilter::ALL_MIMETYPE()) - { - // Use the highest ranked mime-type from the list - mimeType = filters.GetDefaultMimeType(); - } + // The file name either does not contain an extension or the + // extension is unknown. + + // If the file already exists, we stop here because we are not able + // to (over)write the file without adding a custom suffix. If the file + // does not exist, we add the default extension from the currently + // selected filter. If the "All" filter was selected, we only add the + // default extensions if the file name itself does not already contain + // an extension. if (!fileInfo.exists()) { - suffix = QString::fromStdString(mimeType.GetExtensions().front()); - fileName += "." + suffix; - // We changed the file name (added a suffix) so ask in case - // the file aready exists. - fileInfo = QFileInfo(fileName); - if (fileInfo.exists()) + if (filterMimeType == SaveFilter::ALL_MIMETYPE()) { - if (!fileInfo.isFile()) + if (suffix.isEmpty()) { - QMessageBox::warning(parent, "Saving not possible", QString("The path \"%1\" is not a file").arg(fileName)); - continue; + // Use the highest ranked mime-type from the list + selectedMimeType = filters.GetDefaultMimeType(); } - if (QMessageBox::question(parent, "Replace File", - QString("A file named \"%1\" already exists. Do you want to replace it?").arg(fileName)) == - QMessageBox::No) + } + else + { + selectedMimeType = filterMimeType; + } + + if (selectedMimeType.IsValid()) + { + suffix = QString::fromStdString(selectedMimeType.GetExtensions().front()); + fileName += "." + suffix; + stdFileName = QFile::encodeName(fileName).constData(); + // We changed the file name (added a suffix) so ask in case + // the file aready exists. + fileInfo = QFileInfo(fileName); + if (fileInfo.exists()) { - continue; + if (!fileInfo.isFile()) + { + QMessageBox::warning(parent, "Saving not possible", QString("The path \"%1\" is not a file").arg(fileName)); + continue; + } + if (QMessageBox::question(parent, "Replace File", + QString("A file named \"%1\" already exists. Do you want to replace it?").arg(fileName)) == + QMessageBox::No) + { + continue; + } } } } } + if (!selectedMimeType.IsValid()) + { + // The extension/filename is not valid (no mime-type found), bail out + QMessageBox::warning(parent, + "Saving not possible", + QString("No mime-type available which can handle \"%1\".") + .arg(fileName)); + continue; + } + if (!QFileInfo(fileInfo.absolutePath()).isWritable()) { QMessageBox::warning(parent, "Saving not possible", QString("The path \"%1\" is not writable").arg(fileName)); continue; } fileNames.push_back(fileName); saveInfo.m_Path = stdFileName; - saveInfo.m_MimeType = mimeType; + saveInfo.m_MimeType = selectedMimeType; // pre-select the best writer for the chosen mime-type - saveInfo.m_WriterSelector.Select(mimeType.GetName()); + saveInfo.m_WriterSelector.Select(selectedMimeType.GetName()); saveInfos.push_back(saveInfo); } if (!saveInfos.empty()) { Impl::WriterOptionsDialogFunctor optionsCallback; std::string errMsg = Save(saveInfos, &optionsCallback); if (!errMsg.empty()) { QMessageBox::warning(parent, "Error writing files", QString::fromStdString(errMsg)); mitkThrow() << errMsg; } } return fileNames; } void QmitkIOUtil::SaveBaseDataWithDialog(mitk::BaseData* data, std::string fileName, QWidget* /*parent*/) { Save(data, fileName); } void QmitkIOUtil::SaveSurfaceWithDialog(mitk::Surface::Pointer surface, std::string fileName, QWidget* /*parent*/) { Save(surface, fileName); } void QmitkIOUtil::SaveImageWithDialog(mitk::Image::Pointer image, std::string fileName, QWidget* /*parent*/) { Save(image, fileName); } void QmitkIOUtil::SavePointSetWithDialog(mitk::PointSet::Pointer pointset, std::string fileName, QWidget* /*parent*/) { Save(pointset, fileName); } struct QmitkIOUtil::SaveFilter::Impl { Impl(const mitk::IOUtil::SaveInfo& saveInfo) : m_SaveInfo(saveInfo) { // Add an artifical filter for "All" m_MimeTypes.push_back(ALL_MIMETYPE()); m_FilterStrings.push_back("All (*.*)"); // Get all writers and their mime types for the given base data type // (this is sorted already) std::vector mimeTypes = saveInfo.m_WriterSelector.GetMimeTypes(); for (std::vector::const_reverse_iterator iter = mimeTypes.rbegin(), iterEnd = mimeTypes.rend(); iter != iterEnd; ++iter) { QList filterExtensions; mitk::MimeType mimeType = *iter; std::vector extensions = mimeType.GetExtensions(); for (std::vector::iterator extIter = extensions.begin(), extIterEnd = extensions.end(); extIter != extIterEnd; ++extIter) { filterExtensions << QString::fromStdString(*extIter); } if (m_DefaultExtension.isEmpty()) { m_DefaultExtension = QString::fromStdString(extensions.front()); } QString filter = QString::fromStdString(mimeType.GetComment()) + " ("; foreach(const QString& extension, filterExtensions) { filter += "*." + extension + " "; } filter = filter.replace(filter.size()-1, 1, ')'); m_MimeTypes.push_back(mimeType); m_FilterStrings.push_back(filter); } } const mitk::IOUtil::SaveInfo m_SaveInfo; std::vector m_MimeTypes; QStringList m_FilterStrings; QString m_DefaultExtension; }; mitk::MimeType QmitkIOUtil::SaveFilter::ALL_MIMETYPE() { static mitk::CustomMimeType allMimeType(std::string("__all__")); return mitk::MimeType(allMimeType, -1, -1); } QmitkIOUtil::SaveFilter::SaveFilter(const QmitkIOUtil::SaveFilter& other) : d(new Impl(*other.d)) { } QmitkIOUtil::SaveFilter::SaveFilter(const SaveInfo& saveInfo) : d(new Impl(saveInfo)) { } QmitkIOUtil::SaveFilter& QmitkIOUtil::SaveFilter::operator=(const QmitkIOUtil::SaveFilter& other) { d.reset(new Impl(*other.d)); return *this; } +std::vector QmitkIOUtil::SaveFilter::GetMimeTypes() const +{ + return d->m_MimeTypes; +} + QString QmitkIOUtil::SaveFilter::GetFilterForMimeType(const std::string& mimeType) const { std::vector::const_iterator iter = std::find_if(d->m_MimeTypes.begin(), d->m_MimeTypes.end(), MimeTypeComparison(mimeType)); if (iter == d->m_MimeTypes.end()) { return QString(); } int index = static_cast(iter - d->m_MimeTypes.begin()); if (index < 0 || index >= d->m_FilterStrings.size()) { return QString(); } return d->m_FilterStrings[index]; } mitk::MimeType QmitkIOUtil::SaveFilter::GetMimeTypeForFilter(const QString& filter) const { int index = d->m_FilterStrings.indexOf(filter); if (index < 0) { return mitk::MimeType(); } return d->m_MimeTypes[index]; } QString QmitkIOUtil::SaveFilter::GetDefaultFilter() const { if (d->m_FilterStrings.size() > 1) { return d->m_FilterStrings.at(1); } else if (d->m_FilterStrings.size() > 0) { return d->m_FilterStrings.front(); } return QString(); } QString QmitkIOUtil::SaveFilter::GetDefaultExtension() const { return d->m_DefaultExtension; } mitk::MimeType QmitkIOUtil::SaveFilter::GetDefaultMimeType() const { if (d->m_MimeTypes.size() > 1) { return d->m_MimeTypes.at(1); } else if (d->m_MimeTypes.size() > 0) { return d->m_MimeTypes.front(); } return mitk::MimeType(); } QString QmitkIOUtil::SaveFilter::ToString() const { return d->m_FilterStrings.join(";;"); } int QmitkIOUtil::SaveFilter::Size() const { return d->m_FilterStrings.size(); } bool QmitkIOUtil::SaveFilter::IsEmpty() const { return d->m_FilterStrings.isEmpty(); } bool QmitkIOUtil::SaveFilter::ContainsMimeType(const std::string& mimeType) { return std::find_if(d->m_MimeTypes.begin(), d->m_MimeTypes.end(), MimeTypeComparison(mimeType)) != d->m_MimeTypes.end(); } diff --git a/Modules/QtWidgets/QmitkIOUtil.h b/Modules/QtWidgets/QmitkIOUtil.h index 57fd830b33..3cca02851d 100644 --- a/Modules/QtWidgets/QmitkIOUtil.h +++ b/Modules/QtWidgets/QmitkIOUtil.h @@ -1,232 +1,229 @@ /*=================================================================== 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 _QmitkIOUtil__h_ #define _QmitkIOUtil__h_ #include "MitkQtWidgetsExports.h" // std #include // mitk includes #include #include #include #include #include #include #include #include //Qt #include #include +#include +#include class QWidget; class QString; class QStringList; namespace mitk { class DataStorage; class MimeType; struct IFileReader; } /** * @brief QmitkIOUtil Provides static helper methods to open and save files with Qt dialogs. */ class QMITK_EXPORT QmitkIOUtil : public mitk::IOUtil { public: class QMITK_EXPORT SaveFilter { public: static mitk::MimeType ALL_MIMETYPE(); SaveFilter(const SaveFilter& other); SaveFilter(const SaveInfo& saveInfo); SaveFilter& operator=(const SaveFilter& other); + std::vector GetMimeTypes() const; QString GetFilterForMimeType(const std::string& mimeType) const; mitk::MimeType GetMimeTypeForFilter(const QString& filter) const; QString GetDefaultFilter() const; QString GetDefaultExtension() const; mitk::MimeType GetDefaultMimeType() const; QString ToString() const; int Size() const; bool IsEmpty() const; bool ContainsMimeType(const std::string& mimeType); private: struct Impl; QScopedPointer d; }; /** * @brief GetFilterString * @return */ static QString GetFileOpenFilterString(); /** * @brief Loads the specified files * * This methods tries to load all specified files and pop-ups dialog boxes if further * user input is required (e.g. ambiguous mime-types or reader options). * * If the provided DataStorage is not NULL, some files will be added to it automatically, * dependeing on the IFileReader used. * * @param files A list of files to load. * @param ds An optional data storage passed to IFileReader instances * @return A list of BaseData instances which have not already been added to the data storage. */ static QList Load(const QStringList& paths, QWidget* parent = NULL); static mitk::DataStorage::SetOfObjects::Pointer Load(const QStringList& paths, mitk::DataStorage& storage, QWidget* parent = NULL); static QList Load(const QString& path, QWidget* parent = NULL); static mitk::DataStorage::SetOfObjects::Pointer Load(const QString& path, mitk::DataStorage& storage, QWidget* parent = NULL); using mitk::IOUtil::Load; static QString Save(const mitk::BaseData* data, const QString& defaultBaseName, const QString& defaultPath = QString(), QWidget* parent = NULL); /** * @brief Save a list of BaseData objects using a "File Save Dialog". * * For each element in the \c data vector, the following algorithm is * used to find a IFileWriter instance for writing the BaseData object. * * First, the user is prompted to select file names for each BaseData object. This * is equivalent to choosing a specific mime-type, either by selecting a filter * in the save dialog or by explicitly providing a file name extension: *
    *
  1. Get a list of registered IFileWriter objects for the current BaseData object. * If no writers are found, a message box displays a warning and * the process starts from the beginning for the next BaseData object.
  2. *
  3. A QFileDialog for prompting the user to select a file name is opened. * The mime-type associated with each IFileWriter object is used to create * a filter for file name extensions. * The best IFileWriter (see FileWriterSelector) for the current BaseData object * defines the default file name suffix via its associated mime-type. If the * file name is empty (the user cancelled the dialog), the remaining * BaseData objects are skipped. - *
  4. The file name suffix is extracted from the user-supplied file name and validated. - * If the suffix is not empty and it is either not contained in the - * extension list of the selected filter (from the QFileDialog) or the mime-type - * containing the suffix as an extension is not contained in the original - * list of compatible mime-types, a message box displays a warning and - * the process starts from the beginning with the next BaseData object. - * If the suffix is empty, a default suffix is created if the file name does - * not point to an already existing file (in that case, the user already - * confirmed to overwrite that file). The default suffix is the first entry - * in the extension list of the selected filter. If the special "all" - * filter is selected, the first entry from the extensions list of the - * highest-ranked compatible mime-type for the current base data object is used. - * The base data object is associated with the mime-type containing the suffix - * in its extension list. If the suffix is empty (the user is overwriting an - * existing file without an extension, the associated mime-type is the one - * of the selected filter or the mime-type of the best matching IFileWriter - * if the special "all" filter was selected.
  5. + *
  6. The file name is matched against valid mime-types. The first mime-type + * which accepts the file name is associated with the current BaseData object. + * If no mime-type accepts the supplied file name and the file already + * exists, the process starts from the beginning with the next BaseData object. + * Otherwise, if the selected filter is the special "all" filter and the + * file name does not contain periods (which may or may not mark the start of + * a file extension), the current BaseData object is associated with the + * default mime-type. If the selected filter is not the special "all" filter, + * the mime-type for this filter is associated with the current BaseData object. + * The default extension of the associated mime-type is then appended to the + * supplied file name. *
  7. The selected/derived file name and associated mime-type is stored in a list * and the process starts from the beginning for the next BaseData object.
  8. *
* * In the second phase, each BaseData object is saved to disk using the specified * file name and mime-type, according to the following procedure: *
    *
  1. If multiple IFileWriter objects are compatible with the current base data * object or if the single compatible IFileWriter provides configuration * options, a dialog window containing a list of IFileWriter objects and * configurable options is displayed. If the dialog is cancelled by the user, * neither the current nor the remaining base data objects are saved to disk. * If the user previously in this phase enabled the "remember options" checkbox * of the dialog, then the dialog is not shown for base data objects with the * same data type and associated mime-type if the file writer instance reports * a higher or equal confidence level for the current base data object.
  2. *
  3. The selected writer (either the only available one or the user selected one) * is used to write the base data object to disk. On failure, an error is * reported and the second phase continues with the next base data object.
  4. *
* * @param data * @param defaultBaseNames * @param defaultPath * @param parent * @return */ static QStringList Save(const std::vector& data, const QStringList& defaultBaseNames, const QString& defaultPath = QString(), QWidget* parent = NULL); using mitk::IOUtil::Save; /** * @brief SaveBaseDataWithDialog Convenience method to save any data with a Qt dialog. * @param data BaseData holding the data you wish to save. * @param fileName The file name where to save the data (including path and extension). * @param parent An optional QWidget as parent. If no parent is supplied, the QFileDialog can occur anywhere on the screen. * @deprecatedSince{2014_10} Use Save() instead. */ DEPRECATED(static void SaveBaseDataWithDialog(mitk::BaseData *data, std::string fileName, QWidget* parent = NULL)); /** * @brief SaveSurfaceWithDialog Convenience method to save a surface with a Qt dialog. * @param surface The surface to save. * @param fileName The file name where to save the data (including path and extension). * @param parent An optional QWidget as parent. If no parent is supplied, the QFileDialog can occur anywhere on the screen. * @deprecatedSince{2014_10} Use Save() instead. */ DEPRECATED(static void SaveSurfaceWithDialog(mitk::Surface::Pointer surface, std::string fileName = "", QWidget* parent = NULL)); /** * @brief SaveImageWithDialog Convenience method to save an image with a Qt dialog. * @param image The image to save. * @param fileName The file name where to save the data (including path and extension). * @param parent An optional QWidget as parent. If no parent is supplied, the QFileDialog can occur anywhere on the screen. * @deprecatedSince{2014_10} Use Save() instead. */ DEPRECATED(static void SaveImageWithDialog(mitk::Image::Pointer image, std::string fileName = "", QWidget* parent = NULL)); /** * @brief SavePointSetWithDialog Convenience method to save a pointset with a Qt dialog. * @param pointset The pointset to save. * @param fileName The file name where to save the data (including path and extension). * @param parent An optional QWidget as parent. If no parent is supplied, the QFileDialog can occur anywhere on the screen. * @deprecatedSince{2014_10} Use Save() instead. */ DEPRECATED(static void SavePointSetWithDialog(mitk::PointSet::Pointer pointset, std::string fileName = "", QWidget* parent = NULL)); private: struct Impl; }; #endif // _QmitkIOUtil__h_ diff --git a/Modules/QtWidgets/QmitkLevelWindowPresetDefinitionDialog.cpp b/Modules/QtWidgets/QmitkLevelWindowPresetDefinitionDialog.cpp index ae12790b90..ee4bafea7b 100644 --- a/Modules/QtWidgets/QmitkLevelWindowPresetDefinitionDialog.cpp +++ b/Modules/QtWidgets/QmitkLevelWindowPresetDefinitionDialog.cpp @@ -1,330 +1,334 @@ /*=================================================================== 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 "QmitkLevelWindowPresetDefinitionDialog.h" #include #include #include QmitkLevelWindowPresetDefinitionDialog::QmitkLevelWindowPresetDefinitionDialog(QWidget* parent, Qt::WindowFlags f) : QDialog(parent, f), m_TableModel(0), m_SortModel(this) { this->setupUi(this); QObject::connect(addButton, SIGNAL(clicked()), this, SLOT(addPreset())); QObject::connect(removeButton, SIGNAL(clicked()), this, SLOT(removePreset())); QObject::connect(changeButton, SIGNAL(clicked()), this, SLOT(changePreset())); QObject::connect(presetView->horizontalHeader(), SIGNAL(sectionClicked(int)), this, SLOT(sortPresets(int))); presetView->verticalHeader()->setVisible(false); +#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) presetView->horizontalHeader()->setResizeMode(QHeaderView::Fixed); +#else + presetView->horizontalHeader()->setSectionResizeMode(QHeaderView::Fixed); +#endif presetView->setModel(&m_SortModel); } QmitkLevelWindowPresetDefinitionDialog::~QmitkLevelWindowPresetDefinitionDialog() { delete m_TableModel; } void QmitkLevelWindowPresetDefinitionDialog::sortPresets(int index) { static Qt::SortOrder order[3] = {Qt::AscendingOrder}; presetView->sortByColumn(index, order[index]); if (order[index] == Qt::AscendingOrder) order[index] = Qt::DescendingOrder; else order[index] = Qt::AscendingOrder; } void QmitkLevelWindowPresetDefinitionDialog::resizeEvent(QResizeEvent* event) { QDialog::resizeEvent(event); this->resizeColumns(); } void QmitkLevelWindowPresetDefinitionDialog::showEvent(QShowEvent* event) { this->resizeColumns(); QDialog::showEvent(event); } void QmitkLevelWindowPresetDefinitionDialog::resizeColumns() { int width = presetView->viewport()->size().width() - presetView->columnWidth(1) - presetView->columnWidth(2); if (width < 50) width = 50; presetView->setColumnWidth(0, width); } void QmitkLevelWindowPresetDefinitionDialog::addPreset() { std::string name(presetnameLineEdit->text().toStdString()); if (m_TableModel->contains(name)) { QMessageBox::critical( this, "Preset definition", "Presetname already exists.\n" "You have to enter another one." ); } else if (presetnameLineEdit->text() == "") { QMessageBox::critical( this, "Preset definition", "Presetname has to be set.\n" "You have to enter a Presetname." ); } else { m_TableModel->addPreset(name, levelSpinBox->value(), windowSpinBox->value()); } } void QmitkLevelWindowPresetDefinitionDialog::removePreset() { QModelIndex index(presetView->selectionModel()->currentIndex()); if (!index.isValid()) return; m_TableModel->removePreset(index); } void QmitkLevelWindowPresetDefinitionDialog::changePreset() { if (presetView->selectionModel()->hasSelection()) { std::string name(presetnameLineEdit->text().toStdString()); if (name == "") { QMessageBox::critical( this, "Preset definition", "Presetname has to be set.\n" "You have to enter a Presetname." ); } else if (m_TableModel->contains(name) && (m_TableModel->getPreset(presetView->selectionModel()->currentIndex()).name != name)) { QMessageBox::critical( this, "Preset definition", "Presetname already exists.\n" "You have to enter another one." ); } else { m_TableModel->changePreset(presetView->selectionModel()->currentIndex().row(), name, levelSpinBox->value(), windowSpinBox->value()); } } } void QmitkLevelWindowPresetDefinitionDialog::setPresets(std::map& level, std::map& window, QString initLevel, QString initWindow) { levelSpinBox->setValue(initLevel.toInt()); windowSpinBox->setValue(initWindow.toInt()); delete m_TableModel; m_TableModel = new PresetTableModel(level, window, this); m_SortModel.setSourceModel(m_TableModel); QObject::connect(presetView->selectionModel(), SIGNAL(selectionChanged(const QItemSelection&, const QItemSelection&)), this, SLOT(ListViewSelectionChanged(const QItemSelection&, const QItemSelection&))); this->sortPresets(0); presetView->resizeColumnsToContents(); } std::map QmitkLevelWindowPresetDefinitionDialog::getLevelPresets() { std::map levels; m_TableModel->getLevels(levels); return levels; } std::map QmitkLevelWindowPresetDefinitionDialog::getWindowPresets() { std::map windows; m_TableModel->getWindows(windows); return windows; } void QmitkLevelWindowPresetDefinitionDialog::ListViewSelectionChanged(const QItemSelection& selected, const QItemSelection& /*deselected*/) { QModelIndexList indexes(selected.indexes()); if (indexes.empty()) { presetnameLineEdit->setText(""); levelSpinBox->setValue(0); windowSpinBox->setValue(0); } else { //use the sorted index to get the entry PresetTableModel::Entry entry( m_TableModel->getPreset((m_SortModel.mapToSource(indexes.first()))) ); presetnameLineEdit->setText(QString(entry.name.c_str())); levelSpinBox->setValue((int)entry.level); windowSpinBox->setValue((int)entry.window); } } QmitkLevelWindowPresetDefinitionDialog:: PresetTableModel::PresetTableModel(std::map& levels, std::map& windows, QObject* parent) : QAbstractTableModel(parent) { for(std::map::iterator iter = levels.begin(); iter != levels.end(); ++iter ) { m_Entries.push_back(Entry(iter->first, iter->second, windows[iter->first])); } } void QmitkLevelWindowPresetDefinitionDialog:: PresetTableModel::getLevels(std::map& levels) { for (std::vector::iterator iter = m_Entries.begin(); iter != m_Entries.end(); ++iter) { levels[iter->name] = iter->level; } } void QmitkLevelWindowPresetDefinitionDialog:: PresetTableModel::getWindows(std::map& windows) { for (std::vector::iterator iter = m_Entries.begin(); iter != m_Entries.end(); ++iter) { windows[iter->name] = iter->window; } } void QmitkLevelWindowPresetDefinitionDialog:: PresetTableModel::addPreset(std::string& name, double level, double window) { this->beginInsertRows(QModelIndex(), (int) m_Entries.size(), (int) m_Entries.size()); m_Entries.push_back(Entry(name, level, window)); this->endInsertRows(); } bool QmitkLevelWindowPresetDefinitionDialog:: PresetTableModel::contains(std::string& name) { for (std::vector::iterator iter = m_Entries.begin(); iter != m_Entries.end(); ++iter) { if (iter->name == name) return true; } return false; } void QmitkLevelWindowPresetDefinitionDialog:: PresetTableModel::removePreset(const QModelIndex& index) { int row = index.row(); this->beginRemoveRows(QModelIndex(), row, row); m_Entries.erase(m_Entries.begin()+row); this->endRemoveRows(); } void QmitkLevelWindowPresetDefinitionDialog:: PresetTableModel::changePreset(int row, std::string& name, double level, double window) { m_Entries[row].name = name; m_Entries[row].level = level; m_Entries[row].window = window; this->dataChanged(index(row, 0), index(row, 2)); } QmitkLevelWindowPresetDefinitionDialog::PresetTableModel::Entry QmitkLevelWindowPresetDefinitionDialog:: PresetTableModel::getPreset(const QModelIndex& index) const { int row = index.row(); if (row < 0 || (unsigned int)row >= m_Entries.size()) return Entry("", 0, 0); return m_Entries[row]; } int QmitkLevelWindowPresetDefinitionDialog:: PresetTableModel::rowCount(const QModelIndex&) const { return (int) m_Entries.size(); } int QmitkLevelWindowPresetDefinitionDialog:: PresetTableModel::columnCount(const QModelIndex&) const { return 3; } QVariant QmitkLevelWindowPresetDefinitionDialog:: PresetTableModel::data(const QModelIndex& index, int role) const { if (role == Qt::DisplayRole) { switch (index.column()) { case 0: return QVariant(QString(m_Entries[index.row()].name.c_str())); case 1: { return QVariant(m_Entries[index.row()].level); } case 2: return QVariant(m_Entries[index.row()].window); } } return QVariant(); } QVariant QmitkLevelWindowPresetDefinitionDialog:: PresetTableModel::headerData(int section, Qt::Orientation orientation, int role) const { if (role == Qt::DisplayRole && orientation == Qt::Horizontal) { switch (section) { case 0: return QVariant("Preset"); case 1: return QVariant("Level"); case 2: return QVariant("Window"); } } return QVariant(); } diff --git a/Modules/QtWidgets/QmitkMemoryUsageIndicatorView.cpp b/Modules/QtWidgets/QmitkMemoryUsageIndicatorView.cpp index b5601f6a7a..e9136c41ae 100644 --- a/Modules/QtWidgets/QmitkMemoryUsageIndicatorView.cpp +++ b/Modules/QtWidgets/QmitkMemoryUsageIndicatorView.cpp @@ -1,150 +1,150 @@ /*=================================================================== 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. ===================================================================*/ /**************************************************************************** ** ui.h extension file, included from the uic-generated form implementation. ** ** If you want to add, delete, or rename functions or slots, use ** Qt Designer to update this file, preserving your code. ** ** You should not define a constructor or destructor in this file. ** Instead, write your code in functions called init() and destroy(). ** These will automatically be called by the form's constructor and ** destructor. *****************************************************************************/ #include "QmitkMemoryUsageIndicatorView.h" #include #include #include #include #include #include #include #include #include #include "QmitkMemoryUsageIndicatorImagesGreen.xpm" #include "QmitkMemoryUsageIndicatorImagesYellow.xpm" #include "QmitkMemoryUsageIndicatorImagesOrange.xpm" #include "QmitkMemoryUsageIndicatorImagesRed.xpm" QmitkMemoryUsageIndicatorView::QmitkMemoryUsageIndicatorView( QWidget * /*parent*/, Qt::WindowFlags /*f*/ ) { this->setupUi(this); QTimer *timer = new QTimer( this ); QObject::connect( timer, SIGNAL( timeout() ), this, SLOT( UpdateMemoryUsage() ) ); timer->start(1000); - m_LEDGreen = QmitkMemoryUsageIndicatorImagesGreen_xpm; - m_LEDYellow = QmitkMemoryUsageIndicatorImagesYellow_xpm; - m_LEDOrange = QmitkMemoryUsageIndicatorImagesOrange_xpm; - m_LEDRed = QmitkMemoryUsageIndicatorImagesRed_xpm; + m_LEDGreen = QPixmap(QmitkMemoryUsageIndicatorImagesGreen_xpm); + m_LEDYellow = QPixmap(QmitkMemoryUsageIndicatorImagesYellow_xpm); + m_LEDOrange = QPixmap(QmitkMemoryUsageIndicatorImagesOrange_xpm); + m_LEDRed = QPixmap(QmitkMemoryUsageIndicatorImagesRed_xpm); m_LED->setPixmap(m_LEDGreen); m_PreviousState = 0; } QmitkMemoryUsageIndicatorView::~QmitkMemoryUsageIndicatorView() { } void QmitkMemoryUsageIndicatorView::UpdateMemoryUsage() { size_t processSize = mitk::MemoryUtilities::GetProcessMemoryUsage(); size_t totalSize = mitk::MemoryUtilities::GetTotalSizeOfPhysicalRam(); float percentage = ( (float) processSize / (float) totalSize ) * 100.0; m_Label->setText( GetMemoryDescription( processSize, percentage ).c_str() ); if ( percentage < 50.0 ) { if(m_PreviousState != 0) { m_LED->setPixmap(m_LEDGreen); m_PreviousState = 0; m_LED->update(); } } else if ( percentage < 65.0 ) { if(m_PreviousState != 1) { m_LED->setPixmap(m_LEDYellow); m_PreviousState = 1; m_LED->update(); } } else if ( percentage < 80.0 ) { if(m_PreviousState != 2) { m_LED->setPixmap(m_LEDOrange); m_PreviousState = 2; m_LED->update(); } } else { if(m_PreviousState != 3) { m_LED->setPixmap(m_LEDRed); m_PreviousState = 3; m_LED->update(); } } } std::string QmitkMemoryUsageIndicatorView::FormatMemorySize( size_t size ) { double val = size; std::string descriptor("B"); if ( val >= 1000.0 ) { val /= 1024.0; descriptor = "KB"; } if ( val >= 1000.0 ) { val /= 1024.0; descriptor = "MB"; } if ( val >= 1000.0 ) { val /= 1024.0; descriptor = "GB"; } std::ostringstream str; str.imbue(std::locale::classic()); str << std::fixed << std::setprecision(2) << val << " " << descriptor; return str.str(); } std::string QmitkMemoryUsageIndicatorView::FormatPercentage( double val ) { std::ostringstream str; str.imbue(std::locale::classic()); str << std::fixed << std::setprecision(2) << val << " " << "%"; return str.str(); } std::string QmitkMemoryUsageIndicatorView::GetMemoryDescription( size_t processSize, float percentage ) { std::ostringstream str; str.imbue(std::locale::classic()); str << FormatMemorySize(processSize) << " (" << FormatPercentage( percentage ) <<")" ; return str.str(); } diff --git a/Modules/QtWidgets/QmitkMouseModeSwitcher.cpp b/Modules/QtWidgets/QmitkMouseModeSwitcher.cpp index 58d5d7023f..c1a34f749b 100644 --- a/Modules/QtWidgets/QmitkMouseModeSwitcher.cpp +++ b/Modules/QtWidgets/QmitkMouseModeSwitcher.cpp @@ -1,116 +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 "QmitkMouseModeSwitcher.h" - +#include QmitkMouseModeSwitcher::QmitkMouseModeSwitcher( QWidget* parent ) :QToolBar(parent) ,m_ActionGroup(new QActionGroup(this)) ,m_MouseModeSwitcher(NULL) ,m_ObserverTag(0) ,m_InObservationReaction(false) { QToolBar::setOrientation( Qt::Vertical ); QToolBar::setIconSize( QSize(17, 17) ); m_ActionGroup->setExclusive(true); // only one selectable addButton( mitk::MouseModeSwitcher::MousePointer, tr("Pointer"), QIcon(":/Qmitk/mm_pointer.png"), true ); // toggle ON addButton( mitk::MouseModeSwitcher::Scroll, tr("Scroll"), QIcon(":/Qmitk/mm_scroll.png") ); addButton( mitk::MouseModeSwitcher::LevelWindow, tr("Level/Window"), QIcon(":/Qmitk/mm_contrast.png") ); addButton( mitk::MouseModeSwitcher::Zoom, tr("Zoom"), QIcon(":/Qmitk/mm_zoom.png") ); addButton( mitk::MouseModeSwitcher::Pan, tr("Pan"), QIcon(":/Qmitk/mm_pan.png") ); } void QmitkMouseModeSwitcher::addButton( MouseMode id, const QString& toolName, const QIcon& icon, bool on) { QAction* action = new QAction( icon, toolName, this ); action->setCheckable(true); action->setActionGroup(m_ActionGroup); action->setChecked(on); action->setData(id); connect( action, SIGNAL(triggered()), this, SLOT(modeSelectedByUser()) ); QToolBar::addAction( action ); } QmitkMouseModeSwitcher::~QmitkMouseModeSwitcher() { if (m_MouseModeSwitcher) { m_MouseModeSwitcher->RemoveObserver( m_ObserverTag ); } } void QmitkMouseModeSwitcher::setMouseModeSwitcher( mitk::MouseModeSwitcher* mms ) { // goodbye / welcome ceremonies if (m_MouseModeSwitcher) { m_MouseModeSwitcher->RemoveObserver( m_ObserverTag ); } m_MouseModeSwitcher = mms; if ( m_MouseModeSwitcher ) { itk::ReceptorMemberCommand::Pointer command = itk::ReceptorMemberCommand::New(); command->SetCallbackFunction(this, &QmitkMouseModeSwitcher::OnMouseModeChanged); m_ObserverTag = m_MouseModeSwitcher->AddObserver( mitk::MouseModeSwitcher::MouseModeChangedEvent(), command ); } } void QmitkMouseModeSwitcher::modeSelectedByUser() { if (m_InObservationReaction) return; // this was NOT actually by the user but by ourselves QAction* action = dynamic_cast(sender()); if (action) { MouseMode id = static_cast( action->data().toInt() ); //qDebug() << "Mouse mode '" << qPrintable(action->text()) << "' selected, trigger mode id " << id; if (m_MouseModeSwitcher) { m_MouseModeSwitcher->SelectMouseMode( id ); } emit MouseModeSelected( id ); } } void QmitkMouseModeSwitcher::OnMouseModeChanged(const itk::EventObject&) { m_InObservationReaction = true; // push button graphically assert( m_MouseModeSwitcher ); MouseMode activeMode = m_MouseModeSwitcher->GetCurrentMouseMode(); foreach(QAction* action, m_ActionGroup->actions()) { if ( action->data().toInt() == activeMode ) { action->setChecked( true ); } } m_InObservationReaction = false; } diff --git a/Modules/QtWidgets/QmitkMouseModeSwitcher.h b/Modules/QtWidgets/QmitkMouseModeSwitcher.h index 63f1e6a805..d56296ab5e 100644 --- a/Modules/QtWidgets/QmitkMouseModeSwitcher.h +++ b/Modules/QtWidgets/QmitkMouseModeSwitcher.h @@ -1,87 +1,88 @@ /*=================================================================== 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 QmitkMouseModeSwitcher_h #define QmitkMouseModeSwitcher_h #include "MitkQtWidgetsExports.h" #include "mitkMouseModeSwitcher.h" -#include +#include +#include /** * \ingroup QmitkModule * \brief Qt toolbar representing mitk::MouseModeSwitcher. * * Provides buttons for the interaction modes defined in mitk::MouseModeSwitcher * and communicates with this non-graphical class. * * Can be used in a GUI to provide a mouse mode selector to the user. */ class QMITK_EXPORT QmitkMouseModeSwitcher : public QToolBar { Q_OBJECT public: QmitkMouseModeSwitcher( QWidget* parent = 0 ); virtual ~QmitkMouseModeSwitcher(); typedef mitk::MouseModeSwitcher::MouseMode MouseMode; public slots: /** \brief Connect to non-GUI class. When a button is pressed, given mitk::MouseModeSwitcher is informed to adapt interactors. \todo QmitkMouseModeSwitcher could be enhanced to actively observe mitk::MouseModeSwitcher and change available actions or visibility appropriately. */ void setMouseModeSwitcher( mitk::MouseModeSwitcher* ); signals: /** \brief Mode activated. This signal is needed for other GUI element to react appropriately. Sadly this is needed to provide "normal" functionality of QmitkStdMultiWidget, because this must enable/disable automatic reaction of SliceNavigationControllers to mouse clicks - depending on which mode is active. */ void MouseModeSelected(mitk::MouseModeSwitcher::MouseMode id); // TODO change int to enum of MouseModeSwitcher protected slots: void modeSelectedByUser(); void addButton( MouseMode id, const QString& toolName, const QIcon& icon, bool on = false ); // TODO change int to enum of MouseModeSwitcher protected: void OnMouseModeChanged(const itk::EventObject&); QActionGroup* m_ActionGroup; mitk::MouseModeSwitcher* m_MouseModeSwitcher; unsigned long m_ObserverTag; bool m_InObservationReaction; }; #endif diff --git a/Modules/QtWidgets/QmitkPropertiesTableEditor.cpp b/Modules/QtWidgets/QmitkPropertiesTableEditor.cpp index 161c9329ae..5d88497b40 100644 --- a/Modules/QtWidgets/QmitkPropertiesTableEditor.cpp +++ b/Modules/QtWidgets/QmitkPropertiesTableEditor.cpp @@ -1,118 +1,122 @@ /*=================================================================== 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 "QmitkPropertiesTableEditor.h" #include "QmitkPropertiesTableModel.h" #include "QmitkPropertyDelegate.h" #include "mitkBaseRenderer.h" #include "mitkFocusManager.h" #include "mitkGlobalInteraction.h" #include #include #include #include #include #include #include QmitkPropertiesTableEditor::QmitkPropertiesTableEditor(QWidget* parent , Qt::WindowFlags f,mitk::DataNode::Pointer /*_Node*/) : QWidget(parent, f) , m_NodePropertiesTableView(0) , m_Model(0) { // set up empty gui elements this->init(); // set up model m_Model = new QmitkPropertiesTableModel(m_NodePropertiesTableView, 0); m_NodePropertiesTableView->setModel(m_Model); } QmitkPropertiesTableEditor::~QmitkPropertiesTableEditor() { } void QmitkPropertiesTableEditor::SetPropertyList( mitk::PropertyList::Pointer _List ) { if(_List.IsNotNull()) { m_Model->SetPropertyList(_List); m_NodePropertiesTableView->resizeColumnsToContents(); m_NodePropertiesTableView->resizeRowsToContents(); m_NodePropertiesTableView->horizontalHeader()->setStretchLastSection(true); m_NodePropertiesTableView->setEditTriggers(QAbstractItemView::CurrentChanged); } else { m_Model->SetPropertyList(0); } } QmitkPropertiesTableModel* QmitkPropertiesTableEditor::getModel() const { return m_Model; } void QmitkPropertiesTableEditor::init() { // read/ dim QVBoxLayout* _NodePropertiesLayout = new QVBoxLayout; QWidget* _PropertyFilterKeyWordPane = new QWidget(QWidget::parentWidget()); QHBoxLayout* _PropertyFilterKeyWordLayout = new QHBoxLayout; QLabel* _LabelPropertyFilterKeyWord = new QLabel("Filter: ",_PropertyFilterKeyWordPane); m_TxtPropertyFilterKeyWord = new QLineEdit(_PropertyFilterKeyWordPane); m_NodePropertiesTableView = new QTableView(QWidget::parentWidget()); // write setLayout(_NodePropertiesLayout); _PropertyFilterKeyWordPane->setLayout(_PropertyFilterKeyWordLayout); _PropertyFilterKeyWordLayout->setMargin(0); _PropertyFilterKeyWordLayout->addWidget(_LabelPropertyFilterKeyWord); _PropertyFilterKeyWordLayout->addWidget(m_TxtPropertyFilterKeyWord); _NodePropertiesLayout->setMargin(0); _NodePropertiesLayout->addWidget(_PropertyFilterKeyWordPane); _NodePropertiesLayout->addWidget(m_NodePropertiesTableView); m_NodePropertiesTableView->setSelectionMode( QAbstractItemView::SingleSelection ); m_NodePropertiesTableView->setSelectionBehavior( QAbstractItemView::SelectItems ); m_NodePropertiesTableView->verticalHeader()->hide(); m_NodePropertiesTableView->setItemDelegate(new QmitkPropertyDelegate(this)); m_NodePropertiesTableView->setAlternatingRowColors(true); m_NodePropertiesTableView->setSortingEnabled(true); +#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) m_NodePropertiesTableView->verticalHeader()->setResizeMode(QHeaderView::ResizeToContents); +#else + m_NodePropertiesTableView->verticalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents); +#endif QObject::connect( m_TxtPropertyFilterKeyWord, SIGNAL( textChanged(const QString &) ) , this, SLOT( PropertyFilterKeyWordTextChanged(const QString &) ) ); } void QmitkPropertiesTableEditor::PropertyFilterKeyWordTextChanged( const QString & /*text*/ ) { m_Model->SetFilterPropertiesKeyWord(m_TxtPropertyFilterKeyWord->text().toStdString()); } QTableView* QmitkPropertiesTableEditor::getTable() const { return m_NodePropertiesTableView; } diff --git a/Modules/QtWidgets/QmitkPropertiesTableModel.cpp b/Modules/QtWidgets/QmitkPropertiesTableModel.cpp index 57b267fda5..27824780dc 100644 --- a/Modules/QtWidgets/QmitkPropertiesTableModel.cpp +++ b/Modules/QtWidgets/QmitkPropertiesTableModel.cpp @@ -1,543 +1,545 @@ /*=================================================================== 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 "QmitkPropertiesTableModel.h" //# Own includes #include "mitkStringProperty.h" #include "mitkColorProperty.h" #include "mitkProperties.h" #include "mitkEnumerationProperty.h" #include "mitkRenderingManager.h" #include "QmitkCustomVariants.h" //# Toolkit includes #include #include #include #include //# PUBLIC CTORS,DTOR QmitkPropertiesTableModel::QmitkPropertiesTableModel(QObject* parent, mitk::PropertyList::Pointer _PropertyList) : QAbstractTableModel(parent) , m_PropertyList(0) , m_BlockEvents(false) , m_SortDescending(false) , m_FilterKeyWord("") { this->SetPropertyList(_PropertyList); } QmitkPropertiesTableModel::~QmitkPropertiesTableModel() { // remove all event listeners by setting the property list to 0 this->SetPropertyList(0); } //# PUBLIC GETTER mitk::PropertyList::Pointer QmitkPropertiesTableModel::GetPropertyList() const { return m_PropertyList.GetPointer(); } Qt::ItemFlags QmitkPropertiesTableModel::flags(const QModelIndex& index) const { // no editing so far, return default (enabled, selectable) Qt::ItemFlags flags = QAbstractItemModel::flags(index); if (index.column() == PROPERTY_VALUE_COLUMN) { // there are also read only property items -> do not allow editing them if(index.data(Qt::EditRole).isValid()) flags |= Qt::ItemIsEditable; if(index.data(Qt::CheckStateRole).isValid()) flags |= Qt::ItemIsUserCheckable; } return flags; } QVariant QmitkPropertiesTableModel::headerData(int section, Qt::Orientation orientation, int role) const { if (role != Qt::DisplayRole) return QVariant(); if (orientation == Qt::Horizontal) { switch (section) { case PROPERTY_NAME_COLUMN: return tr("Name"); case PROPERTY_VALUE_COLUMN: return tr("Value"); default: return QVariant(); } } return QVariant(); } QVariant QmitkPropertiesTableModel::data(const QModelIndex& index, int role) const { // empty data by default QVariant data; if(!index.isValid() || m_SelectedProperties.empty() || index.row() > (int)(m_SelectedProperties.size()-1)) return data; // the properties name if(index.column() == PROPERTY_NAME_COLUMN) { if(role == Qt::DisplayRole) data = QString::fromStdString(m_SelectedProperties[index.row()].first); } // the real properties value else if(index.column() == PROPERTY_VALUE_COLUMN) { mitk::BaseProperty* baseProp = m_SelectedProperties[index.row()].second; if (const mitk::ColorProperty* colorProp = dynamic_cast(baseProp)) { mitk::Color col = colorProp->GetColor(); QColor qcol((int)(col.GetRed() * 255), (int)(col.GetGreen() * 255),(int)( col.GetBlue() * 255)); if(role == Qt::DisplayRole) data.setValue(qcol); else if(role == Qt::EditRole) data.setValue(qcol); } else if(mitk::BoolProperty* boolProp = dynamic_cast(baseProp)) { if(role == Qt::CheckStateRole) data = boolProp->GetValue() ? Qt::Checked : Qt::Unchecked; } else if (mitk::StringProperty* stringProp = dynamic_cast(baseProp)) { if(role == Qt::DisplayRole) data.setValue(QString::fromStdString(stringProp->GetValue())); else if(role == Qt::EditRole) data.setValue(QString::fromStdString(stringProp->GetValue())); } else if (mitk::IntProperty* intProp = dynamic_cast(baseProp)) { if(role == Qt::DisplayRole) data.setValue(intProp->GetValue()); else if(role == Qt::EditRole) data.setValue(intProp->GetValue()); } else if (mitk::FloatProperty* floatProp = dynamic_cast(baseProp)) { if(role == Qt::DisplayRole) data.setValue(floatProp->GetValue()); else if(role == Qt::EditRole) data.setValue(floatProp->GetValue()); } else if (mitk::EnumerationProperty* enumerationProp = dynamic_cast(baseProp)) { if(role == Qt::DisplayRole) data.setValue(QString::fromStdString(baseProp->GetValueAsString())); else if(role == Qt::EditRole) { QStringList values; for(mitk::EnumerationProperty::EnumConstIterator it=enumerationProp->Begin(); it!=enumerationProp->End() ; it++) { values << QString::fromStdString(it->second); } data.setValue(values); } } else { if(role == Qt::DisplayRole) data.setValue(QString::fromStdString(m_SelectedProperties[index.row()].second->GetValueAsString())); } } return data; } int QmitkPropertiesTableModel::rowCount(const QModelIndex& /*parent*/) const { // return the number of properties in the properties list. return m_SelectedProperties.size(); } int QmitkPropertiesTableModel::columnCount(const QModelIndex & /*parent*/)const { return 2; } //# PUBLIC SETTER void QmitkPropertiesTableModel::SetPropertyList( mitk::PropertyList* _PropertyList ) { // if propertylist really changed if(m_PropertyList.GetPointer() != _PropertyList) { // Remove delete listener if there was a propertylist before if(m_PropertyList.IsNotNull()) { m_PropertyList.ObjectDelete.RemoveListener (mitk::MessageDelegate1( this, &QmitkPropertiesTableModel::PropertyListDelete )); } // set new list m_PropertyList = _PropertyList; if(m_PropertyList.IsNotNull()) { m_PropertyList.ObjectDelete.AddListener (mitk::MessageDelegate1( this, &QmitkPropertiesTableModel::PropertyListDelete )); } this->Reset(); } } void QmitkPropertiesTableModel::PropertyListDelete( const itk::Object * /*_PropertyList*/ ) { if(!m_BlockEvents) { m_BlockEvents = true; this->Reset(); m_BlockEvents = false; } } void QmitkPropertiesTableModel::PropertyModified( const itk::Object *caller, const itk::EventObject & /*event*/ ) { if(!m_BlockEvents) { m_BlockEvents = true; int row = this->FindProperty(dynamic_cast(caller)); QModelIndex indexOfChangedProperty = index(row, 1); emit dataChanged(indexOfChangedProperty, indexOfChangedProperty); m_BlockEvents = false; } } void QmitkPropertiesTableModel::PropertyDelete( const itk::Object *caller, const itk::EventObject & /*event*/ ) { if(!m_BlockEvents) { m_BlockEvents = true; int row = this->FindProperty(dynamic_cast(caller)); if(row >= 0) this->Reset(); m_BlockEvents = false; } } bool QmitkPropertiesTableModel::setData(const QModelIndex &index, const QVariant &value, int role) { if (index.isValid() && !m_SelectedProperties.empty() && index.row() < (int)(m_SelectedProperties.size()) && (role == Qt::EditRole || Qt::CheckStateRole)) { // block all events now! m_BlockEvents = true; // the properties name if(index.column() == PROPERTY_VALUE_COLUMN) { mitk::BaseProperty* baseProp = m_SelectedProperties[index.row()].second; if (mitk::ColorProperty* colorProp = dynamic_cast(baseProp)) { QColor qcolor = value.value(); if(!qcolor.isValid()) return false; mitk::Color col = colorProp->GetColor(); col.SetRed(qcolor.red() / 255.0); col.SetGreen(qcolor.green() / 255.0); col.SetBlue(qcolor.blue() / 255.0); colorProp->SetColor(col); m_PropertyList->InvokeEvent(itk::ModifiedEvent()); m_PropertyList->Modified(); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } else if(mitk::BoolProperty* boolProp = dynamic_cast(baseProp)) { boolProp->SetValue(value.toInt() == Qt::Checked ? true : false); m_PropertyList->InvokeEvent(itk::ModifiedEvent()); m_PropertyList->Modified(); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } else if (mitk::StringProperty* stringProp = dynamic_cast(baseProp)) { stringProp->SetValue((value.value()).toStdString()); m_PropertyList->InvokeEvent(itk::ModifiedEvent()); m_PropertyList->Modified(); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } else if (mitk::IntProperty* intProp = dynamic_cast(baseProp)) { int intValue = value.value(); if (intValue != intProp->GetValue()) { intProp->SetValue(intValue); m_PropertyList->InvokeEvent(itk::ModifiedEvent()); m_PropertyList->Modified(); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } } else if (mitk::FloatProperty* floatProp = dynamic_cast(baseProp)) { float floatValue = value.value(); if (floatValue != floatProp->GetValue()) { floatProp->SetValue(floatValue); m_PropertyList->InvokeEvent(itk::ModifiedEvent()); m_PropertyList->Modified(); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } } else if (mitk::EnumerationProperty* enumerationProp = dynamic_cast(baseProp)) { std::string activatedItem = value.value().toStdString(); if ( activatedItem != enumerationProp->GetValueAsString() ) { if ( enumerationProp->IsValidEnumerationValue( activatedItem ) ) { enumerationProp->SetValue( activatedItem ); m_PropertyList->InvokeEvent( itk::ModifiedEvent() ); m_PropertyList->Modified(); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } } } } // property was changed by us, now we can accept property changes triggered by someone else m_BlockEvents = false; emit dataChanged(index, index); return true; } return false; } void QmitkPropertiesTableModel::sort( int column, Qt::SortOrder order /*= Qt::AscendingOrder */ ) { bool sortDescending = (order == Qt::DescendingOrder) ? true: false; // do not sort twice !!! (dont know why, but qt calls this func twice. STUPID!) if(sortDescending != m_SortDescending) { m_SortDescending = sortDescending; PropertyDataSetCompareFunction::CompareCriteria _CompareCriteria = PropertyDataSetCompareFunction::CompareByName; PropertyDataSetCompareFunction::CompareOperator _CompareOperator = m_SortDescending ? PropertyDataSetCompareFunction::Greater: PropertyDataSetCompareFunction::Less; if(column == PROPERTY_VALUE_COLUMN) _CompareCriteria = PropertyDataSetCompareFunction::CompareByValue; PropertyDataSetCompareFunction compareFunc(_CompareCriteria, _CompareOperator); std::sort(m_SelectedProperties.begin(), m_SelectedProperties.end(), compareFunc); - QAbstractTableModel::reset(); + QAbstractTableModel::beginResetModel(); + QAbstractTableModel::endResetModel(); } } //# PROTECTED GETTER int QmitkPropertiesTableModel::FindProperty( const mitk::BaseProperty* _Property ) const { int row = -1; if(_Property) { // search for property that changed and emit datachanged on the corresponding ModelIndex std::vector::const_iterator propertyIterator; for( propertyIterator=m_SelectedProperties.begin(); propertyIterator!=m_SelectedProperties.end() ; propertyIterator++) { if(propertyIterator->second == _Property) break; } if(propertyIterator != m_SelectedProperties.end()) row = std::distance(m_SelectedProperties.begin(), propertyIterator); } return row; } //# PROTECTED SETTER void QmitkPropertiesTableModel::AddSelectedProperty( PropertyDataSet& _PropertyDataSet ) { // subscribe for modified event itk::MemberCommand::Pointer _PropertyDataSetModifiedCommand = itk::MemberCommand::New(); _PropertyDataSetModifiedCommand->SetCallbackFunction(this, &QmitkPropertiesTableModel::PropertyModified); m_PropertyModifiedObserverTags.push_back(_PropertyDataSet.second->AddObserver(itk::ModifiedEvent(), _PropertyDataSetModifiedCommand)); // subscribe for delete event itk::MemberCommand::Pointer _PropertyDataSetDeleteCommand = itk::MemberCommand::New(); _PropertyDataSetDeleteCommand->SetCallbackFunction(this, &QmitkPropertiesTableModel::PropertyDelete); m_PropertyDeleteObserverTags.push_back(_PropertyDataSet.second->AddObserver(itk::DeleteEvent(), _PropertyDataSetDeleteCommand)); // add to the selection m_SelectedProperties.push_back(_PropertyDataSet); } void QmitkPropertiesTableModel::RemoveSelectedProperty( unsigned int _Index ) { PropertyDataSet& _PropertyDataSet = m_SelectedProperties.at(_Index); // remove modified event listener _PropertyDataSet.second->RemoveObserver(m_PropertyModifiedObserverTags[_Index]); m_PropertyModifiedObserverTags.erase(m_PropertyModifiedObserverTags.begin()+_Index); // remove delete event listener _PropertyDataSet.second->RemoveObserver(m_PropertyDeleteObserverTags[_Index]); m_PropertyDeleteObserverTags.erase(m_PropertyDeleteObserverTags.begin()+_Index); // remove from selection m_SelectedProperties.erase(m_SelectedProperties.begin()+_Index); } void QmitkPropertiesTableModel::Reset() { // remove all selected properties while(!m_SelectedProperties.empty()) { this->RemoveSelectedProperty(m_SelectedProperties.size()-1); } std::vector allPredicates; if(m_PropertyList.IsNotNull()) { // first of all: collect all properties from the list for(mitk::PropertyList::PropertyMap::const_iterator it=m_PropertyList->GetMap()->begin() ; it!=m_PropertyList->GetMap()->end() ; it++) { allPredicates.push_back(*it); //% TODO } } // make a subselection if a keyword is specified if(!m_FilterKeyWord.empty()) { std::vector subSelection; for(std::vector::iterator it=allPredicates.begin() ; it!=allPredicates.end() ; it++) { // add this to the selection if it is matched by the keyword if((*it).first.find(m_FilterKeyWord) != std::string::npos) subSelection.push_back((*it)); } allPredicates.clear(); allPredicates = subSelection; } PropertyDataSet tmpPropertyDataSet; // add all selected now to the Model for(std::vector::iterator it=allPredicates.begin() ; it!=allPredicates.end() ; it++) { tmpPropertyDataSet = *it; this->AddSelectedProperty(tmpPropertyDataSet); } // sort the list as indicated by m_SortDescending this->sort(m_SortDescending); // model was resetted - QAbstractTableModel::reset(); + QAbstractTableModel::beginResetModel(); + QAbstractTableModel::endResetModel(); } void QmitkPropertiesTableModel::SetFilterPropertiesKeyWord( std::string _FilterKeyWord ) { m_FilterKeyWord = _FilterKeyWord; this->Reset(); } QmitkPropertiesTableModel::PropertyDataSetCompareFunction::PropertyDataSetCompareFunction( CompareCriteria _CompareCriteria , CompareOperator _CompareOperator ) : m_CompareCriteria(_CompareCriteria) , m_CompareOperator(_CompareOperator) { } bool QmitkPropertiesTableModel::PropertyDataSetCompareFunction::operator() ( const PropertyDataSet& _Left , const PropertyDataSet& _Right ) const { switch(m_CompareCriteria) { case CompareByValue: if(m_CompareOperator == Less) return (_Left.second->GetValueAsString() < _Right.second->GetValueAsString()); else return (_Left.second->GetValueAsString() > _Right.second->GetValueAsString()); break; // CompareByName: default: if(m_CompareOperator == Less) return (_Left.first < _Right.first); else return (_Left.first > _Right.first); break; } } QmitkPropertiesTableModel::PropertyListElementFilterFunction::PropertyListElementFilterFunction( const std::string& _FilterKeyWord ) : m_FilterKeyWord(_FilterKeyWord) { } bool QmitkPropertiesTableModel::PropertyListElementFilterFunction::operator()( const PropertyDataSet& _Elem ) const { if(m_FilterKeyWord.empty()) return true; return (_Elem.first.find(m_FilterKeyWord) == 0); } diff --git a/Modules/QtWidgets/QmitkRenderWindowMenu.cpp b/Modules/QtWidgets/QmitkRenderWindowMenu.cpp index 2dfbedadc0..76b4986be9 100644 --- a/Modules/QtWidgets/QmitkRenderWindowMenu.cpp +++ b/Modules/QtWidgets/QmitkRenderWindowMenu.cpp @@ -1,1027 +1,1019 @@ /*=================================================================== 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 "QmitkRenderWindowMenu.h" #include "mitkResliceMethodProperty.h" #include "mitkProperties.h" #include #include #include #include #include #include #include #include #include #include #include #include "QmitkStdMultiWidget.h" //#include"iconClose.xpm" #include"iconFullScreen.xpm" #include"iconCrosshairMode.xpm" //#include"iconHoriSplit.xpm" #include"iconSettings.xpm" //#include"iconVertiSplit.xpm" #include"iconLeaveFullScreen.xpm" #include #ifdef QMITK_USE_EXTERNAL_RENDERWINDOW_MENU QmitkRenderWindowMenu::QmitkRenderWindowMenu(QWidget *parent, Qt::WindowFlags f, mitk::BaseRenderer *b, QmitkStdMultiWidget* mw ) :QWidget(parent, Qt::Tool | Qt::FramelessWindowHint ), #else QmitkRenderWindowMenu::QmitkRenderWindowMenu(QWidget *parent, Qt::WindowFlags f, mitk::BaseRenderer *b, QmitkStdMultiWidget* mw ) :QWidget(parent,f), #endif m_Settings(NULL), m_CrosshairMenu(NULL), m_Layout(0), m_LayoutDesign(0), m_OldLayoutDesign(0), m_FullScreenMode(false), m_Entered(false), m_Hidden(true), m_Renderer(b), m_MultiWidget(mw) { MITK_DEBUG << "creating renderwindow menu on baserenderer " << b; //Create Menu Widget this->CreateMenuWidget(); this->setMinimumWidth(61); //DIRTY.. If you add or remove a button, you need to change the size. this->setMaximumWidth(61); this->setAutoFillBackground( true ); //Else part fixes the render window menu issue on Linux bug but caused bugs on Mac OS and Windows //for Mac OS see bug 3192 //for Windows see bug 12130 //... so Mac OS and Windows must be treated differently: #if defined(Q_OS_MAC) || defined(_WIN32) this->show(); this->setWindowOpacity(0.0f); #else this->setVisible(false); #endif //this->setAttribute( Qt::WA_NoSystemBackground ); //this->setBackgroundRole( QPalette::Dark ); //this->update(); //SetOpacity -- its just posible if the widget is a window. //Windows indicates that the widget is a window, usually with a window system frame and a title bar, //irrespective of whether the widget has a parent or not. /* this->setWindowFlags( Qt::Window | Qt::FramelessWindowHint); */ //this->setAttribute(Qt::WA_TranslucentBackground); //this->setWindowOpacity(0.75); currentCrosshairRotationMode = 0; // for autorotating m_AutoRotationTimer.setInterval( 75 ); connect( &m_AutoRotationTimer, SIGNAL(timeout()), this, SLOT(AutoRotateNextStep()) ); } QmitkRenderWindowMenu::~QmitkRenderWindowMenu() { if( m_AutoRotationTimer.isActive() ) m_AutoRotationTimer.stop(); } void QmitkRenderWindowMenu::CreateMenuWidget() { QHBoxLayout* layout = new QHBoxLayout(this); layout->setAlignment( Qt::AlignRight ); layout->setContentsMargins(1,1,1,1); QSize size( 13, 13 ); m_CrosshairMenu = new QMenu(this); connect( m_CrosshairMenu, SIGNAL( aboutToShow() ), this, SLOT(OnCrossHairMenuAboutToShow()) ); // button for changing rotation mode m_CrosshairModeButton = new QPushButton(this); m_CrosshairModeButton->setMaximumSize(15, 15); m_CrosshairModeButton->setIconSize(size); m_CrosshairModeButton->setFlat( true ); m_CrosshairModeButton->setMenu( m_CrosshairMenu ); - m_CrosshairModeButton->setIcon( QIcon( iconCrosshairMode_xpm ) ); + m_CrosshairModeButton->setIcon(QIcon(QPixmap(iconCrosshairMode_xpm))); layout->addWidget( m_CrosshairModeButton ); //fullScreenButton m_FullScreenButton = new QPushButton(this); m_FullScreenButton->setMaximumSize(15, 15); m_FullScreenButton->setIconSize(size); m_FullScreenButton->setFlat( true ); - m_FullScreenButton->setIcon( QIcon( iconFullScreen_xpm )); + m_FullScreenButton->setIcon(QIcon(QPixmap(iconFullScreen_xpm))); layout->addWidget( m_FullScreenButton ); //settingsButton m_SettingsButton = new QPushButton(this); m_SettingsButton->setMaximumSize(15, 15); m_SettingsButton->setIconSize(size); m_SettingsButton->setFlat( true ); - m_SettingsButton->setIcon( QIcon( iconSettings_xpm )); + m_SettingsButton->setIcon(QIcon(QPixmap(iconSettings_xpm))); layout->addWidget( m_SettingsButton ); //Create Connections -- coming soon? connect( m_FullScreenButton, SIGNAL( clicked(bool) ), this, SLOT(OnFullScreenButton(bool)) ); connect( m_SettingsButton, SIGNAL( clicked(bool) ), this, SLOT(OnSettingsButton(bool)) ); } void QmitkRenderWindowMenu::CreateSettingsWidget() { m_Settings = new QMenu(this); m_DefaultLayoutAction = new QAction( "standard layout", m_Settings ); m_DefaultLayoutAction->setDisabled( true ); m_2DImagesUpLayoutAction = new QAction( "2D images top, 3D bottom", m_Settings ); m_2DImagesUpLayoutAction->setDisabled( false ); m_2DImagesLeftLayoutAction = new QAction( "2D images left, 3D right", m_Settings ); m_2DImagesLeftLayoutAction->setDisabled( false ); m_Big3DLayoutAction = new QAction( "Big 3D", m_Settings ); m_Big3DLayoutAction->setDisabled( false ); m_Widget1LayoutAction = new QAction( "Axial plane", m_Settings ); m_Widget1LayoutAction->setDisabled( false ); m_Widget2LayoutAction = new QAction( "Sagittal plane", m_Settings ); m_Widget2LayoutAction->setDisabled( false ); m_Widget3LayoutAction = new QAction( "Coronal plane", m_Settings ); m_Widget3LayoutAction->setDisabled( false ); m_RowWidget3And4LayoutAction = new QAction( "Coronal top, 3D bottom", m_Settings ); m_RowWidget3And4LayoutAction->setDisabled( false ); m_ColumnWidget3And4LayoutAction = new QAction( "Coronal left, 3D right", m_Settings ); m_ColumnWidget3And4LayoutAction->setDisabled( false ); m_SmallUpperWidget2Big3and4LayoutAction = new QAction( "Sagittal top, Coronal n 3D bottom", m_Settings ); m_SmallUpperWidget2Big3and4LayoutAction->setDisabled( false ); m_2x2Dand3DWidgetLayoutAction = new QAction( "Axial n Sagittal left, 3D right", m_Settings ); m_2x2Dand3DWidgetLayoutAction->setDisabled( false ); m_Left2Dand3DRight2DLayoutAction = new QAction( "Axial n 3D left, Sagittal right", m_Settings ); m_Left2Dand3DRight2DLayoutAction->setDisabled( false ); m_Settings->addAction(m_DefaultLayoutAction); m_Settings->addAction(m_2DImagesUpLayoutAction); m_Settings->addAction(m_2DImagesLeftLayoutAction); m_Settings->addAction(m_Big3DLayoutAction); m_Settings->addAction(m_Widget1LayoutAction); m_Settings->addAction(m_Widget2LayoutAction); m_Settings->addAction(m_Widget3LayoutAction); m_Settings->addAction(m_RowWidget3And4LayoutAction); m_Settings->addAction(m_ColumnWidget3And4LayoutAction); m_Settings->addAction(m_SmallUpperWidget2Big3and4LayoutAction); m_Settings->addAction(m_2x2Dand3DWidgetLayoutAction); m_Settings->addAction(m_Left2Dand3DRight2DLayoutAction); m_Settings->setVisible( false ); connect( m_DefaultLayoutAction, SIGNAL( triggered(bool) ), this, SLOT(OnChangeLayoutToDefault(bool)) ); connect( m_2DImagesUpLayoutAction, SIGNAL( triggered(bool) ), this, SLOT(OnChangeLayoutTo2DImagesUp(bool)) ); connect( m_2DImagesLeftLayoutAction, SIGNAL( triggered(bool) ), this, SLOT(OnChangeLayoutTo2DImagesLeft(bool)) ); connect( m_Big3DLayoutAction, SIGNAL( triggered(bool) ), this, SLOT(OnChangeLayoutToBig3D(bool)) ); connect( m_Widget1LayoutAction, SIGNAL( triggered(bool) ), this, SLOT(OnChangeLayoutToWidget1(bool)) ); connect( m_Widget2LayoutAction, SIGNAL( triggered(bool) ), this, SLOT(OnChangeLayoutToWidget2(bool)) ); connect( m_Widget3LayoutAction , SIGNAL( triggered(bool) ), this, SLOT(OnChangeLayoutToWidget3(bool)) ); connect( m_RowWidget3And4LayoutAction, SIGNAL( triggered(bool) ), this, SLOT(OnChangeLayoutToRowWidget3And4(bool)) ); connect( m_ColumnWidget3And4LayoutAction, SIGNAL( triggered(bool) ), this, SLOT(OnChangeLayoutToColumnWidget3And4(bool)) ); connect( m_SmallUpperWidget2Big3and4LayoutAction, SIGNAL( triggered(bool) ), this, SLOT(OnChangeLayoutToSmallUpperWidget2Big3and4(bool)) ); connect( m_2x2Dand3DWidgetLayoutAction, SIGNAL( triggered(bool) ), this, SLOT(OnChangeLayoutTo2x2Dand3DWidget(bool)) ); connect( m_Left2Dand3DRight2DLayoutAction, SIGNAL( triggered(bool) ), this, SLOT(OnChangeLayoutToLeft2Dand3DRight2D(bool)) ); } void QmitkRenderWindowMenu::paintEvent( QPaintEvent* /*e*/ ) { QPainter painter(this); QColor semiTransparentColor = Qt::black; semiTransparentColor.setAlpha(255); painter.fillRect(rect(), semiTransparentColor); } void QmitkRenderWindowMenu::SetLayoutIndex( unsigned int layoutIndex ) { m_Layout = layoutIndex; } void QmitkRenderWindowMenu::HideMenu( ) { MITK_DEBUG << "menu hideEvent"; m_Hidden = true; if( ! m_Entered ) { //Else part fixes the render window menu issue on Linux bug but caused bugs on Mac OS and Windows //for Mac OS see bug 3192 //for Windows see bug 12130 //... so Mac OS and Windows must be treated differently: #if defined(Q_OS_MAC) || defined(_WIN32) this->setWindowOpacity(0.0f); #else this->setVisible(false); #endif } } void QmitkRenderWindowMenu::ShowMenu( ) { MITK_DEBUG << "menu showMenu"; m_Hidden = false; //Else part fixes the render window menu issue on Linux bug but caused bugs on Mac OS and Windows //for Mac OS see bug 3192 //for Windows see bug 12130 //... so Mac OS and Windows must be treated differently: #if defined(Q_OS_MAC) || defined(_WIN32) this->setWindowOpacity(1.0f); #else this->setVisible(true); #endif } void QmitkRenderWindowMenu::enterEvent( QEvent * /*e*/ ) { MITK_DEBUG << "menu enterEvent"; m_Entered=true; m_Hidden=false; } void QmitkRenderWindowMenu::DeferredHideMenu( ) { MITK_DEBUG << "menu deferredhidemenu"; if(m_Hidden) { //Else part fixes the render window menu issue on Linux bug but caused bugs on Mac OS and Windows //for Mac OS see bug 3192 //for Windows see bug 12130 //... so Mac OS and Windows must be treated differently: #if defined(Q_OS_MAC) || defined(_WIN32) this->setWindowOpacity(0.0f); #else this->setVisible(false); #endif } // setVisible(false); // setWindowOpacity(0.0f); ///hide(); } void QmitkRenderWindowMenu::leaveEvent( QEvent * /*e*/ ) { MITK_DEBUG << "menu leaveEvent"; smoothHide(); } /* This method is responsible for non fluttering of the renderWindowMenu when mouse cursor moves along the renderWindowMenu*/ void QmitkRenderWindowMenu::smoothHide() { MITK_DEBUG<< "menu leaveEvent"; m_Entered=false; m_Hidden = true; QTimer::singleShot(10,this,SLOT( DeferredHideMenu( ) ) ); } void QmitkRenderWindowMenu::ChangeFullScreenMode( bool state ) { this->OnFullScreenButton( state ); } /// \brief void QmitkRenderWindowMenu::OnFullScreenButton( bool /*checked*/ ) { if( !m_FullScreenMode ) { m_FullScreenMode = true; m_OldLayoutDesign = m_LayoutDesign; switch( m_Layout ) { case AXIAL: { emit SignalChangeLayoutDesign( LAYOUT_AXIAL ); break; } case SAGITTAL: { emit SignalChangeLayoutDesign( LAYOUT_SAGITTAL ); break; } case CORONAL: { emit SignalChangeLayoutDesign( LAYOUT_CORONAL ); break; } case THREE_D: { emit SignalChangeLayoutDesign( LAYOUT_BIG3D ); break; } } //Move Widget and show again this->MoveWidgetToCorrectPos(1.0f); //change icon this->ChangeFullScreenIcon(); } else { m_FullScreenMode = false; emit SignalChangeLayoutDesign( m_OldLayoutDesign ); //Move Widget and show again this->MoveWidgetToCorrectPos(1.0f); //change icon this->ChangeFullScreenIcon(); } DeferredShowMenu( ); } /// \brief void QmitkRenderWindowMenu::OnSettingsButton( bool /*checked*/ ) { if( m_Settings == NULL ) this->CreateSettingsWidget(); QPoint point = this->mapToGlobal( m_SettingsButton->geometry().topLeft() ); m_Settings->setVisible( true ); m_Settings->exec( point ); } void QmitkRenderWindowMenu::OnChangeLayoutTo2DImagesUp(bool) { //set Full Screen Mode to false, if Layout Design was changed by the LayoutDesign_List m_FullScreenMode = false; this->ChangeFullScreenIcon(); m_LayoutDesign = LAYOUT_2DIMAGEUP; emit SignalChangeLayoutDesign( LAYOUT_2DIMAGEUP ); DeferredShowMenu( ); } void QmitkRenderWindowMenu::OnChangeLayoutTo2DImagesLeft(bool) { //set Full Screen Mode to false, if Layout Design was changed by the LayoutDesign_List m_FullScreenMode = false; this->ChangeFullScreenIcon(); m_LayoutDesign = LAYOUT_2DIMAGELEFT; emit SignalChangeLayoutDesign( LAYOUT_2DIMAGELEFT ); DeferredShowMenu( ); } void QmitkRenderWindowMenu::OnChangeLayoutToDefault(bool) { //set Full Screen Mode to false, if Layout Design was changed by the LayoutDesign_List m_FullScreenMode = false; this->ChangeFullScreenIcon(); m_LayoutDesign = LAYOUT_DEFAULT; emit SignalChangeLayoutDesign( LAYOUT_DEFAULT ); DeferredShowMenu( ); } void QmitkRenderWindowMenu::DeferredShowMenu() { MITK_DEBUG << "deferred show menu"; //Else part fixes the render window menu issue on Linux bug but caused bugs on Mac OS and Windows //for Mac OS see bug 3192 //for Windows see bug 12130 //... so Mac OS and Windows must be treated differently: #if defined(Q_OS_MAC) || defined(_WIN32) this->setWindowOpacity(1.0f); #else this->setVisible(true); #endif } void QmitkRenderWindowMenu::OnChangeLayoutToBig3D(bool) { MITK_DEBUG << "OnChangeLayoutToBig3D"; //set Full Screen Mode to false, if Layout Design was changed by the LayoutDesign_List m_FullScreenMode = false; this->ChangeFullScreenIcon(); m_LayoutDesign = LAYOUT_BIG3D; emit SignalChangeLayoutDesign( LAYOUT_BIG3D ); DeferredShowMenu( ); } void QmitkRenderWindowMenu::OnChangeLayoutToWidget1(bool) { //set Full Screen Mode to false, if Layout Design was changed by the LayoutDesign_List m_FullScreenMode = false; this->ChangeFullScreenIcon(); m_LayoutDesign = LAYOUT_AXIAL; emit SignalChangeLayoutDesign( LAYOUT_AXIAL ); DeferredShowMenu( ); } void QmitkRenderWindowMenu::OnChangeLayoutToWidget2(bool) { //set Full Screen Mode to false, if Layout Design was changed by the LayoutDesign_List m_FullScreenMode = false; this->ChangeFullScreenIcon(); m_LayoutDesign = LAYOUT_SAGITTAL; emit SignalChangeLayoutDesign( LAYOUT_SAGITTAL ); DeferredShowMenu( ); } void QmitkRenderWindowMenu::OnChangeLayoutToWidget3(bool) { //set Full Screen Mode to false, if Layout Design was changed by the LayoutDesign_List m_FullScreenMode = false; this->ChangeFullScreenIcon(); m_LayoutDesign = LAYOUT_CORONAL; emit SignalChangeLayoutDesign( LAYOUT_CORONAL ); DeferredShowMenu( ); } void QmitkRenderWindowMenu::OnChangeLayoutToRowWidget3And4(bool) { //set Full Screen Mode to false, if Layout Design was changed by the LayoutDesign_List m_FullScreenMode = false; this->ChangeFullScreenIcon(); m_LayoutDesign = LAYOUT_ROWWIDGET3AND4; emit SignalChangeLayoutDesign( LAYOUT_ROWWIDGET3AND4 ); DeferredShowMenu( ); } void QmitkRenderWindowMenu::OnChangeLayoutToColumnWidget3And4(bool) { //set Full Screen Mode to false, if Layout Design was changed by the LayoutDesign_List m_FullScreenMode = false; this->ChangeFullScreenIcon(); m_LayoutDesign = LAYOUT_COLUMNWIDGET3AND4; emit SignalChangeLayoutDesign( LAYOUT_COLUMNWIDGET3AND4 ); DeferredShowMenu( ); } void QmitkRenderWindowMenu::OnChangeLayoutToSmallUpperWidget2Big3and4(bool) { //set Full Screen Mode to false, if Layout Design was changed by the LayoutDesign_List m_FullScreenMode = false; this->ChangeFullScreenIcon(); m_LayoutDesign = LAYOUT_SMALLUPPERWIDGET2BIGAND4; emit SignalChangeLayoutDesign( LAYOUT_SMALLUPPERWIDGET2BIGAND4 ); DeferredShowMenu( ); } void QmitkRenderWindowMenu::OnChangeLayoutTo2x2Dand3DWidget(bool) { //set Full Screen Mode to false, if Layout Design was changed by the LayoutDesign_List m_FullScreenMode = false; this->ChangeFullScreenIcon(); m_LayoutDesign = LAYOUT_2X2DAND3DWIDGET; emit SignalChangeLayoutDesign( LAYOUT_2X2DAND3DWIDGET ); DeferredShowMenu( ); } void QmitkRenderWindowMenu::OnChangeLayoutToLeft2Dand3DRight2D(bool) { //set Full Screen Mode to false, if Layout Design was changed by the LayoutDesign_List m_FullScreenMode = false; this->ChangeFullScreenIcon(); m_LayoutDesign = LAYOUT_LEFT2DAND3DRIGHT2D; emit SignalChangeLayoutDesign( LAYOUT_LEFT2DAND3DRIGHT2D ); DeferredShowMenu( ); } void QmitkRenderWindowMenu::UpdateLayoutDesignList( int layoutDesignIndex ) { m_LayoutDesign = layoutDesignIndex; if( m_Settings == NULL ) this->CreateSettingsWidget(); switch( m_LayoutDesign ) { case LAYOUT_DEFAULT: { m_DefaultLayoutAction->setEnabled(false); m_2DImagesUpLayoutAction->setEnabled(true); m_2DImagesLeftLayoutAction->setEnabled(true); m_Big3DLayoutAction->setEnabled(true); m_Widget1LayoutAction->setEnabled(true); m_Widget2LayoutAction->setEnabled(true); m_Widget3LayoutAction->setEnabled(true); m_RowWidget3And4LayoutAction->setEnabled(true); m_ColumnWidget3And4LayoutAction->setEnabled(true); m_SmallUpperWidget2Big3and4LayoutAction->setEnabled(true); m_2x2Dand3DWidgetLayoutAction->setEnabled(true); m_Left2Dand3DRight2DLayoutAction->setEnabled(true); break; } case LAYOUT_2DIMAGEUP: { m_DefaultLayoutAction->setEnabled(true); m_2DImagesUpLayoutAction->setEnabled(false); m_2DImagesLeftLayoutAction->setEnabled(true); m_Big3DLayoutAction->setEnabled(true); m_Widget1LayoutAction->setEnabled(true); m_Widget2LayoutAction->setEnabled(true); m_Widget3LayoutAction->setEnabled(true); m_RowWidget3And4LayoutAction->setEnabled(true); m_ColumnWidget3And4LayoutAction->setEnabled(true); m_SmallUpperWidget2Big3and4LayoutAction->setEnabled(true); m_2x2Dand3DWidgetLayoutAction->setEnabled(true); m_Left2Dand3DRight2DLayoutAction->setEnabled(true); break; } case LAYOUT_2DIMAGELEFT: { m_DefaultLayoutAction->setEnabled(true); m_2DImagesUpLayoutAction->setEnabled(true); m_2DImagesLeftLayoutAction->setEnabled(false); m_Big3DLayoutAction->setEnabled(true); m_Widget1LayoutAction->setEnabled(true); m_Widget2LayoutAction->setEnabled(true); m_Widget3LayoutAction->setEnabled(true); m_RowWidget3And4LayoutAction->setEnabled(true); m_ColumnWidget3And4LayoutAction->setEnabled(true); m_SmallUpperWidget2Big3and4LayoutAction->setEnabled(true); m_2x2Dand3DWidgetLayoutAction->setEnabled(true); m_Left2Dand3DRight2DLayoutAction->setEnabled(true); break; } case LAYOUT_BIG3D: { m_DefaultLayoutAction->setEnabled(true); m_2DImagesUpLayoutAction->setEnabled(true); m_2DImagesLeftLayoutAction->setEnabled(true); m_Big3DLayoutAction->setEnabled(false); m_Widget1LayoutAction->setEnabled(true); m_Widget2LayoutAction->setEnabled(true); m_Widget3LayoutAction->setEnabled(true); m_RowWidget3And4LayoutAction->setEnabled(true); m_ColumnWidget3And4LayoutAction->setEnabled(true); m_SmallUpperWidget2Big3and4LayoutAction->setEnabled(true); m_2x2Dand3DWidgetLayoutAction->setEnabled(true); m_Left2Dand3DRight2DLayoutAction->setEnabled(true); break; } case LAYOUT_AXIAL: { m_DefaultLayoutAction->setEnabled(true); m_2DImagesUpLayoutAction->setEnabled(true); m_2DImagesLeftLayoutAction->setEnabled(true); m_Big3DLayoutAction->setEnabled(true); m_Widget1LayoutAction->setEnabled(false); m_Widget2LayoutAction->setEnabled(true); m_Widget3LayoutAction->setEnabled(true); m_RowWidget3And4LayoutAction->setEnabled(true); m_ColumnWidget3And4LayoutAction->setEnabled(true); m_SmallUpperWidget2Big3and4LayoutAction->setEnabled(true); m_2x2Dand3DWidgetLayoutAction->setEnabled(true); m_Left2Dand3DRight2DLayoutAction->setEnabled(true); break; } case LAYOUT_SAGITTAL: { m_DefaultLayoutAction->setEnabled(true); m_2DImagesUpLayoutAction->setEnabled(true); m_2DImagesLeftLayoutAction->setEnabled(true); m_Big3DLayoutAction->setEnabled(true); m_Widget1LayoutAction->setEnabled(true); m_Widget2LayoutAction->setEnabled(false); m_Widget3LayoutAction->setEnabled(true); m_RowWidget3And4LayoutAction->setEnabled(true); m_ColumnWidget3And4LayoutAction->setEnabled(true); m_SmallUpperWidget2Big3and4LayoutAction->setEnabled(true); m_2x2Dand3DWidgetLayoutAction->setEnabled(true); m_Left2Dand3DRight2DLayoutAction->setEnabled(true); break; } case LAYOUT_CORONAL: { m_DefaultLayoutAction->setEnabled(true); m_2DImagesUpLayoutAction->setEnabled(true); m_2DImagesLeftLayoutAction->setEnabled(true); m_Big3DLayoutAction->setEnabled(true); m_Widget1LayoutAction->setEnabled(true); m_Widget2LayoutAction->setEnabled(true); m_Widget3LayoutAction->setEnabled(false); m_RowWidget3And4LayoutAction->setEnabled(true); m_ColumnWidget3And4LayoutAction->setEnabled(true); m_SmallUpperWidget2Big3and4LayoutAction->setEnabled(true); m_2x2Dand3DWidgetLayoutAction->setEnabled(true); m_Left2Dand3DRight2DLayoutAction->setEnabled(true); break; } case LAYOUT_2X2DAND3DWIDGET: { m_DefaultLayoutAction->setEnabled(true); m_2DImagesUpLayoutAction->setEnabled(true); m_2DImagesLeftLayoutAction->setEnabled(true); m_Big3DLayoutAction->setEnabled(true); m_Widget1LayoutAction->setEnabled(true); m_Widget2LayoutAction->setEnabled(true); m_Widget3LayoutAction->setEnabled(true); m_RowWidget3And4LayoutAction->setEnabled(true); m_ColumnWidget3And4LayoutAction->setEnabled(true); m_SmallUpperWidget2Big3and4LayoutAction->setEnabled(true); m_2x2Dand3DWidgetLayoutAction->setEnabled(false); m_Left2Dand3DRight2DLayoutAction->setEnabled(true); break; } case LAYOUT_ROWWIDGET3AND4: { m_DefaultLayoutAction->setEnabled(true); m_2DImagesUpLayoutAction->setEnabled(true); m_2DImagesLeftLayoutAction->setEnabled(true); m_Big3DLayoutAction->setEnabled(true); m_Widget1LayoutAction->setEnabled(true); m_Widget2LayoutAction->setEnabled(true); m_Widget3LayoutAction->setEnabled(true); m_RowWidget3And4LayoutAction->setEnabled(false); m_ColumnWidget3And4LayoutAction->setEnabled(true); m_SmallUpperWidget2Big3and4LayoutAction->setEnabled(true); m_2x2Dand3DWidgetLayoutAction->setEnabled(true); m_Left2Dand3DRight2DLayoutAction->setEnabled(true); break; } case LAYOUT_COLUMNWIDGET3AND4: { m_DefaultLayoutAction->setEnabled(true); m_2DImagesUpLayoutAction->setEnabled(true); m_2DImagesLeftLayoutAction->setEnabled(true); m_Big3DLayoutAction->setEnabled(true); m_Widget1LayoutAction->setEnabled(true); m_Widget2LayoutAction->setEnabled(true); m_Widget3LayoutAction->setEnabled(true); m_RowWidget3And4LayoutAction->setEnabled(true); m_ColumnWidget3And4LayoutAction->setEnabled(false); m_SmallUpperWidget2Big3and4LayoutAction->setEnabled(true); m_2x2Dand3DWidgetLayoutAction->setEnabled(true); m_Left2Dand3DRight2DLayoutAction->setEnabled(true); break; } case LAYOUT_SMALLUPPERWIDGET2BIGAND4: { m_DefaultLayoutAction->setEnabled(true); m_2DImagesUpLayoutAction->setEnabled(true); m_2DImagesLeftLayoutAction->setEnabled(true); m_Big3DLayoutAction->setEnabled(true); m_Widget1LayoutAction->setEnabled(true); m_Widget2LayoutAction->setEnabled(true); m_Widget3LayoutAction->setEnabled(true); m_RowWidget3And4LayoutAction->setEnabled(true); m_ColumnWidget3And4LayoutAction->setEnabled(true); m_SmallUpperWidget2Big3and4LayoutAction->setEnabled(false); m_2x2Dand3DWidgetLayoutAction->setEnabled(true); m_Left2Dand3DRight2DLayoutAction->setEnabled(true); break; } case LAYOUT_LEFT2DAND3DRIGHT2D: { m_DefaultLayoutAction->setEnabled(true); m_2DImagesUpLayoutAction->setEnabled(true); m_2DImagesLeftLayoutAction->setEnabled(true); m_Big3DLayoutAction->setEnabled(true); m_Widget1LayoutAction->setEnabled(true); m_Widget2LayoutAction->setEnabled(true); m_Widget3LayoutAction->setEnabled(true); m_RowWidget3And4LayoutAction->setEnabled(true); m_ColumnWidget3And4LayoutAction->setEnabled(true); m_SmallUpperWidget2Big3and4LayoutAction->setEnabled(true); m_2x2Dand3DWidgetLayoutAction->setEnabled(true); m_Left2Dand3DRight2DLayoutAction->setEnabled(false); break; } } } #ifdef QMITK_USE_EXTERNAL_RENDERWINDOW_MENU void QmitkRenderWindowMenu::MoveWidgetToCorrectPos(float opacity) #else void QmitkRenderWindowMenu::MoveWidgetToCorrectPos(float /*opacity*/) #endif { #ifdef QMITK_USE_EXTERNAL_RENDERWINDOW_MENU int X=floor( double(this->parentWidget()->width() - this->width() - 8.0) ); int Y=7; QPoint pos = this->parentWidget()->mapToGlobal( QPoint(0,0) ); this->move( X+pos.x(), Y+pos.y() ); if(opacity<0) opacity=0; else if(opacity>1) opacity=1; this->setWindowOpacity(opacity); #else int moveX= floor( double(this->parentWidget()->width() - this->width() - 4.0) ); this->move( moveX, 3 ); this->show(); #endif } void QmitkRenderWindowMenu::ChangeFullScreenIcon() { - - if( m_FullScreenMode ) - { - const QIcon icon( iconLeaveFullScreen_xpm ); - m_FullScreenButton->setIcon(icon); - } - else - { - const QIcon icon( iconFullScreen_xpm ); - m_FullScreenButton->setIcon(icon); - } + m_FullScreenButton->setIcon(m_FullScreenMode + ? QPixmap(iconLeaveFullScreen_xpm) + : QPixmap(iconFullScreen_xpm)); } void QmitkRenderWindowMenu::OnCrosshairRotationModeSelected(QAction* action) { MITK_DEBUG << "selected crosshair mode " << action->data().toInt() ; emit ChangeCrosshairRotationMode( action->data().toInt() ); } void QmitkRenderWindowMenu::SetCrossHairVisibility( bool state ) { if(m_Renderer.IsNotNull()) { mitk::DataNode *n; if(this->m_MultiWidget) { n = this->m_MultiWidget->GetWidgetPlane1(); if(n) n->SetVisibility(state); n = this->m_MultiWidget->GetWidgetPlane2(); if(n) n->SetVisibility(state); n = this->m_MultiWidget->GetWidgetPlane3(); if(n) n->SetVisibility(state); m_Renderer->GetRenderingManager()->RequestUpdateAll(); } } } void QmitkRenderWindowMenu::OnTSNumChanged(int num) { MITK_DEBUG << "Thickslices num: " << num << " on renderer " << m_Renderer.GetPointer(); if(m_Renderer.IsNotNull()) { if(num==0) { m_Renderer->GetCurrentWorldPlaneGeometryNode()->SetProperty( "reslice.thickslices", mitk::ResliceMethodProperty::New( 0 ) ); m_Renderer->GetCurrentWorldPlaneGeometryNode()->SetProperty( "reslice.thickslices.num", mitk::IntProperty::New( num ) ); m_Renderer->GetCurrentWorldPlaneGeometryNode()->SetProperty( "reslice.thickslices.showarea", mitk::BoolProperty::New( false ) ); } else { m_Renderer->GetCurrentWorldPlaneGeometryNode()->SetProperty( "reslice.thickslices", mitk::ResliceMethodProperty::New( 1 ) ); m_Renderer->GetCurrentWorldPlaneGeometryNode()->SetProperty( "reslice.thickslices.num", mitk::IntProperty::New( num ) ); m_Renderer->GetCurrentWorldPlaneGeometryNode()->SetProperty( "reslice.thickslices.showarea", mitk::BoolProperty::New( true ) ); } m_TSLabel->setText(QString::number(num*2+1)); m_Renderer->SendUpdateSlice(); m_Renderer->GetRenderingManager()->RequestUpdateAll(); } } void QmitkRenderWindowMenu::OnCrossHairMenuAboutToShow() { QMenu *crosshairModesMenu = m_CrosshairMenu; crosshairModesMenu->clear(); QAction* resetViewAction = new QAction(crosshairModesMenu); resetViewAction->setText("Reset view"); crosshairModesMenu->addAction( resetViewAction ); connect( resetViewAction, SIGNAL(triggered()), this, SIGNAL(ResetView())); // Show hide crosshairs { bool currentState = true; if(m_Renderer.IsNotNull()) { mitk::DataStorage *ds=m_Renderer->GetDataStorage(); mitk::DataNode *n; if(ds) { n = this->m_MultiWidget->GetWidgetPlane1(); if(n) { bool v; if(n->GetVisibility(v,0)) currentState&=v; } n = this->m_MultiWidget->GetWidgetPlane2(); if(n) { bool v; if(n->GetVisibility(v,0)) currentState&=v; } n = this->m_MultiWidget->GetWidgetPlane3(); if(n) { bool v; if(n->GetVisibility(v,0)) currentState&=v; } } } QAction* showHideCrosshairVisibilityAction = new QAction(crosshairModesMenu); showHideCrosshairVisibilityAction->setText("Show crosshair"); showHideCrosshairVisibilityAction->setCheckable(true); showHideCrosshairVisibilityAction->setChecked(currentState); crosshairModesMenu->addAction( showHideCrosshairVisibilityAction ); connect( showHideCrosshairVisibilityAction, SIGNAL(toggled(bool)), this, SLOT(SetCrossHairVisibility(bool))); } // Rotation mode { QAction* rotationGroupSeparator = new QAction(crosshairModesMenu); rotationGroupSeparator->setSeparator(true); rotationGroupSeparator->setText("Rotation mode"); crosshairModesMenu->addAction( rotationGroupSeparator ); QActionGroup* rotationModeActionGroup = new QActionGroup(crosshairModesMenu); rotationModeActionGroup->setExclusive(true); QAction* noCrosshairRotation = new QAction(crosshairModesMenu); noCrosshairRotation->setActionGroup(rotationModeActionGroup); noCrosshairRotation->setText("No crosshair rotation"); noCrosshairRotation->setCheckable(true); noCrosshairRotation->setChecked(currentCrosshairRotationMode==0); noCrosshairRotation->setData( 0 ); crosshairModesMenu->addAction( noCrosshairRotation ); QAction* singleCrosshairRotation = new QAction(crosshairModesMenu); singleCrosshairRotation->setActionGroup(rotationModeActionGroup); singleCrosshairRotation->setText("Crosshair rotation"); singleCrosshairRotation->setCheckable(true); singleCrosshairRotation->setChecked(currentCrosshairRotationMode==1); singleCrosshairRotation->setData( 1 ); crosshairModesMenu->addAction( singleCrosshairRotation ); QAction* coupledCrosshairRotation = new QAction(crosshairModesMenu); coupledCrosshairRotation->setActionGroup(rotationModeActionGroup); coupledCrosshairRotation->setText("Coupled crosshair rotation"); coupledCrosshairRotation->setCheckable(true); coupledCrosshairRotation->setChecked(currentCrosshairRotationMode==2); coupledCrosshairRotation->setData( 2 ); crosshairModesMenu->addAction( coupledCrosshairRotation ); QAction* swivelMode = new QAction(crosshairModesMenu); swivelMode->setActionGroup(rotationModeActionGroup); swivelMode->setText("Swivel mode"); swivelMode->setCheckable(true); swivelMode->setChecked(currentCrosshairRotationMode==3); swivelMode->setData( 3 ); crosshairModesMenu->addAction( swivelMode ); connect( rotationModeActionGroup, SIGNAL(triggered(QAction*)), this, SLOT(OnCrosshairRotationModeSelected(QAction*)) ); } // auto rotation support if( m_Renderer.IsNotNull() && m_Renderer->GetMapperID() == mitk::BaseRenderer::Standard3D ) { QAction* autoRotationGroupSeparator = new QAction(crosshairModesMenu); autoRotationGroupSeparator->setSeparator(true); crosshairModesMenu->addAction( autoRotationGroupSeparator ); QAction* autoRotationAction = crosshairModesMenu->addAction( "Auto Rotation" ); autoRotationAction->setCheckable(true); autoRotationAction->setChecked( m_AutoRotationTimer.isActive() ); connect( autoRotationAction, SIGNAL(triggered()), this, SLOT(OnAutoRotationActionTriggered()) ); } // Thickslices support if( m_Renderer.IsNotNull() && m_Renderer->GetMapperID() == mitk::BaseRenderer::Standard2D ) { QAction* thickSlicesGroupSeparator = new QAction(crosshairModesMenu); thickSlicesGroupSeparator->setSeparator(true); thickSlicesGroupSeparator->setText("ThickSlices mode"); crosshairModesMenu->addAction( thickSlicesGroupSeparator ); QActionGroup* thickSlicesActionGroup = new QActionGroup(crosshairModesMenu); thickSlicesActionGroup->setExclusive(true); int currentMode = 0; { mitk::ResliceMethodProperty::Pointer m = dynamic_cast(m_Renderer->GetCurrentWorldPlaneGeometryNode()->GetProperty( "reslice.thickslices" )); if( m.IsNotNull() ) currentMode = m->GetValueAsId(); } int currentNum = 1; { mitk::IntProperty::Pointer m = dynamic_cast(m_Renderer->GetCurrentWorldPlaneGeometryNode()->GetProperty( "reslice.thickslices.num" )); if( m.IsNotNull() ) { currentNum = m->GetValue(); if(currentNum < 1) currentNum = 1; if(currentNum > 10) currentNum = 10; } } if(currentMode==0) currentNum=0; QSlider *m_TSSlider = new QSlider(crosshairModesMenu); m_TSSlider->setMinimum(0); m_TSSlider->setMaximum(9); m_TSSlider->setValue(currentNum); m_TSSlider->setOrientation(Qt::Horizontal); connect( m_TSSlider, SIGNAL( valueChanged(int) ), this, SLOT( OnTSNumChanged(int) ) ); QHBoxLayout* _TSLayout = new QHBoxLayout; _TSLayout->setContentsMargins(4,4,4,4); _TSLayout->addWidget(new QLabel("TS: ")); _TSLayout->addWidget(m_TSSlider); _TSLayout->addWidget(m_TSLabel=new QLabel(QString::number(currentNum*2+1),this)); QWidget* _TSWidget = new QWidget; _TSWidget->setLayout(_TSLayout); QWidgetAction *m_TSSliderAction = new QWidgetAction(crosshairModesMenu); m_TSSliderAction->setDefaultWidget(_TSWidget); crosshairModesMenu->addAction(m_TSSliderAction); } } void QmitkRenderWindowMenu::NotifyNewWidgetPlanesMode( int mode ) { currentCrosshairRotationMode = mode; } void QmitkRenderWindowMenu::OnAutoRotationActionTriggered() { if(m_AutoRotationTimer.isActive()) { m_AutoRotationTimer.stop(); m_Renderer->GetCameraRotationController()->GetSlice()->PingPongOff(); } else { m_Renderer->GetCameraRotationController()->GetSlice()->PingPongOn(); m_AutoRotationTimer.start(); } } void QmitkRenderWindowMenu::AutoRotateNextStep() { if(m_Renderer->GetCameraRotationController()) m_Renderer->GetCameraRotationController()->GetSlice()->Next(); } diff --git a/Modules/QtWidgets/QmitkRenderWindowMenu.h b/Modules/QtWidgets/QmitkRenderWindowMenu.h index 8b55966a57..dff23edd29 100644 --- a/Modules/QtWidgets/QmitkRenderWindowMenu.h +++ b/Modules/QtWidgets/QmitkRenderWindowMenu.h @@ -1,328 +1,331 @@ /*=================================================================== 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 QmitkRenderWindowMenu_h #define QmitkRenderWindowMenu_h #if defined(_WIN32) || defined(__APPLE__) #define QMITK_USE_EXTERNAL_RENDERWINDOW_MENU #endif #include #include "mitkBaseRenderer.h" #include #include #include #include #include #include #include class QmitkStdMultiWidget; /** * \ingroup QmitkModule * \brief The QmitkRenderWindowMenu is a popup Widget which shows * up when the mouse curser enter a QmitkRenderWindow. * The Menu Widget is located in the right top corner of each * RenderWindow. It includes different settings. For example * the layout design can be changed with the setting button. Switching * between full-screen mode and layout design can be done * with the full-screen button. Splitting the Widget horizontal or * vertical as well closing the Widget is not implemented yet. * The popup Widget can be deactivated with ActivateMenuWidget(false) in * QmitkRenderWindow. * * \sa QmitkRenderWindow * \sa QmitkStdMultiWidget * */ class QMITK_EXPORT QmitkRenderWindowMenu : public QWidget { Q_OBJECT public: - +#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) + QmitkRenderWindowMenu( QWidget* parent = 0, Qt::WindowFlags f = 0, mitk::BaseRenderer * b = 0, QmitkStdMultiWidget* mw = 0 ); +#else QmitkRenderWindowMenu( QWidget* parent = 0, Qt::WFlags f = 0, mitk::BaseRenderer * b = 0, QmitkStdMultiWidget* mw = 0 ); +#endif virtual ~QmitkRenderWindowMenu(); /*! Return visibility of settings menu. The menu is connected with m_SettingsButton and includes layout direction (axial, coronal .. ) and layout design (standard layout, 2D images top, 3D bottom ... ). */ bool GetSettingsMenuVisibilty() { if( m_Settings == NULL) return false; else return m_Settings->isVisible(); } /*! Set layout index. Defines layout direction (axial, coronal, sagital or threeD) of the parent. */ void SetLayoutIndex( unsigned int layoutIndex ); /*! Return layout direction of parent (axial, coronal, sagital or threeD) */ unsigned int GetLayoutIndex() { return m_Layout; } /*! Update list of layout design (standard layout, 2D images top, 3D bottom ..). Set action of current layout design to disable and all other to enable. */ void UpdateLayoutDesignList( int layoutDesignIndex ); /*! Move menu widget to correct position (right upper corner). E.g. it is necessary when the full-screen mode is activated.*/ #ifdef QMITK_USE_EXTERNAL_RENDERWINDOW_MENU void MoveWidgetToCorrectPos(float opacity); #else void MoveWidgetToCorrectPos(float /*opacity*/); #endif void ChangeFullScreenMode( bool state ); void NotifyNewWidgetPlanesMode( int mode ); protected: /*! Create menu widget. The menu contains five QPushButtons (hori-split, verti-split, full-screen, settings and close button) and their signal/slot connection for handling. */ void CreateMenuWidget(); /*! Create settings menu which contains layout direction and the different layout designs. */ void CreateSettingsWidget(); /*! Reimplemented from QWidget. The paint event is a request to repaint all or part of a widget.*/ void paintEvent(QPaintEvent *event); /*! Update list of layout direction (axial, coronal, sagital or threeD). Set action of currect layout direction to disable and all other to enable. Normaly the user can switch here between the different layout direction, but this is not supported yet. */ void UpdateLayoutList(); /*! Change Icon of full-screen button depending on full-screen mode. */ void ChangeFullScreenIcon(); int currentCrosshairRotationMode; public slots: void SetCrossHairVisibility( bool state ) ; signals: void ResetView(); // == "global reinit" // \brief int parameters are enum from QmitkStdMultiWidget void ChangeCrosshairRotationMode(int); /*! emit signal, when layout design changed by the setting menu.*/ void SignalChangeLayoutDesign( int layoutDesign ); public slots: void DeferredHideMenu( ); void DeferredShowMenu( ); void smoothHide( ); protected slots: /// /// this function is continously called by a timer /// to do the auto rotation /// void AutoRotateNextStep(); /// /// this function is invoked when the auto-rotate action /// is clicked /// void OnAutoRotationActionTriggered(); void enterEvent( QEvent* /*e*/ ); void leaveEvent( QEvent* /*e*/ ); void OnTSNumChanged(int); void OnCrosshairRotationModeSelected(QAction*); /*! slot for activating/deactivating the full-screen mode. The slot is connected to the clicked() event of m_FullScreenButton. Activating the full-screen maximize the current widget, deactivating restore If layout design changed by the settings menu, the full-Screen mode is automatically switch to false. */ void OnFullScreenButton( bool checked ); /*! Slot for opening setting menu. The slot is connected to the clicked() event of m_SettingsButton. The settings menu includes differen layout directions (axial, coronal, saggital and 3D) as well all layout design (standard layout, 2D images top, 3D bottom ..)*/ void OnSettingsButton( bool checked ); /*! Slot for changing layout design to standard layout. The slot is connected to the triggered() signal of m_DefaultLayoutAction. */ void OnChangeLayoutToDefault(bool); /*! Slot for changing layout design to 2D images top, 3D bottom layout. The slot is connected to the triggered() signal of m_2DImagesUpLayoutAction. */ void OnChangeLayoutTo2DImagesUp(bool); /*! Slot for changing layout design to 2D images left, 3D right layout. The slot is connected to the triggered() signal of m_2DImagesLeftLayoutAction. */ void OnChangeLayoutTo2DImagesLeft(bool); /*! Slot for changing layout to Big 3D layout. The slot is connected to the triggered() signal of m_Big3DLayoutAction. */ void OnChangeLayoutToBig3D(bool); /*! Slot for changing layout design to Axial plane layout. The slot is connected to the triggered() signal of m_Widget1LayoutAction. */ void OnChangeLayoutToWidget1(bool); /*! Slot for changing layout design to Sagittal plane layout. The slot is connected to the triggered() signal of m_Widget2LayoutAction. */ void OnChangeLayoutToWidget2(bool); /*! Slot for changing layout design to Coronal plane layout. The slot is connected to the triggered() signal of m_Widget3LayoutAction. */ void OnChangeLayoutToWidget3(bool); /*! Slot for changing layout design to Coronal top, 3D bottom layout. The slot is connected to the triggered() signal of m_RowWidget3And4LayoutAction. */ void OnChangeLayoutToRowWidget3And4(bool); /*! Slot for changing layout design to Coronal left, 3D right layout. The slot is connected to the triggered() signal of m_ColumnWidget3And4LayoutAction. */ void OnChangeLayoutToColumnWidget3And4(bool); /*! Slot for changing layout design to Sagittal top, Coronal n 3D bottom layout. The slot is connected to the triggered() signal of m_SmallUpperWidget2Big3and4LayoutAction. */ void OnChangeLayoutToSmallUpperWidget2Big3and4(bool); /*! Slot for changing layout design to Axial n Sagittal left, 3D right layout. The slot is connected to the triggered() signal of m_2x2Dand3DWidgetLayoutAction. */ void OnChangeLayoutTo2x2Dand3DWidget(bool); /*! Slot for changing layout design to Axial n 3D left, Sagittal right layout. The slot is connected to the triggered() signal of m_Left2Dand3DRight2DLayoutAction. */ void OnChangeLayoutToLeft2Dand3DRight2D(bool); void OnCrossHairMenuAboutToShow(); public: /*! enum for layout direction*/ enum { AXIAL, SAGITTAL, CORONAL, THREE_D }; /*! enum for layout design */ enum { LAYOUT_DEFAULT, LAYOUT_2DIMAGEUP, LAYOUT_2DIMAGELEFT, LAYOUT_BIG3D, LAYOUT_AXIAL, LAYOUT_SAGITTAL, LAYOUT_CORONAL, LAYOUT_2X2DAND3DWIDGET, LAYOUT_ROWWIDGET3AND4, LAYOUT_COLUMNWIDGET3AND4, LAYOUT_ROWWIDGETSMALL3ANDBIG4, //not in use in this class, but we need it here to synchronize with the SdtMultiWidget. LAYOUT_SMALLUPPERWIDGET2BIGAND4, LAYOUT_LEFT2DAND3DRIGHT2D }; void ShowMenu(); void HideMenu(); protected: QPushButton* m_CrosshairModeButton; //QAction* m_ShowHideCrosshairVisibilityAction; /*! QPushButton for activating/deactivating full-screen mode*/ QPushButton* m_FullScreenButton; /*! QPushButton for open the settings menu*/ QPushButton* m_SettingsButton; /*! QAction for Default layout design */ QAction* m_DefaultLayoutAction; /*! QAction for 2D images up layout design */ QAction* m_2DImagesUpLayoutAction; /*! QAction for 2D images left layout design */ QAction* m_2DImagesLeftLayoutAction; /*! QAction for big 3D layout design */ QAction* m_Big3DLayoutAction; /*! QAction for big axial layout design */ QAction* m_Widget1LayoutAction; /*! QAction for big saggital layout design */ QAction* m_Widget2LayoutAction; /*! QAction for big coronal layout design */ QAction* m_Widget3LayoutAction; /*! QAction for coronal top, 3D bottom layout design */ QAction* m_RowWidget3And4LayoutAction; /*! QAction for coronal left, 3D right layout design */ QAction* m_ColumnWidget3And4LayoutAction; /*! QAction for sagittal top, coronal n 3D bottom layout design */ QAction* m_SmallUpperWidget2Big3and4LayoutAction; /*! QAction for axial n sagittal left, 3D right layout design */ QAction* m_2x2Dand3DWidgetLayoutAction; /*! QAction for axial n 3D left, sagittal right layout design*/ QAction* m_Left2Dand3DRight2DLayoutAction; QLabel *m_TSLabel; /*! QMenu containg all layout direction and layout design settings.*/ QMenu* m_Settings; QMenu* m_CrosshairMenu; /*! Index of layout direction. 0: axial; 1: saggital; 2: coronal; 3: threeD */ unsigned int m_Layout; /*! Index of layout design. 0: LAYOUT_DEFAULT; 1: LAYOUT_2DIMAGEUP; 2: LAYOUT_2DIMAGELEFT; 3: LAYOUT_BIG3D 4: LAYOUT_AXIAL; 5: LAYOUT_SAGITTAL; 6: LAYOUT_CORONAL; 7: LAYOUT_2X2DAND3DWIDGET; 8: LAYOUT_ROWWIDGET3AND4; 9: LAYOUT_COLUMNWIDGET3AND4; 10: LAYOUT_ROWWIDGETSMALL3ANDBIG4; 11: LAYOUT_SMALLUPPERWIDGET2BIGAND4; 12: LAYOUT_LEFT2DAND3DRIGHT2D */ unsigned int m_LayoutDesign; /*! Store index of old layout design. It is used e.g. for the full-screen mode, when deactivating the mode the former layout design will restore.*/ unsigned int m_OldLayoutDesign; /*! Flag if full-screen mode is activated or deactivated. */ bool m_FullScreenMode; bool m_Entered; bool m_Hidden; private: mitk::BaseRenderer::Pointer m_Renderer; QmitkStdMultiWidget* m_MultiWidget; /// /// a timer for the auto rotate action /// QTimer m_AutoRotationTimer; }; #endif // QmitkRenderWindowMenu_H diff --git a/Modules/QtWidgets/QmitkSliderLevelWindowWidget.cpp b/Modules/QtWidgets/QmitkSliderLevelWindowWidget.cpp index 348fb788d6..cde0bad1c8 100644 --- a/Modules/QtWidgets/QmitkSliderLevelWindowWidget.cpp +++ b/Modules/QtWidgets/QmitkSliderLevelWindowWidget.cpp @@ -1,526 +1,524 @@ /*=================================================================== 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 #include #include #include #include #include #include #include #include /** * Constructor */ QmitkSliderLevelWindowWidget::QmitkSliderLevelWindowWidget( QWidget * parent, Qt::WindowFlags f ) : QWidget( parent, f ) { m_Manager = mitk::LevelWindowManager::New(); itk::ReceptorMemberCommand::Pointer command = itk::ReceptorMemberCommand::New(); command->SetCallbackFunction(this, &QmitkSliderLevelWindowWidget::OnPropertyModified); m_ObserverTag = m_Manager->AddObserver(itk::ModifiedEvent(), command); m_IsObserverTagSet = true; setMouseTracking(true); m_Resize = false; m_Bottom = false; m_CtrlPressed = false; m_MouseDown = false; m_Font.setPointSize( 6 ); m_MoveHeight = height() - 25; m_ScaleVisible = true; m_Contextmenu = new QmitkLevelWindowWidgetContextMenu(this); //, true); //setBackgroundMode( Qt::NoBackground ); this->hide(); update(); } QmitkSliderLevelWindowWidget::~QmitkSliderLevelWindowWidget() { if ( m_IsObserverTagSet) { m_Manager->RemoveObserver(m_ObserverTag); m_IsObserverTagSet = false; } } void QmitkSliderLevelWindowWidget::setLevelWindowManager(mitk::LevelWindowManager* levelWindowManager) { if ( m_IsObserverTagSet) { m_Manager->RemoveObserver(m_ObserverTag); m_IsObserverTagSet = false; } m_Manager = levelWindowManager; if ( m_Manager.IsNotNull() ) { itk::ReceptorMemberCommand::Pointer command = itk::ReceptorMemberCommand::New(); command->SetCallbackFunction(this, &QmitkSliderLevelWindowWidget::OnPropertyModified); m_ObserverTag = m_Manager->AddObserver(itk::ModifiedEvent(), command); m_IsObserverTagSet = true; } } void QmitkSliderLevelWindowWidget::OnPropertyModified(const itk::EventObject& ) { try { m_LevelWindow = m_Manager->GetLevelWindow(); this->show(); update(); } catch(...) { try { this->hide(); } catch(...) { } } } void QmitkSliderLevelWindowWidget::paintEvent( QPaintEvent* itkNotUsed(e) ) { QPixmap pm(width(), height()); - //pm.fill( static_cast(parent())->paletteBackgroundColor() ); - pm.fill(this, 0, 0); + pm.fill(this->palette().color(this->backgroundRole())); QPainter painter(&pm); painter.setFont( m_Font ); - //painter.setPen(static_cast(parent())->paletteForegroundColor()); painter.setPen(this->palette().color(this->foregroundRole())); QColor c(93,144,169); QColor cl = c.light(); QColor cd = c.dark(); painter.setBrush(c); painter.drawRect(m_Rect); float mr = m_LevelWindow.GetRange(); if ( mr < 1 ) mr = 1; float fact = (float) m_MoveHeight / mr; //begin draw scale if (m_ScaleVisible) { int minRange = (int)m_LevelWindow.GetRangeMin(); int maxRange = (int)m_LevelWindow.GetRangeMax(); int yValue = m_MoveHeight + (int)(minRange*fact); QString s = " 0"; if (minRange <= 0 && maxRange >= 0) { painter.drawLine( 5, yValue , 15, yValue); painter.drawText( 21, yValue + 3, s ); } int count = 1; int k = 5; bool enoughSpace = false; bool enoughSpace2 = false; double dStepSize = pow(10,floor(log10(mr/100))+1); for(int i = m_MoveHeight + (int)(minRange*fact); i < m_MoveHeight;)//negative { if (-count*dStepSize < minRange) break; yValue = m_MoveHeight + (int)((minRange + count*dStepSize)*fact); s = QString::number(-count*dStepSize); if (count % k && ((dStepSize*fact) > 2.5)) { painter.drawLine( 8, yValue, 12, yValue); enoughSpace = true; } else if (!(count % k)) { if ((k*dStepSize*fact) > 7) { painter.drawLine( 5, yValue, 15, yValue); painter.drawText( 21, yValue + 3, s ); enoughSpace2 = true; } else { k += 5; } } if (enoughSpace) { i=yValue; count++; } else if (enoughSpace2) { i=yValue; count += k; } else { i=yValue; count = k; } } count = 1; k = 5; enoughSpace = false; enoughSpace2 = false; for(int i = m_MoveHeight + (int)(minRange*fact); i >= 0;) { if (count*dStepSize > maxRange) break; yValue = m_MoveHeight + (int)((minRange - count*dStepSize)*fact); s = QString::number(count*dStepSize); if(count % k && ((dStepSize*fact) > 2.5)) { if (!(minRange > 0 && (count*dStepSize) < minRange)) painter.drawLine( 8, yValue, 12, yValue); enoughSpace = true; } else if (!(count % k)) { if ((k*dStepSize*fact) > 7) { if (!(minRange > 0 && (count*dStepSize) < minRange)) { painter.drawLine( 5, yValue, 15, yValue); painter.drawText( 21, yValue + 3, s ); } enoughSpace2 = true; } else { k += 5; } } if (enoughSpace) { i=yValue; count++; } else if (enoughSpace2) { i=yValue; count += k; } else { i=yValue; count = k; } } } //end draw scale painter.setPen (cl); painter.drawLine(m_Rect.topLeft(),m_Rect.topRight()); painter.drawLine(m_Rect.topLeft(),m_Rect.bottomLeft()); painter.setPen (cd); painter.drawLine(m_Rect.topRight(),m_Rect.bottomRight()); painter.drawLine(m_Rect.bottomRight(),m_Rect.bottomLeft()); painter.end(); QPainter p (this); p.drawPixmap(0, 0, pm); } /** * */ void QmitkSliderLevelWindowWidget::mouseMoveEvent( QMouseEvent* mouseEvent ) { if(!mouseEvent) return; if ( m_LevelWindow.IsFixed() ) return; if (!m_MouseDown) { if ( mouseEvent->pos().y() >= 0 && mouseEvent->pos().y() <= (m_Rect.topLeft().y() + 3) ) { setCursor(Qt::SizeVerCursor); m_UpperBound.setRect(m_Rect.topLeft().x(), m_Rect.topLeft().y() - 3, 17, 7); this->setToolTip("Ctrl + left click to change only upper bound"); m_Resize = true; } else if ( mouseEvent->pos().y() >= (m_Rect.bottomLeft().y() - 3) ) { setCursor(Qt::SizeVerCursor); m_LowerBound.setRect(m_Rect.bottomLeft().x(), m_Rect.bottomLeft().y() - 3, 17, 7); this->setToolTip("Ctrl + left click to change only lower bound"); m_Resize = true; m_Bottom = true; } else { setCursor(Qt::ArrowCursor); this->setToolTip("Left click and mouse move to adjust the slider"); m_Resize = false; m_Bottom = false; } } else { float fact = (float) m_MoveHeight / m_LevelWindow.GetRange(); if ( m_Leftbutton ) { if (m_Resize && !m_CtrlPressed) { double diff = (mouseEvent->pos().y()) / fact; diff -= (m_StartPos.y()) / fact; m_StartPos = mouseEvent->pos(); if (diff == 0) return; float value; if (m_Bottom) value = m_LevelWindow.GetWindow() + ( ( 2 * diff ) ); else value = m_LevelWindow.GetWindow() - ( ( 2 * diff ) ); if ( value < 0 ) value = 0; m_LevelWindow.SetLevelWindow( m_LevelWindow.GetLevel(), value ); } else if(m_Resize && m_CtrlPressed) { if (!m_Bottom) { double diff = (mouseEvent->pos().y()) / fact; diff -= (m_StartPos.y()) / fact; m_StartPos = mouseEvent->pos(); if (diff == 0) return; float value; value = m_LevelWindow.GetWindow() - ( ( diff ) ); if ( value < 0 ) value = 0; float oldWindow; float oldLevel; float newLevel; oldWindow = m_LevelWindow.GetWindow(); oldLevel = m_LevelWindow.GetLevel(); newLevel = oldLevel + (value - oldWindow)/2; if (!((newLevel + value/2) > m_LevelWindow.GetRangeMax())) m_LevelWindow.SetLevelWindow( newLevel, value ); } else { double diff = (mouseEvent->pos().y()) / fact; diff -= (m_StartPos.y()) / fact; m_StartPos = mouseEvent->pos(); if (diff == 0) return; float value; value = m_LevelWindow.GetWindow() + ( ( diff ) ); if ( value < 0 ) value = 0; float oldWindow; float oldLevel; float newLevel; oldWindow = m_LevelWindow.GetWindow(); oldLevel = m_LevelWindow.GetLevel(); newLevel = oldLevel - (value - oldWindow)/2; if (!((newLevel - value/2) < m_LevelWindow.GetRangeMin())) m_LevelWindow.SetLevelWindow( newLevel, value ); } } else { const float minv = m_LevelWindow.GetRangeMin(); const float level = (m_MoveHeight - mouseEvent->pos().y()) / fact + minv; double diff = (mouseEvent->pos().x()) / fact; diff -= (m_StartPos.x()) / fact; m_StartPos = mouseEvent->pos(); float window; if (m_Bottom) window = m_LevelWindow.GetWindow() + ( ( 2 * diff ) ); else window = m_LevelWindow.GetWindow() - ( ( 2 * diff ) ); if ( window < 0 ) window = 0; m_LevelWindow.SetLevelWindow( level, window ); } m_Manager->SetLevelWindow(m_LevelWindow); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } } } void QmitkSliderLevelWindowWidget::enterEvent ( QEvent * /*event*/ ) { /* if(event->type() != QEvent::MouseMove) return;*/ //mouseMoveEvent( static_cast< QMouseEvent* > ( event ) ); QPoint p = QCursor::pos(); p = this->mapFromGlobal(p); QMouseEvent ev(QEvent::MouseMove, p, Qt::NoButton, Qt::NoButton , Qt::NoModifier ); this->mouseMoveEvent( &ev ); } /** * */ void QmitkSliderLevelWindowWidget::mousePressEvent( QMouseEvent* mouseEvent ) { if ( m_LevelWindow.IsFixed() ) return; m_MouseDown = true; m_StartPos = mouseEvent->pos(); if ( mouseEvent->button() == Qt::LeftButton ) { if (mouseEvent->modifiers() == Qt::ControlModifier || mouseEvent->modifiers() == Qt::ShiftModifier) { m_CtrlPressed = true; } else { m_CtrlPressed = false; } m_Leftbutton = true; } else m_Leftbutton = false; mouseMoveEvent( mouseEvent ); } /** * */ void QmitkSliderLevelWindowWidget::resizeEvent ( QResizeEvent * event ) { m_MoveHeight = event->size().height() - 25; update(); } /** * */ void QmitkSliderLevelWindowWidget::mouseReleaseEvent( QMouseEvent* ) { if ( m_LevelWindow.IsFixed() ) return; m_MouseDown = false; } /** * */ void QmitkSliderLevelWindowWidget::update() { int rectWidth; if(m_ScaleVisible) { rectWidth = 17; setMinimumSize ( QSize( 50, 50 ) ); setMaximumSize ( QSize( 50, 2000 ) ); setSizePolicy( QSizePolicy( QSizePolicy::Minimum, QSizePolicy::Expanding ) ); } else { rectWidth = 26; setMinimumSize ( QSize( 40, 50 ) ); setMaximumSize ( QSize( 50, 2000 ) ); setSizePolicy( QSizePolicy( QSizePolicy::Minimum, QSizePolicy::Expanding ) ); } float mr = m_LevelWindow.GetRange(); if ( mr < 1 ) mr = 1; float fact = (float) m_MoveHeight / mr; float rectHeight = m_LevelWindow.GetWindow() * fact; if ( rectHeight < 15 ) rectHeight = 15; if ( m_LevelWindow.GetLowerWindowBound() < 0 ) m_Rect.setRect( 2, (int) (m_MoveHeight - (m_LevelWindow.GetUpperWindowBound() - m_LevelWindow.GetRangeMin()) * fact) , rectWidth, (int) rectHeight ); else m_Rect.setRect( 2, (int) (m_MoveHeight - (m_LevelWindow.GetUpperWindowBound() - m_LevelWindow.GetRangeMin()) * fact), rectWidth, (int) rectHeight ); QWidget::repaint(); } void QmitkSliderLevelWindowWidget::contextMenuEvent( QContextMenuEvent * ) { m_Contextmenu->setLevelWindowManager(m_Manager.GetPointer()); QMenu *contextMenu = new QMenu( this ); Q_CHECK_PTR( contextMenu ); if (m_ScaleVisible) contextMenu->addAction(tr("Hide Scale"), this, SLOT(hideScale())); else contextMenu->addAction(tr("Show Scale"), this, SLOT(showScale())); contextMenu->addSeparator(); m_Contextmenu->getContextMenu(contextMenu); // Fix: Bug #13327 we need to reset the m_MouseDown value // otherwise the cursor is not correctly restored afterwards m_MouseDown = false; } void QmitkSliderLevelWindowWidget::hideScale() { m_ScaleVisible = false; update(); } void QmitkSliderLevelWindowWidget::showScale() { m_ScaleVisible = true; update(); } void QmitkSliderLevelWindowWidget::setDataStorage(mitk::DataStorage* ds) { m_Manager->SetDataStorage(ds); } mitk::LevelWindowManager* QmitkSliderLevelWindowWidget::GetManager() { return m_Manager.GetPointer(); } diff --git a/Modules/QtWidgets/QmitkStdMultiWidget.cpp b/Modules/QtWidgets/QmitkStdMultiWidget.cpp index c6eb5047c7..bf1969311f 100644 --- a/Modules/QtWidgets/QmitkStdMultiWidget.cpp +++ b/Modules/QtWidgets/QmitkStdMultiWidget.cpp @@ -1,2206 +1,2205 @@ /*=================================================================== 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. ===================================================================*/ #define SMW_INFO MITK_INFO("widget.stdmulti") #include "QmitkStdMultiWidget.h" #include #include #include #include -#include #include #include #include #include "mitkProperties.h" #include "mitkPlaneGeometryDataMapper2D.h" #include "mitkGlobalInteraction.h" #include "mitkDisplayInteractor.h" #include "mitkPointSet.h" #include "mitkPositionEvent.h" #include "mitkStateEvent.h" #include "mitkLine.h" #include "mitkInteractionConst.h" #include "mitkDataStorage.h" #include "mitkOverlayManager.h" #include "mitkNodePredicateBase.h" #include "mitkNodePredicateDataType.h" #include "mitkNodePredicateNot.h" #include "mitkNodePredicateProperty.h" #include "mitkStatusBar.h" #include "mitkImage.h" #include "mitkVtkLayerController.h" #include QmitkStdMultiWidget::QmitkStdMultiWidget(QWidget* parent, Qt::WindowFlags f, mitk::RenderingManager* renderingManager, mitk::BaseRenderer::RenderingMode::Type renderingMode, const QString& name) : QWidget(parent, f), mitkWidget1(NULL), mitkWidget2(NULL), mitkWidget3(NULL), mitkWidget4(NULL), levelWindowWidget(NULL), QmitkStdMultiWidgetLayout(NULL), m_Layout(LAYOUT_DEFAULT), m_PlaneMode(PLANE_MODE_SLICING), m_RenderingManager(renderingManager), m_GradientBackgroundFlag(true), m_TimeNavigationController(NULL), m_MainSplit(NULL), m_LayoutSplit(NULL), m_SubSplit1(NULL), m_SubSplit2(NULL), mitkWidget1Container(NULL), mitkWidget2Container(NULL), mitkWidget3Container(NULL), mitkWidget4Container(NULL), m_PendingCrosshairPositionEvent(false), m_CrosshairNavigationEnabled(false) { /****************************************************** * Use the global RenderingManager if none was specified * ****************************************************/ if (m_RenderingManager == NULL) { m_RenderingManager = mitk::RenderingManager::GetInstance(); } m_TimeNavigationController = m_RenderingManager->GetTimeNavigationController(); /*******************************/ //Create Widget manually /*******************************/ //create Layouts QmitkStdMultiWidgetLayout = new QHBoxLayout( this ); QmitkStdMultiWidgetLayout->setContentsMargins(0,0,0,0); //Set Layout to widget this->setLayout(QmitkStdMultiWidgetLayout); // QmitkNavigationToolBar* toolBar = new QmitkNavigationToolBar(); // QmitkStdMultiWidgetLayout->addWidget( toolBar ); //create main splitter m_MainSplit = new QSplitter( this ); QmitkStdMultiWidgetLayout->addWidget( m_MainSplit ); //create m_LayoutSplit and add to the mainSplit m_LayoutSplit = new QSplitter( Qt::Vertical, m_MainSplit ); m_MainSplit->addWidget( m_LayoutSplit ); //create m_SubSplit1 and m_SubSplit2 m_SubSplit1 = new QSplitter( m_LayoutSplit ); m_SubSplit2 = new QSplitter( m_LayoutSplit ); //creae Widget Container mitkWidget1Container = new QWidget(m_SubSplit1); mitkWidget2Container = new QWidget(m_SubSplit1); mitkWidget3Container = new QWidget(m_SubSplit2); mitkWidget4Container = new QWidget(m_SubSplit2); mitkWidget1Container->setContentsMargins(0,0,0,0); mitkWidget2Container->setContentsMargins(0,0,0,0); mitkWidget3Container->setContentsMargins(0,0,0,0); mitkWidget4Container->setContentsMargins(0,0,0,0); //create Widget Layout QHBoxLayout *mitkWidgetLayout1 = new QHBoxLayout(mitkWidget1Container); QHBoxLayout *mitkWidgetLayout2 = new QHBoxLayout(mitkWidget2Container); QHBoxLayout *mitkWidgetLayout3 = new QHBoxLayout(mitkWidget3Container); QHBoxLayout *mitkWidgetLayout4 = new QHBoxLayout(mitkWidget4Container); mitkWidgetLayout1->setMargin(0); mitkWidgetLayout2->setMargin(0); mitkWidgetLayout3->setMargin(0); mitkWidgetLayout4->setMargin(0); //set Layout to Widget Container mitkWidget1Container->setLayout(mitkWidgetLayout1); mitkWidget2Container->setLayout(mitkWidgetLayout2); mitkWidget3Container->setLayout(mitkWidgetLayout3); mitkWidget4Container->setLayout(mitkWidgetLayout4); //set SizePolicy mitkWidget1Container->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding); mitkWidget2Container->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding); mitkWidget3Container->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding); mitkWidget4Container->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding); //insert Widget Container into the splitters m_SubSplit1->addWidget( mitkWidget1Container ); m_SubSplit1->addWidget( mitkWidget2Container ); m_SubSplit2->addWidget( mitkWidget3Container ); m_SubSplit2->addWidget( mitkWidget4Container ); // m_RenderingManager->SetGlobalInteraction( mitk::GlobalInteraction::GetInstance() ); //Create RenderWindows 1 mitkWidget1 = new QmitkRenderWindow(mitkWidget1Container, name + ".widget1", NULL, m_RenderingManager,renderingMode); mitkWidget1->setMaximumSize(2000,2000); mitkWidget1->SetLayoutIndex( AXIAL ); mitkWidgetLayout1->addWidget(mitkWidget1); //Create RenderWindows 2 mitkWidget2 = new QmitkRenderWindow(mitkWidget2Container, name + ".widget2", NULL, m_RenderingManager,renderingMode); mitkWidget2->setMaximumSize(2000,2000); - mitkWidget2->setEnabled( TRUE ); + mitkWidget2->setEnabled( true ); mitkWidget2->SetLayoutIndex( SAGITTAL ); mitkWidgetLayout2->addWidget(mitkWidget2); //Create RenderWindows 3 mitkWidget3 = new QmitkRenderWindow(mitkWidget3Container, name + ".widget3", NULL, m_RenderingManager,renderingMode); mitkWidget3->setMaximumSize(2000,2000); mitkWidget3->SetLayoutIndex( CORONAL ); mitkWidgetLayout3->addWidget(mitkWidget3); //Create RenderWindows 4 mitkWidget4 = new QmitkRenderWindow(mitkWidget4Container, name + ".widget4", NULL, m_RenderingManager,renderingMode); mitkWidget4->setMaximumSize(2000,2000); mitkWidget4->SetLayoutIndex( THREE_D ); mitkWidgetLayout4->addWidget(mitkWidget4); //create SignalSlot Connection connect( mitkWidget1, SIGNAL( SignalLayoutDesignChanged(int) ), this, SLOT( OnLayoutDesignChanged(int) ) ); connect( mitkWidget1, SIGNAL( ResetView() ), this, SLOT( ResetCrosshair() ) ); connect( mitkWidget1, SIGNAL( ChangeCrosshairRotationMode(int) ), this, SLOT( SetWidgetPlaneMode(int) ) ); connect( this, SIGNAL(WidgetNotifyNewCrossHairMode(int)), mitkWidget1, SLOT(OnWidgetPlaneModeChanged(int)) ); connect( mitkWidget2, SIGNAL( SignalLayoutDesignChanged(int) ), this, SLOT( OnLayoutDesignChanged(int) ) ); connect( mitkWidget2, SIGNAL( ResetView() ), this, SLOT( ResetCrosshair() ) ); connect( mitkWidget2, SIGNAL( ChangeCrosshairRotationMode(int) ), this, SLOT( SetWidgetPlaneMode(int) ) ); connect( this, SIGNAL(WidgetNotifyNewCrossHairMode(int)), mitkWidget2, SLOT(OnWidgetPlaneModeChanged(int)) ); connect( mitkWidget3, SIGNAL( SignalLayoutDesignChanged(int) ), this, SLOT( OnLayoutDesignChanged(int) ) ); connect( mitkWidget3, SIGNAL( ResetView() ), this, SLOT( ResetCrosshair() ) ); connect( mitkWidget3, SIGNAL( ChangeCrosshairRotationMode(int) ), this, SLOT( SetWidgetPlaneMode(int) ) ); connect( this, SIGNAL(WidgetNotifyNewCrossHairMode(int)), mitkWidget3, SLOT(OnWidgetPlaneModeChanged(int)) ); connect( mitkWidget4, SIGNAL( SignalLayoutDesignChanged(int) ), this, SLOT( OnLayoutDesignChanged(int) ) ); connect( mitkWidget4, SIGNAL( ResetView() ), this, SLOT( ResetCrosshair() ) ); connect( mitkWidget4, SIGNAL( ChangeCrosshairRotationMode(int) ), this, SLOT( SetWidgetPlaneMode(int) ) ); connect( this, SIGNAL(WidgetNotifyNewCrossHairMode(int)), mitkWidget4, SLOT(OnWidgetPlaneModeChanged(int)) ); //Create Level Window Widget levelWindowWidget = new QmitkLevelWindowWidget( m_MainSplit ); //this levelWindowWidget->setObjectName(QString::fromUtf8("levelWindowWidget")); QSizePolicy sizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); sizePolicy.setHorizontalStretch(0); sizePolicy.setVerticalStretch(0); sizePolicy.setHeightForWidth(levelWindowWidget->sizePolicy().hasHeightForWidth()); levelWindowWidget->setSizePolicy(sizePolicy); levelWindowWidget->setMaximumSize(QSize(50, 2000)); //add LevelWindow Widget to mainSplitter m_MainSplit->addWidget( levelWindowWidget ); //show mainSplitt and add to Layout m_MainSplit->show(); //resize Image. this->resize( QSize(364, 477).expandedTo(minimumSizeHint()) ); //Initialize the widgets. this->InitializeWidget(); //Activate Widget Menu this->ActivateMenuWidget( true ); } void QmitkStdMultiWidget::InitializeWidget() { m_PositionTracker = NULL; // transfer colors in WorldGeometry-Nodes of the associated Renderer QColor qcolor; //float color[3] = {1.0f,1.0f,1.0f}; mitk::DataNode::Pointer planeNode; mitk::IntProperty::Pointer layer; // of widget 1 planeNode = mitk::BaseRenderer::GetInstance(mitkWidget1->GetRenderWindow())->GetCurrentWorldPlaneGeometryNode(); planeNode->SetColor(1.0,0.0,0.0); layer = mitk::IntProperty::New(1000); planeNode->SetProperty("layer",layer); // ... of widget 2 planeNode = mitk::BaseRenderer::GetInstance(mitkWidget2->GetRenderWindow())->GetCurrentWorldPlaneGeometryNode(); planeNode->SetColor(0.0,1.0,0.0); layer = mitk::IntProperty::New(1000); planeNode->SetProperty("layer",layer); // ... of widget 3 planeNode = mitk::BaseRenderer::GetInstance(mitkWidget3->GetRenderWindow())->GetCurrentWorldPlaneGeometryNode(); planeNode->SetColor(0.0,0.0,1.0); layer = mitk::IntProperty::New(1000); planeNode->SetProperty("layer",layer); // ... of widget 4 planeNode = mitk::BaseRenderer::GetInstance(mitkWidget4->GetRenderWindow())->GetCurrentWorldPlaneGeometryNode(); planeNode->SetColor(1.0,1.0,0.0); layer = mitk::IntProperty::New(1000); planeNode->SetProperty("layer",layer); mitk::OverlayManager::Pointer OverlayManager = mitk::OverlayManager::New(); mitk::BaseRenderer::GetInstance(mitkWidget1->GetRenderWindow())->SetOverlayManager(OverlayManager); mitk::BaseRenderer::GetInstance(mitkWidget2->GetRenderWindow())->SetOverlayManager(OverlayManager); mitk::BaseRenderer::GetInstance(mitkWidget3->GetRenderWindow())->SetOverlayManager(OverlayManager); mitk::BaseRenderer::GetInstance(mitkWidget4->GetRenderWindow())->SetOverlayManager(OverlayManager); mitk::BaseRenderer::GetInstance(mitkWidget4->GetRenderWindow())->SetMapperID(mitk::BaseRenderer::Standard3D); // Set plane mode (slicing/rotation behavior) to slicing (default) m_PlaneMode = PLANE_MODE_SLICING; // Set default view directions for SNCs mitkWidget1->GetSliceNavigationController()->SetDefaultViewDirection( mitk::SliceNavigationController::Axial ); mitkWidget2->GetSliceNavigationController()->SetDefaultViewDirection( mitk::SliceNavigationController::Sagittal ); mitkWidget3->GetSliceNavigationController()->SetDefaultViewDirection( mitk::SliceNavigationController::Frontal ); mitkWidget4->GetSliceNavigationController()->SetDefaultViewDirection( mitk::SliceNavigationController::Original ); /*************************************************/ //Write Layout Names into the viewers -- hardCoded //Info for later: //int view = this->GetRenderWindow1()->GetSliceNavigationController()->GetDefaultViewDirection(); //QString layoutName; //if( view == mitk::SliceNavigationController::Axial ) // layoutName = "Axial"; //else if( view == mitk::SliceNavigationController::Sagittal ) // layoutName = "Sagittal"; //else if( view == mitk::SliceNavigationController::Frontal ) // layoutName = "Coronal"; //else if( view == mitk::SliceNavigationController::Original ) // layoutName = "Original"; //if( view >= 0 && view < 4 ) // //write LayoutName --> Viewer 3D shoudn't write the layoutName. //Render Window 1 == axial m_CornerAnnotaions[0].cornerText = vtkCornerAnnotation::New(); m_CornerAnnotaions[0].cornerText->SetText(0, "Axial"); m_CornerAnnotaions[0].cornerText->SetMaximumFontSize(12); m_CornerAnnotaions[0].textProp = vtkTextProperty::New(); m_CornerAnnotaions[0].textProp->SetColor( 1.0, 0.0, 0.0 ); m_CornerAnnotaions[0].cornerText->SetTextProperty( m_CornerAnnotaions[0].textProp ); m_CornerAnnotaions[0].ren = vtkRenderer::New(); m_CornerAnnotaions[0].ren->AddActor(m_CornerAnnotaions[0].cornerText); m_CornerAnnotaions[0].ren->InteractiveOff(); mitk::VtkLayerController::GetInstance(this->GetRenderWindow1()->GetRenderWindow())->InsertForegroundRenderer(m_CornerAnnotaions[0].ren,true); //Render Window 2 == sagittal m_CornerAnnotaions[1].cornerText = vtkCornerAnnotation::New(); m_CornerAnnotaions[1].cornerText->SetText(0, "Sagittal"); m_CornerAnnotaions[1].cornerText->SetMaximumFontSize(12); m_CornerAnnotaions[1].textProp = vtkTextProperty::New(); m_CornerAnnotaions[1].textProp->SetColor( 0.0, 1.0, 0.0 ); m_CornerAnnotaions[1].cornerText->SetTextProperty( m_CornerAnnotaions[1].textProp ); m_CornerAnnotaions[1].ren = vtkRenderer::New(); m_CornerAnnotaions[1].ren->AddActor(m_CornerAnnotaions[1].cornerText); m_CornerAnnotaions[1].ren->InteractiveOff(); mitk::VtkLayerController::GetInstance(this->GetRenderWindow2()->GetRenderWindow())->InsertForegroundRenderer(m_CornerAnnotaions[1].ren,true); //Render Window 3 == coronal m_CornerAnnotaions[2].cornerText = vtkCornerAnnotation::New(); m_CornerAnnotaions[2].cornerText->SetText(0, "Coronal"); m_CornerAnnotaions[2].cornerText->SetMaximumFontSize(12); m_CornerAnnotaions[2].textProp = vtkTextProperty::New(); m_CornerAnnotaions[2].textProp->SetColor( 0.295, 0.295, 1.0 ); m_CornerAnnotaions[2].cornerText->SetTextProperty( m_CornerAnnotaions[2].textProp ); m_CornerAnnotaions[2].ren = vtkRenderer::New(); m_CornerAnnotaions[2].ren->AddActor(m_CornerAnnotaions[2].cornerText); m_CornerAnnotaions[2].ren->InteractiveOff(); mitk::VtkLayerController::GetInstance(this->GetRenderWindow3()->GetRenderWindow())->InsertForegroundRenderer(m_CornerAnnotaions[2].ren,true); /*************************************************/ // create a slice rotator // m_SlicesRotator = mitk::SlicesRotator::New(); // @TODO next line causes sure memory leak // rotator will be created nonetheless (will be switched on and off) m_SlicesRotator = mitk::SlicesRotator::New("slices-rotator"); m_SlicesRotator->AddSliceController( mitkWidget1->GetSliceNavigationController() ); m_SlicesRotator->AddSliceController( mitkWidget2->GetSliceNavigationController() ); m_SlicesRotator->AddSliceController( mitkWidget3->GetSliceNavigationController() ); // create a slice swiveller (using the same state-machine as SlicesRotator) m_SlicesSwiveller = mitk::SlicesSwiveller::New("slices-rotator"); m_SlicesSwiveller->AddSliceController( mitkWidget1->GetSliceNavigationController() ); m_SlicesSwiveller->AddSliceController( mitkWidget2->GetSliceNavigationController() ); m_SlicesSwiveller->AddSliceController( mitkWidget3->GetSliceNavigationController() ); //connect to the "time navigation controller": send time via sliceNavigationControllers m_TimeNavigationController->ConnectGeometryTimeEvent( mitkWidget1->GetSliceNavigationController() , false); m_TimeNavigationController->ConnectGeometryTimeEvent( mitkWidget2->GetSliceNavigationController() , false); m_TimeNavigationController->ConnectGeometryTimeEvent( mitkWidget3->GetSliceNavigationController() , false); m_TimeNavigationController->ConnectGeometryTimeEvent( mitkWidget4->GetSliceNavigationController() , false); mitkWidget1->GetSliceNavigationController() ->ConnectGeometrySendEvent(mitk::BaseRenderer::GetInstance(mitkWidget4->GetRenderWindow())); //reverse connection between sliceNavigationControllers and m_TimeNavigationController mitkWidget1->GetSliceNavigationController() ->ConnectGeometryTimeEvent(m_TimeNavigationController, false); mitkWidget2->GetSliceNavigationController() ->ConnectGeometryTimeEvent(m_TimeNavigationController, false); mitkWidget3->GetSliceNavigationController() ->ConnectGeometryTimeEvent(m_TimeNavigationController, false); mitkWidget4->GetSliceNavigationController() ->ConnectGeometryTimeEvent(m_TimeNavigationController, false); m_MouseModeSwitcher = mitk::MouseModeSwitcher::New(); m_LastLeftClickPositionSupplier = mitk::CoordinateSupplier::New("navigation", NULL); mitk::GlobalInteraction::GetInstance()->AddListener( m_LastLeftClickPositionSupplier ); // setup gradient background m_GradientBackground1 = mitk::GradientBackground::New(); m_GradientBackground1->SetRenderWindow( mitkWidget1->GetRenderWindow() ); m_GradientBackground1->Disable(); m_GradientBackground2 = mitk::GradientBackground::New(); m_GradientBackground2->SetRenderWindow( mitkWidget2->GetRenderWindow() ); m_GradientBackground2->Disable(); m_GradientBackground3 = mitk::GradientBackground::New(); m_GradientBackground3->SetRenderWindow( mitkWidget3->GetRenderWindow() ); m_GradientBackground3->Disable(); m_GradientBackground4 = mitk::GradientBackground::New(); m_GradientBackground4->SetRenderWindow( mitkWidget4->GetRenderWindow() ); m_GradientBackground4->SetGradientColors(0.1,0.1,0.1,0.5,0.5,0.5); m_GradientBackground4->Enable(); // setup the department logo rendering m_LogoRendering = mitk::LogoOverlay::New(); mitk::BaseRenderer::Pointer renderer4 = mitk::BaseRenderer::GetInstance(mitkWidget4->GetRenderWindow()); m_LogoRendering->SetOpacity(0.5); mitk::Point2D offset; offset.Fill(0.03); m_LogoRendering->SetOffsetVector(offset); m_LogoRendering->SetRelativeSize(0.15); m_LogoRendering->SetCornerPosition(1); renderer4->GetOverlayManager()->AddOverlay(m_LogoRendering.GetPointer(),renderer4); m_RectangleRendering1 = mitk::RenderWindowFrame::New(); m_RectangleRendering1->SetRenderWindow( mitkWidget1->GetRenderWindow() ); m_RectangleRendering1->Enable(1.0,0.0,0.0); m_RectangleRendering2 = mitk::RenderWindowFrame::New(); m_RectangleRendering2->SetRenderWindow( mitkWidget2->GetRenderWindow() ); m_RectangleRendering2->Enable(0.0,1.0,0.0); m_RectangleRendering3 = mitk::RenderWindowFrame::New(); m_RectangleRendering3->SetRenderWindow( mitkWidget3->GetRenderWindow() ); m_RectangleRendering3->Enable(0.0,0.0,1.0); m_RectangleRendering4 = mitk::RenderWindowFrame::New(); m_RectangleRendering4->SetRenderWindow( mitkWidget4->GetRenderWindow() ); m_RectangleRendering4->Enable(1.0,1.0,0.0); } QmitkStdMultiWidget::~QmitkStdMultiWidget() { DisablePositionTracking(); DisableNavigationControllerEventListening(); m_TimeNavigationController->Disconnect(mitkWidget1->GetSliceNavigationController()); m_TimeNavigationController->Disconnect(mitkWidget2->GetSliceNavigationController()); m_TimeNavigationController->Disconnect(mitkWidget3->GetSliceNavigationController()); m_TimeNavigationController->Disconnect(mitkWidget4->GetSliceNavigationController()); mitk::VtkLayerController::GetInstance(this->GetRenderWindow1()->GetRenderWindow())->RemoveRenderer( m_CornerAnnotaions[0].ren ); mitk::VtkLayerController::GetInstance(this->GetRenderWindow2()->GetRenderWindow())->RemoveRenderer( m_CornerAnnotaions[1].ren ); mitk::VtkLayerController::GetInstance(this->GetRenderWindow3()->GetRenderWindow())->RemoveRenderer( m_CornerAnnotaions[2].ren ); //Delete CornerAnnotation m_CornerAnnotaions[0].cornerText->Delete(); m_CornerAnnotaions[0].textProp->Delete(); m_CornerAnnotaions[0].ren->Delete(); m_CornerAnnotaions[1].cornerText->Delete(); m_CornerAnnotaions[1].textProp->Delete(); m_CornerAnnotaions[1].ren->Delete(); m_CornerAnnotaions[2].cornerText->Delete(); m_CornerAnnotaions[2].textProp->Delete(); m_CornerAnnotaions[2].ren->Delete(); } void QmitkStdMultiWidget::RemovePlanesFromDataStorage() { if (m_PlaneNode1.IsNotNull() && m_PlaneNode2.IsNotNull() && m_PlaneNode3.IsNotNull() && m_Node.IsNotNull()) { if(m_DataStorage.IsNotNull()) { m_DataStorage->Remove(m_PlaneNode1); m_DataStorage->Remove(m_PlaneNode2); m_DataStorage->Remove(m_PlaneNode3); m_DataStorage->Remove(m_Node); } } } void QmitkStdMultiWidget::AddPlanesToDataStorage() { if (m_PlaneNode1.IsNotNull() && m_PlaneNode2.IsNotNull() && m_PlaneNode3.IsNotNull() && m_Node.IsNotNull()) { if (m_DataStorage.IsNotNull()) { m_DataStorage->Add(m_Node); m_DataStorage->Add(m_PlaneNode1, m_Node); m_DataStorage->Add(m_PlaneNode2, m_Node); m_DataStorage->Add(m_PlaneNode3, m_Node); static_cast(m_PlaneNode1->GetMapper(mitk::BaseRenderer::Standard2D))->SetDatastorageAndGeometryBaseNode(m_DataStorage, m_Node); static_cast(m_PlaneNode2->GetMapper(mitk::BaseRenderer::Standard2D))->SetDatastorageAndGeometryBaseNode(m_DataStorage, m_Node); static_cast(m_PlaneNode3->GetMapper(mitk::BaseRenderer::Standard2D))->SetDatastorageAndGeometryBaseNode(m_DataStorage, m_Node); } } } void QmitkStdMultiWidget::changeLayoutTo2DImagesUp() { SMW_INFO << "changing layout to 2D images up... " << std::endl; //Hide all Menu Widgets this->HideAllWidgetToolbars(); delete QmitkStdMultiWidgetLayout ; //create Main Layout QmitkStdMultiWidgetLayout = new QHBoxLayout( this ); //Set Layout to widget this->setLayout(QmitkStdMultiWidgetLayout); //create main splitter m_MainSplit = new QSplitter( this ); QmitkStdMultiWidgetLayout->addWidget( m_MainSplit ); //create m_LayoutSplit and add to the mainSplit m_LayoutSplit = new QSplitter( Qt::Vertical, m_MainSplit ); m_MainSplit->addWidget( m_LayoutSplit ); //add LevelWindow Widget to mainSplitter m_MainSplit->addWidget( levelWindowWidget ); //create m_SubSplit1 and m_SubSplit2 m_SubSplit1 = new QSplitter( m_LayoutSplit ); m_SubSplit2 = new QSplitter( m_LayoutSplit ); //insert Widget Container into splitter top m_SubSplit1->addWidget( mitkWidget1Container ); m_SubSplit1->addWidget( mitkWidget2Container ); m_SubSplit1->addWidget( mitkWidget3Container ); //set SplitterSize for splitter top QList splitterSize; splitterSize.push_back(1000); splitterSize.push_back(1000); splitterSize.push_back(1000); m_SubSplit1->setSizes( splitterSize ); //insert Widget Container into splitter bottom m_SubSplit2->addWidget( mitkWidget4Container ); //set SplitterSize for splitter m_LayoutSplit splitterSize.clear(); splitterSize.push_back(400); splitterSize.push_back(1000); m_LayoutSplit->setSizes( splitterSize ); //show mainSplitt m_MainSplit->show(); //show Widget if hidden if ( mitkWidget1->isHidden() ) mitkWidget1->show(); if ( mitkWidget2->isHidden() ) mitkWidget2->show(); if ( mitkWidget3->isHidden() ) mitkWidget3->show(); if ( mitkWidget4->isHidden() ) mitkWidget4->show(); //Change Layout Name m_Layout = LAYOUT_2D_IMAGES_UP; //update Layout Design List mitkWidget1->LayoutDesignListChanged( LAYOUT_2D_IMAGES_UP ); mitkWidget2->LayoutDesignListChanged( LAYOUT_2D_IMAGES_UP ); mitkWidget3->LayoutDesignListChanged( LAYOUT_2D_IMAGES_UP ); mitkWidget4->LayoutDesignListChanged( LAYOUT_2D_IMAGES_UP ); //update Alle Widgets this->UpdateAllWidgets(); } void QmitkStdMultiWidget::changeLayoutTo2DImagesLeft() { SMW_INFO << "changing layout to 2D images left... " << std::endl; //Hide all Menu Widgets this->HideAllWidgetToolbars(); delete QmitkStdMultiWidgetLayout ; //create Main Layout QmitkStdMultiWidgetLayout = new QHBoxLayout( this ); //create main splitter m_MainSplit = new QSplitter( this ); QmitkStdMultiWidgetLayout->addWidget( m_MainSplit ); //create m_LayoutSplit and add to the mainSplit m_LayoutSplit = new QSplitter( m_MainSplit ); m_MainSplit->addWidget( m_LayoutSplit ); //add LevelWindow Widget to mainSplitter m_MainSplit->addWidget( levelWindowWidget ); //create m_SubSplit1 and m_SubSplit2 m_SubSplit1 = new QSplitter( Qt::Vertical, m_LayoutSplit ); m_SubSplit2 = new QSplitter( m_LayoutSplit ); //insert Widget into the splitters m_SubSplit1->addWidget( mitkWidget1Container ); m_SubSplit1->addWidget( mitkWidget2Container ); m_SubSplit1->addWidget( mitkWidget3Container ); //set splitterSize of SubSplit1 QList splitterSize; splitterSize.push_back(1000); splitterSize.push_back(1000); splitterSize.push_back(1000); m_SubSplit1->setSizes( splitterSize ); m_SubSplit2->addWidget( mitkWidget4Container ); //set splitterSize of Layout Split splitterSize.clear(); splitterSize.push_back(400); splitterSize.push_back(1000); m_LayoutSplit->setSizes( splitterSize ); //show mainSplitt and add to Layout m_MainSplit->show(); //show Widget if hidden if ( mitkWidget1->isHidden() ) mitkWidget1->show(); if ( mitkWidget2->isHidden() ) mitkWidget2->show(); if ( mitkWidget3->isHidden() ) mitkWidget3->show(); if ( mitkWidget4->isHidden() ) mitkWidget4->show(); //update Layout Name m_Layout = LAYOUT_2D_IMAGES_LEFT; //update Layout Design List mitkWidget1->LayoutDesignListChanged( LAYOUT_2D_IMAGES_LEFT ); mitkWidget2->LayoutDesignListChanged( LAYOUT_2D_IMAGES_LEFT ); mitkWidget3->LayoutDesignListChanged( LAYOUT_2D_IMAGES_LEFT ); mitkWidget4->LayoutDesignListChanged( LAYOUT_2D_IMAGES_LEFT ); //update Alle Widgets this->UpdateAllWidgets(); } void QmitkStdMultiWidget::changeLayoutToDefault() { SMW_INFO << "changing layout to default... " << std::endl; //Hide all Menu Widgets this->HideAllWidgetToolbars(); delete QmitkStdMultiWidgetLayout ; //create Main Layout QmitkStdMultiWidgetLayout = new QHBoxLayout( this ); //create main splitter m_MainSplit = new QSplitter( this ); QmitkStdMultiWidgetLayout->addWidget( m_MainSplit ); //create m_LayoutSplit and add to the mainSplit m_LayoutSplit = new QSplitter( Qt::Vertical, m_MainSplit ); m_MainSplit->addWidget( m_LayoutSplit ); //add LevelWindow Widget to mainSplitter m_MainSplit->addWidget( levelWindowWidget ); //create m_SubSplit1 and m_SubSplit2 m_SubSplit1 = new QSplitter( m_LayoutSplit ); m_SubSplit2 = new QSplitter( m_LayoutSplit ); //insert Widget container into the splitters m_SubSplit1->addWidget( mitkWidget1Container ); m_SubSplit1->addWidget( mitkWidget2Container ); m_SubSplit2->addWidget( mitkWidget3Container ); m_SubSplit2->addWidget( mitkWidget4Container ); //set splitter Size QList splitterSize; splitterSize.push_back(1000); splitterSize.push_back(1000); m_SubSplit1->setSizes( splitterSize ); m_SubSplit2->setSizes( splitterSize ); m_LayoutSplit->setSizes( splitterSize ); //show mainSplitt and add to Layout m_MainSplit->show(); //show Widget if hidden if ( mitkWidget1->isHidden() ) mitkWidget1->show(); if ( mitkWidget2->isHidden() ) mitkWidget2->show(); if ( mitkWidget3->isHidden() ) mitkWidget3->show(); if ( mitkWidget4->isHidden() ) mitkWidget4->show(); m_Layout = LAYOUT_DEFAULT; //update Layout Design List mitkWidget1->LayoutDesignListChanged( LAYOUT_DEFAULT ); mitkWidget2->LayoutDesignListChanged( LAYOUT_DEFAULT ); mitkWidget3->LayoutDesignListChanged( LAYOUT_DEFAULT ); mitkWidget4->LayoutDesignListChanged( LAYOUT_DEFAULT ); //update Alle Widgets this->UpdateAllWidgets(); } void QmitkStdMultiWidget::changeLayoutToBig3D() { SMW_INFO << "changing layout to big 3D ..." << std::endl; //Hide all Menu Widgets this->HideAllWidgetToolbars(); delete QmitkStdMultiWidgetLayout ; //create Main Layout QmitkStdMultiWidgetLayout = new QHBoxLayout( this ); //create main splitter m_MainSplit = new QSplitter( this ); QmitkStdMultiWidgetLayout->addWidget( m_MainSplit ); //add widget Splitter to main Splitter m_MainSplit->addWidget( mitkWidget4Container ); //add LevelWindow Widget to mainSplitter m_MainSplit->addWidget( levelWindowWidget ); //show mainSplitt and add to Layout m_MainSplit->show(); //show/hide Widgets mitkWidget1->hide(); mitkWidget2->hide(); mitkWidget3->hide(); if ( mitkWidget4->isHidden() ) mitkWidget4->show(); m_Layout = LAYOUT_BIG_3D; //update Layout Design List mitkWidget1->LayoutDesignListChanged( LAYOUT_BIG_3D ); mitkWidget2->LayoutDesignListChanged( LAYOUT_BIG_3D ); mitkWidget3->LayoutDesignListChanged( LAYOUT_BIG_3D ); mitkWidget4->LayoutDesignListChanged( LAYOUT_BIG_3D ); //update Alle Widgets this->UpdateAllWidgets(); } void QmitkStdMultiWidget::changeLayoutToWidget1() { SMW_INFO << "changing layout to big Widget1 ..." << std::endl; //Hide all Menu Widgets this->HideAllWidgetToolbars(); delete QmitkStdMultiWidgetLayout ; //create Main Layout QmitkStdMultiWidgetLayout = new QHBoxLayout( this ); //create main splitter m_MainSplit = new QSplitter( this ); QmitkStdMultiWidgetLayout->addWidget( m_MainSplit ); //add widget Splitter to main Splitter m_MainSplit->addWidget( mitkWidget1Container ); //add LevelWindow Widget to mainSplitter m_MainSplit->addWidget( levelWindowWidget ); //show mainSplitt and add to Layout m_MainSplit->show(); //show/hide Widgets if ( mitkWidget1->isHidden() ) mitkWidget1->show(); mitkWidget2->hide(); mitkWidget3->hide(); mitkWidget4->hide(); m_Layout = LAYOUT_WIDGET1; //update Layout Design List mitkWidget1->LayoutDesignListChanged( LAYOUT_WIDGET1 ); mitkWidget2->LayoutDesignListChanged( LAYOUT_WIDGET1 ); mitkWidget3->LayoutDesignListChanged( LAYOUT_WIDGET1 ); mitkWidget4->LayoutDesignListChanged( LAYOUT_WIDGET1 ); //update Alle Widgets this->UpdateAllWidgets(); } void QmitkStdMultiWidget::changeLayoutToWidget2() { SMW_INFO << "changing layout to big Widget2 ..." << std::endl; //Hide all Menu Widgets this->HideAllWidgetToolbars(); delete QmitkStdMultiWidgetLayout ; //create Main Layout QmitkStdMultiWidgetLayout = new QHBoxLayout( this ); //create main splitter m_MainSplit = new QSplitter( this ); QmitkStdMultiWidgetLayout->addWidget( m_MainSplit ); //add widget Splitter to main Splitter m_MainSplit->addWidget( mitkWidget2Container ); //add LevelWindow Widget to mainSplitter m_MainSplit->addWidget( levelWindowWidget ); //show mainSplitt and add to Layout m_MainSplit->show(); //show/hide Widgets mitkWidget1->hide(); if ( mitkWidget2->isHidden() ) mitkWidget2->show(); mitkWidget3->hide(); mitkWidget4->hide(); m_Layout = LAYOUT_WIDGET2; //update Layout Design List mitkWidget1->LayoutDesignListChanged( LAYOUT_WIDGET2 ); mitkWidget2->LayoutDesignListChanged( LAYOUT_WIDGET2 ); mitkWidget3->LayoutDesignListChanged( LAYOUT_WIDGET2 ); mitkWidget4->LayoutDesignListChanged( LAYOUT_WIDGET2 ); //update Alle Widgets this->UpdateAllWidgets(); } void QmitkStdMultiWidget::changeLayoutToWidget3() { SMW_INFO << "changing layout to big Widget3 ..." << std::endl; //Hide all Menu Widgets this->HideAllWidgetToolbars(); delete QmitkStdMultiWidgetLayout ; //create Main Layout QmitkStdMultiWidgetLayout = new QHBoxLayout( this ); //create main splitter m_MainSplit = new QSplitter( this ); QmitkStdMultiWidgetLayout->addWidget( m_MainSplit ); //add widget Splitter to main Splitter m_MainSplit->addWidget( mitkWidget3Container ); //add LevelWindow Widget to mainSplitter m_MainSplit->addWidget( levelWindowWidget ); //show mainSplitt and add to Layout m_MainSplit->show(); //show/hide Widgets mitkWidget1->hide(); mitkWidget2->hide(); if ( mitkWidget3->isHidden() ) mitkWidget3->show(); mitkWidget4->hide(); m_Layout = LAYOUT_WIDGET3; //update Layout Design List mitkWidget1->LayoutDesignListChanged( LAYOUT_WIDGET3 ); mitkWidget2->LayoutDesignListChanged( LAYOUT_WIDGET3 ); mitkWidget3->LayoutDesignListChanged( LAYOUT_WIDGET3 ); mitkWidget4->LayoutDesignListChanged( LAYOUT_WIDGET3 ); //update Alle Widgets this->UpdateAllWidgets(); } void QmitkStdMultiWidget::changeLayoutToRowWidget3And4() { SMW_INFO << "changing layout to Widget3 and 4 in a Row..." << std::endl; //Hide all Menu Widgets this->HideAllWidgetToolbars(); delete QmitkStdMultiWidgetLayout ; //create Main Layout QmitkStdMultiWidgetLayout = new QHBoxLayout( this ); //create main splitter m_MainSplit = new QSplitter( this ); QmitkStdMultiWidgetLayout->addWidget( m_MainSplit ); //create m_LayoutSplit and add to the mainSplit m_LayoutSplit = new QSplitter( Qt::Vertical, m_MainSplit ); m_MainSplit->addWidget( m_LayoutSplit ); //add LevelWindow Widget to mainSplitter m_MainSplit->addWidget( levelWindowWidget ); //add Widgets to splitter m_LayoutSplit->addWidget( mitkWidget3Container ); m_LayoutSplit->addWidget( mitkWidget4Container ); //set Splitter Size QList splitterSize; splitterSize.push_back(1000); splitterSize.push_back(1000); m_LayoutSplit->setSizes( splitterSize ); //show mainSplitt and add to Layout m_MainSplit->show(); //show/hide Widgets mitkWidget1->hide(); mitkWidget2->hide(); if ( mitkWidget3->isHidden() ) mitkWidget3->show(); if ( mitkWidget4->isHidden() ) mitkWidget4->show(); m_Layout = LAYOUT_ROW_WIDGET_3_AND_4; //update Layout Design List mitkWidget1->LayoutDesignListChanged( LAYOUT_ROW_WIDGET_3_AND_4 ); mitkWidget2->LayoutDesignListChanged( LAYOUT_ROW_WIDGET_3_AND_4 ); mitkWidget3->LayoutDesignListChanged( LAYOUT_ROW_WIDGET_3_AND_4 ); mitkWidget4->LayoutDesignListChanged( LAYOUT_ROW_WIDGET_3_AND_4 ); //update Alle Widgets this->UpdateAllWidgets(); } void QmitkStdMultiWidget::changeLayoutToColumnWidget3And4() { SMW_INFO << "changing layout to Widget3 and 4 in one Column..." << std::endl; //Hide all Menu Widgets this->HideAllWidgetToolbars(); delete QmitkStdMultiWidgetLayout ; //create Main Layout QmitkStdMultiWidgetLayout = new QHBoxLayout( this ); //create main splitter m_MainSplit = new QSplitter( this ); QmitkStdMultiWidgetLayout->addWidget( m_MainSplit ); //create m_LayoutSplit and add to the mainSplit m_LayoutSplit = new QSplitter( m_MainSplit ); m_MainSplit->addWidget( m_LayoutSplit ); //add LevelWindow Widget to mainSplitter m_MainSplit->addWidget( levelWindowWidget ); //add Widgets to splitter m_LayoutSplit->addWidget( mitkWidget3Container ); m_LayoutSplit->addWidget( mitkWidget4Container ); //set SplitterSize QList splitterSize; splitterSize.push_back(1000); splitterSize.push_back(1000); m_LayoutSplit->setSizes( splitterSize ); //show mainSplitt and add to Layout m_MainSplit->show(); //show/hide Widgets mitkWidget1->hide(); mitkWidget2->hide(); if ( mitkWidget3->isHidden() ) mitkWidget3->show(); if ( mitkWidget4->isHidden() ) mitkWidget4->show(); m_Layout = LAYOUT_COLUMN_WIDGET_3_AND_4; //update Layout Design List mitkWidget1->LayoutDesignListChanged( LAYOUT_COLUMN_WIDGET_3_AND_4 ); mitkWidget2->LayoutDesignListChanged( LAYOUT_COLUMN_WIDGET_3_AND_4 ); mitkWidget3->LayoutDesignListChanged( LAYOUT_COLUMN_WIDGET_3_AND_4 ); mitkWidget4->LayoutDesignListChanged( LAYOUT_COLUMN_WIDGET_3_AND_4 ); //update Alle Widgets this->UpdateAllWidgets(); } void QmitkStdMultiWidget::changeLayoutToRowWidgetSmall3andBig4() { SMW_INFO << "changing layout to Widget3 and 4 in a Row..." << std::endl; this->changeLayoutToRowWidget3And4(); m_Layout = LAYOUT_ROW_WIDGET_SMALL3_AND_BIG4; } void QmitkStdMultiWidget::changeLayoutToSmallUpperWidget2Big3and4() { SMW_INFO << "changing layout to Widget3 and 4 in a Row..." << std::endl; //Hide all Menu Widgets this->HideAllWidgetToolbars(); delete QmitkStdMultiWidgetLayout ; //create Main Layout QmitkStdMultiWidgetLayout = new QHBoxLayout( this ); //create main splitter m_MainSplit = new QSplitter( this ); QmitkStdMultiWidgetLayout->addWidget( m_MainSplit ); //create m_LayoutSplit and add to the mainSplit m_LayoutSplit = new QSplitter( Qt::Vertical, m_MainSplit ); m_MainSplit->addWidget( m_LayoutSplit ); //add LevelWindow Widget to mainSplitter m_MainSplit->addWidget( levelWindowWidget ); //create m_SubSplit1 and m_SubSplit2 m_SubSplit1 = new QSplitter( Qt::Vertical, m_LayoutSplit ); m_SubSplit2 = new QSplitter( m_LayoutSplit ); //insert Widget into the splitters m_SubSplit1->addWidget( mitkWidget2Container ); m_SubSplit2->addWidget( mitkWidget3Container ); m_SubSplit2->addWidget( mitkWidget4Container ); //set Splitter Size QList splitterSize; splitterSize.push_back(1000); splitterSize.push_back(1000); m_SubSplit2->setSizes( splitterSize ); splitterSize.clear(); splitterSize.push_back(500); splitterSize.push_back(1000); m_LayoutSplit->setSizes( splitterSize ); //show mainSplitt m_MainSplit->show(); //show Widget if hidden mitkWidget1->hide(); if ( mitkWidget2->isHidden() ) mitkWidget2->show(); if ( mitkWidget3->isHidden() ) mitkWidget3->show(); if ( mitkWidget4->isHidden() ) mitkWidget4->show(); m_Layout = LAYOUT_SMALL_UPPER_WIDGET2_BIG3_AND4; //update Layout Design List mitkWidget1->LayoutDesignListChanged( LAYOUT_SMALL_UPPER_WIDGET2_BIG3_AND4 ); mitkWidget2->LayoutDesignListChanged( LAYOUT_SMALL_UPPER_WIDGET2_BIG3_AND4 ); mitkWidget3->LayoutDesignListChanged( LAYOUT_SMALL_UPPER_WIDGET2_BIG3_AND4 ); mitkWidget4->LayoutDesignListChanged( LAYOUT_SMALL_UPPER_WIDGET2_BIG3_AND4 ); //update Alle Widgets this->UpdateAllWidgets(); } void QmitkStdMultiWidget::changeLayoutTo2x2Dand3DWidget() { SMW_INFO << "changing layout to 2 x 2D and 3D Widget" << std::endl; //Hide all Menu Widgets this->HideAllWidgetToolbars(); delete QmitkStdMultiWidgetLayout ; //create Main Layout QmitkStdMultiWidgetLayout = new QHBoxLayout( this ); //create main splitter m_MainSplit = new QSplitter( this ); QmitkStdMultiWidgetLayout->addWidget( m_MainSplit ); //create m_LayoutSplit and add to the mainSplit m_LayoutSplit = new QSplitter( m_MainSplit ); m_MainSplit->addWidget( m_LayoutSplit ); //add LevelWindow Widget to mainSplitter m_MainSplit->addWidget( levelWindowWidget ); //create m_SubSplit1 and m_SubSplit2 m_SubSplit1 = new QSplitter( Qt::Vertical, m_LayoutSplit ); m_SubSplit2 = new QSplitter( m_LayoutSplit ); //add Widgets to splitter m_SubSplit1->addWidget( mitkWidget1Container ); m_SubSplit1->addWidget( mitkWidget2Container ); m_SubSplit2->addWidget( mitkWidget4Container ); //set Splitter Size QList splitterSize; splitterSize.push_back(1000); splitterSize.push_back(1000); m_SubSplit1->setSizes( splitterSize ); m_LayoutSplit->setSizes( splitterSize ); //show mainSplitt and add to Layout m_MainSplit->show(); //show/hide Widgets if ( mitkWidget1->isHidden() ) mitkWidget1->show(); if ( mitkWidget2->isHidden() ) mitkWidget2->show(); mitkWidget3->hide(); if ( mitkWidget4->isHidden() ) mitkWidget4->show(); m_Layout = LAYOUT_2X_2D_AND_3D_WIDGET; //update Layout Design List mitkWidget1->LayoutDesignListChanged( LAYOUT_2X_2D_AND_3D_WIDGET ); mitkWidget2->LayoutDesignListChanged( LAYOUT_2X_2D_AND_3D_WIDGET ); mitkWidget3->LayoutDesignListChanged( LAYOUT_2X_2D_AND_3D_WIDGET ); mitkWidget4->LayoutDesignListChanged( LAYOUT_2X_2D_AND_3D_WIDGET ); //update Alle Widgets this->UpdateAllWidgets(); } void QmitkStdMultiWidget::changeLayoutToLeft2Dand3DRight2D() { SMW_INFO << "changing layout to 2D and 3D left, 2D right Widget" << std::endl; //Hide all Menu Widgets this->HideAllWidgetToolbars(); delete QmitkStdMultiWidgetLayout ; //create Main Layout QmitkStdMultiWidgetLayout = new QHBoxLayout( this ); //create main splitter m_MainSplit = new QSplitter( this ); QmitkStdMultiWidgetLayout->addWidget( m_MainSplit ); //create m_LayoutSplit and add to the mainSplit m_LayoutSplit = new QSplitter( m_MainSplit ); m_MainSplit->addWidget( m_LayoutSplit ); //add LevelWindow Widget to mainSplitter m_MainSplit->addWidget( levelWindowWidget ); //create m_SubSplit1 and m_SubSplit2 m_SubSplit1 = new QSplitter( Qt::Vertical, m_LayoutSplit ); m_SubSplit2 = new QSplitter( m_LayoutSplit ); //add Widgets to splitter m_SubSplit1->addWidget( mitkWidget1Container ); m_SubSplit1->addWidget( mitkWidget4Container ); m_SubSplit2->addWidget( mitkWidget2Container ); //set Splitter Size QList splitterSize; splitterSize.push_back(1000); splitterSize.push_back(1000); m_SubSplit1->setSizes( splitterSize ); m_LayoutSplit->setSizes( splitterSize ); //show mainSplitt and add to Layout m_MainSplit->show(); //show/hide Widgets if ( mitkWidget1->isHidden() ) mitkWidget1->show(); if ( mitkWidget2->isHidden() ) mitkWidget2->show(); mitkWidget3->hide(); if ( mitkWidget4->isHidden() ) mitkWidget4->show(); m_Layout = LAYOUT_2D_AND_3D_LEFT_2D_RIGHT_WIDGET; //update Layout Design List mitkWidget1->LayoutDesignListChanged( LAYOUT_2D_AND_3D_LEFT_2D_RIGHT_WIDGET ); mitkWidget2->LayoutDesignListChanged( LAYOUT_2D_AND_3D_LEFT_2D_RIGHT_WIDGET ); mitkWidget3->LayoutDesignListChanged( LAYOUT_2D_AND_3D_LEFT_2D_RIGHT_WIDGET ); mitkWidget4->LayoutDesignListChanged( LAYOUT_2D_AND_3D_LEFT_2D_RIGHT_WIDGET ); //update Alle Widgets this->UpdateAllWidgets(); } void QmitkStdMultiWidget::changeLayoutTo2DUpAnd3DDown() { SMW_INFO << "changing layout to 2D up and 3D down" << std::endl; //Hide all Menu Widgets this->HideAllWidgetToolbars(); delete QmitkStdMultiWidgetLayout ; //create Main Layout QmitkStdMultiWidgetLayout = new QHBoxLayout( this ); //Set Layout to widget this->setLayout(QmitkStdMultiWidgetLayout); //create main splitter m_MainSplit = new QSplitter( this ); QmitkStdMultiWidgetLayout->addWidget( m_MainSplit ); //create m_LayoutSplit and add to the mainSplit m_LayoutSplit = new QSplitter( Qt::Vertical, m_MainSplit ); m_MainSplit->addWidget( m_LayoutSplit ); //add LevelWindow Widget to mainSplitter m_MainSplit->addWidget( levelWindowWidget ); //create m_SubSplit1 and m_SubSplit2 m_SubSplit1 = new QSplitter( m_LayoutSplit ); m_SubSplit2 = new QSplitter( m_LayoutSplit ); //insert Widget Container into splitter top m_SubSplit1->addWidget( mitkWidget1Container ); //set SplitterSize for splitter top QList splitterSize; // splitterSize.push_back(1000); // splitterSize.push_back(1000); // splitterSize.push_back(1000); // m_SubSplit1->setSizes( splitterSize ); //insert Widget Container into splitter bottom m_SubSplit2->addWidget( mitkWidget4Container ); //set SplitterSize for splitter m_LayoutSplit splitterSize.clear(); splitterSize.push_back(700); splitterSize.push_back(700); m_LayoutSplit->setSizes( splitterSize ); //show mainSplitt m_MainSplit->show(); //show/hide Widgets if ( mitkWidget1->isHidden() ) mitkWidget1->show(); mitkWidget2->hide(); mitkWidget3->hide(); if ( mitkWidget4->isHidden() ) mitkWidget4->show(); m_Layout = LAYOUT_2D_UP_AND_3D_DOWN; //update Layout Design List mitkWidget1->LayoutDesignListChanged( LAYOUT_2D_UP_AND_3D_DOWN ); mitkWidget2->LayoutDesignListChanged( LAYOUT_2D_UP_AND_3D_DOWN ); mitkWidget3->LayoutDesignListChanged( LAYOUT_2D_UP_AND_3D_DOWN ); mitkWidget4->LayoutDesignListChanged( LAYOUT_2D_UP_AND_3D_DOWN ); //update all Widgets this->UpdateAllWidgets(); } void QmitkStdMultiWidget::SetDataStorage( mitk::DataStorage* ds ) { mitk::BaseRenderer::GetInstance(mitkWidget1->GetRenderWindow())->SetDataStorage(ds); mitk::BaseRenderer::GetInstance(mitkWidget2->GetRenderWindow())->SetDataStorage(ds); mitk::BaseRenderer::GetInstance(mitkWidget3->GetRenderWindow())->SetDataStorage(ds); mitk::BaseRenderer::GetInstance(mitkWidget4->GetRenderWindow())->SetDataStorage(ds); m_DataStorage = ds; } void QmitkStdMultiWidget::Fit() { vtkRenderer * vtkrenderer; mitk::BaseRenderer::GetInstance(mitkWidget1->GetRenderWindow())->GetDisplayGeometry()->Fit(); mitk::BaseRenderer::GetInstance(mitkWidget2->GetRenderWindow())->GetDisplayGeometry()->Fit(); mitk::BaseRenderer::GetInstance(mitkWidget3->GetRenderWindow())->GetDisplayGeometry()->Fit(); mitk::BaseRenderer::GetInstance(mitkWidget4->GetRenderWindow())->GetDisplayGeometry()->Fit(); int w = vtkObject::GetGlobalWarningDisplay(); vtkObject::GlobalWarningDisplayOff(); vtkrenderer = mitk::BaseRenderer::GetInstance(mitkWidget1->GetRenderWindow())->GetVtkRenderer(); if ( vtkrenderer!= NULL ) vtkrenderer->ResetCamera(); vtkrenderer = mitk::BaseRenderer::GetInstance(mitkWidget2->GetRenderWindow())->GetVtkRenderer(); if ( vtkrenderer!= NULL ) vtkrenderer->ResetCamera(); vtkrenderer = mitk::BaseRenderer::GetInstance(mitkWidget3->GetRenderWindow())->GetVtkRenderer(); if ( vtkrenderer!= NULL ) vtkrenderer->ResetCamera(); vtkrenderer = mitk::BaseRenderer::GetInstance(mitkWidget4->GetRenderWindow())->GetVtkRenderer(); if ( vtkrenderer!= NULL ) vtkrenderer->ResetCamera(); vtkObject::SetGlobalWarningDisplay(w); } void QmitkStdMultiWidget::InitPositionTracking() { //PoinSetNode for MouseOrientation m_PositionTrackerNode = mitk::DataNode::New(); m_PositionTrackerNode->SetProperty("name", mitk::StringProperty::New("Mouse Position")); m_PositionTrackerNode->SetData( mitk::PointSet::New() ); m_PositionTrackerNode->SetColor(1.0,0.33,0.0); m_PositionTrackerNode->SetProperty("layer", mitk::IntProperty::New(1001)); m_PositionTrackerNode->SetVisibility(true); m_PositionTrackerNode->SetProperty("inputdevice", mitk::BoolProperty::New(true) ); m_PositionTrackerNode->SetProperty("BaseRendererMapperID", mitk::IntProperty::New(0) );//point position 2D mouse m_PositionTrackerNode->SetProperty("baserenderer", mitk::StringProperty::New("N/A")); } void QmitkStdMultiWidget::AddDisplayPlaneSubTree() { // add the displayed planes of the multiwidget to a node to which the subtree // @a planesSubTree points ... float white[3] = {1.0f,1.0f,1.0f}; mitk::PlaneGeometryDataMapper2D::Pointer mapper; // ... of widget 1 mitk::BaseRenderer* renderer1 = mitk::BaseRenderer::GetInstance(mitkWidget1->GetRenderWindow()); m_PlaneNode1 = renderer1->GetCurrentWorldPlaneGeometryNode(); m_PlaneNode1->SetColor(white, mitk::BaseRenderer::GetInstance(mitkWidget4->GetRenderWindow())); m_PlaneNode1->SetProperty("visible", mitk::BoolProperty::New(true)); m_PlaneNode1->SetProperty("name", mitk::StringProperty::New(std::string(renderer1->GetName()) + ".plane")); m_PlaneNode1->SetProperty("includeInBoundingBox", mitk::BoolProperty::New(false)); m_PlaneNode1->SetProperty("helper object", mitk::BoolProperty::New(true)); mapper = mitk::PlaneGeometryDataMapper2D::New(); m_PlaneNode1->SetMapper(mitk::BaseRenderer::Standard2D, mapper); // ... of widget 2 mitk::BaseRenderer* renderer2 = mitk::BaseRenderer::GetInstance(mitkWidget2->GetRenderWindow()); m_PlaneNode2 = renderer2->GetCurrentWorldPlaneGeometryNode(); m_PlaneNode2->SetColor(white, mitk::BaseRenderer::GetInstance(mitkWidget4->GetRenderWindow())); m_PlaneNode2->SetProperty("visible", mitk::BoolProperty::New(true)); m_PlaneNode2->SetProperty("name", mitk::StringProperty::New(std::string(renderer2->GetName()) + ".plane")); m_PlaneNode2->SetProperty("includeInBoundingBox", mitk::BoolProperty::New(false)); m_PlaneNode2->SetProperty("helper object", mitk::BoolProperty::New(true)); mapper = mitk::PlaneGeometryDataMapper2D::New(); m_PlaneNode2->SetMapper(mitk::BaseRenderer::Standard2D, mapper); // ... of widget 3 mitk::BaseRenderer* renderer3 = mitk::BaseRenderer::GetInstance(mitkWidget3->GetRenderWindow()); m_PlaneNode3 = renderer3->GetCurrentWorldPlaneGeometryNode(); m_PlaneNode3->SetColor(white, mitk::BaseRenderer::GetInstance(mitkWidget4->GetRenderWindow())); m_PlaneNode3->SetProperty("visible", mitk::BoolProperty::New(true)); m_PlaneNode3->SetProperty("name", mitk::StringProperty::New(std::string(renderer3->GetName()) + ".plane")); m_PlaneNode3->SetProperty("includeInBoundingBox", mitk::BoolProperty::New(false)); m_PlaneNode3->SetProperty("helper object", mitk::BoolProperty::New(true)); mapper = mitk::PlaneGeometryDataMapper2D::New(); m_PlaneNode3->SetMapper(mitk::BaseRenderer::Standard2D, mapper); m_Node = mitk::DataNode::New(); m_Node->SetProperty("name", mitk::StringProperty::New("Widgets")); m_Node->SetProperty("helper object", mitk::BoolProperty::New(true)); } mitk::SliceNavigationController* QmitkStdMultiWidget::GetTimeNavigationController() { return m_TimeNavigationController; } void QmitkStdMultiWidget::EnableStandardLevelWindow() { levelWindowWidget->disconnect(this); levelWindowWidget->SetDataStorage(mitk::BaseRenderer::GetInstance(mitkWidget1->GetRenderWindow())->GetDataStorage()); levelWindowWidget->show(); } void QmitkStdMultiWidget::DisableStandardLevelWindow() { levelWindowWidget->disconnect(this); levelWindowWidget->hide(); } // CAUTION: Legacy code for enabling Qt-signal-controlled view initialization. // Use RenderingManager::InitializeViews() instead. bool QmitkStdMultiWidget::InitializeStandardViews( const mitk::Geometry3D * geometry ) { return m_RenderingManager->InitializeViews( geometry ); } void QmitkStdMultiWidget::RequestUpdate() { m_RenderingManager->RequestUpdate(mitkWidget1->GetRenderWindow()); m_RenderingManager->RequestUpdate(mitkWidget2->GetRenderWindow()); m_RenderingManager->RequestUpdate(mitkWidget3->GetRenderWindow()); m_RenderingManager->RequestUpdate(mitkWidget4->GetRenderWindow()); } void QmitkStdMultiWidget::ForceImmediateUpdate() { m_RenderingManager->ForceImmediateUpdate(mitkWidget1->GetRenderWindow()); m_RenderingManager->ForceImmediateUpdate(mitkWidget2->GetRenderWindow()); m_RenderingManager->ForceImmediateUpdate(mitkWidget3->GetRenderWindow()); m_RenderingManager->ForceImmediateUpdate(mitkWidget4->GetRenderWindow()); } void QmitkStdMultiWidget::wheelEvent( QWheelEvent * e ) { emit WheelMoved( e ); } void QmitkStdMultiWidget::mousePressEvent(QMouseEvent * e) { if (e->button() == Qt::LeftButton) { mitk::Point3D pointValue = this->GetLastLeftClickPosition(); emit LeftMouseClicked(pointValue); } } void QmitkStdMultiWidget::moveEvent( QMoveEvent* e ) { QWidget::moveEvent( e ); // it is necessary to readjust the position of the overlays as the StdMultiWidget has moved // unfortunately it's not done by QmitkRenderWindow::moveEvent -> must be done here emit Moved(); } void QmitkStdMultiWidget::leaveEvent ( QEvent * /*e*/ ) { //set cursor back to initial state m_SlicesRotator->ResetMouseCursor(); } QmitkRenderWindow* QmitkStdMultiWidget::GetRenderWindow1() const { return mitkWidget1; } QmitkRenderWindow* QmitkStdMultiWidget::GetRenderWindow2() const { return mitkWidget2; } QmitkRenderWindow* QmitkStdMultiWidget::GetRenderWindow3() const { return mitkWidget3; } QmitkRenderWindow* QmitkStdMultiWidget::GetRenderWindow4() const { return mitkWidget4; } const mitk::Point3D& QmitkStdMultiWidget::GetLastLeftClickPosition() const { return m_LastLeftClickPositionSupplier->GetCurrentPoint(); } const mitk::Point3D QmitkStdMultiWidget::GetCrossPosition() const { const mitk::PlaneGeometry *plane1 = mitkWidget1->GetSliceNavigationController()->GetCurrentPlaneGeometry(); const mitk::PlaneGeometry *plane2 = mitkWidget2->GetSliceNavigationController()->GetCurrentPlaneGeometry(); const mitk::PlaneGeometry *plane3 = mitkWidget3->GetSliceNavigationController()->GetCurrentPlaneGeometry(); mitk::Line3D line; if ( (plane1 != NULL) && (plane2 != NULL) && (plane1->IntersectionLine( plane2, line )) ) { mitk::Point3D point; if ( (plane3 != NULL) && (plane3->IntersectionPoint( line, point )) ) { return point; } } return m_LastLeftClickPositionSupplier->GetCurrentPoint(); } void QmitkStdMultiWidget::EnablePositionTracking() { if (!m_PositionTracker) { m_PositionTracker = mitk::PositionTracker::New("PositionTracker", NULL); } mitk::GlobalInteraction* globalInteraction = mitk::GlobalInteraction::GetInstance(); if (globalInteraction) { if(m_DataStorage.IsNotNull()) m_DataStorage->Add(m_PositionTrackerNode); globalInteraction->AddListener(m_PositionTracker); } } void QmitkStdMultiWidget::DisablePositionTracking() { mitk::GlobalInteraction* globalInteraction = mitk::GlobalInteraction::GetInstance(); if(globalInteraction) { if (m_DataStorage.IsNotNull()) m_DataStorage->Remove(m_PositionTrackerNode); globalInteraction->RemoveListener(m_PositionTracker); } } void QmitkStdMultiWidget::EnsureDisplayContainsPoint( mitk::DisplayGeometry* displayGeometry, const mitk::Point3D& p) { mitk::Point2D pointOnPlane; displayGeometry->Map( p, pointOnPlane ); // point minus origin < width or height ==> outside ? mitk::Vector2D pointOnRenderWindow_MM; pointOnRenderWindow_MM = pointOnPlane.GetVectorFromOrigin() - displayGeometry->GetOriginInMM(); mitk::Vector2D sizeOfDisplay( displayGeometry->GetSizeInMM() ); if ( sizeOfDisplay[0] < pointOnRenderWindow_MM[0] || 0 > pointOnRenderWindow_MM[0] || sizeOfDisplay[1] < pointOnRenderWindow_MM[1] || 0 > pointOnRenderWindow_MM[1] ) { // point is not visible -> move geometry mitk::Vector2D offset( (pointOnRenderWindow_MM - sizeOfDisplay / 2.0) / displayGeometry->GetScaleFactorMMPerDisplayUnit() ); displayGeometry->MoveBy( offset ); } } void QmitkStdMultiWidget::MoveCrossToPosition(const mitk::Point3D& newPosition) { // create a PositionEvent with the given position and // tell the slice navigation controllers to move there mitk::Point2D p2d; mitk::PositionEvent event( mitk::BaseRenderer::GetInstance(mitkWidget1->GetRenderWindow()), 0, 0, 0, mitk::Key_unknown, p2d, newPosition ); mitk::StateEvent stateEvent(mitk::EIDLEFTMOUSEBTN, &event); mitk::StateEvent stateEvent2(mitk::EIDLEFTMOUSERELEASE, &event); switch ( m_PlaneMode ) { default: case PLANE_MODE_SLICING: mitkWidget1->GetSliceNavigationController()->HandleEvent( &stateEvent ); mitkWidget2->GetSliceNavigationController()->HandleEvent( &stateEvent ); mitkWidget3->GetSliceNavigationController()->HandleEvent( &stateEvent ); // just in case SNCs will develop something that depends on the mouse // button being released again mitkWidget1->GetSliceNavigationController()->HandleEvent( &stateEvent2 ); mitkWidget2->GetSliceNavigationController()->HandleEvent( &stateEvent2 ); mitkWidget3->GetSliceNavigationController()->HandleEvent( &stateEvent2 ); break; case PLANE_MODE_ROTATION: m_SlicesRotator->HandleEvent( &stateEvent ); // just in case SNCs will develop something that depends on the mouse // button being released again m_SlicesRotator->HandleEvent( &stateEvent2 ); break; case PLANE_MODE_SWIVEL: m_SlicesSwiveller->HandleEvent( &stateEvent ); // just in case SNCs will develop something that depends on the mouse // button being released again m_SlicesSwiveller->HandleEvent( &stateEvent2 ); break; } // determine if cross is now out of display // if so, move the display window EnsureDisplayContainsPoint( mitk::BaseRenderer::GetInstance(mitkWidget1->GetRenderWindow()) ->GetDisplayGeometry(), newPosition ); EnsureDisplayContainsPoint( mitk::BaseRenderer::GetInstance(mitkWidget2->GetRenderWindow()) ->GetDisplayGeometry(), newPosition ); EnsureDisplayContainsPoint( mitk::BaseRenderer::GetInstance(mitkWidget3->GetRenderWindow()) ->GetDisplayGeometry(), newPosition ); // update displays m_RenderingManager->RequestUpdateAll(); } void QmitkStdMultiWidget::HandleCrosshairPositionEvent() { if(!m_PendingCrosshairPositionEvent) { m_PendingCrosshairPositionEvent=true; QTimer::singleShot(0,this,SLOT( HandleCrosshairPositionEventDelayed() ) ); } } mitk::DataNode::Pointer QmitkStdMultiWidget::GetTopLayerNode(mitk::DataStorage::SetOfObjects::ConstPointer nodes) { mitk::Point3D crosshairPos = this->GetCrossPosition(); mitk::DataNode::Pointer node; int maxlayer = -32768; if(nodes.IsNotNull()) { mitk::BaseRenderer* baseRenderer = this->mitkWidget1->GetSliceNavigationController()->GetRenderer(); // find node with largest layer, that is the node shown on top in the render window for (unsigned int x = 0; x < nodes->size(); x++) { if ( (nodes->at(x)->GetData()->GetGeometry() != NULL) && nodes->at(x)->GetData()->GetGeometry()->IsInside(crosshairPos) ) { int layer = 0; if(!(nodes->at(x)->GetIntProperty("layer", layer))) continue; if(layer > maxlayer) { if( static_cast(nodes->at(x))->IsVisible( baseRenderer ) ) { node = nodes->at(x); maxlayer = layer; } } } } } return node; } void QmitkStdMultiWidget::HandleCrosshairPositionEventDelayed() { m_PendingCrosshairPositionEvent = false; // find image with highest layer mitk::TNodePredicateDataType::Pointer isImageData = mitk::TNodePredicateDataType::New(); mitk::DataStorage::SetOfObjects::ConstPointer nodes = this->m_DataStorage->GetSubset(isImageData).GetPointer(); mitk::DataNode::Pointer node; mitk::DataNode::Pointer topSourceNode; mitk::Image::Pointer image; bool isBinary = false; node = this->GetTopLayerNode(nodes); int component = 0; if(node.IsNotNull()) { node->GetBoolProperty("binary",isBinary); if(isBinary) { mitk::DataStorage::SetOfObjects::ConstPointer sourcenodes = m_DataStorage->GetSources(node, NULL, true); if(!sourcenodes->empty()) { topSourceNode = this->GetTopLayerNode(sourcenodes); } if(topSourceNode.IsNotNull()) { image = dynamic_cast(topSourceNode->GetData()); topSourceNode->GetIntProperty("Image.Displayed Component", component); } else { image = dynamic_cast(node->GetData()); node->GetIntProperty("Image.Displayed Component", component); } } else { image = dynamic_cast(node->GetData()); node->GetIntProperty("Image.Displayed Component", component); } } mitk::Point3D crosshairPos = this->GetCrossPosition(); std::string statusText; std::stringstream stream; itk::Index<3> p; mitk::BaseRenderer* baseRenderer = this->mitkWidget1->GetSliceNavigationController()->GetRenderer(); unsigned int timestep = baseRenderer->GetTimeStep(); if(image.IsNotNull() && (image->GetTimeSteps() > timestep )) { image->GetGeometry()->WorldToIndex(crosshairPos, p); stream.precision(2); stream<<"Position: <" << std::fixed < mm"; stream<<"; Index: <"< "; mitk::ScalarType pixelValue = image->GetPixelValueByIndex(p, timestep, component); if (fabs(pixelValue)>1000000 || fabs(pixelValue) < 0.01) { stream<<"; Time: " << baseRenderer->GetTime() << " ms; Pixelvalue: "<< std::scientific<< pixelValue <<" "; } else { stream<<"; Time: " << baseRenderer->GetTime() << " ms; Pixelvalue: "<< pixelValue <<" "; } } else { stream << "No image information at this position!"; } statusText = stream.str(); mitk::StatusBar::GetInstance()->DisplayGreyValueText(statusText.c_str()); } void QmitkStdMultiWidget::EnableNavigationControllerEventListening() { // Let NavigationControllers listen to GlobalInteraction mitk::GlobalInteraction *gi = mitk::GlobalInteraction::GetInstance(); // Listen for SliceNavigationController mitkWidget1->GetSliceNavigationController()->crosshairPositionEvent.AddListener( mitk::MessageDelegate( this, &QmitkStdMultiWidget::HandleCrosshairPositionEvent ) ); mitkWidget2->GetSliceNavigationController()->crosshairPositionEvent.AddListener( mitk::MessageDelegate( this, &QmitkStdMultiWidget::HandleCrosshairPositionEvent ) ); mitkWidget3->GetSliceNavigationController()->crosshairPositionEvent.AddListener( mitk::MessageDelegate( this, &QmitkStdMultiWidget::HandleCrosshairPositionEvent ) ); switch ( m_PlaneMode ) { default: case PLANE_MODE_SLICING: gi->AddListener( mitkWidget1->GetSliceNavigationController() ); gi->AddListener( mitkWidget2->GetSliceNavigationController() ); gi->AddListener( mitkWidget3->GetSliceNavigationController() ); gi->AddListener( mitkWidget4->GetSliceNavigationController() ); break; case PLANE_MODE_ROTATION: gi->AddListener( m_SlicesRotator ); break; case PLANE_MODE_SWIVEL: gi->AddListener( m_SlicesSwiveller ); break; } gi->AddListener( m_TimeNavigationController ); m_CrosshairNavigationEnabled = true; } void QmitkStdMultiWidget::DisableNavigationControllerEventListening() { // Do not let NavigationControllers listen to GlobalInteraction mitk::GlobalInteraction *gi = mitk::GlobalInteraction::GetInstance(); switch ( m_PlaneMode ) { default: case PLANE_MODE_SLICING: gi->RemoveListener( mitkWidget1->GetSliceNavigationController() ); gi->RemoveListener( mitkWidget2->GetSliceNavigationController() ); gi->RemoveListener( mitkWidget3->GetSliceNavigationController() ); gi->RemoveListener( mitkWidget4->GetSliceNavigationController() ); break; case PLANE_MODE_ROTATION: m_SlicesRotator->ResetMouseCursor(); gi->RemoveListener( m_SlicesRotator ); break; case PLANE_MODE_SWIVEL: m_SlicesSwiveller->ResetMouseCursor(); gi->RemoveListener( m_SlicesSwiveller ); break; } gi->RemoveListener( m_TimeNavigationController ); m_CrosshairNavigationEnabled = false; } int QmitkStdMultiWidget::GetLayout() const { return m_Layout; } bool QmitkStdMultiWidget::GetGradientBackgroundFlag() const { return m_GradientBackgroundFlag; } void QmitkStdMultiWidget::EnableGradientBackground() { // gradient background is by default only in widget 4, otherwise // interferences between 2D rendering and VTK rendering may occur. //m_GradientBackground1->Enable(); //m_GradientBackground2->Enable(); //m_GradientBackground3->Enable(); m_GradientBackground4->Enable(); m_GradientBackgroundFlag = true; } void QmitkStdMultiWidget::DisableGradientBackground() { //m_GradientBackground1->Disable(); //m_GradientBackground2->Disable(); //m_GradientBackground3->Disable(); m_GradientBackground4->Disable(); m_GradientBackgroundFlag = false; } void QmitkStdMultiWidget::EnableDepartmentLogo() { m_LogoRendering->SetVisibility(true); } void QmitkStdMultiWidget::DisableDepartmentLogo() { m_LogoRendering->SetVisibility(false); } bool QmitkStdMultiWidget::IsDepartmentLogoEnabled() const { return m_LogoRendering->IsVisible(mitk::BaseRenderer::GetInstance(mitkWidget4->GetRenderWindow())); } bool QmitkStdMultiWidget::IsCrosshairNavigationEnabled() const { return m_CrosshairNavigationEnabled; } mitk::SlicesRotator * QmitkStdMultiWidget::GetSlicesRotator() const { return m_SlicesRotator; } mitk::SlicesSwiveller * QmitkStdMultiWidget::GetSlicesSwiveller() const { return m_SlicesSwiveller; } void QmitkStdMultiWidget::SetWidgetPlaneVisibility(const char* widgetName, bool visible, mitk::BaseRenderer *renderer) { if (m_DataStorage.IsNotNull()) { mitk::DataNode* n = m_DataStorage->GetNamedNode(widgetName); if (n != NULL) n->SetVisibility(visible, renderer); } } void QmitkStdMultiWidget::SetWidgetPlanesVisibility(bool visible, mitk::BaseRenderer *renderer) { if (m_PlaneNode1.IsNotNull()) { m_PlaneNode1->SetVisibility(visible, renderer); } if (m_PlaneNode2.IsNotNull()) { m_PlaneNode2->SetVisibility(visible, renderer); } if (m_PlaneNode3.IsNotNull()) { m_PlaneNode3->SetVisibility(visible, renderer); } m_RenderingManager->RequestUpdateAll(); } void QmitkStdMultiWidget::SetWidgetPlanesLocked(bool locked) { //do your job and lock or unlock slices. GetRenderWindow1()->GetSliceNavigationController()->SetSliceLocked(locked); GetRenderWindow2()->GetSliceNavigationController()->SetSliceLocked(locked); GetRenderWindow3()->GetSliceNavigationController()->SetSliceLocked(locked); } void QmitkStdMultiWidget::SetWidgetPlanesRotationLocked(bool locked) { //do your job and lock or unlock slices. GetRenderWindow1()->GetSliceNavigationController()->SetSliceRotationLocked(locked); GetRenderWindow2()->GetSliceNavigationController()->SetSliceRotationLocked(locked); GetRenderWindow3()->GetSliceNavigationController()->SetSliceRotationLocked(locked); } void QmitkStdMultiWidget::SetWidgetPlanesRotationLinked( bool link ) { m_SlicesRotator->SetLinkPlanes( link ); m_SlicesSwiveller->SetLinkPlanes( link ); emit WidgetPlanesRotationLinked( link ); } void QmitkStdMultiWidget::SetWidgetPlaneMode( int userMode ) { MITK_DEBUG << "Changing crosshair mode to " << userMode; // first of all reset left mouse button interaction to default if PACS interaction style is active m_MouseModeSwitcher->SelectMouseMode( mitk::MouseModeSwitcher::MousePointer ); emit WidgetNotifyNewCrossHairMode( userMode ); int mode = m_PlaneMode; bool link = false; // Convert user interface mode to actual mode { switch(userMode) { case 0: mode = PLANE_MODE_SLICING; link = false; break; case 1: mode = PLANE_MODE_ROTATION; link = false; break; case 2: mode = PLANE_MODE_ROTATION; link = true; break; case 3: mode = PLANE_MODE_SWIVEL; link = false; break; } } // Slice rotation linked m_SlicesRotator->SetLinkPlanes( link ); m_SlicesSwiveller->SetLinkPlanes( link ); // Do nothing if mode didn't change if ( m_PlaneMode == mode ) { return; } mitk::GlobalInteraction *gi = mitk::GlobalInteraction::GetInstance(); // Remove listeners of previous mode switch ( m_PlaneMode ) { default: case PLANE_MODE_SLICING: // Notify MainTemplate GUI that this mode has been deselected emit WidgetPlaneModeSlicing( false ); gi->RemoveListener( mitkWidget1->GetSliceNavigationController() ); gi->RemoveListener( mitkWidget2->GetSliceNavigationController() ); gi->RemoveListener( mitkWidget3->GetSliceNavigationController() ); gi->RemoveListener( mitkWidget4->GetSliceNavigationController() ); break; case PLANE_MODE_ROTATION: // Notify MainTemplate GUI that this mode has been deselected emit WidgetPlaneModeRotation( false ); m_SlicesRotator->ResetMouseCursor(); gi->RemoveListener( m_SlicesRotator ); break; case PLANE_MODE_SWIVEL: // Notify MainTemplate GUI that this mode has been deselected emit WidgetPlaneModeSwivel( false ); m_SlicesSwiveller->ResetMouseCursor(); gi->RemoveListener( m_SlicesSwiveller ); break; } // Set new mode and add corresponding listener to GlobalInteraction m_PlaneMode = mode; switch ( m_PlaneMode ) { default: case PLANE_MODE_SLICING: // Notify MainTemplate GUI that this mode has been selected emit WidgetPlaneModeSlicing( true ); // Add listeners gi->AddListener( mitkWidget1->GetSliceNavigationController() ); gi->AddListener( mitkWidget2->GetSliceNavigationController() ); gi->AddListener( mitkWidget3->GetSliceNavigationController() ); gi->AddListener( mitkWidget4->GetSliceNavigationController() ); m_RenderingManager->InitializeViews(); break; case PLANE_MODE_ROTATION: // Notify MainTemplate GUI that this mode has been selected emit WidgetPlaneModeRotation( true ); // Add listener gi->AddListener( m_SlicesRotator ); break; case PLANE_MODE_SWIVEL: // Notify MainTemplate GUI that this mode has been selected emit WidgetPlaneModeSwivel( true ); // Add listener gi->AddListener( m_SlicesSwiveller ); break; } // Notify MainTemplate GUI that mode has changed emit WidgetPlaneModeChange(m_PlaneMode); } void QmitkStdMultiWidget::SetGradientBackgroundColors( const mitk::Color & upper, const mitk::Color & lower ) { m_GradientBackground1->SetGradientColors(upper[0], upper[1], upper[2], lower[0], lower[1], lower[2]); m_GradientBackground2->SetGradientColors(upper[0], upper[1], upper[2], lower[0], lower[1], lower[2]); m_GradientBackground3->SetGradientColors(upper[0], upper[1], upper[2], lower[0], lower[1], lower[2]); m_GradientBackground4->SetGradientColors(upper[0], upper[1], upper[2], lower[0], lower[1], lower[2]); m_GradientBackgroundFlag = true; } void QmitkStdMultiWidget::SetDepartmentLogoPath( const char * path ) { m_LogoRendering->SetLogoImagePath(path); mitk::BaseRenderer* renderer = mitk::BaseRenderer::GetInstance(mitkWidget4->GetRenderWindow()); m_LogoRendering->Update(renderer); RequestUpdate(); } void QmitkStdMultiWidget::SetWidgetPlaneModeToSlicing( bool activate ) { if ( activate ) { this->SetWidgetPlaneMode( PLANE_MODE_SLICING ); } } void QmitkStdMultiWidget::SetWidgetPlaneModeToRotation( bool activate ) { if ( activate ) { this->SetWidgetPlaneMode( PLANE_MODE_ROTATION ); } } void QmitkStdMultiWidget::SetWidgetPlaneModeToSwivel( bool activate ) { if ( activate ) { this->SetWidgetPlaneMode( PLANE_MODE_SWIVEL ); } } void QmitkStdMultiWidget::OnLayoutDesignChanged( int layoutDesignIndex ) { switch( layoutDesignIndex ) { case LAYOUT_DEFAULT: { this->changeLayoutToDefault(); break; } case LAYOUT_2D_IMAGES_UP: { this->changeLayoutTo2DImagesUp(); break; } case LAYOUT_2D_IMAGES_LEFT: { this->changeLayoutTo2DImagesLeft(); break; } case LAYOUT_BIG_3D: { this->changeLayoutToBig3D(); break; } case LAYOUT_WIDGET1: { this->changeLayoutToWidget1(); break; } case LAYOUT_WIDGET2: { this->changeLayoutToWidget2(); break; } case LAYOUT_WIDGET3: { this->changeLayoutToWidget3(); break; } case LAYOUT_2X_2D_AND_3D_WIDGET: { this->changeLayoutTo2x2Dand3DWidget(); break; } case LAYOUT_ROW_WIDGET_3_AND_4: { this->changeLayoutToRowWidget3And4(); break; } case LAYOUT_COLUMN_WIDGET_3_AND_4: { this->changeLayoutToColumnWidget3And4(); break; } case LAYOUT_ROW_WIDGET_SMALL3_AND_BIG4: { this->changeLayoutToRowWidgetSmall3andBig4(); break; } case LAYOUT_SMALL_UPPER_WIDGET2_BIG3_AND4: { this->changeLayoutToSmallUpperWidget2Big3and4(); break; } case LAYOUT_2D_AND_3D_LEFT_2D_RIGHT_WIDGET: { this->changeLayoutToLeft2Dand3DRight2D(); break; } }; } void QmitkStdMultiWidget::UpdateAllWidgets() { mitkWidget1->resize( mitkWidget1Container->frameSize().width()-1, mitkWidget1Container->frameSize().height() ); mitkWidget1->resize( mitkWidget1Container->frameSize().width(), mitkWidget1Container->frameSize().height() ); mitkWidget2->resize( mitkWidget2Container->frameSize().width()-1, mitkWidget2Container->frameSize().height() ); mitkWidget2->resize( mitkWidget2Container->frameSize().width(), mitkWidget2Container->frameSize().height() ); mitkWidget3->resize( mitkWidget3Container->frameSize().width()-1, mitkWidget3Container->frameSize().height() ); mitkWidget3->resize( mitkWidget3Container->frameSize().width(), mitkWidget3Container->frameSize().height() ); mitkWidget4->resize( mitkWidget4Container->frameSize().width()-1, mitkWidget4Container->frameSize().height() ); mitkWidget4->resize( mitkWidget4Container->frameSize().width(), mitkWidget4Container->frameSize().height() ); } void QmitkStdMultiWidget::HideAllWidgetToolbars() { mitkWidget1->HideRenderWindowMenu(); mitkWidget2->HideRenderWindowMenu(); mitkWidget3->HideRenderWindowMenu(); mitkWidget4->HideRenderWindowMenu(); } void QmitkStdMultiWidget::ActivateMenuWidget( bool state ) { mitkWidget1->ActivateMenuWidget( state, this ); mitkWidget2->ActivateMenuWidget( state, this ); mitkWidget3->ActivateMenuWidget( state, this ); mitkWidget4->ActivateMenuWidget( state, this ); } bool QmitkStdMultiWidget::IsMenuWidgetEnabled() const { return mitkWidget1->GetActivateMenuWidgetFlag(); } void QmitkStdMultiWidget::ResetCrosshair() { if (m_DataStorage.IsNotNull()) { m_RenderingManager->InitializeViewsByBoundingObjects(m_DataStorage); //m_RenderingManager->InitializeViews( m_DataStorage->ComputeVisibleBoundingGeometry3D() ); // reset interactor to normal slicing this->SetWidgetPlaneMode(PLANE_MODE_SLICING); } } void QmitkStdMultiWidget::EnableColoredRectangles() { m_RectangleRendering1->Enable(1.0, 0.0, 0.0); m_RectangleRendering2->Enable(0.0, 1.0, 0.0); m_RectangleRendering3->Enable(0.0, 0.0, 1.0); m_RectangleRendering4->Enable(1.0, 1.0, 0.0); } void QmitkStdMultiWidget::DisableColoredRectangles() { m_RectangleRendering1->Disable(); m_RectangleRendering2->Disable(); m_RectangleRendering3->Disable(); m_RectangleRendering4->Disable(); } bool QmitkStdMultiWidget::IsColoredRectanglesEnabled() const { return m_RectangleRendering1->IsEnabled(); } mitk::MouseModeSwitcher* QmitkStdMultiWidget::GetMouseModeSwitcher() { return m_MouseModeSwitcher; } void QmitkStdMultiWidget::MouseModeSelected( mitk::MouseModeSwitcher::MouseMode mouseMode ) { if ( mouseMode == 0 ) { this->EnableNavigationControllerEventListening(); } else { this->DisableNavigationControllerEventListening(); } } mitk::DataNode::Pointer QmitkStdMultiWidget::GetWidgetPlane1() { return this->m_PlaneNode1; } mitk::DataNode::Pointer QmitkStdMultiWidget::GetWidgetPlane2() { return this->m_PlaneNode2; } mitk::DataNode::Pointer QmitkStdMultiWidget::GetWidgetPlane3() { return this->m_PlaneNode3; } mitk::DataNode::Pointer QmitkStdMultiWidget::GetWidgetPlane(int id) { switch(id) { case 1: return this->m_PlaneNode1; break; case 2: return this->m_PlaneNode2; break; case 3: return this->m_PlaneNode3; break; default: return NULL; } } diff --git a/Modules/QtWidgetsExt/CMakeLists.txt b/Modules/QtWidgetsExt/CMakeLists.txt index fb35dcde93..5bf4886802 100644 --- a/Modules/QtWidgetsExt/CMakeLists.txt +++ b/Modules/QtWidgetsExt/CMakeLists.txt @@ -1,6 +1,6 @@ MITK_CREATE_MODULE( INCLUDE_DIRS QmitkApplicationBase QmitkPropertyObservers DEPENDS MitkImageStatistics MitkQtWidgets - PACKAGE_DEPENDS Qt4|QtWebKit Qwt Qxt + PACKAGE_DEPENDS CTK|CTKWidgets Qt4|QtWebKit Qt5|Concurrent+Svg+WebKitWidgets+Xml Qwt WARNINGS_AS_ERRORS ) diff --git a/Modules/QtWidgetsExt/QmitkCorrespondingPointSetsModel.cpp b/Modules/QtWidgetsExt/QmitkCorrespondingPointSetsModel.cpp index 1135e759da..7f38e78391 100644 --- a/Modules/QtWidgetsExt/QmitkCorrespondingPointSetsModel.cpp +++ b/Modules/QtWidgetsExt/QmitkCorrespondingPointSetsModel.cpp @@ -1,739 +1,748 @@ /*=================================================================== 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 "QmitkCorrespondingPointSetsModel.h" #include #include "mitkInteractionConst.h" #include "mitkPointOperation.h" #include "mitkRenderingManager.h" #include #include #include #include #include #include #include QmitkCorrespondingPointSetsModel::QmitkCorrespondingPointSetsModel(int, QObject* parent) : QAbstractTableModel(parent), m_PointSetNode(NULL), m_ReferencePointSetNode(NULL), m_TimeStepper(NULL), m_SelectedPointSetIndex(-1), m_Interactor(NULL), m_MultiWidget( NULL ), m_PointSetModifiedObserverTag(0), m_ReferencePointSetModifiedObserverTag(0) { } Qt::ItemFlags QmitkCorrespondingPointSetsModel::flags(const QModelIndex& index) const { if (index.isValid()) return Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled | Qt::ItemIsSelectable | Qt::ItemIsEnabled; else return Qt::ItemIsDropEnabled | Qt::ItemIsSelectable | Qt::ItemIsEnabled; } Qt::DropActions QmitkCorrespondingPointSetsModel::supportedDropActions() const { return Qt::CopyAction | Qt::MoveAction; } bool QmitkCorrespondingPointSetsModel::dropMimeData(const QMimeData*, Qt::DropAction action, int row, int, const QModelIndex &parent) { if (action == Qt::IgnoreAction) return true; int targetRow; if (row != -1) targetRow = row; else if (parent.isValid()) targetRow = parent.row(); else targetRow = rowCount(QModelIndex()); this->MoveSelectedPoint(targetRow); return true; } QmitkCorrespondingPointSetsModel::~QmitkCorrespondingPointSetsModel() { ; } void QmitkCorrespondingPointSetsModel::RemoveObservers(){ if (m_PointSetNode) { mitk::PointSet::Pointer oldPointSet = dynamic_cast(m_PointSetNode->GetData()); if (oldPointSet.IsNotNull()) { oldPointSet->RemoveObserver(m_PointSetModifiedObserverTag); } } if (m_ReferencePointSetNode) { mitk::PointSet::Pointer oldPointSet = dynamic_cast(m_ReferencePointSetNode->GetData()); if (oldPointSet.IsNotNull()) { oldPointSet->RemoveObserver(m_ReferencePointSetModifiedObserverTag); } } } void QmitkCorrespondingPointSetsModel::AddObservers() { mitk::PointSet::Pointer pointSet = this->CheckForPointSetInNode(m_PointSetNode); if ( pointSet.IsNotNull()) { // add new observer for modified if necessary itk::ReceptorMemberCommand::Pointer modCommand = itk::ReceptorMemberCommand::New(); modCommand->SetCallbackFunction( this, &QmitkCorrespondingPointSetsModel::OnPointSetChanged ); m_PointSetModifiedObserverTag = pointSet->AddObserver( itk::ModifiedEvent(), modCommand ); } else { m_PointSetModifiedObserverTag = 0; } pointSet = this->CheckForPointSetInNode(m_ReferencePointSetNode); if ( pointSet.IsNotNull()) { // add new observer for modified if necessary itk::ReceptorMemberCommand::Pointer modCommand = itk::ReceptorMemberCommand::New(); modCommand->SetCallbackFunction( this, &QmitkCorrespondingPointSetsModel::OnPointSetChanged ); m_ReferencePointSetModifiedObserverTag = pointSet->AddObserver( itk::ModifiedEvent(), modCommand ); } else { m_ReferencePointSetModifiedObserverTag = 0; } } void QmitkCorrespondingPointSetsModel::OnPointSetChanged(const itk::EventObject&) { - QAbstractTableModel::reset(); + QAbstractTableModel::beginResetModel(); + QAbstractTableModel::endResetModel(); } void QmitkCorrespondingPointSetsModel::SetPointSetNodes( std::vector nodes ) { this->RemoveObservers(); if ( nodes.size() > 1 ) { m_PointSetNode = nodes.front(); m_ReferencePointSetNode = nodes.back(); } else if ( nodes.size() == 1 ) { m_PointSetNode = nodes.front(); m_ReferencePointSetNode = NULL; } else { m_PointSetNode = NULL; m_ReferencePointSetNode = NULL; } this->AddObservers(); - QAbstractTableModel::reset(); + QAbstractTableModel::beginResetModel(); + QAbstractTableModel::endResetModel(); } void QmitkCorrespondingPointSetsModel::SetTimeStep(int t) { if (!m_TimeStepper) return; m_TimeStepper->SetPos(t); - QAbstractTableModel::reset(); + QAbstractTableModel::beginResetModel(); + QAbstractTableModel::endResetModel(); } int QmitkCorrespondingPointSetsModel::GetTimeStep() const { if (!m_TimeStepper) return 0; return m_TimeStepper->GetPos(); } int QmitkCorrespondingPointSetsModel::rowCount(const QModelIndex&) const { if (!m_TimeStepper) return 0; mitk::PointSet::Pointer pointSet = this->CheckForPointSetInNode(m_PointSetNode); mitk::PointSet::Pointer referencePointSet = this->CheckForPointSetInNode(m_ReferencePointSetNode); int sizePS = 0; int sizeRPS = 0; if ( pointSet.IsNotNull() ) { sizePS = pointSet->GetSize(m_TimeStepper->GetPos()); } if ( referencePointSet.IsNotNull() ) { sizeRPS = referencePointSet->GetSize(m_TimeStepper->GetPos()); } if ( sizePS > sizeRPS ) return sizePS; return sizeRPS; } int QmitkCorrespondingPointSetsModel::columnCount(const QModelIndex&) const { return 2; } QVariant QmitkCorrespondingPointSetsModel::data(const QModelIndex& index, int role) const { mitk::PointSet::Pointer pointSet = NULL; if ( index.column() == 0 ) pointSet = this->CheckForPointSetInNode(m_PointSetNode); else if ( index.column() == 1 ) pointSet = this->CheckForPointSetInNode(m_ReferencePointSetNode); if ( pointSet.IsNull() ) { return QVariant(); } if ( !index.isValid() ) { return QVariant(); } if ( index.row() >= pointSet->GetSize(m_TimeStepper->GetPos()) ) { return QVariant(); } if (role == Qt::DisplayRole) { int id; mitk::PointSet::PointType p; bool pointFound = this->GetPointForModelIndex(index, p, id); if (pointFound == false) return QVariant(); QString s = ""; bool firstProp = true; if (this->QTPropIdsEnabled()) { s.append(QString("%0").arg( id, 3)); firstProp = false; } if (this->QTPropCoordinatesEnabled()) { if(!firstProp) s.append(QString(": ")); s.append(QString("(%0, %1, %2)") .arg( p[0], 0, 'f', 2 ) .arg( p[1], 0, 'f', 2 ) .arg( p[2], 0, 'f', 2 )); } return QVariant(s); } else { return QVariant(); } } QVariant QmitkCorrespondingPointSetsModel::headerData(int section, Qt::Orientation orientation, int role) const { if (role != Qt::DisplayRole) { return QVariant(); } if (orientation == Qt::Horizontal) { if (section == 0) { if ( m_PointSetNode ) return QString::fromStdString(this->m_PointSetNode->GetName()); } else if (section == 1) { if ( m_ReferencePointSetNode ) return QString::fromStdString(this->m_ReferencePointSetNode->GetName()); } return QString(); } return QString("%1").arg(section); } bool QmitkCorrespondingPointSetsModel::GetPointForModelIndex(const QModelIndex &index, mitk::PointSet::PointType& p, int& id) const { if (!m_TimeStepper) return false; mitk::PointSet::Pointer pointSet = NULL; if ( index.column() == 0 ) pointSet = this->CheckForPointSetInNode(m_PointSetNode); else if ( index.column() == 1 ) pointSet = this->CheckForPointSetInNode(m_ReferencePointSetNode); if (pointSet.IsNull() || !pointSet->GetPointSet(m_TimeStepper->GetPos())) return false; if ((index.row() < 0) || (index.row() >= (int)pointSet->GetPointSet(m_TimeStepper->GetPos())->GetPoints()->Size())) return false; // get the nth. element, if it exists. // we can not use the index directly, because PointSet uses a map container, // where the index is not necessarily the same as the key. // Therefore we have to count the elements mitk::PointSet::PointsContainer::Iterator it = pointSet->GetPointSet(m_TimeStepper->GetPos())->GetPoints()->Begin(); for (int i = 0; i < index.row(); ++i) { ++it; if (it == pointSet->GetPointSet(m_TimeStepper->GetPos())->GetPoints()->End()) return false; } if (it != pointSet->GetPointSet(m_TimeStepper->GetPos())->GetPoints()->End()) // not at the end, { p = it->Value(); id = it->Index(); return true; } return false; } bool QmitkCorrespondingPointSetsModel::GetPointForModelIndex(int row, int column, mitk::PointSet::PointType& p, int& id) const { if (!m_TimeStepper) return false; mitk::PointSet::Pointer pointSet = NULL; if (column == 0 ) pointSet = this->CheckForPointSetInNode(m_PointSetNode); else if ( column == 1 ) pointSet = this->CheckForPointSetInNode(m_ReferencePointSetNode); if (pointSet.IsNull() || !pointSet->GetPointSet(m_TimeStepper->GetPos())) return false; if ((row < 0) || (row >= (int)pointSet->GetPointSet(m_TimeStepper->GetPos())->GetPoints()->Size())) return false; // get the nth. element, if it exists. // we can not use the index directly, because PointSet uses a map container, // where the index is not necessarily the same as the key. // Therefore we have to count the elements mitk::PointSet::PointsContainer::Iterator it = pointSet->GetPointSet(m_TimeStepper->GetPos())->GetPoints()->Begin(); for (int i = 0; i < row; ++i) { ++it; if (it == pointSet->GetPointSet(m_TimeStepper->GetPos())->GetPoints()->End()) return false; } if (it != pointSet->GetPointSet(m_TimeStepper->GetPos())->GetPoints()->End()) // not at the end, { p = it->Value(); id = it->Index(); return true; } return false; } bool QmitkCorrespondingPointSetsModel::GetModelIndexForPointID(int id, QModelIndex& index, int column) const { if (!m_TimeStepper) return false; mitk::PointSet::Pointer pointSet = NULL; if (column == 0) pointSet = this->CheckForPointSetInNode(m_PointSetNode); else if (column == 1) pointSet = this->CheckForPointSetInNode(m_ReferencePointSetNode); if (!pointSet.IsNull() || !pointSet->GetPointSet(m_TimeStepper->GetPos())) { mitk::PointSet::PointsContainer::Pointer points = pointSet->GetPointSet(m_TimeStepper->GetPos())->GetPoints(); if (!points->IndexExists(id)) return false; unsigned int idx = 0; for (mitk::PointSet::PointsContainer::Iterator it = points->Begin(); it != points->End(); ++it) { if (static_cast(it->Index()) == id) // we found the correct element { index = this->index(idx, column); return true; } idx++; } } return false; // nothing found } bool QmitkCorrespondingPointSetsModel::GetModelIndexForSelectedPoint(QModelIndex& index) const { if (!m_TimeStepper) return false; mitk::DataNode* dataNode = NULL; if (this->m_SelectedPointSetIndex == 0) dataNode = this->m_PointSetNode; else if (this->m_SelectedPointSetIndex == 1) dataNode = this->m_ReferencePointSetNode; mitk::PointSet::Pointer pointSet = this->CheckForPointSetInNode(dataNode); if (pointSet.IsNull()) return false; return this->GetModelIndexForPointID( pointSet->SearchSelectedPoint(m_TimeStepper->GetPos()), index, this->m_SelectedPointSetIndex); } void QmitkCorrespondingPointSetsModel::MoveSelectedPointUp() { if (!m_TimeStepper) return; mitk::DataNode* dataNode = NULL; if (this->m_SelectedPointSetIndex == 0) dataNode = this->m_PointSetNode; else if (this->m_SelectedPointSetIndex == 1) dataNode = this->m_ReferencePointSetNode; mitk::PointSet::Pointer pointSet = this->CheckForPointSetInNode(dataNode); if (pointSet.IsNull()) return; int selectedID = pointSet->SearchSelectedPoint(m_TimeStepper->GetPos()); if (selectedID == -1) return; mitk::ScalarType tsInMS = pointSet->GetTimeGeometry()->TimeStepToTimePoint(m_TimeStepper->GetPos()); mitk::PointOperation* doOp = new mitk::PointOperation(mitk::OpMOVEPOINTUP,tsInMS, pointSet->GetPoint(selectedID, m_TimeStepper->GetPos()), selectedID, true); pointSet->ExecuteOperation(doOp); - QAbstractTableModel::reset(); + QAbstractTableModel::beginResetModel(); + QAbstractTableModel::endResetModel(); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); emit SignalPointSetChanged(); } void QmitkCorrespondingPointSetsModel::MoveSelectedPointDown() { if (!m_TimeStepper) return; mitk::DataNode* dataNode = NULL; if (this->m_SelectedPointSetIndex == 0) dataNode = this->m_PointSetNode; else if (this->m_SelectedPointSetIndex == 1) dataNode = this->m_ReferencePointSetNode; mitk::PointSet::Pointer pointSet = this->CheckForPointSetInNode(dataNode); if (pointSet.IsNull()) return; int selectedID = pointSet->SearchSelectedPoint(m_TimeStepper->GetPos()); if (selectedID == -1) return; mitk::ScalarType tsInMS = pointSet->GetTimeGeometry()->TimeStepToTimePoint(m_TimeStepper->GetPos()); mitk::PointOperation* doOp = new mitk::PointOperation(mitk::OpMOVEPOINTDOWN, tsInMS, pointSet->GetPoint(selectedID, m_TimeStepper->GetPos()), selectedID, true); pointSet->ExecuteOperation(doOp); - QAbstractTableModel::reset(); + QAbstractTableModel::beginResetModel(); + QAbstractTableModel::endResetModel(); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); emit SignalPointSetChanged(); } int QmitkCorrespondingPointSetsModel::SearchSelectedPoint() { if (!m_TimeStepper) return -1; mitk::DataNode* dataNode = NULL; if (this->m_SelectedPointSetIndex == 0) dataNode = this->m_PointSetNode; else if (this->m_SelectedPointSetIndex == 1) dataNode = this->m_ReferencePointSetNode; mitk::PointSet::Pointer pointSet = this->CheckForPointSetInNode(dataNode); if (pointSet.IsNull()) return -1; return pointSet->SearchSelectedPoint(m_TimeStepper->GetPos()); } void QmitkCorrespondingPointSetsModel::RemoveSelectedPoint() { if (!m_TimeStepper) return; mitk::DataNode* dataNode = NULL; if (this->m_SelectedPointSetIndex == 0){ dataNode = this->m_PointSetNode; } else if (this->m_SelectedPointSetIndex == 1){ dataNode = this->m_ReferencePointSetNode; } if (dataNode == NULL) return; //send a DEL event to pointsetinteractor const mitk::Event* delEvent = new mitk::Event(this->m_MultiWidget->GetRenderWindow1()->GetRenderer(), mitk::Type_KeyPress, mitk::BS_NoButton, mitk::BS_NoButton, mitk::Key_Delete); mitk::StateEvent* delStateEvent = new mitk::StateEvent(mitk::EIDDELETE, delEvent); m_Interactor->HandleEvent(delStateEvent); delete delEvent; delete delStateEvent; - QAbstractTableModel::reset(); + QAbstractTableModel::beginResetModel(); + QAbstractTableModel::endResetModel(); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); emit SignalPointSetChanged(); } void QmitkCorrespondingPointSetsModel::MoveSelectedPoint(int targetID) { if (!m_TimeStepper) return; mitk::DataNode* dataNode = NULL; if (this->m_SelectedPointSetIndex == 0) dataNode = this->m_PointSetNode; else if (this->m_SelectedPointSetIndex == 1) dataNode = this->m_ReferencePointSetNode; if (dataNode == NULL) return; mitk::PointSet::Pointer pointSet = this->CheckForPointSetInNode(dataNode); if (pointSet.IsNull()) return; int selectedID = pointSet->SearchSelectedPoint(m_TimeStepper->GetPos()); if (targetID >= pointSet->GetSize()) targetID = pointSet->GetSize()-1; mitk::PointSet::PointsContainer::Iterator it = pointSet->GetPointSet(m_TimeStepper->GetPos())->GetPoints()->Begin(); for (int i=0; iIndex(); if (selectedID < 0 || targetID < 0) return; int direction = mitk::OpNOTHING; if (selectedID > targetID) direction = mitk::OpMOVEPOINTUP; else if (selectedID < targetID) direction = mitk::OpMOVEPOINTDOWN; while (selectedID != targetID){ mitk::ScalarType tsInMS = pointSet->GetTimeGeometry()->TimeStepToTimePoint(m_TimeStepper->GetPos()); mitk::PointOperation* doOp = new mitk::PointOperation(direction, tsInMS, pointSet->GetPoint(selectedID, m_TimeStepper->GetPos()), selectedID, true); pointSet->ExecuteOperation(doOp); selectedID = pointSet->SearchSelectedPoint(m_TimeStepper->GetPos()); } - QAbstractTableModel::reset(); + QAbstractTableModel::beginResetModel(); + QAbstractTableModel::endResetModel(); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); emit SignalPointSetChanged(); } mitk::PointSet* QmitkCorrespondingPointSetsModel::CheckForPointSetInNode(mitk::DataNode* node) const { if (node != NULL) { mitk::PointSet::Pointer pointSet = dynamic_cast(node->GetData()); if (pointSet.IsNotNull()) return pointSet; } return NULL; } bool QmitkCorrespondingPointSetsModel::QTPropCoordinatesEnabled() const { return this->QTPropShowCoordinates; } void QmitkCorrespondingPointSetsModel::QTPropSetCoordinatesEnabled(bool showCoordinates) { this->QTPropShowCoordinates = showCoordinates; } bool QmitkCorrespondingPointSetsModel::QTPropIdsEnabled() const { return this->QTPropShowIds; } void QmitkCorrespondingPointSetsModel::QTPropSetIdsEnabled(bool showIds) { this->QTPropShowIds = showIds; } std::vector QmitkCorrespondingPointSetsModel::GetPointSetNodes(){ std::vector pointSetNodes; if ( this->m_PointSetNode ) pointSetNodes.push_back(this->m_PointSetNode); if ( this->m_ReferencePointSetNode ) pointSetNodes.push_back(this->m_ReferencePointSetNode); return pointSetNodes; } void QmitkCorrespondingPointSetsModel::SetSelectedPointSetIndex(int index) { if (index<-1 || index>1) return; this->m_SelectedPointSetIndex = index; } void QmitkCorrespondingPointSetsModel::ClearSelectedPointSet() { mitk::DataNode* dataNode = NULL; if (this->m_SelectedPointSetIndex == 0) dataNode = this->m_PointSetNode; else if (this->m_SelectedPointSetIndex == 1) dataNode = this->m_ReferencePointSetNode; if (dataNode == NULL) return; mitk::PointSet* pointSet = dynamic_cast(dataNode->GetData()); mitk::PointSet::PointsContainer::Iterator it; if (this->m_TimeStepper->GetRangeMax()==-1) { while( !pointSet->IsEmptyTimeStep(0) ) { if (pointSet->GetPointSet(0)) { it = pointSet->GetPointSet(0)->GetPoints()->Begin(); pointSet->SetSelectInfo(it->Index(),true, 0); this->RemoveSelectedPoint(); } else { break; } } } else { int oldTimeStep = this->m_TimeStepper->GetPos(); for (int i=0; im_TimeStepper->GetRangeMax(); i++) { this->m_TimeStepper->SetPos(i); while( !pointSet->IsEmptyTimeStep(i) ) { if (pointSet->GetPointSet(i)) { it = pointSet->GetPointSet(i)->GetPoints()->Begin(); pointSet->SetSelectInfo(it->Index(),true, i); this->RemoveSelectedPoint(); } } } this->m_TimeStepper->SetPos(oldTimeStep); } - QAbstractTableModel::reset(); + QAbstractTableModel::beginResetModel(); + QAbstractTableModel::endResetModel(); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); emit SignalPointSetChanged(); } void QmitkCorrespondingPointSetsModel::ClearCurrentTimeStep() { if (!m_TimeStepper) return; mitk::DataNode* dataNode = NULL; if (this->m_SelectedPointSetIndex == 0) dataNode = this->m_PointSetNode; else if (this->m_SelectedPointSetIndex == 1) dataNode = this->m_ReferencePointSetNode; if (dataNode == NULL) return; mitk::PointSet* pointSet = dynamic_cast(dataNode->GetData()); mitk::PointSet::PointsContainer::Iterator it; while( !pointSet->IsEmptyTimeStep(m_TimeStepper->GetPos()) ) { it = pointSet->GetPointSet(m_TimeStepper->GetPos())->GetPoints()->Begin(); pointSet->SetSelectInfo(it->Index(),true, m_TimeStepper->GetPos()); this->RemoveSelectedPoint(); } - QAbstractTableModel::reset(); + QAbstractTableModel::beginResetModel(); + QAbstractTableModel::endResetModel(); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); emit SignalPointSetChanged(); } mitk::Stepper::Pointer QmitkCorrespondingPointSetsModel::GetStepper() { return this->m_TimeStepper; } void QmitkCorrespondingPointSetsModel::SetStepper(mitk::Stepper::Pointer stepper) { this->m_TimeStepper = stepper; } int QmitkCorrespondingPointSetsModel::GetSelectedPointSetIndex() { return this->m_SelectedPointSetIndex; } void QmitkCorrespondingPointSetsModel::UpdateSelection(mitk::DataNode* selectedNode) { this->RemoveInteractor(); if(!selectedNode) return; m_Interactor = dynamic_cast(selectedNode->GetInteractor()); if (m_Interactor.IsNull())//if not present, instanciate one m_Interactor = mitk::PointSetInteractor::New("pointsetinteractor", selectedNode); //add it to global interaction to activate it mitk::GlobalInteraction::GetInstance()->AddInteractor( m_Interactor ); } void QmitkCorrespondingPointSetsModel::RemoveInteractor() { if (m_Interactor){ mitk::GlobalInteraction::GetInstance()->RemoveInteractor( m_Interactor ); m_Interactor = NULL; } } QmitkStdMultiWidget* QmitkCorrespondingPointSetsModel::GetMultiWidget() { return this->m_MultiWidget; } void QmitkCorrespondingPointSetsModel::SetMultiWidget( QmitkStdMultiWidget* multiWidget ) { this->m_MultiWidget = multiWidget; this->m_TimeStepper = m_MultiWidget->GetTimeNavigationController()->GetTime(); } diff --git a/Modules/QtWidgetsExt/QmitkFloatingPointSpanSlider.cpp b/Modules/QtWidgetsExt/QmitkFloatingPointSpanSlider.cpp deleted file mode 100644 index 9aac03cc38..0000000000 --- a/Modules/QtWidgetsExt/QmitkFloatingPointSpanSlider.cpp +++ /dev/null @@ -1,245 +0,0 @@ -/*=================================================================== - -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 "QmitkFloatingPointSpanSlider.h" -#include - -QmitkFloatingPointSpanSlider::QmitkFloatingPointSpanSlider(QWidget *parent) - : QxtSpanSlider(parent), m_LowerValue(0), m_UpperValue(1000), - m_Minimum(0), m_Maximum(1000), offset(0.0), factor(1.0), m_IntMode(false) -{ - this->QxtSpanSlider::setMinimum(0); - this->QxtSpanSlider::setMaximum(1000); - - connect(this, SIGNAL(spanChanged(int,int)), this, SLOT(IntSpanChanged(int,int))); -} - -void QmitkFloatingPointSpanSlider::setIntegerMode(bool intMode) -{ - m_IntMode = intMode; - this->QxtSpanSlider::setMinimum(m_Minimum); - this->QxtSpanSlider::setMaximum(m_Maximum); -} - -double QmitkFloatingPointSpanSlider::lowerValue() const -{ - if (m_IntMode) return this->QxtSpanSlider::lowerValue(); - return m_LowerValue; -} - -double QmitkFloatingPointSpanSlider::upperValue() const -{ - if (m_IntMode) return this->QxtSpanSlider::upperValue(); - return m_UpperValue; -} - -void QmitkFloatingPointSpanSlider::setLowerValue(double lower) -{ - m_LowerValue = lower; - if (m_IntMode) - { - this->QxtSpanSlider::setLowerValue(lower); - } - else - { - this->QxtSpanSlider::setLowerValue(scaleValue(lower)); - emit lowerValueChanged(lower); - } -} - -void QmitkFloatingPointSpanSlider::setUpperValue(double upper) -{ - m_UpperValue = upper; - if (m_IntMode) - { - this->QxtSpanSlider::setUpperValue(upper); - } - else - { - this->QxtSpanSlider::setUpperValue(scaleValue(upper)); - emit upperValueChanged(upper); - } -} - -void QmitkFloatingPointSpanSlider::setSpan(double lower, double upper) -{ - m_LowerValue = lower; - m_UpperValue = upper; - if (m_IntMode) - { - this->QxtSpanSlider::setLowerValue(lower); - this->QxtSpanSlider::setUpperValue(upper); - } - else - { - this->QxtSpanSlider::setLowerValue(scaleValue(lower)); - this->QxtSpanSlider::setUpperValue(scaleValue(upper)); - emit spanChanged(lower, upper); - } -} - -double QmitkFloatingPointSpanSlider::maximum() const -{ - if (m_IntMode) return this->QxtSpanSlider::maximum(); - return m_Maximum; -} - -double QmitkFloatingPointSpanSlider::minimum() const -{ - if (m_IntMode) return this->QxtSpanSlider::minimum(); - return m_Minimum; -} - -void QmitkFloatingPointSpanSlider::setMaximum(double max) -{ - if (m_IntMode) - { - this->QxtSpanSlider::setMaximum(max); - return; - } - - if (max < m_Minimum) - { - m_Minimum = max; - } - m_Maximum = max; - scaleSliderToInt(); - - if (m_LowerValue > m_Maximum) - { - m_LowerValue = m_Maximum; - this->QxtSpanSlider::setLowerValue(scaleValue(m_LowerValue)); - } - if (m_UpperValue > m_Maximum) - { - m_UpperValue = m_Maximum; - this->QxtSpanSlider::setUpperValue(scaleValue(m_UpperValue)); - } -} - -void QmitkFloatingPointSpanSlider::setMinimum(double min) -{ - if (m_IntMode) - { - this->QxtSpanSlider::setMinimum(min); - return; - } - - if (min > m_Maximum) - { - m_Maximum = min; - } - m_Minimum = min; - scaleSliderToInt(); - - if (m_LowerValue < m_Minimum) - { - m_LowerValue = m_Minimum; - this->QxtSpanSlider::setLowerValue(scaleValue(m_LowerValue)); - } - if (m_UpperValue < m_Minimum) - { - m_UpperValue = m_Minimum; - this->QxtSpanSlider::setUpperValue(scaleValue(m_UpperValue)); - } -} - -void QmitkFloatingPointSpanSlider::setRange(double min, double max) -{ - if (m_IntMode) - { - this->QxtSpanSlider::setRange(min, max); - m_Minimum = minimum(); - m_Maximum = maximum(); - m_LowerValue = lowerValue(); - m_UpperValue = upperValue(); - return; - } - - if (min > max) - { - min = max; - } - m_Minimum = min; - m_Maximum = max; - - if (m_LowerValue > m_Maximum) - { - m_LowerValue = m_Maximum; - this->QxtSpanSlider::setLowerValue(scaleValue(m_LowerValue)); - } - else if (m_LowerValue < m_Minimum) - { - m_LowerValue = m_Minimum; - this->QxtSpanSlider::setLowerValue(scaleValue(m_LowerValue)); - } - - if (m_UpperValue > m_Maximum) - { - m_UpperValue = m_Maximum; - this->QxtSpanSlider::setUpperValue(scaleValue(m_UpperValue)); - } - else if (m_UpperValue < m_Minimum) - { - m_UpperValue = m_Minimum; - this->QxtSpanSlider::setUpperValue(scaleValue(m_UpperValue)); - } - - scaleSliderToInt(); -} - -void QmitkFloatingPointSpanSlider::IntSpanChanged(int lower, int upper) -{ - if (m_IntMode) - { - m_LowerValue = lower; - m_UpperValue = upper; - } - else - { - m_LowerValue = unscaleValue(lower); - m_UpperValue = unscaleValue(upper); - } - - emit spanChanged(m_LowerValue, m_UpperValue); -} - -void QmitkFloatingPointSpanSlider::scaleSliderToInt() -{ - int tmpLower = unscaleValue(m_LowerValue); - int tmpUpper = unscaleValue(m_UpperValue); - - double range = m_Maximum - m_Minimum; - factor = range ? 1000.0 / range : 0; - offset = -m_Minimum; - - m_LowerValue = scaleValue(tmpLower); - m_UpperValue = scaleValue(tmpUpper); -} - -int QmitkFloatingPointSpanSlider::scaleValue(double val) -{ - int scaled = factor ? (offset + val)*factor : 0; - return scaled; -} - -double QmitkFloatingPointSpanSlider::unscaleValue(int val) -{ - double unscaled = factor ? static_cast(val)/factor - offset : 0; - return unscaled; -} - diff --git a/Modules/QtWidgetsExt/QmitkFloatingPointSpanSlider.h b/Modules/QtWidgetsExt/QmitkFloatingPointSpanSlider.h deleted file mode 100644 index c97de011a8..0000000000 --- a/Modules/QtWidgetsExt/QmitkFloatingPointSpanSlider.h +++ /dev/null @@ -1,87 +0,0 @@ -/*=================================================================== - -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 QMITKFLOATINGPOINTSPANSLIDER_H -#define QMITKFLOATINGPOINTSPANSLIDER_H - -#include - -#include -#include - -class MitkQtWidgetsExt_EXPORT QmitkFloatingPointSpanSlider : public QxtSpanSlider -{ - Q_OBJECT - Q_PROPERTY(double loweralue READ lowerValue WRITE setLowerValue - NOTIFY lowerValueChanged) - Q_PROPERTY(double upperValue READ upperValue WRITE setUpperValue - NOTIFY upperValueChanged) - Q_PROPERTY(double maximum READ maximum WRITE setMaximum) - Q_PROPERTY(double minimum READ minimum WRITE setMinimum) - -public: - - QmitkFloatingPointSpanSlider(QWidget *parent = 0); - - void setIntegerMode(bool intMode); - - double lowerValue() const; - double upperValue() const; - - double maximum() const; - double minimum() const; - - void setMaximum(double max); - void setMinimum(double min); - void setRange(double min, double max); - -signals: - - void lowerValueChanged(double lower); - void upperValueChanged(double upper); - void spanChanged(double lower, double upper); - -public slots: - - void setLowerValue(double lower); - void setUpperValue(double upper); - void setSpan(double lower, double upper); - -private slots: - - void IntSpanChanged(int lower, int upper); - -private: - - void scaleSliderToInt(); - inline int scaleValue(double val); - inline double unscaleValue(int val); - - double m_LowerValue; - double m_UpperValue; - - double m_Minimum; - double m_Maximum; - - double offset; - double factor; - - bool m_IntMode; -}; - -#endif - diff --git a/Modules/QtWidgetsExt/QmitkGnuplotWidget.cpp b/Modules/QtWidgetsExt/QmitkGnuplotWidget.cpp index b12ae3e7eb..d134224f01 100644 --- a/Modules/QtWidgetsExt/QmitkGnuplotWidget.cpp +++ b/Modules/QtWidgetsExt/QmitkGnuplotWidget.cpp @@ -1,221 +1,221 @@ /*=================================================================== 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 #include #include #include #include "QmitkGnuplotWidget.h" QmitkGnuplotWidget::QmitkGnuplotWidget(QWidget* parent) : QWidget(parent), m_Ui(new Ui::QmitkGnuplotWidget), m_ContextMenu(NULL), m_CopyPlotAction(NULL), m_CopyScriptAction(NULL), m_Process(new QProcess(this)) { m_Ui->setupUi(this); connect(m_Process, SIGNAL(stateChanged(QProcess::ProcessState)), this, SLOT(OnProcessStateChanged(QProcess::ProcessState))); connect(m_Process, SIGNAL(error(QProcess::ProcessError)), this, SLOT(OnProcessError(QProcess::ProcessError))); connect(m_Process, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(OnProcessFinished(int, QProcess::ExitStatus))); this->CreateContextMenu(); } QmitkGnuplotWidget::~QmitkGnuplotWidget() { } void QmitkGnuplotWidget::CreateContextMenu() { m_CopyPlotAction = new QAction("Copy &Plot", this); connect(m_CopyPlotAction, SIGNAL(triggered()), this, SLOT(OnCopyPlot())); m_CopyScriptAction = new QAction("Copy &Script", this); connect(m_CopyScriptAction, SIGNAL(triggered()), this, SLOT(OnCopyScript())); m_ContextMenu = new QMenu(this); m_ContextMenu->addActions(QList() << m_CopyPlotAction << m_CopyScriptAction); } void QmitkGnuplotWidget::contextMenuEvent(QContextMenuEvent* event) { const QPixmap* plot = m_Ui->label->pixmap(); m_CopyPlotAction->setEnabled(plot != NULL && !plot->isNull()); m_CopyScriptAction->setEnabled(!m_Commands.empty()); m_ContextMenu->popup(event->globalPos()); event->accept(); } void QmitkGnuplotWidget::OnCopyPlot() { const QPixmap* plot = m_Ui->label->pixmap(); if (plot != NULL && !plot->isNull()) QApplication::clipboard()->setPixmap(*plot); } void QmitkGnuplotWidget::OnCopyScript() { if (m_Commands.empty()) return; QString script = this->CreateSetTermCommand(); Q_FOREACH(const QString& command, m_Commands) { script += command + "\n"; } QApplication::clipboard()->setText(script); } void QmitkGnuplotWidget::resizeEvent(QResizeEvent*) { m_ModifiedTime.Modified(); if (m_Process->isOpen() || m_Commands.isEmpty() || m_GnuplotPath.isEmpty()) return; this->Update(); } QString QmitkGnuplotWidget::GetGnuplotPath() const { return m_GnuplotPath; } void QmitkGnuplotWidget::SetGnuplotPath(const QString &path) { m_GnuplotPath = path; m_ModifiedTime.Modified(); } QStringList QmitkGnuplotWidget::GetCommands() const { return m_Commands; } void QmitkGnuplotWidget::SetCommands(const QStringList& commands) { m_Commands = commands; m_ModifiedTime.Modified(); } void QmitkGnuplotWidget::Update() { if (m_UpdateTime < m_ModifiedTime) m_Process->start(m_GnuplotPath, QStringList() << "-"); } QSize QmitkGnuplotWidget::sizeHint() const { return QSize(400, 300); } QString QmitkGnuplotWidget::CreateSetTermCommand() const { return QString("set term pngcairo size %1,%2 enhanced font '%3,%4'\n") .arg(this->width()) .arg(this->height()) .arg(this->font().family()) .arg(this->font().pointSize()); } void QmitkGnuplotWidget::OnProcessStateChanged(QProcess::ProcessState state) { if (state == QProcess::Running) { m_UpdateTime = m_ModifiedTime; - m_Process->write(this->CreateSetTermCommand().toAscii()); + m_Process->write(this->CreateSetTermCommand().toLatin1()); Q_FOREACH(const QString& command, m_Commands) { - m_Process->write(QString("%1\n").arg(command).toAscii()); + m_Process->write(QString("%1\n").arg(command).toLatin1()); } m_Process->write("exit\n"); m_Process->closeWriteChannel(); } } void QmitkGnuplotWidget::OnProcessError(QProcess::ProcessError error) { switch (error) { case QProcess::FailedToStart: m_Ui->label->setText("Gnuplot failed to start!"); break; case QProcess::Crashed: m_Ui->label->setText("Gnuplot crashed!"); break; case QProcess::Timedout: m_Ui->label->setText("Gnuplot timed out!"); break; case QProcess::WriteError: m_Ui->label->setText("Could not write to gnuplot!"); break; case QProcess::ReadError: m_Ui->label->setText("Could not read from gnuplot!"); break; default: m_Ui->label->setText("An unknown error occurred!"); break; } } void QmitkGnuplotWidget::OnProcessFinished(int exitCode, QProcess::ExitStatus exitStatus) { bool needUpdate = false; if (exitStatus != QProcess::CrashExit) { if (exitCode == 0) { if (m_UpdateTime < m_ModifiedTime) { needUpdate = true; } else { m_Ui->label->setPixmap(QPixmap::fromImage(QImage::fromData(m_Process->readAllStandardOutput(), "PNG"))); } } else { m_Ui->label->setText(QString("Gnuplot exit code: %1!").arg(exitCode)); } } m_Process->close(); if (needUpdate) this->Update(); } diff --git a/Modules/QtWidgetsExt/QmitkHistogramJSWidget.cpp b/Modules/QtWidgetsExt/QmitkHistogramJSWidget.cpp index 453cce79dd..76f0ccd1a9 100644 --- a/Modules/QtWidgetsExt/QmitkHistogramJSWidget.cpp +++ b/Modules/QtWidgetsExt/QmitkHistogramJSWidget.cpp @@ -1,239 +1,240 @@ /*=================================================================== 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 "QmitkHistogramJSWidget.h" #include "mitkPixelTypeMultiplex.h" #include #include #include "mitkRenderingManager.h" #include "mitkBaseRenderer.h" #include "mitkImageTimeSelector.h" #include "mitkExtractSliceFilter.h" +#include QmitkHistogramJSWidget::QmitkHistogramJSWidget(QWidget *parent) : QWebView(parent) { // set histogram type to barchart in first instance m_UseLineGraph = false; m_Page = new QmitkJSWebPage(this); setPage(m_Page); // set html from source connect(page()->mainFrame(), SIGNAL(javaScriptWindowObjectCleared()), this, SLOT(AddJSObject())); QUrl myUrl = QUrl("qrc:///QtWidgetsExt/Histogram.html"); setUrl(myUrl); // set Scrollbars to be always disabled page()->mainFrame()->setScrollBarPolicy(Qt::Horizontal, Qt::ScrollBarAlwaysOff); page()->mainFrame()->setScrollBarPolicy(Qt::Vertical, Qt::ScrollBarAlwaysOff); m_ParametricPath = ParametricPathType::New(); } QmitkHistogramJSWidget::~QmitkHistogramJSWidget() { } // adds an Object of Type QmitkHistogramJSWidget to the JavaScript, using QtWebkitBridge void QmitkHistogramJSWidget::AddJSObject() { page()->mainFrame()->addToJavaScriptWindowObject(QString("histogramData"), this); } // reloads WebView, everytime its size has been changed, so the size of the Histogram fits to the size of the widget void QmitkHistogramJSWidget::resizeEvent(QResizeEvent* resizeEvent) { QWebView::resizeEvent(resizeEvent); // workaround for Qt Bug: https://bugs.webkit.org/show_bug.cgi?id=75984 page()->mainFrame()->evaluateJavaScript("disconnectSignals()"); this->reload(); } // method to expose data to JavaScript by using properties void QmitkHistogramJSWidget::ComputeHistogram(HistogramType* histogram) { m_Histogram = histogram; HistogramConstIteratorType startIt = m_Histogram->End(); HistogramConstIteratorType endIt = m_Histogram->End(); HistogramConstIteratorType it = m_Histogram->Begin(); ClearData(); unsigned int i = 0; bool firstValue = false; // removes frequencies of 0, which are outside the first and last bin for (; it != m_Histogram->End(); ++it) { if (it.GetFrequency() > 0.0) { endIt = it; if (!firstValue) { firstValue = true; startIt = it; } } } ++endIt; // generating Lists of measurement and frequencies for (it = startIt ; it != endIt; ++it, ++i) { QVariant frequency = QVariant::fromValue(it.GetFrequency()); QVariant measurement = it.GetMeasurementVector()[0]; m_Frequency.insert(i, frequency); m_Measurement.insert(i, measurement); } m_IntensityProfile = false; this->SignalDataChanged(); } void QmitkHistogramJSWidget::ClearData() { m_Frequency.clear(); m_Measurement.clear(); } void QmitkHistogramJSWidget::ClearHistogram() { this->ClearData(); this->SignalDataChanged(); } QList QmitkHistogramJSWidget::GetFrequency() { return m_Frequency; } QList QmitkHistogramJSWidget::GetMeasurement() { return m_Measurement; } bool QmitkHistogramJSWidget::GetUseLineGraph() { return m_UseLineGraph; } void QmitkHistogramJSWidget::OnBarRadioButtonSelected() { if (m_UseLineGraph) { m_UseLineGraph = false; this->SignalGraphChanged(); } } void QmitkHistogramJSWidget::OnLineRadioButtonSelected() { if (!m_UseLineGraph) { m_UseLineGraph = true; this->SignalGraphChanged(); } } void QmitkHistogramJSWidget::SetImage(mitk::Image* image) { m_Image = image; } void QmitkHistogramJSWidget::SetPlanarFigure(const mitk::PlanarFigure* planarFigure) { m_PlanarFigure = planarFigure; } template void ReadPixel(mitk::PixelType, mitk::Image::Pointer image, itk::Index<3> indexPoint, double& value) { if (image->GetDimension() == 2) { mitk::ImagePixelReadAccessor readAccess(image, image->GetSliceData(0)); itk::Index<2> idx; idx[0] = indexPoint[0]; idx[1] = indexPoint[1]; value = readAccess.GetPixelByIndex(idx); } else if (image->GetDimension() == 3) { mitk::ImagePixelReadAccessor readAccess(image, image->GetVolumeData(0)); itk::Index<3> idx; idx[0] = indexPoint[0]; idx[1] = indexPoint[1]; idx[2] = indexPoint[2]; value = readAccess.GetPixelByIndex(idx); } else { //unhandled } } void QmitkHistogramJSWidget::ComputeIntensityProfile(unsigned int timeStep) { this->ClearData(); m_ParametricPath->Initialize(); if (m_PlanarFigure.IsNull()) { mitkThrow() << "PlanarFigure not set!"; } if (m_Image.IsNull()) { mitkThrow() << "Image not set!"; } mitk::Image::Pointer image; if (m_Image->GetDimension() == 4) { mitk::ImageTimeSelector::Pointer timeSelector = mitk::ImageTimeSelector::New(); timeSelector->SetInput(m_Image); timeSelector->SetTimeNr(timeStep); timeSelector->Update(); image = timeSelector->GetOutput(); } else { image = m_Image; } mitk::IntensityProfile::Pointer intensityProfile = mitk::ComputeIntensityProfile(image, const_cast(m_PlanarFigure.GetPointer())); m_Frequency.clear(); m_Measurement.clear(); int i = -1; mitk::IntensityProfile::ConstIterator end = intensityProfile->End(); for (mitk::IntensityProfile::ConstIterator it = intensityProfile->Begin(); it != end; ++it) { m_Frequency.push_back(it.GetMeasurementVector()[0]); m_Measurement.push_back(++i); } m_IntensityProfile = true; m_UseLineGraph = true; this->SignalDataChanged(); } bool QmitkHistogramJSWidget::GetIntensityProfile() { return m_IntensityProfile; } diff --git a/Modules/QtWidgetsExt/QmitkHistogramJSWidget.h b/Modules/QtWidgetsExt/QmitkHistogramJSWidget.h index b0de9b52f5..b5c1909c44 100644 --- a/Modules/QtWidgetsExt/QmitkHistogramJSWidget.h +++ b/Modules/QtWidgetsExt/QmitkHistogramJSWidget.h @@ -1,278 +1,278 @@ /*=================================================================== 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 QMITKHISTOGRAMJSWIDGET_H #define QMITKHISTOGRAMJSWIDGET_H #include #include -#include +#include #include "MitkQtWidgetsExtExports.h" #include #include "mitkImage.h" #include "mitkPlanarFigure.h" #include #include /** * \brief Widget which shows a histogram using JavaScript. * * This class is a QWebView. It shows the histogram for a selected image * or segmentation. It also can display an intesity profile for * path elements, which lais over an image. */ class MitkQtWidgetsExt_EXPORT QmitkHistogramJSWidget : public QWebView { Q_OBJECT /** * \brief Measurement property. * * This property is used in JavaScript as member of the current object. * It holds a QList, containing the measurements of the current histogram. * @see GetMeasurement() */ Q_PROPERTY(QList measurement READ GetMeasurement) /** * \brief Frequency property. * * This property is used in JavaScript as member of the current object. * It holds a QList, containing the frequencies of the current histogram. * @see GetFrequency() */ Q_PROPERTY(QList frequency READ GetFrequency) /** * \brief Line graph property. * * This property is used in JavaScript as member of the current object. * It holds a boolean, which sais wether to use a line or not. * @see GetUseLineGraph() */ Q_PROPERTY(bool useLineGraph READ GetUseLineGraph) /** * @brief Intesity profile property. * * This property is used in JavaScript as member of the current object. * It holds a boolean, which sais wether to use an intesity profile or not. * @see GetIntensityProfile() */ Q_PROPERTY(bool intensityProfile READ GetIntensityProfile) public: typedef mitk::Image::HistogramType HistogramType; typedef mitk::Image::HistogramType::ConstIterator HistogramConstIteratorType; typedef itk::PolyLineParametricPath< 3 > ParametricPathType; typedef itk::ParametricPath< 3 >::Superclass PathType; typedef mitk::PlanarFigure::PolyLineType VertexContainerType; explicit QmitkHistogramJSWidget(QWidget *parent = 0); ~QmitkHistogramJSWidget(); /** * \brief Event which notifies a change of the widget size. * * Reimplemented from QWebView::resizeEvent(), * reloads the webframe */ void resizeEvent(QResizeEvent* resizeEvent); /** * \brief Calculates the histogram. * * This function removes all frequencies of 0 until the first bin and behind the last bin. * It writes the measurement and frequency, which are given from the HistogramType, into * m_Measurement and m_Frequency. * The SignalDataChanged is called, to update the information, which is displayed in the webframe. */ void ComputeHistogram(HistogramType* histogram); /** * \brief Calculates the intesityprofile. * * If an image and a pathelement are set, this function * calculates an intensity profile for a pathelement which lies over an image. * Sets m_IntensityProfile and m_UseLineGraph to true. * The SignalDataChanged is called, to update the information, which is displayed in the webframe. */ void ComputeIntensityProfile(unsigned int timeStep = 0); /** * \brief Clears the Histogram. * * This function clears the data and calls SignalDataChanged to update * the displayed information in the webframe. */ void ClearHistogram(); /** * \brief Getter for measurement. * * @return List of measurements. */ QList GetMeasurement(); /** * \brief Getter for frequency. * * @return List of frequencies. */ QList GetFrequency(); /** * \brief Getter for uselineGraph. * * @return True if a linegraph should be used. */ bool GetUseLineGraph(); /** * \brief Getter for intensity profile. * * @return True if current histogram is an intesityprofile */ bool GetIntensityProfile(); /** * \brief Setter for reference image. * * @param image The corresponding image for an intensity profile. */ void SetImage(mitk::Image* image); /** * \brief Setter for planarFigure. * * @param planarFigure The pathelement for an intensity profile. */ void SetPlanarFigure(const mitk::PlanarFigure* planarFigure); private: /** * \brief List of frequencies. * * A QList which holds the frequencies of the current histogram * or holds the intesities of current intensity profile. */ QList m_Frequency; /** * \brief List of measurements. * * A QList which holds the measurements of the current histogram * or holds the distances of current intensity profile. */ QList m_Measurement; /** * \brief Reference image. * * Holds the image to calculate an intesity profile. */ mitk::Image::Pointer m_Image; /** * \brief Pathelement. * * Holds a not closed planar figure to calculate an intesity profile. */ mitk::PlanarFigure::ConstPointer m_PlanarFigure; bool m_UseLineGraph; bool m_IntensityProfile; /** * Holds the current histogram */ HistogramType::ConstPointer m_Histogram; /** * Path derived either form user-specified path or from PlanarFigure-generated * path */ PathType::ConstPointer m_DerivedPath; /** * Parametric path as generated from PlanarFigure */ ParametricPathType::Pointer m_ParametricPath; /** * \brief Clears data. * * Clears the QLists m_Measurement and m_Frequency */ void ClearData(); QmitkJSWebPage* m_Page; private slots: /** * \brief Adds an object to JavaScript. * * Adds an object of the widget to JavaScript. * By using this object JavaScript can react to the signals of the widget * and can access the QProperties as members of the object. */ void AddJSObject(); public slots: /** * \brief Slot for radiobutton m_barRadioButton. * * Sets m_UseLineGraph to false. * Calls signal GraphChanged to update the graph in the webframe. */ void OnBarRadioButtonSelected(); /** * \brief Slot for radiobutton m_lineRadioButton. * * Sets m_UseLineGraph to true. * Calls signal GraphChanged to update the graph in the webframe. */ void OnLineRadioButtonSelected(); signals: /** * \brief Signal data has changed. * * It has to be called when the data of the histogram or intesity profile has changed. */ void SignalDataChanged(); /** * \brief Signal graph has changed. * * It has to be called when the graph changed from barchart to linegraph. Vice versa. */ void SignalGraphChanged(); }; #endif diff --git a/Modules/QtWidgetsExt/QmitkModulesDialog.cpp b/Modules/QtWidgetsExt/QmitkModulesDialog.cpp index 3c3f339a3a..2f3f0636ac 100644 --- a/Modules/QtWidgetsExt/QmitkModulesDialog.cpp +++ b/Modules/QtWidgetsExt/QmitkModulesDialog.cpp @@ -1,66 +1,72 @@ /*=================================================================== 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 "QmitkModulesDialog.h" #include #include #include #include #include #include "QmitkModuleTableModel.h" QmitkModulesDialog::QmitkModulesDialog(QWidget *parent, Qt::WindowFlags f) : QDialog(parent, f) { this->setWindowTitle("MITK Modules"); QVBoxLayout* layout = new QVBoxLayout(); this->setLayout(layout); QTableView* tableView = new QTableView(this); QmitkModuleTableModel* tableModel = new QmitkModuleTableModel(tableView); QSortFilterProxyModel* sortProxyModel = new QSortFilterProxyModel(tableView); sortProxyModel->setSourceModel(tableModel); sortProxyModel->setDynamicSortFilter(true); tableView->setModel(sortProxyModel); tableView->verticalHeader()->hide(); tableView->setHorizontalScrollMode(QAbstractItemView::ScrollPerPixel); tableView->setSelectionBehavior(QAbstractItemView::SelectRows); tableView->setSelectionMode(QAbstractItemView::ExtendedSelection); tableView->setTextElideMode(Qt::ElideMiddle); tableView->setSortingEnabled(true); tableView->sortByColumn(0, Qt::AscendingOrder); +#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) tableView->horizontalHeader()->setResizeMode(0, QHeaderView::ResizeToContents); tableView->horizontalHeader()->setResizeMode(2, QHeaderView::ResizeToContents); tableView->horizontalHeader()->setResizeMode(5, QHeaderView::ResizeToContents); +#else + tableView->horizontalHeader()->setSectionResizeMode(0, QHeaderView::ResizeToContents); + tableView->horizontalHeader()->setSectionResizeMode(2, QHeaderView::ResizeToContents); + tableView->horizontalHeader()->setSectionResizeMode(5, QHeaderView::ResizeToContents); +#endif tableView->horizontalHeader()->setStretchLastSection(true); tableView->horizontalHeader()->setCascadingSectionResizes(true); layout->addWidget(tableView); QDialogButtonBox* btnBox = new QDialogButtonBox(QDialogButtonBox::Close); layout->addWidget(btnBox); this->resize(800, 600); connect(btnBox, SIGNAL(rejected()), this, SLOT(reject())); } diff --git a/Modules/QtWidgetsExt/QmitkPointListModel.cpp b/Modules/QtWidgetsExt/QmitkPointListModel.cpp index 7967c7ac2e..94b137cf96 100644 --- a/Modules/QtWidgetsExt/QmitkPointListModel.cpp +++ b/Modules/QtWidgetsExt/QmitkPointListModel.cpp @@ -1,322 +1,326 @@ /*=================================================================== 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 "QmitkPointListModel.h" #include #include "mitkInteractionConst.h" #include "mitkPointOperation.h" #include "mitkRenderingManager.h" #include #include #include #include #include QmitkPointListModel::QmitkPointListModel( mitk::DataNode* pointSetNode, int t, QObject* parent ) :QAbstractListModel(parent), m_PointSetNode(NULL), m_PointSetModifiedObserverTag(0), m_PointSetDeletedObserverTag(0), m_TimeStep(t) { ObserveNewPointSet( pointSetNode ); } Qt::ItemFlags QmitkPointListModel::flags(const QModelIndex& /*index*/) const { // no editing so far, return default (enabled, selectable) return Qt::ItemIsSelectable | Qt::ItemIsEnabled; } QmitkPointListModel::~QmitkPointListModel() { this->ObserveNewPointSet( NULL ); } void QmitkPointListModel::SetPointSetNode( mitk::DataNode* pointSetNode ) { this->ObserveNewPointSet( pointSetNode ); - QAbstractListModel::reset(); + QAbstractListModel::beginResetModel(); + QAbstractListModel::beginResetModel(); emit SignalUpdateSelection(); } mitk::PointSet* QmitkPointListModel::GetPointSet() const { return this->CheckForPointSetInNode(m_PointSetNode); } void QmitkPointListModel::SetTimeStep(int t) { m_TimeStep = t; - QAbstractListModel::reset(); + QAbstractListModel::beginResetModel(); + QAbstractListModel::endResetModel(); emit SignalUpdateSelection(); } int QmitkPointListModel::GetTimeStep() const { return m_TimeStep; } void QmitkPointListModel::ObserveNewPointSet( mitk::DataNode* pointSetNode ) { //remove old observers if (m_PointSetNode != NULL) { try //here sometimes an exception is thrown which leads to a crash. So catch this exception but give an error message. See bug 18316 for details. { mitk::PointSet::Pointer oldPointSet = dynamic_cast(m_PointSetNode->GetData()); if (oldPointSet.IsNotNull()) { oldPointSet->RemoveObserver(m_PointSetModifiedObserverTag); oldPointSet->RemoveObserver(m_PointSetDeletedObserverTag); } } catch(std::exception& e) { MITK_ERROR << "Exception while removing observer from old point set node: " << e.what(); } } //get the new pointset mitk::PointSet::Pointer pointSet = this->CheckForPointSetInNode(pointSetNode); m_PointSetNode = pointSetNode; if ( pointSet.IsNotNull()) { // add new observer for modified if necessary itk::ReceptorMemberCommand::Pointer modCommand = itk::ReceptorMemberCommand::New(); modCommand->SetCallbackFunction( this, &QmitkPointListModel::OnPointSetChanged ); m_PointSetModifiedObserverTag = pointSet->AddObserver( itk::ModifiedEvent(), modCommand ); // add new observer for detele if necessary itk::ReceptorMemberCommand::Pointer delCommand = itk::ReceptorMemberCommand::New(); delCommand->SetCallbackFunction( this, &QmitkPointListModel::OnPointSetDeleted ); m_PointSetDeletedObserverTag = pointSet->AddObserver( itk::DeleteEvent(), delCommand ); } else { m_PointSetModifiedObserverTag = 0; m_PointSetDeletedObserverTag = 0; } } void QmitkPointListModel::OnPointSetChanged(const itk::EventObject&) { - QAbstractListModel::reset(); + QAbstractListModel::beginResetModel(); + QAbstractListModel::endResetModel(); emit SignalUpdateSelection(); } void QmitkPointListModel::OnPointSetDeleted(const itk::EventObject&) { mitk::PointSet::Pointer ps = CheckForPointSetInNode(m_PointSetNode); if (ps) { ps->RemoveObserver(m_PointSetModifiedObserverTag); ps->RemoveObserver(m_PointSetDeletedObserverTag); } m_PointSetModifiedObserverTag = 0; m_PointSetDeletedObserverTag = 0; - QAbstractListModel::reset(); + QAbstractListModel::beginResetModel(); + QAbstractListModel::endResetModel(); } int QmitkPointListModel::rowCount(const QModelIndex&) const { mitk::PointSet::Pointer pointSet = this->CheckForPointSetInNode(m_PointSetNode); if ( pointSet.IsNotNull() ) { return pointSet->GetSize(m_TimeStep); } else { return 0; } } QVariant QmitkPointListModel::data(const QModelIndex& index, int role) const { mitk::PointSet::Pointer pointSet = this->CheckForPointSetInNode(m_PointSetNode); if ( pointSet.IsNull() ) { return QVariant(); } if ( !index.isValid() ) { return QVariant(); } if ( index.row() >= pointSet->GetSize(m_TimeStep) ) { return QVariant(); } if (role == Qt::DisplayRole) { mitk::PointSet::PointsContainer::ElementIdentifier id; mitk::PointSet::PointType p; bool pointFound = this->GetPointForModelIndex(index, p, id); if (pointFound == false) return QVariant(); QString s = QString("%0: (%1, %2, %3)") .arg( id, 3) .arg( p[0], 0, 'f', 3 ) .arg( p[1], 0, 'f', 3 ) .arg( p[2], 0, 'f', 3 ); return QVariant(s); } else { return QVariant(); } } QVariant QmitkPointListModel::headerData(int section, Qt::Orientation orientation, int role) const { if (role != Qt::DisplayRole) { return QVariant(); } if (orientation == Qt::Horizontal) { return QString("Coordinates").arg(section); } else { return QString("Row %1").arg(section); } } bool QmitkPointListModel::GetPointForModelIndex( const QModelIndex &index, mitk::PointSet::PointType& p, mitk::PointSet::PointIdentifier& id) const { mitk::PointSet::Pointer pointSet = this->CheckForPointSetInNode(m_PointSetNode); if (pointSet.IsNull()) return false; if ((index.row() < 0) || (index.row() >= (int)pointSet->GetPointSet(m_TimeStep)->GetPoints()->Size())) return false; // get the nth. element, if it exists. // we can not use the index directly, because PointSet uses a map container, // where the index is not necessarily the same as the key. // Therefore we have to count the elements mitk::PointSet::PointsContainer::Iterator it = pointSet->GetPointSet(m_TimeStep)->GetPoints()->Begin(); for (int i = 0; i < index.row(); ++i) { ++it; if (it == pointSet->GetPointSet(m_TimeStep)->GetPoints()->End()) return false; } if (it != pointSet->GetPointSet(m_TimeStep)->GetPoints()->End()) // not at the end, { p = it->Value(); id = it->Index(); return true; } return false; } bool QmitkPointListModel::GetModelIndexForPointID(mitk::PointSet::PointIdentifier id, QModelIndex& index) const { mitk::PointSet::Pointer pointSet = this->CheckForPointSetInNode(m_PointSetNode); if (pointSet.IsNull()) return false; mitk::PointSet::PointsContainer::Pointer points = pointSet->GetPointSet(m_TimeStep)->GetPoints(); if (points->IndexExists(id) == false) return false; unsigned int idx = 0; for (mitk::PointSet::PointsContainer::Iterator it = points->Begin(); it != points->End(); ++it) { if (it->Index() == id) // we found the correct element { index = this->index(idx); return true; } idx++; } return false; // nothing found } void QmitkPointListModel::MoveSelectedPointUp() { mitk::PointSet::Pointer pointSet = this->CheckForPointSetInNode(m_PointSetNode); if (pointSet.IsNull()) return; mitk::PointSet::PointIdentifier selectedID; selectedID = pointSet->SearchSelectedPoint(m_TimeStep); mitk::ScalarType tsInMS = pointSet->GetTimeGeometry()->TimeStepToTimePoint(m_TimeStep); mitk::PointOperation* doOp = new mitk::PointOperation(mitk::OpMOVEPOINTUP,tsInMS, pointSet->GetPoint(selectedID, m_TimeStep), selectedID, true); pointSet->ExecuteOperation(doOp); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); // Workaround for update problem in Pointset/Mapper } void QmitkPointListModel::MoveSelectedPointDown() { mitk::PointSet::Pointer pointSet = this->CheckForPointSetInNode(m_PointSetNode); if (pointSet.IsNull()) return; mitk::PointSet::PointIdentifier selectedID; selectedID = pointSet->SearchSelectedPoint(m_TimeStep); mitk::ScalarType tsInMS = pointSet->GetTimeGeometry()->TimeStepToTimePoint(m_TimeStep); mitk::PointOperation* doOp = new mitk::PointOperation(mitk::OpMOVEPOINTDOWN, tsInMS, pointSet->GetPoint(selectedID, m_TimeStep), selectedID, true); pointSet->ExecuteOperation(doOp); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); // Workaround for update problem in Pointset/Mapper } void QmitkPointListModel::RemoveSelectedPoint() { mitk::PointSet::Pointer pointSet = this->CheckForPointSetInNode(m_PointSetNode); if (pointSet.IsNull()) return; mitk::PointSet::PointIdentifier selectedID; selectedID = pointSet->SearchSelectedPoint(m_TimeStep); mitk::ScalarType tsInMS = pointSet->GetTimeGeometry()->TimeStepToTimePoint(m_TimeStep); mitk::PointOperation* doOp = new mitk::PointOperation(mitk::OpREMOVE, tsInMS, pointSet->GetPoint(selectedID, m_TimeStep), selectedID, true); pointSet->ExecuteOperation(doOp); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); // Workaround for update problem in Pointset/Mapper } mitk::PointSet* QmitkPointListModel::CheckForPointSetInNode(mitk::DataNode* node) const { if (node != NULL) { mitk::PointSet::Pointer pointSet = dynamic_cast(node->GetData()); if (pointSet.IsNotNull()) return pointSet; } return NULL; } diff --git a/Modules/QtWidgetsExt/QmitkPropertyObservers/QmitkColorPropertyEditor.cpp b/Modules/QtWidgetsExt/QmitkPropertyObservers/QmitkColorPropertyEditor.cpp index 27da658354..be6a02cfe5 100644 --- a/Modules/QtWidgetsExt/QmitkPropertyObservers/QmitkColorPropertyEditor.cpp +++ b/Modules/QtWidgetsExt/QmitkPropertyObservers/QmitkColorPropertyEditor.cpp @@ -1,296 +1,296 @@ /*=================================================================== 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 "QmitkColorPropertyEditor.h" #include #include #include #include #include #include #include //----- QmitkPopupColorChooser --------------------------------------------------------- QmitkPopupColorChooser::QmitkPopupColorChooser(QWidget* parent, unsigned int steps, unsigned int size) : QFrame (parent, Qt::WindowStaysOnTopHint | Qt::FramelessWindowHint | Qt::Tool | Qt::X11BypassWindowManagerHint), my_parent(parent) { setSteps(steps); setLineWidth(2); - setMouseTracking ( TRUE ); + setMouseTracking ( true ); setFrameStyle ( QFrame::Panel | QFrame::Raised ); setLineWidth( 1 ); ensurePolished(); resize(size, size); hide(); } QmitkPopupColorChooser::~QmitkPopupColorChooser() { } void QmitkPopupColorChooser::setSteps(int steps) { m_Steps = steps; m_Steps2 = m_Steps / 2; m_HStep = 360 / m_Steps; m_SStep = 512 / m_Steps; m_VStep = 512 / m_Steps; } void QmitkPopupColorChooser::keyReleaseEvent(QKeyEvent*) { emit colorSelected( m_OriginalColor ); close(); } void QmitkPopupColorChooser::mouseMoveEvent (QMouseEvent* e) { double x(e->pos().x()); double y(e->pos().y()); x /= width(); if ( x >= 0.0 ) { x = (int)(x * (float)(m_Steps-1)) / (float)(m_Steps-1); if (x > 1.0) x = 1.0; if (x < 0.0) x = 0.0; } y /= height(); if (y >= 1.0) y = 0.9; if (y < 0.0) y = 0.0; y = (int)(y * (float)m_Steps) / (float)m_Steps; m_H = static_cast( y * 359.0 ); if ( x >= 0.5 ) { m_S = static_cast( (1.0 - x) * 511.0 ); if ( m_S > 255 ) m_S = 255; m_V = 255; } else { m_S = 255; if ( x < 0.0 ) m_V = 0; else { m_V = static_cast( x * 511.0 + 511.0 / (float)(m_Steps-1) ); if ( m_V > 255 ) m_V = 255; } } QColor color; color.setHsv(m_H, m_S, m_V); emit colorSelected( color ); } void QmitkPopupColorChooser::mouseReleaseEvent (QMouseEvent*) { close (); } void QmitkPopupColorChooser::closeEvent (QCloseEvent*e) { e->accept (); releaseKeyboard(); releaseMouse(); if (!m_popupParent) return; // remember that we (as a popup) might recieve the mouse release // event instead of the popupParent. This is due to the fact that // the popupParent popped us up in its mousePressEvent handler. To // avoid the button remaining in pressed state we simply send a // faked mouse button release event to it. // Maleike: parent should not pop us on MouseRelease! QMouseEvent me( QEvent::MouseButtonRelease, QPoint(0,0), QPoint(0,0), Qt::LeftButton, Qt::NoButton, Qt::NoModifier); QApplication::sendEvent ( m_popupParent, &me ); } void QmitkPopupColorChooser::popup(QWidget* parent, const QPoint& point, const mitk::Color* color) { m_popupParent = parent; if (m_popupParent) { QPoint newPos; if (color) { QColor qcolor( (int)((*color)[0] * 255.0) , (int)((*color)[1] * 255.0) , (int)((*color)[2] * 255.0) ); int h,s,v; qcolor.getHsv(&h, &s, &v); if ( h == -1 ) // set by Qt if color is achromatic ( but this widget does not display grays ) h = 10; // red int x, y; float cellwidth = (float)width() / (float)(m_Steps); if ( s > v ) // restrict to the colors we can display { // left side, ramp from v = 255/m_Steps to v = 255 s = 255; x = (int)( ( ((float)v / 255.0) * ((float)m_Steps2) - 1.0 ) * cellwidth + cellwidth/2 ); } else { v = 255; x = (int)( ( (1.0 - ((float)s / 255.0)) * ((float)m_Steps2) ) * cellwidth + cellwidth/2 + width() / 2 ); } y = (int)( (float)h/360.0 * (float)m_Steps * cellwidth ); m_OriginalColor.setHsv(h,s,v); // move to color newPos.setX( point.x() - x ); newPos.setY( point.y() - y ); } else { // center widget m_OriginalColor.setHsv(-1, 0, 0); newPos.setX( point.x() - width() / 2 ); newPos.setY( point.y() - height() / 2 ); } move ( m_popupParent->mapToGlobal( newPos ) ); } show(); raise(); grabMouse(); grabKeyboard(); } void QmitkPopupColorChooser::paintEvent(QPaintEvent*) { QPainter painter(this); drawGradient( &painter ); } void QmitkPopupColorChooser::drawGradient( QPainter* p) { p->setWindow( 0, 0, m_Steps-1, m_Steps ); // defines coordinate system p->setPen( Qt::NoPen ); QColor c; for ( unsigned int h = 0; h < m_Steps; ++h ) { for ( unsigned int v = 1; v < m_Steps2; ++v ) { c.setHsv( h*m_HStep, 255, v*m_VStep ); // rainbow effect p->setBrush( c ); // solid fill with color c p->drawRect( v-1, h, m_Steps2, m_Steps ); // draw the rectangle } for ( unsigned int s = 0; s < m_Steps2; ++s ) { c.setHsv( h*m_HStep, 255 - s*m_SStep, 255 ); // rainbow effect p->setBrush( c ); // solid fill with color c p->drawRect( m_Steps2+s-1, h, m_Steps2, m_Steps ); // draw the rectangle } } } //----- QmitkColorPropertyEditor -------------------------------------------------- // initialization of static pointer to color picker widget QmitkPopupColorChooser* QmitkColorPropertyEditor::colorChooser = NULL; int QmitkColorPropertyEditor::colorChooserRefCount = 0; QmitkColorPropertyEditor::QmitkColorPropertyEditor( const mitk::ColorProperty* property, QWidget* parent ) : QmitkColorPropertyView( property, parent ) { // our popup belongs to the whole screen, so it could be drawn outside the toplevel window's borders int scr; if ( QApplication::desktop()->isVirtualDesktop() ) scr = QApplication::desktop()->screenNumber( parent->mapToGlobal( pos() ) ); else scr = QApplication::desktop()->screenNumber( parent ); if ( colorChooserRefCount == 0 ) { colorChooser = new QmitkPopupColorChooser( QApplication::desktop()->screen( scr ), 50 ); } ++colorChooserRefCount; } QmitkColorPropertyEditor::~QmitkColorPropertyEditor() { --colorChooserRefCount; if (!colorChooserRefCount) { delete colorChooser; colorChooser = NULL; } } void QmitkColorPropertyEditor::mousePressEvent(QMouseEvent* e) { connect( colorChooser, SIGNAL(colorSelected(QColor)), this, SLOT(onColorSelected(QColor)) ); if (m_ColorProperty) { colorChooser->popup( this, e->pos(), &(m_ColorProperty->GetColor()) ); } } void QmitkColorPropertyEditor::mouseReleaseEvent(QMouseEvent*) { disconnect( colorChooser, SIGNAL(colorSelected(QColor)), this, SLOT(onColorSelected(QColor)) ); } void QmitkColorPropertyEditor::onColorSelected(QColor c) { if (m_ColorProperty) { int r,g,b; c.getRgb( &r, &g, &b ); const_cast(m_ColorProperty)->SetColor( r / 255.0, g / 255.0, b / 255.0 ); const_cast(m_ColorProperty)->Modified(); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } } diff --git a/Modules/QtWidgetsExt/QmitkTransferFunctionWidget.cpp b/Modules/QtWidgetsExt/QmitkTransferFunctionWidget.cpp index 51b1d48376..245e019d3c 100755 --- a/Modules/QtWidgetsExt/QmitkTransferFunctionWidget.cpp +++ b/Modules/QtWidgetsExt/QmitkTransferFunctionWidget.cpp @@ -1,268 +1,259 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "QmitkTransferFunctionWidget.h" #include -#include QmitkTransferFunctionWidget::QmitkTransferFunctionWidget(QWidget* parent, Qt::WindowFlags f) : QWidget(parent, f) { this->setupUi(this); // signals and slots connections connect(m_XEditScalarOpacity, SIGNAL(textEdited ( const QString & )), this, SLOT(SetXValueScalar( const QString & ))); connect(m_YEditScalarOpacity, SIGNAL(textEdited ( const QString & )), this, SLOT(SetYValueScalar( const QString & ))); connect(m_XEditGradientOpacity, SIGNAL(textEdited ( const QString & )), this, SLOT(SetXValueGradient( const QString & ))); connect(m_YEditGradientOpacity, SIGNAL(textEdited ( const QString & )), this, SLOT(SetYValueGradient( const QString & ))); connect(m_XEditColor, SIGNAL( textEdited ( const QString & ) ), this, SLOT(SetXValueColor( const QString & ))); - QPlastiqueStyle *sliderStyle = new QPlastiqueStyle(); - - m_RangeSlider->setMaximum(2048); m_RangeSlider->setMinimum(-2048); - m_RangeSlider->setHandleMovementMode(QxtSpanSlider::NoOverlapping); - m_RangeSlider->setStyle(sliderStyle); - connect(m_RangeSlider, SIGNAL(spanChanged(double,double)),this, SLOT(OnSpanChanged(double,double))); + m_RangeSlider->setMaximum(2048); + connect(m_RangeSlider, SIGNAL(valuesChanged(int,int)),this, SLOT(OnSpanChanged(int,int))); //reset button connect(m_RangeSliderReset, SIGNAL(pressed()), this, SLOT(OnResetSlider())); m_ScalarOpacityFunctionCanvas->SetQLineEdits(m_XEditScalarOpacity, m_YEditScalarOpacity); m_GradientOpacityCanvas->SetQLineEdits(m_XEditGradientOpacity, m_YEditGradientOpacity); m_ColorTransferFunctionCanvas->SetQLineEdits(m_XEditColor, 0); m_ScalarOpacityFunctionCanvas->SetTitle("Grayvalue -> Opacity"); m_GradientOpacityCanvas->SetTitle("Grayvalue/Gradient -> Opacity"); m_ColorTransferFunctionCanvas->SetTitle("Grayvalue -> Color"); } QmitkTransferFunctionWidget::~QmitkTransferFunctionWidget() { } -void QmitkTransferFunctionWidget::SetIntegerMode(bool intMode) -{ - m_RangeSlider->setIntegerMode(intMode); -} - void QmitkTransferFunctionWidget::SetScalarLabel(const QString& scalarLabel) { m_textLabelX->setText(scalarLabel); m_textLabelX_2->setText(scalarLabel); m_textLabelX_3->setText(scalarLabel); m_ScalarOpacityFunctionCanvas->SetTitle(scalarLabel + " -> Opacity"); m_GradientOpacityCanvas->SetTitle(scalarLabel + "/Gradient -> Opacity"); m_ColorTransferFunctionCanvas->SetTitle(scalarLabel + " -> Color"); } void QmitkTransferFunctionWidget::ShowScalarOpacityFunction(bool show) { m_ScalarOpacityWidget->setVisible(show); } void QmitkTransferFunctionWidget::ShowColorFunction(bool show) { m_ColorWidget->setVisible(show); } void QmitkTransferFunctionWidget::ShowGradientOpacityFunction(bool show) { m_GradientOpacityWidget->setVisible(show); } void QmitkTransferFunctionWidget::SetScalarOpacityFunctionEnabled(bool enable) { m_ScalarOpacityWidget->setEnabled(enable); } void QmitkTransferFunctionWidget::SetColorFunctionEnabled(bool enable) { m_ColorWidget->setEnabled(enable); } void QmitkTransferFunctionWidget::SetGradientOpacityFunctionEnabled(bool enable) { m_GradientOpacityWidget->setEnabled(enable); } void QmitkTransferFunctionWidget::SetDataNode(mitk::DataNode* node, const mitk::BaseRenderer* renderer) { if (node) { tfpToChange = dynamic_cast(node->GetProperty("TransferFunction", renderer)); if(!tfpToChange) { if (! dynamic_cast(node->GetData())) { MITK_WARN << "QmitkTransferFunctionWidget::SetDataNode called with non-image node"; goto turnOff; } node->SetProperty("TransferFunction", tfpToChange = mitk::TransferFunctionProperty::New() ); } mitk::TransferFunction::Pointer tf = tfpToChange->GetValue(); if( mitk::BaseData* data = node->GetData() ) { mitk::SimpleHistogram *h = histogramCache[data]; m_RangeSliderMin= h->GetMin(); m_RangeSliderMax= h->GetMax(); m_RangeSlider->blockSignals(true); m_RangeSlider->setMinimum(m_RangeSliderMin); m_RangeSlider->setMaximum(m_RangeSliderMax); - m_RangeSlider->setSpan( m_RangeSliderMin, m_RangeSliderMax); + m_RangeSlider->setMinimumValue(m_RangeSliderMin); + m_RangeSlider->setMaximumValue(m_RangeSliderMax); m_RangeSlider->blockSignals(false); m_ScalarOpacityFunctionCanvas->SetHistogram( h ); m_GradientOpacityCanvas->SetHistogram( h ); m_ColorTransferFunctionCanvas->SetHistogram( h ); } OnUpdateCanvas(); return; } turnOff: m_ScalarOpacityFunctionCanvas->setEnabled(false); m_ScalarOpacityFunctionCanvas->SetHistogram(0); m_GradientOpacityCanvas->setEnabled(false); m_GradientOpacityCanvas->SetHistogram(0); m_ColorTransferFunctionCanvas->setEnabled(false); m_ColorTransferFunctionCanvas->SetHistogram(0); tfpToChange = 0; } void QmitkTransferFunctionWidget::OnUpdateCanvas() { if(tfpToChange.IsNull()) return; mitk::TransferFunction::Pointer tf = tfpToChange->GetValue(); if(tf.IsNull()) return; m_ScalarOpacityFunctionCanvas->SetPiecewiseFunction( tf->GetScalarOpacityFunction() ); m_GradientOpacityCanvas->SetPiecewiseFunction( tf->GetGradientOpacityFunction() ); m_ColorTransferFunctionCanvas->SetColorTransferFunction( tf->GetColorTransferFunction() ); UpdateRanges(); m_ScalarOpacityFunctionCanvas->update(); m_GradientOpacityCanvas->update(); m_ColorTransferFunctionCanvas->update(); } void QmitkTransferFunctionWidget::SetXValueScalar( const QString text ) { if ( !text.endsWith( "." )) { m_ScalarOpacityFunctionCanvas->SetX(text.toFloat()); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } } void QmitkTransferFunctionWidget::SetYValueScalar( const QString text ) { if ( !text.endsWith( "." )) { m_ScalarOpacityFunctionCanvas->SetY(text.toFloat()); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } } void QmitkTransferFunctionWidget::SetXValueGradient( const QString text ) { if ( !text.endsWith( "." )) { m_GradientOpacityCanvas->SetX(text.toFloat()); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } } void QmitkTransferFunctionWidget::SetYValueGradient( const QString text ) { if ( !text.endsWith( "." )) { m_GradientOpacityCanvas->SetY(text.toFloat()); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } } void QmitkTransferFunctionWidget::SetXValueColor( const QString text ) { if ( !text.endsWith( "." )) { m_ColorTransferFunctionCanvas->SetX(text.toFloat()); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } } void QmitkTransferFunctionWidget::UpdateRanges() { - double lower = m_RangeSlider->lowerValue(); - double upper = m_RangeSlider->upperValue(); + int lower = m_RangeSlider->minimumValue(); + int upper = m_RangeSlider->maximumValue(); m_ScalarOpacityFunctionCanvas->SetMin(lower); m_ScalarOpacityFunctionCanvas->SetMax(upper); m_GradientOpacityCanvas->SetMin(lower); m_GradientOpacityCanvas->SetMax(upper); m_ColorTransferFunctionCanvas->SetMin(lower); m_ColorTransferFunctionCanvas->SetMax(upper); } -void QmitkTransferFunctionWidget::OnSpanChanged(double, double) +void QmitkTransferFunctionWidget::OnSpanChanged(int, int) { UpdateRanges(); m_GradientOpacityCanvas->update(); m_ColorTransferFunctionCanvas->update(); m_ScalarOpacityFunctionCanvas->update(); } void QmitkTransferFunctionWidget::OnResetSlider() { m_RangeSlider->blockSignals(true); - m_RangeSlider->setUpperValue(m_RangeSliderMax); - m_RangeSlider->setLowerValue(m_RangeSliderMin); + m_RangeSlider->setMaximumValue(m_RangeSliderMax); + m_RangeSlider->setMinimumValue(m_RangeSliderMin); m_RangeSlider->blockSignals(false); UpdateRanges(); m_GradientOpacityCanvas->update(); m_ColorTransferFunctionCanvas->update(); m_ScalarOpacityFunctionCanvas->update(); } diff --git a/Modules/QtWidgetsExt/QmitkTransferFunctionWidget.h b/Modules/QtWidgetsExt/QmitkTransferFunctionWidget.h index 093e56e891..686f5b79d0 100755 --- a/Modules/QtWidgetsExt/QmitkTransferFunctionWidget.h +++ b/Modules/QtWidgetsExt/QmitkTransferFunctionWidget.h @@ -1,90 +1,88 @@ /*=================================================================== 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 QMITKTRANSFERFUNCTIONWIDGET_H #define QMITKTRANSFERFUNCTIONWIDGET_H #include "ui_QmitkTransferFunctionWidget.h" #include "MitkQtWidgetsExtExports.h" #include #include #include #include #include #include #include namespace mitk { class BaseRenderer; } class MitkQtWidgetsExt_EXPORT QmitkTransferFunctionWidget : public QWidget, public Ui::QmitkTransferFunctionWidget { Q_OBJECT public: QmitkTransferFunctionWidget(QWidget* parent = 0, Qt::WindowFlags f = 0); ~QmitkTransferFunctionWidget () ; void SetDataNode(mitk::DataNode* node, const mitk::BaseRenderer* renderer = NULL); - void SetIntegerMode(bool intMode); - void SetScalarLabel(const QString& scalarLabel); void ShowScalarOpacityFunction(bool show); void ShowColorFunction(bool show); void ShowGradientOpacityFunction(bool show); void SetScalarOpacityFunctionEnabled(bool enable); void SetColorFunctionEnabled(bool enable); void SetGradientOpacityFunctionEnabled(bool enable); public slots: void SetXValueScalar( const QString text ); void SetYValueScalar( const QString text ); void SetXValueGradient( const QString text ); void SetYValueGradient( const QString text ); void SetXValueColor( const QString text ); void OnUpdateCanvas(); void UpdateRanges(); void OnResetSlider(); - void OnSpanChanged (double lower, double upper); + void OnSpanChanged (int lower, int upper); protected: mitk::TransferFunctionProperty::Pointer tfpToChange; - double m_RangeSliderMin; - double m_RangeSliderMax; + int m_RangeSliderMin; + int m_RangeSliderMax; mitk::SimpleHistogramCache histogramCache; }; #endif diff --git a/Modules/QtWidgetsExt/QmitkTransferFunctionWidget.ui b/Modules/QtWidgetsExt/QmitkTransferFunctionWidget.ui index daa42305ef..7332ab3bae 100755 --- a/Modules/QtWidgetsExt/QmitkTransferFunctionWidget.ui +++ b/Modules/QtWidgetsExt/QmitkTransferFunctionWidget.ui @@ -1,557 +1,557 @@ QmitkTransferFunctionWidget 0 0 300 542 1 1 Form 0 0 0 0 - + Change transfer function window range. Qt::Horizontal 0 0 48 16777215 Resets range to histogram minimum and maximum. Reset 0 3 0 0 0 0 0 1 0 64 Left-click to select a point or add a new point. Hold left mouse button to move selected point. Click right mouse button to delete a point. true 0 0 64 0 64 16777215 Edit x-coordinate (grayvalue) of currently selected point. Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 0 0 Edit x-coordinate (grayvalue) of currently selected point. Grayvalue false Qt::Horizontal 40 20 0 0 Edit y-coordinate (opacity) of currently selected point. Opacity Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter false 0 0 64 0 64 16777215 Edit y-coordinate (opacity) of currently selected point. Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 0 0 0 0 0 0 0 1 0 48 Left-click to select a point or add a new point. Hold left mouse button to move selected point. Click right mouse button to delete a point. Double-click left mouse button to change color of a point. 0 0 64 0 64 16777215 Edit x-coordinate (grayvalue) of currently selected point. Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter Edit x-coordinate (grayvalue) of currently selected point. Grayvalue false Qt::Horizontal 40 20 0 2 0 0 0 0 0 1 0 64 Left-click to select a point or add a new point. Hold left mouse button to move selected point. Click right mouse button to delete a point. 0 0 64 0 64 16777215 Edit x-coordinate (grayvalue) of currently selected point. Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter Edit x-coordinate (grayvalue) of currently selected point. Grayvalue false Qt::Horizontal 40 20 Edit y-coordinate (opacity) of currently selected point. Opacity Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter false 0 0 64 0 64 16777215 Edit y-coordinate (opacity) of currently selected point. Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter Qt::Vertical 20 0 QmitkPiecewiseFunctionCanvas QWidget
QmitkPiecewiseFunctionCanvas.h
QmitkColorTransferFunctionCanvas QWidget
QmitkColorTransferFunctionCanvas.h
- QmitkFloatingPointSpanSlider - QSlider -
QmitkFloatingPointSpanSlider.h
+ ctkRangeSlider + QWidget +
ctkRangeSlider.h
diff --git a/Modules/QtWidgetsExt/QmitkWebPage.h b/Modules/QtWidgetsExt/QmitkWebPage.h index c7a6c33ca8..90a55ae0ee 100644 --- a/Modules/QtWidgetsExt/QmitkWebPage.h +++ b/Modules/QtWidgetsExt/QmitkWebPage.h @@ -1,54 +1,54 @@ /*=================================================================== 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 +#include #ifndef QMITK_WEBPAGE_H #define QMITK_WEBPAGE_H /** * @brief The QmitkWebPage class * * This class reimplements QWebPage as a fix for bug 16158. */ class QmitkJSWebPage : public QWebPage { Q_OBJECT public: /** * @brief Constructor */ QmitkJSWebPage(QObject *parent=0); /** * @brief Destructor */ virtual ~QmitkJSWebPage(); public slots: /** * @brief shouldInterruptJavaScript * * Overwritten from QWebView, to stop asking Qt to stop the JavaScript. * @return false so JavaScript is not stopped */ bool shouldInterruptJavaScript(); }; #endif diff --git a/Modules/QtWidgetsExt/files.cmake b/Modules/QtWidgetsExt/files.cmake index b388a28ff2..5986b01ad1 100644 --- a/Modules/QtWidgetsExt/files.cmake +++ b/Modules/QtWidgetsExt/files.cmake @@ -1,116 +1,114 @@ set(CPP_FILES QmitkAboutDialog/QmitkAboutDialog.cpp QmitkPropertyObservers/QmitkBasePropertyView.cpp QmitkPropertyObservers/QmitkBoolPropertyWidget.cpp QmitkPropertyObservers/QmitkColorPropertyEditor.cpp QmitkPropertyObservers/QmitkColorPropertyView.cpp QmitkPropertyObservers/QmitkEnumerationPropertyWidget.cpp QmitkPropertyObservers/QmitkNumberPropertyEditor.cpp QmitkPropertyObservers/QmitkNumberPropertySlider.cpp QmitkPropertyObservers/QmitkNumberPropertyView.cpp QmitkPropertyObservers/QmitkPropertyViewFactory.cpp QmitkPropertyObservers/QmitkStringPropertyEditor.cpp QmitkPropertyObservers/QmitkStringPropertyOnDemandEdit.cpp QmitkPropertyObservers/QmitkStringPropertyView.cpp QmitkPropertyObservers/QmitkUGCombinedRepresentationPropertyWidget.cpp qclickablelabel.cpp QmitkBoundingObjectWidget.cpp QmitkCallbackFromGUIThread.cpp QmitkColorTransferFunctionCanvas.cpp QmitkCorrespondingPointSetsModel.cpp QmitkCorrespondingPointSetsView.cpp QmitkCorrespondingPointSetsWidget.cpp QmitkCrossWidget.cpp QmitkEditPointDialog.cpp QmitkFileChooser.cpp - QmitkFloatingPointSpanSlider.cpp QmitkGnuplotWidget.cpp QmitkHistogram.cpp QmitkHistogramJSWidget.cpp QmitkHistogramWidget.cpp QmitkHotkeyLineEdit.cpp QmitkModulesDialog.cpp QmitkModuleTableModel.cpp QmitkPiecewiseFunctionCanvas.cpp QmitkPlotWidget.cpp QmitkPlotDialog.cpp QmitkPointListModel.cpp QmitkPointListView.cpp QmitkPointListViewWidget.cpp QmitkPointListWidget.cpp QmitkPrimitiveMovieNavigatorWidget.cpp QmitkSelectableGLWidget.cpp QmitkSliceWidget.cpp QmitkSliderNavigatorWidget.cpp QmitkStandardViews.cpp QmitkStepperAdapter.cpp QmitkTransferFunctionCanvas.cpp QmitkTransferFunctionGeneratorWidget.cpp QmitkTransferFunctionWidget.cpp QmitkVideoBackground.cpp QmitkWebPage.cpp QtWidgetsExtRegisterClasses.cpp ) set(MOC_H_FILES QmitkAboutDialog/QmitkAboutDialog.h QmitkPropertyObservers/QmitkBasePropertyView.h QmitkPropertyObservers/QmitkBoolPropertyWidget.h QmitkPropertyObservers/QmitkColorPropertyEditor.h QmitkPropertyObservers/QmitkColorPropertyView.h QmitkPropertyObservers/QmitkEnumerationPropertyWidget.h QmitkPropertyObservers/QmitkNumberPropertyEditor.h QmitkPropertyObservers/QmitkNumberPropertySlider.h QmitkPropertyObservers/QmitkNumberPropertyView.h QmitkPropertyObservers/QmitkStringPropertyEditor.h QmitkPropertyObservers/QmitkStringPropertyOnDemandEdit.h QmitkPropertyObservers/QmitkStringPropertyView.h QmitkPropertyObservers/QmitkUGCombinedRepresentationPropertyWidget.h qclickablelabel.h QmitkBoundingObjectWidget.h QmitkCallbackFromGUIThread.h QmitkColorTransferFunctionCanvas.h QmitkCorrespondingPointSetsModel.h QmitkCorrespondingPointSetsView.h QmitkCorrespondingPointSetsWidget.h QmitkCrossWidget.h QmitkEditPointDialog.h QmitkFileChooser.h - QmitkFloatingPointSpanSlider.h QmitkGnuplotWidget.h QmitkHistogramJSWidget.h QmitkHistogramWidget.h QmitkHotkeyLineEdit.h QmitkPiecewiseFunctionCanvas.h QmitkPlotWidget.h QmitkPointListModel.h QmitkPointListView.h QmitkPointListViewWidget.h QmitkPointListWidget.h QmitkPrimitiveMovieNavigatorWidget.h QmitkSelectableGLWidget.h QmitkSliceWidget.h QmitkSliderNavigatorWidget.h QmitkStandardViews.h QmitkStepperAdapter.h QmitkTransferFunctionCanvas.h QmitkTransferFunctionGeneratorWidget.h QmitkTransferFunctionWidget.h QmitkVideoBackground.h QmitkWebPage.h ) set(UI_FILES QmitkAboutDialog/QmitkAboutDialogGUI.ui QmitkGnuplotWidget.ui QmitkPrimitiveMovieNavigatorWidget.ui QmitkSelectableGLWidget.ui QmitkSliceWidget.ui QmitkSliderNavigator.ui QmitkTransferFunctionGeneratorWidget.ui QmitkTransferFunctionWidget.ui ) set(QRC_FILES resources/QtWidgetsExt.qrc ) diff --git a/Modules/QtWidgetsExt/qclickablelabel.cpp b/Modules/QtWidgetsExt/qclickablelabel.cpp index a6fc72a82d..fb441c85b3 100644 --- a/Modules/QtWidgetsExt/qclickablelabel.cpp +++ b/Modules/QtWidgetsExt/qclickablelabel.cpp @@ -1,115 +1,123 @@ /*=================================================================== 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 "qclickablelabel.h" #include #include +#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) QClickableLabel::QClickableLabel( QWidget* parent, Qt::WFlags f ) +#else +QClickableLabel::QClickableLabel( QWidget* parent, Qt::WindowFlags f ) +#endif :QLabel(parent, f) { } +#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) QClickableLabel::QClickableLabel( const QString& text, QWidget* parent, Qt::WFlags f ) +#else +QClickableLabel::QClickableLabel( const QString& text, QWidget* parent, Qt::WindowFlags f ) +#endif :QLabel(text, parent, f) { } QClickableLabel::~QClickableLabel() { } void QClickableLabel::AddHotspot( const QString& name, const QRect position ) { m_Hotspots.push_back( position ); m_HotspotIndexForName.insert( std::make_pair( name, (int)m_Hotspots.size()-1 ) ); m_HotspotNameForIndex.insert( std::make_pair( (int)m_Hotspots.size()-1, name ) ); } void QClickableLabel::RemoveHotspot( const QString& name ) { NameToIndexMapType::iterator iter = m_HotspotIndexForName.find( name ); if ( iter != m_HotspotIndexForName.end() ) { RemoveHotspot( iter->second ); } } void QClickableLabel::RemoveHotspot( unsigned int hotspotIndex ) { if ( hotspotIndex < m_Hotspots.size() ) { m_Hotspots.erase( m_Hotspots.begin() + hotspotIndex ); QString name = m_HotspotNameForIndex[hotspotIndex]; m_HotspotNameForIndex.erase( hotspotIndex ); m_HotspotIndexForName.erase( name ); } } void QClickableLabel::RemoveAllHotspots() { m_Hotspots.clear(); m_HotspotIndexForName.clear(); m_HotspotNameForIndex.clear(); } void QClickableLabel::mousePressEvent( QMouseEvent* e ) { unsigned int index = matchingRect( e->pos() ); if ( index < m_Hotspots.size() ) { emit mouseReleased( index ); emit mouseReleased( m_HotspotNameForIndex[index] ); } } void QClickableLabel::mouseReleaseEvent( QMouseEvent* e ) { unsigned int index = matchingRect( e->pos() ); if ( index < m_Hotspots.size() ) { emit mousePressed( index ); emit mousePressed( m_HotspotNameForIndex[index] ); } } unsigned int QClickableLabel::matchingRect( const QPoint& p ) { unsigned int index(0); for ( RectVectorType::iterator iter = m_Hotspots.begin(); iter != m_Hotspots.end(); ++iter ) { if ( iter->contains(p) ) { return index; } ++index; } return index; } diff --git a/Modules/QtWidgetsExt/qclickablelabel.h b/Modules/QtWidgetsExt/qclickablelabel.h index 8da31dca32..5daf55ce5f 100644 --- a/Modules/QtWidgetsExt/qclickablelabel.h +++ b/Modules/QtWidgetsExt/qclickablelabel.h @@ -1,77 +1,81 @@ /*=================================================================== 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 qclickablelabelhincluded #define qclickablelabelhincluded #include #include "MitkQtWidgetsExtExports.h" #include #include #include "mitkCommon.h" /** \brief A QLabel with multiple hotspots, that can be clicked Specially useful in connection with a pixmap. Stretched images should be avoided, because the hotspots will not be adjusted in any way. */ class MitkQtWidgetsExt_EXPORT QClickableLabel : public QLabel { Q_OBJECT public: - +#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) QClickableLabel( QWidget* parent, Qt::WFlags f = 0 ); QClickableLabel( const QString& text, QWidget* parent, Qt::WFlags f = 0 ); +#else + QClickableLabel( QWidget* parent, Qt::WindowFlags f = 0 ); + QClickableLabel( const QString& text, QWidget* parent, Qt::WindowFlags f = 0 ); +#endif virtual ~QClickableLabel(); void AddHotspot( const QString& name, const QRect position ); void RemoveHotspot( const QString& name ); void RemoveHotspot( unsigned int hotspotIndex ); void RemoveAllHotspots(); signals: void mousePressed( const QString& hotspotName ); void mousePressed( unsigned int hotspotIndex ); void mouseReleased( const QString& hotspotName ); void mouseReleased( unsigned int hotspotIndex ); protected: virtual void mousePressEvent ( QMouseEvent* e ); virtual void mouseReleaseEvent ( QMouseEvent* e ); /// returns index == m_Hotspots.size() if nothing is hit unsigned int matchingRect( const QPoint& p ); typedef std::vector< QRect > RectVectorType; RectVectorType m_Hotspots; typedef std::map< QString, unsigned int > NameToIndexMapType; typedef std::map< unsigned int, QString > IndexToNameMapType; NameToIndexMapType m_HotspotIndexForName; IndexToNameMapType m_HotspotNameForIndex; }; #endif diff --git a/Modules/Remeshing/CMakeLists.txt b/Modules/Remeshing/CMakeLists.txt index ac6516a386..c3da914c8e 100644 --- a/Modules/Remeshing/CMakeLists.txt +++ b/Modules/Remeshing/CMakeLists.txt @@ -1,8 +1,7 @@ -if(MITK_USE_ACVD) - MITK_CREATE_MODULE( +mitk_create_module( DEPENDS MitkCore PACKAGE_DEPENDS ACVD VTK|vtkIOPLY+vtkIOMINC ) - add_subdirectory(Testing) -endif() +add_subdirectory(Testing) + diff --git a/Modules/Segmentation/Interactions/mitkLiveWireTool2D.cpp b/Modules/Segmentation/Interactions/mitkLiveWireTool2D.cpp index 823fb28fe6..4c68f2f839 100644 --- a/Modules/Segmentation/Interactions/mitkLiveWireTool2D.cpp +++ b/Modules/Segmentation/Interactions/mitkLiveWireTool2D.cpp @@ -1,710 +1,707 @@ /*=================================================================== 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 #include #include #include #include #include #include #include #include #include #include #include #include #include "mitkLiveWireTool2D.h" #include "mitkLiveWireTool2D.xpm" namespace mitk { MITK_TOOL_MACRO(MitkSegmentation_EXPORT, LiveWireTool2D, "LiveWire tool"); } static void AddInteractorToGlobalInteraction(mitk::Interactor* interactor) { mitk::GlobalInteraction::GetInstance()->AddInteractor(interactor); } static void RemoveInteractorFromGlobalInteraction(mitk::Interactor* interactor) { mitk::GlobalInteraction::GetInstance()->RemoveInteractor(interactor); } class RemoveFromDataStorage { public: RemoveFromDataStorage(mitk::DataStorage::Pointer dataStorage) : m_DataStorage(dataStorage) { } void operator()(mitk::DataNode* dataNode) { m_DataStorage->Remove(dataNode); } void operator()(const std::pair& dataNode) { m_DataStorage->Remove(dataNode.first); } private: mitk::DataStorage::Pointer m_DataStorage; }; mitk::LiveWireTool2D::LiveWireTool2D() : SegTool2D("LiveWireTool"), m_PlaneGeometry(NULL) { } mitk::LiveWireTool2D::~LiveWireTool2D() { this->ClearSegmentation(); } void mitk::LiveWireTool2D::RemoveHelperObjects() { DataStorage* dataStorage = m_ToolManager->GetDataStorage(); if (!m_EditingContours.empty()) std::for_each(m_EditingContours.begin(), m_EditingContours.end(), RemoveFromDataStorage(dataStorage)); if (!m_WorkingContours.empty()) std::for_each(m_WorkingContours.begin(), m_WorkingContours.end(), RemoveFromDataStorage(dataStorage)); if (m_EditingContourNode.IsNotNull()) dataStorage->Remove(m_EditingContourNode); if (m_LiveWireContourNode.IsNotNull()) dataStorage->Remove(m_LiveWireContourNode); if (m_ContourModelNode.IsNotNull()) dataStorage->Remove(m_ContourModelNode); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } void mitk::LiveWireTool2D::ReleaseHelperObjects() { this->RemoveHelperObjects(); if (!m_EditingContours.empty()) m_EditingContours.clear(); if (!m_WorkingContours.empty()) m_WorkingContours.clear(); m_EditingContourNode = NULL; m_EditingContour = NULL; m_LiveWireContourNode = NULL; m_LiveWireContour = NULL; m_ContourModelNode = NULL; m_Contour = NULL; } void mitk::LiveWireTool2D::ReleaseInteractors() { this->EnableContourLiveWireInteraction(false); m_LiveWireInteractors.clear(); } void mitk::LiveWireTool2D::ConnectActionsAndFunctions() { CONNECT_CONDITION("CheckContourClosed", OnCheckPoint); CONNECT_FUNCTION("InitObject", OnInitLiveWire); CONNECT_FUNCTION("AddPoint", OnAddPoint); CONNECT_FUNCTION("CtrlAddPoint", OnAddPoint); CONNECT_FUNCTION("MovePoint", OnMouseMoveNoDynamicCosts); CONNECT_FUNCTION("FinishContour", OnFinish); CONNECT_FUNCTION("DeletePoint", OnLastSegmentDelete); CONNECT_FUNCTION("CtrlMovePoint", OnMouseMoved); } const char** mitk::LiveWireTool2D::GetXPM() const { return mitkLiveWireTool2D_xpm; } us::ModuleResource mitk::LiveWireTool2D::GetIconResource() const { return us::GetModuleContext()->GetModule()->GetResource("LiveWire_48x48.png"); } us::ModuleResource mitk::LiveWireTool2D::GetCursorIconResource() const { return us::GetModuleContext()->GetModule()->GetResource("LiveWire_Cursor_32x32.png"); } const char* mitk::LiveWireTool2D::GetName() const { return "Live Wire"; } void mitk::LiveWireTool2D::Activated() { Superclass::Activated(); this->ResetToStartState(); this->EnableContourLiveWireInteraction(true); } void mitk::LiveWireTool2D::Deactivated() { Superclass::Deactivated(); this->ConfirmSegmentation(); } void mitk::LiveWireTool2D::EnableContourLiveWireInteraction(bool on) { std::for_each(m_LiveWireInteractors.begin(), m_LiveWireInteractors.end(), on ? AddInteractorToGlobalInteraction : RemoveInteractorFromGlobalInteraction); } void mitk::LiveWireTool2D::ConfirmSegmentation() { DataNode* workingNode( m_ToolManager->GetWorkingData(0) ); if (!workingNode) return; Image* workingImage = dynamic_cast(workingNode->GetData()); if (!workingImage) return; // for all contours in list (currently created by tool) std::vector< std::pair >::iterator itWorkingContours = this->m_WorkingContours.begin(); std::vector sliceList; sliceList.reserve(m_WorkingContours.size()); while(itWorkingContours != this->m_WorkingContours.end() ) { // if node contains data if( itWorkingContours->first->GetData() ) { // if this is a contourModel mitk::ContourModel* contourModel = dynamic_cast(itWorkingContours->first->GetData()); if( contourModel ) { // for each timestep of this contourModel for( TimeStepType currentTimestep = 0; currentTimestep < contourModel->GetTimeGeometry()->CountTimeSteps(); ++currentTimestep) { //get the segmentation image slice at current timestep mitk::Image::Pointer workingSlice = this->GetAffectedImageSliceAs2DImage(itWorkingContours->second, workingImage, currentTimestep); mitk::ContourModel::Pointer projectedContour = mitk::ContourModelUtils::ProjectContourTo2DSlice(workingSlice, contourModel, true, false); mitk::ContourModelUtils::FillContourInSlice(projectedContour, workingSlice, 1.0); //write back to image volume SliceInformation sliceInfo (workingSlice, itWorkingContours->second, currentTimestep); sliceList.push_back(sliceInfo); + this->WriteSliceToVolume(sliceInfo); } } } - ++itWorkingContours; } - this->WriteBackSegmentationResult(sliceList); + this->WriteBackSegmentationResult(sliceList, false); this->ClearSegmentation(); } void mitk::LiveWireTool2D::ClearSegmentation() { this->ReleaseHelperObjects(); this->ReleaseInteractors(); this->ResetToStartState(); } bool mitk::LiveWireTool2D::OnInitLiveWire ( StateMachineAction*, InteractionEvent* interactionEvent ) { if ( SegTool2D::CanHandleEvent(interactionEvent) < 1.0 ) return false; mitk::InteractionPositionEvent* positionEvent = dynamic_cast( interactionEvent ); if (!mitk::SegTool2D::CanHandleEvent(interactionEvent)) return false; if (!positionEvent) return false; m_LastEventSender = positionEvent->GetSender(); m_LastEventSlice = m_LastEventSender->GetSlice(); int timestep = positionEvent->GetSender()->GetTimeStep(); m_Contour = mitk::ContourModel::New(); m_Contour->Expand(timestep+1); m_ContourModelNode = mitk::DataNode::New(); m_ContourModelNode->SetData( m_Contour ); m_ContourModelNode->SetName("working contour node"); m_ContourModelNode->SetProperty( "layer", IntProperty::New(100)); m_ContourModelNode->AddProperty( "fixedLayer", BoolProperty::New(true)); m_ContourModelNode->SetProperty( "helper object", mitk::BoolProperty::New(true)); m_ContourModelNode->AddProperty( "contour.color", ColorProperty::New(1, 1, 0), NULL, true ); m_ContourModelNode->AddProperty( "contour.points.color", ColorProperty::New(1.0, 0.0, 0.1), NULL, true ); m_ContourModelNode->AddProperty( "contour.controlpoints.show", BoolProperty::New(true), NULL, true ); m_LiveWireContour = mitk::ContourModel::New(); m_LiveWireContour->Expand(timestep+1); m_LiveWireContourNode = mitk::DataNode::New(); m_LiveWireContourNode->SetData( m_LiveWireContour ); m_LiveWireContourNode->SetName("active livewire node"); m_LiveWireContourNode->SetProperty( "layer", IntProperty::New(101)); m_LiveWireContourNode->AddProperty( "fixedLayer", BoolProperty::New(true)); m_LiveWireContourNode->SetProperty( "helper object", mitk::BoolProperty::New(true)); m_LiveWireContourNode->AddProperty( "contour.color", ColorProperty::New(0.1, 1.0, 0.1), NULL, true ); m_LiveWireContourNode->AddProperty( "contour.width", mitk::FloatProperty::New( 4.0 ), NULL, true ); m_EditingContour = mitk::ContourModel::New(); m_EditingContour->Expand(timestep+1); m_EditingContourNode = mitk::DataNode::New(); m_EditingContourNode->SetData( m_EditingContour ); m_EditingContourNode->SetName("editing node"); m_EditingContourNode->SetProperty( "layer", IntProperty::New(102)); m_EditingContourNode->AddProperty( "fixedLayer", BoolProperty::New(true)); m_EditingContourNode->SetProperty( "helper object", mitk::BoolProperty::New(true)); m_EditingContourNode->AddProperty( "contour.color", ColorProperty::New(0.1, 1.0, 0.1), NULL, true ); m_EditingContourNode->AddProperty( "contour.points.color", ColorProperty::New(0.0, 0.0, 1.0), NULL, true ); m_EditingContourNode->AddProperty( "contour.width", mitk::FloatProperty::New( 4.0 ), NULL, true ); mitk::DataNode* workingDataNode = m_ToolManager->GetWorkingData(0); m_ToolManager->GetDataStorage()->Add(m_ContourModelNode, workingDataNode); m_ToolManager->GetDataStorage()->Add(m_LiveWireContourNode, workingDataNode); m_ToolManager->GetDataStorage()->Add(m_EditingContourNode, workingDataNode); //set current slice as input for ImageToLiveWireContourFilter m_WorkingSlice = this->GetAffectedReferenceSlice(positionEvent); //Transfer LiveWire's center based contour output to corner based via the adaption of the input //slice image. Just in case someone stumbles across the 0.5 here I know what I'm doing ;-). mitk::Point3D newOrigin = m_WorkingSlice->GetSlicedGeometry()->GetOrigin(); m_WorkingSlice->GetSlicedGeometry()->WorldToIndex(newOrigin, newOrigin); newOrigin[0] -= 0.5; newOrigin[1] -= 0.5; m_WorkingSlice->GetSlicedGeometry()->IndexToWorld(newOrigin, newOrigin); m_WorkingSlice->GetSlicedGeometry()->SetOrigin(newOrigin); m_LiveWireFilter = mitk::ImageLiveWireContourModelFilter::New(); m_LiveWireFilter->SetInput(m_WorkingSlice); //map click to pixel coordinates mitk::Point3D click = positionEvent->GetPositionInWorld(); itk::Index<3> idx; m_WorkingSlice->GetGeometry()->WorldToIndex(click, idx); // get the pixel the gradient in region of 5x5 itk::Index<3> indexWithHighestGradient; AccessFixedDimensionByItk_2(m_WorkingSlice, FindHighestGradientMagnitudeByITK, 2, idx, indexWithHighestGradient); // itk::Index to mitk::Point3D click[0] = indexWithHighestGradient[0]; click[1] = indexWithHighestGradient[1]; click[2] = indexWithHighestGradient[2]; m_WorkingSlice->GetGeometry()->IndexToWorld(click, click); //set initial start point m_Contour->AddVertex( click, true, timestep ); m_LiveWireFilter->SetStartPoint(click); // remember plane geometry to determine if events were triggered in same plane m_PlaneGeometry = interactionEvent->GetSender()->GetCurrentWorldPlaneGeometry(); m_CreateAndUseDynamicCosts = true; //render assert( positionEvent->GetSender()->GetRenderWindow() ); mitk::RenderingManager::GetInstance()->RequestUpdate( positionEvent->GetSender()->GetRenderWindow() ); return true; } bool mitk::LiveWireTool2D::OnAddPoint ( StateMachineAction*, InteractionEvent* interactionEvent ) { if ( SegTool2D::CanHandleEvent(interactionEvent) < 1.0 ) return false; //complete LiveWire interaction for last segment //add current LiveWire contour to the finished contour and reset //to start new segment and computation /* check if event can be handled */ if (!mitk::SegTool2D::CanHandleEvent(interactionEvent)) return false; mitk::InteractionPositionEvent* positionEvent = dynamic_cast( interactionEvent ); if (!positionEvent) return false; if (m_PlaneGeometry != NULL) { // this checks that the point is in the correct slice if (m_PlaneGeometry->DistanceFromPlane(positionEvent->GetPositionInWorld()) > mitk::eps) return false; - // this also covers the cases where points are outside of the images bounding box - if (!m_PlaneGeometry->IsInside(positionEvent->GetPositionInWorld())) - return false; } int timestep = positionEvent->GetSender()->GetTimeStep(); //add repulsive points to avoid to get the same path again typedef mitk::ImageLiveWireContourModelFilter::InternalImageType::IndexType IndexType; mitk::ContourModel::ConstVertexIterator iter = m_LiveWireContour->IteratorBegin(timestep); for (;iter != m_LiveWireContour->IteratorEnd(timestep); iter++) { IndexType idx; this->m_WorkingSlice->GetGeometry()->WorldToIndex((*iter)->Coordinates, idx); this->m_LiveWireFilter->AddRepulsivePoint( idx ); } //remove duplicate first vertex, it's already contained in m_Contour m_LiveWireContour->RemoveVertexAt(0, timestep); // set last added point as control point m_LiveWireContour->SetControlVertexAt(m_LiveWireContour->GetNumberOfVertices(timestep)-1, timestep); //merge contours m_Contour->Concatenate(m_LiveWireContour, timestep); //clear the livewire contour and reset the corresponding datanode m_LiveWireContour->Clear(timestep); //set new start point m_LiveWireFilter->SetStartPoint(positionEvent->GetPositionInWorld()); if( m_CreateAndUseDynamicCosts ) { //use dynamic cost map for next update m_LiveWireFilter->CreateDynamicCostMap(m_Contour); m_LiveWireFilter->SetUseDynamicCostMap(true); //m_CreateAndUseDynamicCosts = false; } //render assert( positionEvent->GetSender()->GetRenderWindow() ); mitk::RenderingManager::GetInstance()->RequestUpdate( positionEvent->GetSender()->GetRenderWindow() ); return true; } bool mitk::LiveWireTool2D::OnMouseMoved( StateMachineAction*, InteractionEvent* interactionEvent ) { if ( SegTool2D::CanHandleEvent(interactionEvent) < 1.0 ) return false; //compute LiveWire segment from last control point to current mouse position if (!mitk::SegTool2D::CanHandleEvent(interactionEvent)) return false; mitk::InteractionPositionEvent* positionEvent = dynamic_cast( interactionEvent ); if (!positionEvent) return false; // actual LiveWire computation int timestep = positionEvent->GetSender()->GetTimeStep(); m_LiveWireFilter->SetEndPoint(positionEvent->GetPositionInWorld()); m_LiveWireFilter->SetTimeStep( timestep ); m_LiveWireFilter->Update(); m_LiveWireContour = this->m_LiveWireFilter->GetOutput(); m_LiveWireContourNode->SetData( this->m_LiveWireContour ); //render assert( positionEvent->GetSender()->GetRenderWindow() ); positionEvent->GetSender()->GetRenderingManager()->RequestUpdate( positionEvent->GetSender()->GetRenderWindow() ); return true; } bool mitk::LiveWireTool2D::OnMouseMoveNoDynamicCosts( StateMachineAction*, InteractionEvent* interactionEvent ) { //do not use dynamic cost map m_LiveWireFilter->SetUseDynamicCostMap(false); OnMouseMoved( NULL, interactionEvent); m_LiveWireFilter->SetUseDynamicCostMap(true); return true; } bool mitk::LiveWireTool2D::OnCheckPoint( const InteractionEvent* interactionEvent) { //check double click on first control point to finish the LiveWire tool // //Check distance to first point. //Transition YES if click close to first control point // if (!mitk::SegTool2D::CanHandleEvent(interactionEvent)) return false; const mitk::InteractionPositionEvent* positionEvent = dynamic_cast( interactionEvent ); if (positionEvent) { int timestep = positionEvent->GetSender()->GetTimeStep(); mitk::Point3D click = positionEvent->GetPositionInWorld(); mitk::Point3D first = this->m_Contour->GetVertexAt(0, timestep)->Coordinates; if (first.EuclideanDistanceTo(click) < 4.5) { // allow to finish return true; } else { return false; } } return false; } bool mitk::LiveWireTool2D::OnFinish( StateMachineAction*, InteractionEvent* interactionEvent ) { if ( SegTool2D::CanHandleEvent(interactionEvent) < 1.0 ) return false; // finish livewire tool interaction if (!mitk::SegTool2D::CanHandleEvent(interactionEvent)) return false; mitk::InteractionPositionEvent* positionEvent = dynamic_cast( interactionEvent ); if (!positionEvent) return false; // Have to do that here so that the m_LastEventSender is set correctly mitk::SegTool2D::AddContourmarker(); // actual timestep int timestep = positionEvent->GetSender()->GetTimeStep(); // remove last control point being added by double click m_Contour->RemoveVertexAt(m_Contour->GetNumberOfVertices(timestep) - 1, timestep); // save contour and corresponding plane geometry to list std::pair cp(m_ContourModelNode, dynamic_cast(positionEvent->GetSender()->GetCurrentWorldPlaneGeometry()->Clone().GetPointer()) ); this->m_WorkingContours.push_back(cp); std::pair ecp(m_EditingContourNode, dynamic_cast(positionEvent->GetSender()->GetCurrentWorldPlaneGeometry()->Clone().GetPointer()) ); this->m_EditingContours.push_back(ecp); m_LiveWireFilter->SetUseDynamicCostMap(false); this->FinishTool(); return true; } void mitk::LiveWireTool2D::FinishTool() { TimeStepType numberOfTimesteps = m_Contour->GetTimeGeometry()->CountTimeSteps(); //close contour in each timestep for( int i = 0; i <= numberOfTimesteps; i++) { m_Contour->Close(i); } m_ToolManager->GetDataStorage()->Remove( m_LiveWireContourNode ); // clear live wire contour node m_LiveWireContourNode = NULL; m_LiveWireContour = NULL; //set the livewire interactor to edit control points m_ContourInteractor = mitk::ContourModelLiveWireInteractor::New(m_ContourModelNode); m_ContourInteractor->SetWorkingImage(this->m_WorkingSlice); m_ContourInteractor->SetEditingContourModelNode(this->m_EditingContourNode); m_ContourModelNode->SetInteractor(m_ContourInteractor); this->m_LiveWireInteractors.push_back( m_ContourInteractor ); //add interactor to globalInteraction instance mitk::GlobalInteraction::GetInstance()->AddInteractor(m_ContourInteractor); } bool mitk::LiveWireTool2D::OnLastSegmentDelete( StateMachineAction*, InteractionEvent* interactionEvent ) { int timestep = interactionEvent->GetSender()->GetTimeStep(); //if last point of current contour will be removed go to start state and remove nodes if( m_Contour->GetNumberOfVertices(timestep) <= 1 ) { m_ToolManager->GetDataStorage()->Remove( m_LiveWireContourNode ); m_ToolManager->GetDataStorage()->Remove( m_ContourModelNode ); m_ToolManager->GetDataStorage()->Remove( m_EditingContourNode ); m_LiveWireContour = mitk::ContourModel::New(); m_Contour = mitk::ContourModel::New(); m_ContourModelNode->SetData( m_Contour ); m_LiveWireContourNode->SetData( m_LiveWireContour ); this->ResetToStartState(); //go to start state } else //remove last segment from contour and reset livewire contour { m_LiveWireContour = mitk::ContourModel::New(); m_LiveWireContourNode->SetData(m_LiveWireContour); mitk::ContourModel::Pointer newContour = mitk::ContourModel::New(); newContour->Expand(m_Contour->GetTimeSteps()); mitk::ContourModel::VertexIterator begin = m_Contour->IteratorBegin(); //iterate from last point to next active point mitk::ContourModel::VertexIterator newLast = m_Contour->IteratorBegin() + (m_Contour->GetNumberOfVertices() - 1); //go at least one down if(newLast != begin) { newLast--; } //search next active control point while(newLast != begin && !((*newLast)->IsControlPoint) ) { newLast--; } //set position of start point for livewire filter to coordinates of the new last point m_LiveWireFilter->SetStartPoint((*newLast)->Coordinates); mitk::ContourModel::VertexIterator it = m_Contour->IteratorBegin(); //fill new Contour while(it <= newLast) { newContour->AddVertex((*it)->Coordinates, (*it)->IsControlPoint, timestep); it++; } newContour->SetClosed(m_Contour->IsClosed()); //set new contour visible m_ContourModelNode->SetData(newContour); m_Contour = newContour; assert( interactionEvent->GetSender()->GetRenderWindow() ); mitk::RenderingManager::GetInstance()->RequestUpdate( interactionEvent->GetSender()->GetRenderWindow() ); } return true; } template void mitk::LiveWireTool2D::FindHighestGradientMagnitudeByITK(itk::Image* inputImage, itk::Index<3> &index, itk::Index<3> &returnIndex) { typedef itk::Image InputImageType; typedef typename InputImageType::IndexType IndexType; unsigned long xMAX = inputImage->GetLargestPossibleRegion().GetSize()[0]; unsigned long yMAX = inputImage->GetLargestPossibleRegion().GetSize()[1]; returnIndex[0] = index[0]; returnIndex[1] = index[1]; returnIndex[2] = 0.0; double gradientMagnitude = 0.0; double maxGradientMagnitude = 0.0; /* the size and thus the region of 7x7 is only used to calculate the gradient magnitude in that region not for searching the maximum value */ //maximum value in each direction for size typename InputImageType::SizeType size; size[0] = 7; size[1] = 7; //minimum value in each direction for startRegion IndexType startRegion; startRegion[0] = index[0] - 3; startRegion[1] = index[1] - 3; if(startRegion[0] < 0) startRegion[0] = 0; if(startRegion[1] < 0) startRegion[1] = 0; if(xMAX - index[0] < 7) startRegion[0] = xMAX - 7; if(yMAX - index[1] < 7) startRegion[1] = yMAX - 7; index[0] = startRegion[0] + 3; index[1] = startRegion[1] + 3; typename InputImageType::RegionType region; region.SetSize( size ); region.SetIndex( startRegion ); typedef typename itk::GradientMagnitudeImageFilter< InputImageType, InputImageType> GradientMagnitudeFilterType; typename GradientMagnitudeFilterType::Pointer gradientFilter = GradientMagnitudeFilterType::New(); gradientFilter->SetInput(inputImage); gradientFilter->GetOutput()->SetRequestedRegion(region); gradientFilter->Update(); typename InputImageType::Pointer gradientMagnImage; gradientMagnImage = gradientFilter->GetOutput(); IndexType currentIndex; currentIndex[0] = 0; currentIndex[1] = 0; // search max (approximate) gradient magnitude for( int x = -1; x <= 1; ++x) { currentIndex[0] = index[0] + x; for( int y = -1; y <= 1; ++y) { currentIndex[1] = index[1] + y; gradientMagnitude = gradientMagnImage->GetPixel(currentIndex); //check for new max if(maxGradientMagnitude < gradientMagnitude) { maxGradientMagnitude = gradientMagnitude; returnIndex[0] = currentIndex[0]; returnIndex[1] = currentIndex[1]; returnIndex[2] = 0.0; }//end if }//end for y currentIndex[1] = index[1]; }//end for x } diff --git a/Modules/Segmentation/Interactions/mitkSegTool2D.cpp b/Modules/Segmentation/Interactions/mitkSegTool2D.cpp index 93f5d1827f..0affca350e 100644 --- a/Modules/Segmentation/Interactions/mitkSegTool2D.cpp +++ b/Modules/Segmentation/Interactions/mitkSegTool2D.cpp @@ -1,472 +1,473 @@ /*=================================================================== 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 "mitkSegTool2D.h" #include "mitkToolManager.h" #include "mitkDataStorage.h" #include "mitkBaseRenderer.h" #include "mitkPlaneGeometry.h" #include "mitkExtractImageFilter.h" #include "mitkExtractDirectedPlaneImageFilter.h" //Include of the new ImageExtractor #include "mitkExtractDirectedPlaneImageFilterNew.h" #include "mitkPlanarCircle.h" #include "mitkOverwriteSliceImageFilter.h" #include "mitkOverwriteDirectedPlaneImageFilter.h" #include "mitkMorphologicalOperations.h" #include "usGetModuleContext.h" //Includes for 3DSurfaceInterpolation #include "mitkImageToContourFilter.h" #include "mitkSurfaceInterpolationController.h" //includes for resling and overwriting #include #include #include #include #include #include "mitkOperationEvent.h" #include "mitkUndoController.h" #include "mitkAbstractTransformGeometry.h" #define ROUND(a) ((a)>0 ? (int)((a)+0.5) : -(int)(0.5-(a))) bool mitk::SegTool2D::m_SurfaceInterpolationEnabled = true; mitk::SegTool2D::SegTool2D(const char* type) :Tool(type), m_LastEventSender(NULL), m_LastEventSlice(0), m_Contourmarkername ("Position"), m_ShowMarkerNodes (false) { } mitk::SegTool2D::~SegTool2D() { } float mitk::SegTool2D::CanHandleEvent( InteractionEvent const *stateEvent) const { const InteractionPositionEvent* positionEvent = dynamic_cast( stateEvent ); if (!positionEvent) return 0.0; if ( positionEvent->GetSender()->GetMapperID() != BaseRenderer::Standard2D ) return 0.0; // we don't want anything but 2D return 1.0; } bool mitk::SegTool2D::DetermineAffectedImageSlice( const Image* image, const PlaneGeometry* plane, int& affectedDimension, int& affectedSlice ) { assert(image); assert(plane); // compare normal of plane to the three axis vectors of the image Vector3D normal = plane->GetNormal(); Vector3D imageNormal0 = image->GetSlicedGeometry()->GetAxisVector(0); Vector3D imageNormal1 = image->GetSlicedGeometry()->GetAxisVector(1); Vector3D imageNormal2 = image->GetSlicedGeometry()->GetAxisVector(2); normal.Normalize(); imageNormal0.Normalize(); imageNormal1.Normalize(); imageNormal2.Normalize(); imageNormal0.SetVnlVector( vnl_cross_3d(normal.GetVnlVector(),imageNormal0.GetVnlVector()) ); imageNormal1.SetVnlVector( vnl_cross_3d(normal.GetVnlVector(),imageNormal1.GetVnlVector()) ); imageNormal2.SetVnlVector( vnl_cross_3d(normal.GetVnlVector(),imageNormal2.GetVnlVector()) ); double eps( 0.00001 ); // axial if ( imageNormal2.GetNorm() <= eps ) { affectedDimension = 2; } // sagittal else if ( imageNormal1.GetNorm() <= eps ) { affectedDimension = 1; } // frontal else if ( imageNormal0.GetNorm() <= eps ) { affectedDimension = 0; } else { affectedDimension = -1; // no idea return false; } // determine slice number in image BaseGeometry* imageGeometry = image->GetGeometry(0); Point3D testPoint = imageGeometry->GetCenter(); Point3D projectedPoint; plane->Project( testPoint, projectedPoint ); Point3D indexPoint; imageGeometry->WorldToIndex( projectedPoint, indexPoint ); affectedSlice = ROUND( indexPoint[affectedDimension] ); MITK_DEBUG << "indexPoint " << indexPoint << " affectedDimension " << affectedDimension << " affectedSlice " << affectedSlice; // check if this index is still within the image if ( affectedSlice < 0 || affectedSlice >= static_cast(image->GetDimension(affectedDimension)) ) return false; return true; } void mitk::SegTool2D::UpdateSurfaceInterpolation (const Image* slice, const Image* workingImage, const PlaneGeometry *plane, bool detectIntersection) { if (!m_SurfaceInterpolationEnabled) return; ImageToContourFilter::Pointer contourExtractor = ImageToContourFilter::New(); mitk::Surface::Pointer contour; if (detectIntersection) { // Test whether there is something to extract or whether the slice just contains intersections of others mitk::Image::Pointer slice2 = slice->Clone(); mitk::MorphologicalOperations::Erode(slice2, 2, mitk::MorphologicalOperations::Ball); contourExtractor->SetInput(slice2); contourExtractor->Update(); contour = contourExtractor->GetOutput(); if (contour->GetVtkPolyData()->GetNumberOfPoints() == 0) { // Remove contour! mitk::SurfaceInterpolationController::ContourPositionInformation contourInfo; contourInfo.contourNormal = plane->GetNormal(); contourInfo.contourPoint = plane->GetOrigin(); mitk::SurfaceInterpolationController::GetInstance()->RemoveContour(contourInfo); return; } } contourExtractor->SetInput(slice); contourExtractor->Update(); contour = contourExtractor->GetOutput(); if (contour->GetVtkPolyData()->GetNumberOfPoints() != 0 && workingImage->GetDimension() == 3) { mitk::SurfaceInterpolationController::GetInstance()->AddNewContour( contour ); contour->DisconnectPipeline(); } else { // Remove contour! mitk::SurfaceInterpolationController::ContourPositionInformation contourInfo; contourInfo.contourNormal = plane->GetNormal(); contourInfo.contourPoint = plane->GetOrigin(); mitk::SurfaceInterpolationController::GetInstance()->RemoveContour(contourInfo); } } mitk::Image::Pointer mitk::SegTool2D::GetAffectedImageSliceAs2DImage(const InteractionPositionEvent* positionEvent, const Image* image) { if (!positionEvent) return NULL; assert( positionEvent->GetSender() ); // sure, right? unsigned int timeStep = positionEvent->GetSender()->GetTimeStep( image ); // get the timestep of the visible part (time-wise) of the image // first, we determine, which slice is affected const PlaneGeometry* planeGeometry( dynamic_cast (positionEvent->GetSender()->GetCurrentWorldPlaneGeometry() ) ); return this->GetAffectedImageSliceAs2DImage(planeGeometry, image, timeStep); } mitk::Image::Pointer mitk::SegTool2D::GetAffectedImageSliceAs2DImage(const PlaneGeometry* planeGeometry, const Image* image, unsigned int timeStep) { if ( !image || !planeGeometry ) return NULL; //Make sure that for reslicing and overwriting the same alogrithm is used. We can specify the mode of the vtk reslicer vtkSmartPointer reslice = vtkSmartPointer::New(); //set to false to extract a slice reslice->SetOverwriteMode(false); reslice->Modified(); //use ExtractSliceFilter with our specific vtkImageReslice for overwriting and extracting mitk::ExtractSliceFilter::Pointer extractor = mitk::ExtractSliceFilter::New(reslice); extractor->SetInput( image ); extractor->SetTimeStep( timeStep ); extractor->SetWorldGeometry( planeGeometry ); extractor->SetVtkOutputRequest(false); extractor->SetResliceTransformByGeometry( image->GetTimeGeometry()->GetGeometryForTimeStep( timeStep ) ); extractor->Modified(); extractor->Update(); Image::Pointer slice = extractor->GetOutput(); /*============= BEGIN undo feature block ========================*/ //specify the undo operation with the non edited slice m_undoOperation = new DiffSliceOperation(const_cast(image), extractor->GetVtkOutput(), dynamic_cast(slice->GetGeometry()), timeStep, const_cast(planeGeometry)); /*============= END undo feature block ========================*/ return slice; } mitk::Image::Pointer mitk::SegTool2D::GetAffectedWorkingSlice(const InteractionPositionEvent* positionEvent) { DataNode* workingNode( m_ToolManager->GetWorkingData(0) ); if ( !workingNode ) return NULL; Image* workingImage = dynamic_cast(workingNode->GetData()); if ( !workingImage ) return NULL; return GetAffectedImageSliceAs2DImage( positionEvent, workingImage ); } mitk::Image::Pointer mitk::SegTool2D::GetAffectedReferenceSlice(const InteractionPositionEvent* positionEvent) { DataNode* referenceNode( m_ToolManager->GetReferenceData(0) ); if ( !referenceNode ) return NULL; Image* referenceImage = dynamic_cast(referenceNode->GetData()); if ( !referenceImage ) return NULL; return GetAffectedImageSliceAs2DImage( positionEvent, referenceImage ); } void mitk::SegTool2D::WriteBackSegmentationResult (const InteractionPositionEvent* positionEvent, Image* slice) { if(!positionEvent) return; const PlaneGeometry* planeGeometry( dynamic_cast (positionEvent->GetSender()->GetCurrentWorldPlaneGeometry() ) ); const AbstractTransformGeometry* abstractTransformGeometry( dynamic_cast (positionEvent->GetSender()->GetCurrentWorldPlaneGeometry() ) ); if( planeGeometry && slice && !abstractTransformGeometry) { DataNode* workingNode( m_ToolManager->GetWorkingData(0) ); Image* image = dynamic_cast(workingNode->GetData()); unsigned int timeStep = positionEvent->GetSender()->GetTimeStep( image ); this->WriteBackSegmentationResult(planeGeometry, slice, timeStep); } } void mitk::SegTool2D::WriteBackSegmentationResult (const PlaneGeometry* planeGeometry, Image* slice, unsigned int timeStep) { if(!planeGeometry || !slice) return; SliceInformation sliceInfo (slice, const_cast(planeGeometry), timeStep); this->WriteSliceToVolume(sliceInfo); DataNode* workingNode( m_ToolManager->GetWorkingData(0) ); Image* image = dynamic_cast(workingNode->GetData()); this->UpdateSurfaceInterpolation(slice, image, planeGeometry, false); if (m_SurfaceInterpolationEnabled) this->AddContourmarker(); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } -void mitk::SegTool2D::WriteBackSegmentationResult(std::vector sliceList) +void mitk::SegTool2D::WriteBackSegmentationResult(std::vector sliceList, bool writeSliceToVolume) { std::vector contourList; contourList.reserve(sliceList.size()); ImageToContourFilter::Pointer contourExtractor = ImageToContourFilter::New(); DataNode* workingNode( m_ToolManager->GetWorkingData(0) ); Image* image = dynamic_cast(workingNode->GetData()); for (unsigned int i = 0; i < sliceList.size(); ++i) { SliceInformation currentSliceInfo = sliceList.at(i); - this->WriteSliceToVolume(currentSliceInfo); + if(writeSliceToVolume) + this->WriteSliceToVolume(currentSliceInfo); if (m_SurfaceInterpolationEnabled && image->GetDimension() == 3) { currentSliceInfo.slice->DisconnectPipeline(); contourExtractor->SetInput(currentSliceInfo.slice); contourExtractor->Update(); mitk::Surface::Pointer contour = contourExtractor->GetOutput(); contour->DisconnectPipeline(); contourList.push_back(contour); } } mitk::SurfaceInterpolationController::GetInstance()->AddNewContours(contourList); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } void mitk::SegTool2D::WriteSliceToVolume(mitk::SegTool2D::SliceInformation sliceInfo) { DataNode* workingNode( m_ToolManager->GetWorkingData(0) ); Image* image = dynamic_cast(workingNode->GetData()); //Make sure that for reslicing and overwriting the same alogrithm is used. We can specify the mode of the vtk reslicer vtkSmartPointer reslice = vtkSmartPointer::New(); //Set the slice as 'input' reslice->SetInputSlice(sliceInfo.slice->GetVtkImageData()); //set overwrite mode to true to write back to the image volume reslice->SetOverwriteMode(true); reslice->Modified(); mitk::ExtractSliceFilter::Pointer extractor = mitk::ExtractSliceFilter::New(reslice); extractor->SetInput( image ); extractor->SetTimeStep( sliceInfo.timestep ); extractor->SetWorldGeometry( sliceInfo.plane ); extractor->SetVtkOutputRequest(true); extractor->SetResliceTransformByGeometry( image->GetGeometry( sliceInfo.timestep ) ); extractor->Modified(); extractor->Update(); //the image was modified within the pipeline, but not marked so image->Modified(); image->GetVtkImageData()->Modified(); /*============= BEGIN undo feature block ========================*/ //specify the undo operation with the edited slice m_doOperation = new DiffSliceOperation(image, extractor->GetVtkOutput(),dynamic_cast(sliceInfo.slice->GetGeometry()), sliceInfo.timestep, sliceInfo.plane); //create an operation event for the undo stack OperationEvent* undoStackItem = new OperationEvent( DiffSliceOperationApplier::GetInstance(), m_doOperation, m_undoOperation, "Segmentation" ); //add it to the undo controller UndoController::GetCurrentUndoModel()->SetOperationEvent( undoStackItem ); //clear the pointers as the operation are stored in the undocontroller and also deleted from there m_undoOperation = NULL; m_doOperation = NULL; /*============= END undo feature block ========================*/ } void mitk::SegTool2D::SetShowMarkerNodes(bool status) { m_ShowMarkerNodes = status; } void mitk::SegTool2D::SetEnable3DInterpolation(bool enabled) { m_SurfaceInterpolationEnabled = enabled; } unsigned int mitk::SegTool2D::AddContourmarker() { us::ServiceReference serviceRef = us::GetModuleContext()->GetServiceReference(); PlanePositionManagerService* service = us::GetModuleContext()->GetService(serviceRef); unsigned int slicePosition = m_LastEventSender->GetSliceNavigationController()->GetSlice()->GetPos(); // the first geometry is needed otherwise restoring the position is not working const mitk::PlaneGeometry* plane = dynamic_cast (dynamic_cast< const mitk::SlicedGeometry3D*>( m_LastEventSender->GetSliceNavigationController()->GetCurrentGeometry3D())->GetPlaneGeometry(0)); unsigned int size = service->GetNumberOfPlanePositions(); unsigned int id = service->AddNewPlanePosition(plane, slicePosition); mitk::PlanarCircle::Pointer contourMarker = mitk::PlanarCircle::New(); mitk::Point2D p1; plane->Map(plane->GetCenter(), p1); mitk::Point2D p2 = p1; p2[0] -= plane->GetSpacing()[0]; p2[1] -= plane->GetSpacing()[1]; contourMarker->PlaceFigure( p1 ); contourMarker->SetCurrentControlPoint( p1 ); contourMarker->SetPlaneGeometry( const_cast(plane)); std::stringstream markerStream; mitk::DataNode* workingNode (m_ToolManager->GetWorkingData(0)); markerStream << m_Contourmarkername ; markerStream << " "; markerStream << id+1; DataNode::Pointer rotatedContourNode = DataNode::New(); rotatedContourNode->SetData(contourMarker); rotatedContourNode->SetProperty( "name", StringProperty::New(markerStream.str()) ); rotatedContourNode->SetProperty( "isContourMarker", BoolProperty::New(true)); rotatedContourNode->SetBoolProperty( "PlanarFigureInitializedWindow", true, m_LastEventSender ); rotatedContourNode->SetProperty( "includeInBoundingBox", BoolProperty::New(false)); rotatedContourNode->SetProperty( "helper object", mitk::BoolProperty::New(!m_ShowMarkerNodes)); rotatedContourNode->SetProperty( "planarfigure.drawcontrolpoints", BoolProperty::New(false)); rotatedContourNode->SetProperty( "planarfigure.drawname", BoolProperty::New(false)); rotatedContourNode->SetProperty( "planarfigure.drawoutline", BoolProperty::New(false)); rotatedContourNode->SetProperty( "planarfigure.drawshadow", BoolProperty::New(false)); if (plane) { if ( id == size ) { m_ToolManager->GetDataStorage()->Add(rotatedContourNode, workingNode); } else { mitk::NodePredicateProperty::Pointer isMarker = mitk::NodePredicateProperty::New("isContourMarker", mitk::BoolProperty::New(true)); mitk::DataStorage::SetOfObjects::ConstPointer markers = m_ToolManager->GetDataStorage()->GetDerivations(workingNode,isMarker); for ( mitk::DataStorage::SetOfObjects::const_iterator iter = markers->begin(); iter != markers->end(); ++iter) { std::string nodeName = (*iter)->GetName(); unsigned int t = nodeName.find_last_of(" "); unsigned int markerId = atof(nodeName.substr(t+1).c_str())-1; if(id == markerId) { return id; } } m_ToolManager->GetDataStorage()->Add(rotatedContourNode, workingNode); } } return id; } void mitk::SegTool2D::InteractiveSegmentationBugMessage( const std::string& message ) { MITK_ERROR << "********************************************************************************" << std::endl << " " << message << std::endl << "********************************************************************************" << std::endl << " " << std::endl << " If your image is rotated or the 2D views don't really contain the patient image, try to press the button next to the image selection. " << std::endl << " " << std::endl << " Please file a BUG REPORT: " << std::endl << " http://bugs.mitk.org" << std::endl << " Contain the following information:" << std::endl << " - What image were you working on?" << std::endl << " - Which region of the image?" << std::endl << " - Which tool did you use?" << std::endl << " - What did you do?" << std::endl << " - What happened (not)? What did you expect?" << std::endl; } diff --git a/Modules/Segmentation/Interactions/mitkSegTool2D.h b/Modules/Segmentation/Interactions/mitkSegTool2D.h index a6a07efe19..8a42abed4b 100644 --- a/Modules/Segmentation/Interactions/mitkSegTool2D.h +++ b/Modules/Segmentation/Interactions/mitkSegTool2D.h @@ -1,181 +1,181 @@ /*=================================================================== 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 mitkSegTool2D_h_Included #define mitkSegTool2D_h_Included #include "mitkCommon.h" #include #include "mitkTool.h" #include "mitkImage.h" #include "mitkStateEvent.h" #include "mitkInteractionPositionEvent.h" #include "mitkPlanePositionManager.h" #include "mitkRestorePlanePositionOperation.h" #include "mitkInteractionConst.h" #include namespace mitk { class BaseRenderer; /** \brief Abstract base class for segmentation tools. \sa Tool \ingroup Interaction \ingroup ToolManagerEtAl Implements 2D segmentation specific helper methods, that might be of use to all kind of 2D segmentation tools. At the moment these are: - Determination of the slice where the user paints upon (DetermineAffectedImageSlice) - Projection of a 3D contour onto a 2D plane/slice SegTool2D tries to structure the interaction a bit. If you pass "PressMoveRelease" as the interaction type of your derived tool, you might implement the methods OnMousePressed, OnMouseMoved, and OnMouseReleased. Yes, your guess about when they are called is correct. \warning Only to be instantiated by mitk::ToolManager. $Author$ */ class MitkSegmentation_EXPORT SegTool2D : public Tool { public: mitkClassMacro(SegTool2D, Tool); /** \brief Calculates for a given Image and PlaneGeometry, which slice of the image (in index corrdinates) is meant by the plane. \return false, if no slice direction seems right (e.g. rotated planes) \param affectedDimension The image dimension, which is constant for all points in the plane, e.g. Axial --> 2 \param affectedSlice The index of the image slice */ static bool DetermineAffectedImageSlice( const Image* image, const PlaneGeometry* plane, int& affectedDimension, int& affectedSlice ); /** * @brief Updates the surface interpolation by extracting the contour form the given slice. * @param slice the slice from which the contour should be extracted * @param workingImage the segmentation image * @param plane the plane in which the slice lies * @param detectIntersection if true the slice is eroded before contour extraction. If the slice is empty after the erosion it is most * likely an intersecting contour an will not be added to the SurfaceInterpolationController */ static void UpdateSurfaceInterpolation (const Image* slice, const Image* workingImage, const PlaneGeometry *plane, bool detectIntersection); void SetShowMarkerNodes(bool); /** * \brief Enables or disables the 3D interpolation after writing back the 2D segmentation result, and defaults to true. */ void SetEnable3DInterpolation(bool); protected: SegTool2D(); // purposely hidden SegTool2D(const char*); // purposely hidden virtual ~SegTool2D(); struct SliceInformation { mitk::Image::Pointer slice; mitk::PlaneGeometry* plane; unsigned int timestep; SliceInformation () {} SliceInformation (mitk::Image* slice, mitk::PlaneGeometry* plane, unsigned int timestep) { this->slice = slice; this->plane = plane; this->timestep = timestep; } }; /** * \brief Calculates how good the data, this statemachine handles, is hit by the event. * */ virtual float CanHandleEvent( InteractionEvent const *stateEvent) const; /** \brief Extract the slice of an image that the user just scribbles on. \return NULL if SegTool2D is either unable to determine which slice was affected, or if there was some problem getting the image data at that position. */ Image::Pointer GetAffectedImageSliceAs2DImage(const InteractionPositionEvent*, const Image* image); /** \brief Extract the slice of an image cut by given plane. \return NULL if SegTool2D is either unable to determine which slice was affected, or if there was some problem getting the image data at that position. */ Image::Pointer GetAffectedImageSliceAs2DImage(const PlaneGeometry* planeGeometry, const Image* image, unsigned int timeStep); /** \brief Extract the slice of the currently selected working image that the user just scribbles on. \return NULL if SegTool2D is either unable to determine which slice was affected, or if there was some problem getting the image data at that position, or just no working image is selected. */ Image::Pointer GetAffectedWorkingSlice(const InteractionPositionEvent*); /** \brief Extract the slice of the currently selected reference image that the user just scribbles on. \return NULL if SegTool2D is either unable to determine which slice was affected, or if there was some problem getting the image data at that position, or just no reference image is selected. */ Image::Pointer GetAffectedReferenceSlice(const InteractionPositionEvent*); void WriteBackSegmentationResult (const InteractionPositionEvent*, Image*); void WriteBackSegmentationResult (const PlaneGeometry* planeGeometry, Image*, unsigned int timeStep); - void WriteBackSegmentationResult (std::vector sliceList); + void WriteBackSegmentationResult (std::vector sliceList, bool writeSliceToVolume = true); + void WriteSliceToVolume (SliceInformation sliceInfo); /** \brief Adds a new node called Contourmarker to the datastorage which holds a mitk::PlanarFigure. By selecting this node the slicestack will be reoriented according to the PlanarFigure's Geometry */ unsigned int AddContourmarker (); void InteractiveSegmentationBugMessage( const std::string& message ); BaseRenderer* m_LastEventSender; unsigned int m_LastEventSlice; private: - void WriteSliceToVolume (SliceInformation sliceInfo); //The prefix of the contourmarkername. Suffix is a consecutive number const std::string m_Contourmarkername; bool m_ShowMarkerNodes; static bool m_SurfaceInterpolationEnabled; DiffSliceOperation* m_doOperation; DiffSliceOperation* m_undoOperation; }; } // namespace #endif diff --git a/Modules/SegmentationUI/Qmitk/QmitkAdaptiveRegionGrowingToolGUI.cpp b/Modules/SegmentationUI/Qmitk/QmitkAdaptiveRegionGrowingToolGUI.cpp index 1c40262485..447f12fd68 100644 --- a/Modules/SegmentationUI/Qmitk/QmitkAdaptiveRegionGrowingToolGUI.cpp +++ b/Modules/SegmentationUI/Qmitk/QmitkAdaptiveRegionGrowingToolGUI.cpp @@ -1,849 +1,855 @@ /*=================================================================== 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 "QmitkAdaptiveRegionGrowingToolGUI.h" #include "QmitkStdMultiWidget.h" #include #include "mitkNodePredicateDataType.h" #include "mitkProperties.h" #include "mitkITKImageImport.h" #include "mitkImageAccessByItk.h" #include "mitkTransferFunctionProperty.h" #include "mitkImageTimeSelector.h" #include "mitkImageStatisticsHolder.h" #include #include #include #include #include "itkOrImageFilter.h" #include "mitkImageCast.h" #include "QmitkConfirmSegmentationDialog.h" #include "mitkPixelTypeMultiplex.h" #include "mitkImagePixelReadAccessor.h" MITK_TOOL_GUI_MACRO( , QmitkAdaptiveRegionGrowingToolGUI, "") QmitkAdaptiveRegionGrowingToolGUI::QmitkAdaptiveRegionGrowingToolGUI(QWidget* parent) : QmitkToolGUI(), m_MultiWidget(NULL), m_UseVolumeRendering(false), m_UpdateSuggestedThreshold(true), m_SuggestedThValue(0.0), m_DataStorage(NULL) { this->setParent(parent); m_Controls.setupUi(this); m_Controls.m_ThresholdSlider->setDecimals(1); m_Controls.m_ThresholdSlider->setSpinBoxAlignment(Qt::AlignVCenter); m_Controls.m_PreviewSlider->setEnabled(false); m_Controls.m_PreviewSlider->setSingleStep(0.5); //Not yet available //m_Controls.m_PreviewSlider->InvertedAppearance(true); this->CreateConnections(); this->SetDataNodeNames("labeledRGSegmentation","RGResult","RGFeedbackSurface"); connect( this, SIGNAL(NewToolAssociated(mitk::Tool*)), this, SLOT(OnNewToolAssociated(mitk::Tool*)) ); } QmitkAdaptiveRegionGrowingToolGUI::~QmitkAdaptiveRegionGrowingToolGUI() { //Removing the observer of the PointSet node if (m_RegionGrow3DTool->GetPointSetNode().IsNotNull()) { m_RegionGrow3DTool->GetPointSetNode()->GetData()->RemoveObserver(m_PointSetAddObserverTag); + m_RegionGrow3DTool->GetPointSetNode()->GetData()->RemoveObserver(m_PointSetMoveObserverTag); } this->RemoveHelperNodes(); } void QmitkAdaptiveRegionGrowingToolGUI::OnNewToolAssociated(mitk::Tool* tool) { m_RegionGrow3DTool = dynamic_cast (tool); if(m_RegionGrow3DTool.IsNotNull()) { SetInputImageNode( this->m_RegionGrow3DTool->GetReferenceData() ); this->m_DataStorage = this->m_RegionGrow3DTool->GetDataStorage(); this->EnableControls(true); //Watch for point added or modified itk::SimpleMemberCommand::Pointer pointAddedCommand = itk::SimpleMemberCommand::New(); pointAddedCommand->SetCallbackFunction(this, &QmitkAdaptiveRegionGrowingToolGUI::OnPointAdded); m_PointSetAddObserverTag = m_RegionGrow3DTool->GetPointSetNode()->GetData()->AddObserver( mitk::PointSetAddEvent(), pointAddedCommand); - m_PointSetAddObserverTag = m_RegionGrow3DTool->GetPointSetNode()->GetData()->AddObserver( mitk::PointSetMoveEvent(), pointAddedCommand); + m_PointSetMoveObserverTag = m_RegionGrow3DTool->GetPointSetNode()->GetData()->AddObserver( mitk::PointSetMoveEvent(), pointAddedCommand); } else { this->EnableControls(false); } } void QmitkAdaptiveRegionGrowingToolGUI::RemoveHelperNodes() { mitk::DataNode::Pointer imageNode = m_DataStorage->GetNamedNode( m_NAMEFORLABLEDSEGMENTATIONIMAGE); if( imageNode.IsNotNull() ) { m_DataStorage->Remove(imageNode); } } void QmitkAdaptiveRegionGrowingToolGUI::CreateConnections() { //Connecting GUI components connect( (QObject*) (m_Controls.m_pbRunSegmentation), SIGNAL(clicked()), this, SLOT(RunSegmentation())); connect( m_Controls.m_PreviewSlider, SIGNAL(valueChanged(double)), this, SLOT(ChangeLevelWindow(double))); connect( (QObject*) (m_Controls.m_pbConfirmSegementation), SIGNAL(clicked()), this, SLOT(ConfirmSegmentation())); connect( (QObject*) (m_Controls.m_cbVolumeRendering), SIGNAL(toggled(bool)), this, SLOT(UseVolumeRendering(bool) )); connect( m_Controls.m_ThresholdSlider, SIGNAL(maximumValueChanged(double)), this, SLOT(SetUpperThresholdValue(double))); connect( m_Controls.m_ThresholdSlider, SIGNAL(minimumValueChanged(double)), this, SLOT(SetLowerThresholdValue(double))); } void QmitkAdaptiveRegionGrowingToolGUI::SetDataNodeNames(std::string labledSegmentation, std::string binaryImage, std::string surface) { m_NAMEFORLABLEDSEGMENTATIONIMAGE = labledSegmentation; m_NAMEFORBINARYIMAGE = binaryImage; m_NAMEFORSURFACE = surface; } void QmitkAdaptiveRegionGrowingToolGUI::SetDataStorage(mitk::DataStorage* dataStorage) { m_DataStorage = dataStorage; } void QmitkAdaptiveRegionGrowingToolGUI::SetMultiWidget(QmitkStdMultiWidget* multiWidget) { m_MultiWidget = multiWidget; } void QmitkAdaptiveRegionGrowingToolGUI::SetInputImageNode(mitk::DataNode* node) { m_InputImageNode = node; mitk::Image* inputImage = dynamic_cast(m_InputImageNode->GetData()); if (inputImage) { mitk::ScalarType max = inputImage->GetStatistics()->GetScalarValueMax(); mitk::ScalarType min = inputImage->GetStatistics()->GetScalarValueMin(); m_Controls.m_ThresholdSlider->setMaximum(max); m_Controls.m_ThresholdSlider->setMinimum(min); // Just for initialization m_Controls.m_ThresholdSlider->setMaximumValue(max); m_Controls.m_ThresholdSlider->setMinimumValue(min); } } template static void AccessPixel(mitk::PixelType ptype, const mitk::Image::Pointer im, mitk::Point3D p, int & val) { mitk::ImagePixelReadAccessor access(im); val = access.GetPixelByWorldCoordinates(p); } void QmitkAdaptiveRegionGrowingToolGUI::OnPointAdded() { if (m_RegionGrow3DTool.IsNull()) return; mitk::DataNode* node = m_RegionGrow3DTool->GetPointSetNode(); if (node != NULL) { mitk::PointSet::Pointer pointSet = dynamic_cast(node->GetData()); if (pointSet.IsNull()) { QMessageBox::critical(NULL, "QmitkAdaptiveRegionGrowingToolGUI", "PointSetNode does not contain a pointset"); return; } m_Controls.m_lblSetSeedpoint->setText(""); mitk::Image* image = dynamic_cast(m_InputImageNode->GetData()); + mitk::Point3D seedPoint = pointSet->GetPointSet(mitk::BaseRenderer::GetInstance( mitk::BaseRenderer::GetRenderWindowByName("stdmulti.widget1") )->GetTimeStep())->GetPoints()->ElementAt(0); - mitkPixelTypeMultiplex3(AccessPixel,image->GetChannelDescriptor().GetPixelType(),image,seedPoint,m_SeedpointValue); + + if (image->GetGeometry()->IsInside(seedPoint)) + mitkPixelTypeMultiplex3(AccessPixel,image->GetChannelDescriptor().GetPixelType(),image,seedPoint,m_SeedpointValue) + else + return; /* In this case the seedpoint is placed e.g. in the lung or bronchialtree * The lowerFactor sets the windowsize depending on the regiongrowing direction */ m_CurrentRGDirectionIsUpwards = true; if (m_SeedpointValue < -500) { m_CurrentRGDirectionIsUpwards = false; } // Initializing the region by the area around the seedpoint m_SeedPointValueMean = 0; itk::Index<3> currentIndex, runningIndex; mitk::ScalarType pixelValues[125]; unsigned int pos (0); image->GetGeometry(0)->WorldToIndex(seedPoint, currentIndex); runningIndex = currentIndex; for(int i = runningIndex[0]-2; i <= runningIndex[0]+2; i++) { for(int j = runningIndex[1]-2; j <= runningIndex[1]+2; j++) { for(int k = runningIndex[2]-2; k <= runningIndex[2]+2; k++) { currentIndex[0] = i; currentIndex[1] = j; currentIndex[2] = k; if(image->GetGeometry()->IsIndexInside(currentIndex)) { int component = 0; m_InputImageNode->GetIntProperty("Image.Displayed Component", component); pixelValues[pos] = image->GetPixelValueByIndex(currentIndex, 0, component); pos++; } else { pixelValues[pos] = -10000000; pos++; } } } } //Now calculation mean of the pixelValues unsigned int numberOfValues(0); for (unsigned int i = 0; i < 125; i++) { if(pixelValues[i] > -10000000) { m_SeedPointValueMean += pixelValues[i]; numberOfValues++; } } m_SeedPointValueMean = m_SeedPointValueMean/numberOfValues; /* * Here the upper- and lower threshold is calculated: * The windowSize is 20% of the maximum range of the intensity values existing in the current image * If the RG direction is upwards the lower TH is meanSeedValue-0.15*windowSize and upper TH is meanSeedValue+0.85*windowsSize * if the RG direction is downwards the lower TH is meanSeedValue-0.85*windowSize and upper TH is meanSeedValue+0.15*windowsSize */ mitk::ScalarType min = image->GetStatistics()->GetScalarValueMin(); mitk::ScalarType max = image->GetStatistics()->GetScalarValueMax(); mitk::ScalarType windowSize = max - min; windowSize = 0.15*windowSize; if (m_CurrentRGDirectionIsUpwards) { m_LOWERTHRESHOLD = m_SeedPointValueMean; if (m_SeedpointValue < m_SeedPointValueMean) m_LOWERTHRESHOLD = m_SeedpointValue; m_UPPERTHRESHOLD = m_SeedpointValue + windowSize; if (m_UPPERTHRESHOLD > max) m_UPPERTHRESHOLD = max; m_Controls.m_ThresholdSlider->setMaximumValue(m_UPPERTHRESHOLD); m_Controls.m_ThresholdSlider->setMinimumValue(m_LOWERTHRESHOLD); } else { m_UPPERTHRESHOLD = m_SeedPointValueMean; if (m_SeedpointValue > m_SeedPointValueMean) m_UPPERTHRESHOLD = m_SeedpointValue; m_LOWERTHRESHOLD = m_SeedpointValue - windowSize; if (m_LOWERTHRESHOLD < min) m_LOWERTHRESHOLD = min; m_Controls.m_ThresholdSlider->setMinimumValue(m_LOWERTHRESHOLD); m_Controls.m_ThresholdSlider->setMaximumValue(m_UPPERTHRESHOLD); } } } void QmitkAdaptiveRegionGrowingToolGUI::RunSegmentation() { if (m_InputImageNode.IsNull()) { QMessageBox::information( NULL, "Adaptive Region Growing functionality", "Please specify the image in Datamanager!"); return; } mitk::DataNode::Pointer node = m_RegionGrow3DTool->GetPointSetNode(); if (node.IsNull()) { QMessageBox::information( NULL, "Adaptive Region Growing functionality", "Please insert a seed point inside the image.\n\nFirst press the \"Define Seed Point\" button,\nthen click left mouse button inside the image."); return; } //safety if no pointSet or pointSet empty mitk::PointSet::Pointer seedPointSet = dynamic_cast (node->GetData()); if (seedPointSet.IsNull()) { m_Controls.m_pbRunSegmentation->setEnabled(true); QMessageBox::information( NULL, "Adaptive Region Growing functionality", "The seed point is empty! Please choose a new seed point."); return; } int timeStep = mitk::BaseRenderer::GetInstance( mitk::BaseRenderer::GetRenderWindowByName("stdmulti.widget1") )->GetTimeStep(); if (!(seedPointSet->GetSize(timeStep))) { m_Controls.m_pbRunSegmentation->setEnabled(true); QMessageBox::information( NULL, "Adaptive Region Growing functionality", "The seed point is empty! Please choose a new seed point."); return; } QApplication::setOverrideCursor( QCursor(Qt::WaitCursor) ); mitk::PointSet::PointType seedPoint = seedPointSet->GetPointSet(timeStep)->GetPoints()->Begin().Value(); mitk::Image::Pointer orgImage = dynamic_cast (m_InputImageNode->GetData()); if (orgImage.IsNotNull()) { if (orgImage->GetDimension() == 4) { mitk::ImageTimeSelector::Pointer timeSelector = mitk::ImageTimeSelector::New(); timeSelector->SetInput(orgImage); timeSelector->SetTimeNr( timeStep ); timeSelector->UpdateLargestPossibleRegion(); mitk::Image* timedImage = timeSelector->GetOutput(); AccessByItk_2( timedImage , StartRegionGrowing, timedImage->GetGeometry(), seedPoint); } else if (orgImage->GetDimension() == 3) { //QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); //set the cursor to waiting AccessByItk_2(orgImage, StartRegionGrowing, orgImage->GetGeometry(), seedPoint); //QApplication::restoreOverrideCursor();//reset cursor } else { QApplication::restoreOverrideCursor();//reset cursor QMessageBox::information( NULL, "Adaptive Region Growing functionality", "Only images of dimension 3 or 4 can be processed!"); return; } } EnableControls(true); // Segmentation ran successfully, so enable all controls. node->SetVisibility(true); QApplication::restoreOverrideCursor();//reset cursor } template void QmitkAdaptiveRegionGrowingToolGUI::StartRegionGrowing(itk::Image* itkImage, mitk::BaseGeometry* imageGeometry, mitk::PointSet::PointType seedPoint) { typedef itk::Image InputImageType; typedef typename InputImageType::IndexType IndexType; typedef itk::ConnectedAdaptiveThresholdImageFilter RegionGrowingFilterType; typename RegionGrowingFilterType::Pointer regionGrower = RegionGrowingFilterType::New(); typedef itk::MinimumMaximumImageCalculator MinMaxValueFilterType; if ( !imageGeometry->IsInside(seedPoint) ) { QApplication::restoreOverrideCursor();//reset cursor to be able to click ok with the regular mouse cursor QMessageBox::information( NULL, "Segmentation functionality", "The seed point is outside of the image! Please choose a position inside the image!"); return; } IndexType seedIndex; imageGeometry->WorldToIndex( seedPoint, seedIndex);// convert world coordinates to image indices if (m_SeedpointValue>m_UPPERTHRESHOLD || m_SeedpointValueSetGrowingDirectionIsUpwards( m_CurrentRGDirectionIsUpwards ); regionGrower->SetInput( itkImage ); regionGrower->AddSeed( seedIndex ); //In some cases we have to subtract 1 for the lower threshold and add 1 to the upper. //Otherwise no region growing is done. Maybe a bug in the ConnectiveAdaptiveThresholdFilter regionGrower->SetLower( m_LOWERTHRESHOLD-1 ); regionGrower->SetUpper( m_UPPERTHRESHOLD+1); try { regionGrower->Update(); } catch(itk::ExceptionObject &exc) { QMessageBox errorInfo; errorInfo.setWindowTitle("Adaptive RG Segmentation Functionality"); errorInfo.setIcon(QMessageBox::Critical); errorInfo.setText("An error occurred during region growing!"); errorInfo.setDetailedText(exc.what()); errorInfo.exec(); return; // can't work } catch( ... ) { QMessageBox::critical( NULL, "Adaptive RG Segmentation Functionality", "An error occurred during region growing!"); return; } mitk::Image::Pointer resultImage = mitk::ImportItkImage(regionGrower->GetOutput())->Clone(); //initialize slider m_Controls.m_PreviewSlider->setMinimum(m_LOWERTHRESHOLD); mitk::ScalarType max = m_LOWERTHRESHOLD+resultImage->GetStatistics()->GetScalarValueMax(); if (max < m_UPPERTHRESHOLD) m_Controls.m_PreviewSlider->setMaximum(max); else m_Controls.m_PreviewSlider->setMaximum(m_UPPERTHRESHOLD); this->m_DetectedLeakagePoint = regionGrower->GetLeakagePoint(); if(m_CurrentRGDirectionIsUpwards) { m_Controls.m_PreviewSlider->setValue(m_SeedPointValueMean-1); } else { m_Controls.m_PreviewSlider->setValue(m_SeedPointValueMean+1); } this->m_SliderInitialized = true; //create new node and then delete the old one if there is one mitk::DataNode::Pointer newNode = mitk::DataNode::New(); newNode->SetData( resultImage ); // set some properties newNode->SetProperty("name", mitk::StringProperty::New(m_NAMEFORLABLEDSEGMENTATIONIMAGE)); newNode->SetProperty("helper object", mitk::BoolProperty::New(true)); newNode->SetProperty("color", mitk::ColorProperty::New(0.0,1.0,0.0)); newNode->SetProperty("layer", mitk::IntProperty::New(1)); newNode->SetProperty("opacity", mitk::FloatProperty::New(0.7)); //delete the old image, if there was one: mitk::DataNode::Pointer binaryNode = m_DataStorage->GetNamedNode(m_NAMEFORLABLEDSEGMENTATIONIMAGE); m_DataStorage->Remove(binaryNode); // now add result to data tree m_DataStorage->Add( newNode, m_InputImageNode ); this->InitializeLevelWindow(); if(m_UseVolumeRendering) this->EnableVolumeRendering(true); m_UpdateSuggestedThreshold = true;// reset first stored threshold value //Setting progress to finished mitk::ProgressBar::GetInstance()->Progress(357); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } void QmitkAdaptiveRegionGrowingToolGUI::InitializeLevelWindow() { //get the preview from the datatree mitk::DataNode::Pointer newNode = m_DataStorage->GetNamedNode( m_NAMEFORLABLEDSEGMENTATIONIMAGE); mitk::LevelWindow tempLevelWindow; newNode->GetLevelWindow(tempLevelWindow, NULL, "levelwindow"); mitk::ScalarType* level = new mitk::ScalarType(0.0); mitk::ScalarType* window = new mitk::ScalarType(1.0); int upper; if (m_CurrentRGDirectionIsUpwards) { upper = m_UPPERTHRESHOLD - m_SeedpointValue; } else { upper = m_SeedpointValue - m_LOWERTHRESHOLD; } tempLevelWindow.SetRangeMinMax(mitk::ScalarType(0), mitk::ScalarType(upper)); //get the suggested threshold from the detected leakage-point and adjust the slider if (m_CurrentRGDirectionIsUpwards) { this->m_Controls.m_PreviewSlider->setValue(m_SeedpointValue); *level = m_UPPERTHRESHOLD - (m_SeedpointValue) + 0.5; } else { this->m_Controls.m_PreviewSlider->setValue(m_SeedpointValue); *level = (m_SeedpointValue) - m_LOWERTHRESHOLD + 0.5; } tempLevelWindow.SetLevelWindow(*level, *window); newNode->SetLevelWindow(tempLevelWindow, NULL, "levelwindow"); //update the widgets mitk::RenderingManager::GetInstance()->RequestUpdateAll(); m_SliderInitialized = true; //inquiry need to fix bug#1828 static int lastSliderPosition = 0; if ((this->m_SeedpointValue + this->m_DetectedLeakagePoint - 1) == lastSliderPosition) { this->ChangeLevelWindow(lastSliderPosition); } lastSliderPosition = this->m_SeedpointValue + this->m_DetectedLeakagePoint-1; if(m_MultiWidget) { this->m_MultiWidget->levelWindowWidget->GetManager()->SetAutoTopMostImage(false); this->m_MultiWidget->levelWindowWidget->GetManager()->SetLevelWindowProperty(static_cast(newNode->GetProperty("levelwindow"))); } if (m_UseVolumeRendering) this->UpdateVolumeRenderingThreshold((int) (*level + 0.5));//lower threshold for labeled image } void QmitkAdaptiveRegionGrowingToolGUI::ChangeLevelWindow(double newValue) { if (m_SliderInitialized) { //do nothing, if no preview exists mitk::DataNode::Pointer newNode = m_DataStorage->GetNamedNode( m_NAMEFORLABLEDSEGMENTATIONIMAGE); if (newNode.IsNull()) return; mitk::LevelWindow tempLevelWindow; newNode->GetLevelWindow(tempLevelWindow, NULL, "levelwindow"); //get the levelWindow associated with the preview mitk::ScalarType level;// = this->m_UPPERTHRESHOLD - newValue + 0.5; mitk::ScalarType* window = new mitk::ScalarType(1); //adjust the levelwindow according to the position of the slider (newvalue) if (m_CurrentRGDirectionIsUpwards) { level = m_UPPERTHRESHOLD - newValue + 0.5; tempLevelWindow.SetLevelWindow(level, *window); } else { level = newValue - m_LOWERTHRESHOLD +0.5; tempLevelWindow.SetLevelWindow(level, *window); } newNode->SetLevelWindow(tempLevelWindow, NULL, "levelwindow"); if (m_UseVolumeRendering) this->UpdateVolumeRenderingThreshold((int) (level - 0.5));//lower threshold for labeled image newNode->SetVisibility(true); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } } void QmitkAdaptiveRegionGrowingToolGUI::DecreaseSlider() { //moves the slider one step to the left, when the "-"-button is pressed if (this->m_Controls.m_PreviewSlider->value() != this->m_Controls.m_PreviewSlider->minimum()) { int newValue = this->m_Controls.m_PreviewSlider->value() - 1; this->ChangeLevelWindow(newValue); this->m_Controls.m_PreviewSlider->setValue(newValue); } } void QmitkAdaptiveRegionGrowingToolGUI::IncreaseSlider() { //moves the slider one step to the right, when the "+"-button is pressed if (this->m_Controls.m_PreviewSlider->value() != this->m_Controls.m_PreviewSlider->maximum()) { int newValue = this->m_Controls.m_PreviewSlider->value() + 1; this->ChangeLevelWindow(newValue); this->m_Controls.m_PreviewSlider->setValue(newValue); } } void QmitkAdaptiveRegionGrowingToolGUI::ConfirmSegmentation() { //get image node if(m_InputImageNode.IsNull()) { QMessageBox::critical( NULL, "Adaptive region growing functionality", "Please specify the image in Datamanager!"); return; } //get image data mitk::Image::Pointer orgImage = dynamic_cast (m_InputImageNode->GetData()); if(orgImage.IsNull()) { QMessageBox::critical( NULL, "Adaptive region growing functionality", "No Image found!"); return; } //get labeled segmentation mitk::Image::Pointer labeledSeg = (mitk::Image*)m_DataStorage->GetNamedObject(m_NAMEFORLABLEDSEGMENTATIONIMAGE); if(labeledSeg.IsNull()) { QMessageBox::critical( NULL, "Adaptive region growing functionality", "No Segmentation Preview found!"); return; } mitk::DataNode::Pointer newNode = m_DataStorage->GetNamedNode( m_NAMEFORLABLEDSEGMENTATIONIMAGE); if (newNode.IsNull()) return; QmitkConfirmSegmentationDialog dialog; QString segName = QString::fromStdString(m_RegionGrow3DTool->GetCurrentSegmentationName()); dialog.SetSegmentationName(segName); int result = dialog.exec(); switch(result) { case QmitkConfirmSegmentationDialog::CREATE_NEW_SEGMENTATION: m_RegionGrow3DTool->SetOverwriteExistingSegmentation(false); break; case QmitkConfirmSegmentationDialog::OVERWRITE_SEGMENTATION: m_RegionGrow3DTool->SetOverwriteExistingSegmentation(true); break; case QmitkConfirmSegmentationDialog::CANCEL_SEGMENTATION: return; } mitk::Image* img = dynamic_cast(newNode->GetData()); AccessByItk(img, ITKThresholding); // disable volume rendering preview after the segmentation node was created this->EnableVolumeRendering(false); newNode->SetVisibility(false); m_Controls.m_cbVolumeRendering->setChecked(false); //TODO disable slider etc... } template void QmitkAdaptiveRegionGrowingToolGUI::ITKThresholding(itk::Image* itkImage) { mitk::Image::Pointer originalSegmentation = dynamic_cast(this->m_RegionGrow3DTool-> GetTargetSegmentationNode()->GetData()); int timeStep = mitk::BaseRenderer::GetInstance( mitk::BaseRenderer::GetRenderWindowByName("stdmulti.widget1") )->GetTimeStep(); if (originalSegmentation) { typedef itk::Image InputImageType; typedef itk::Image SegmentationType; //select single 3D volume if we have more than one time step typename SegmentationType::Pointer originalSegmentationInITK = SegmentationType::New(); if(originalSegmentation->GetTimeGeometry()->CountTimeSteps() > 1) { mitk::ImageTimeSelector::Pointer timeSelector = mitk::ImageTimeSelector::New(); timeSelector->SetInput( originalSegmentation ); timeSelector->SetTimeNr( timeStep ); timeSelector->UpdateLargestPossibleRegion(); CastToItkImage( timeSelector->GetOutput(), originalSegmentationInITK ); } else //use original { CastToItkImage( originalSegmentation, originalSegmentationInITK ); } //Fill current preiview image in segmentation image originalSegmentationInITK->FillBuffer(0); itk::ImageRegionIterator itOutput( originalSegmentationInITK, originalSegmentationInITK->GetLargestPossibleRegion() ); itk::ImageRegionIterator itInput( itkImage, itkImage->GetLargestPossibleRegion() ); itOutput.GoToBegin(); itInput.GoToBegin(); //calculate threhold from slider value int currentTreshold = 0; if (m_CurrentRGDirectionIsUpwards) { currentTreshold = m_UPPERTHRESHOLD - m_Controls.m_PreviewSlider->value() + 1; } else { currentTreshold = m_Controls.m_PreviewSlider->value() - m_LOWERTHRESHOLD; } //iterate over image and set pixel in segmentation according to thresholded labeled image while( !itOutput.IsAtEnd() && !itInput.IsAtEnd() ) { //Use threshold slider to determine if pixel is set to 1 if( itInput.Value() != 0 && itInput.Value() > currentTreshold ) { itOutput.Set( 1 ); } ++itOutput; ++itInput; } //combine current working segmentation image with our region growing result originalSegmentation->SetVolume( (void*)(originalSegmentationInITK->GetPixelContainer()->GetBufferPointer()), timeStep); originalSegmentation->Modified(); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } } void QmitkAdaptiveRegionGrowingToolGUI::EnableControls(bool enable) { if (m_RegionGrow3DTool.IsNull()) return; // Check if seed point is already set, if not leave RunSegmentation disabled //if even m_DataStorage is NULL leave node NULL mitk::DataNode::Pointer node = m_RegionGrow3DTool->GetPointSetNode(); if (node.IsNull()) { this->m_Controls.m_pbRunSegmentation->setEnabled(false); } else { this->m_Controls.m_pbRunSegmentation->setEnabled(enable); } // Check if a segmentation exists, if not leave segmentation dependent disabled. //if even m_DataStorage is NULL leave node NULL node = m_DataStorage?m_DataStorage->GetNamedNode(m_NAMEFORLABLEDSEGMENTATIONIMAGE):NULL; if (node.IsNull()) { this->m_Controls.m_PreviewSlider->setEnabled(false); this->m_Controls.m_pbConfirmSegementation->setEnabled(false); } else { this->m_Controls.m_PreviewSlider->setEnabled(enable); this->m_Controls.m_pbConfirmSegementation->setEnabled(enable); } this->m_Controls.m_cbVolumeRendering->setEnabled(enable); } void QmitkAdaptiveRegionGrowingToolGUI::EnableVolumeRendering(bool enable) { mitk::DataNode::Pointer node = m_DataStorage->GetNamedNode( m_NAMEFORLABLEDSEGMENTATIONIMAGE); if(node.IsNull()) return; if(m_MultiWidget) m_MultiWidget->SetWidgetPlanesVisibility(!enable); if (enable) { node->SetBoolProperty("volumerendering", enable); node->SetBoolProperty("volumerendering.uselod", true); } else { node->SetBoolProperty("volumerendering", enable); } mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } void QmitkAdaptiveRegionGrowingToolGUI::UpdateVolumeRenderingThreshold(int thValue) { mitk::DataNode::Pointer node = m_DataStorage->GetNamedNode( m_NAMEFORLABLEDSEGMENTATIONIMAGE); mitk::TransferFunction::Pointer tf = mitk::TransferFunction::New(); if (m_UpdateSuggestedThreshold) { m_SuggestedThValue = thValue; m_UpdateSuggestedThreshold = false; } // grayvalue->opacity { vtkPiecewiseFunction *f = tf->GetScalarOpacityFunction(); f->RemoveAllPoints(); f->AddPoint(0, 0); f->AddPoint(thValue+0.5, 0); f->AddPoint(thValue+1.5, 1); f->AddPoint(1000, 1); f->ClampingOn(); f->Modified(); } // grayvalue->color { float a = 255.0; vtkColorTransferFunction *ctf = tf->GetColorTransferFunction(); ctf->RemoveAllPoints(); //ctf->AddRGBPoint(-1000, 0.0, 0.0, 0.0); ctf->AddRGBPoint(m_SuggestedThValue+1, 203/a, 104/a, 102/a); ctf->AddRGBPoint(m_SuggestedThValue, 255/a, 0/a, 0/a); ctf->ClampingOn(); ctf->Modified(); } // GradientOpacityFunction { vtkPiecewiseFunction *gof = tf->GetGradientOpacityFunction(); gof->RemoveAllPoints(); gof->AddPoint(-10000, 1); gof->AddPoint(10000, 1); gof->ClampingOn(); gof->Modified(); } mitk::TransferFunctionProperty::Pointer tfp = mitk::TransferFunctionProperty::New(); tfp->SetValue(tf); node->SetProperty("TransferFunction", tfp); } void QmitkAdaptiveRegionGrowingToolGUI::UseVolumeRendering(bool on) { m_UseVolumeRendering = on; this->EnableVolumeRendering(on); } void QmitkAdaptiveRegionGrowingToolGUI::SetLowerThresholdValue( double lowerThreshold ) { m_LOWERTHRESHOLD = lowerThreshold; } void QmitkAdaptiveRegionGrowingToolGUI::SetUpperThresholdValue( double upperThreshold) { m_UPPERTHRESHOLD = upperThreshold; } void QmitkAdaptiveRegionGrowingToolGUI::Deactivated() { // make the segmentation preview node invisible mitk::DataNode::Pointer node = m_DataStorage->GetNamedNode( m_NAMEFORLABLEDSEGMENTATIONIMAGE); if( node.IsNotNull() ) { node->SetVisibility(false); } // disable volume rendering preview after the segmentation node was created this->EnableVolumeRendering(false); m_Controls.m_cbVolumeRendering->setChecked(false); } void QmitkAdaptiveRegionGrowingToolGUI::Activated() { } diff --git a/Modules/SegmentationUI/Qmitk/QmitkAdaptiveRegionGrowingToolGUI.h b/Modules/SegmentationUI/Qmitk/QmitkAdaptiveRegionGrowingToolGUI.h index 467cd69ad5..690313b614 100644 --- a/Modules/SegmentationUI/Qmitk/QmitkAdaptiveRegionGrowingToolGUI.h +++ b/Modules/SegmentationUI/Qmitk/QmitkAdaptiveRegionGrowingToolGUI.h @@ -1,233 +1,234 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #ifndef QMITK_QmitkAdaptiveRegionGrowingToolGUI_H #define QMITK_QmitkAdaptiveRegionGrowingToolGUI_H #include "mitkDataStorage.h" #include "itkImage.h" #include "mitkGeometry3D.h" #include "mitkPointSet.h" #include "qwidget.h" #include "ui_QmitkAdaptiveRegionGrowingToolGUIControls.h" #include #include "QmitkToolGUI.h" #include "mitkAdaptiveRegionGrowingTool.h" class QmitkStdMultiWidget; class DataNode; class QmitkAdaptiveRegionGrowingToolGUIControls; /*! * * \brief QmitkAdaptiveRegionGrowingToolGUI * * Adaptive Region Growing View class of the segmentation. * */ class MitkSegmentationUI_EXPORT QmitkAdaptiveRegionGrowingToolGUI : public QmitkToolGUI { Q_OBJECT public: /** * @brief mitkClassMacro */ mitkClassMacro(QmitkAdaptiveRegionGrowingToolGUI, QmitkToolGUI); itkFactorylessNewMacro(Self) itkCloneMacro(Self) QmitkAdaptiveRegionGrowingToolGUI(QWidget* parent=0); /** \brief Method to create the connections for the component. This Method is obligatory even if no connections is needed*/ virtual void CreateConnections(); ///** \brief Method to set the default data storage.*/ virtual void SetDataStorage(mitk::DataStorage* dataStorage); /** * @brief Method to set the used multiwidget. * @param multiWidget */ void SetMultiWidget(QmitkStdMultiWidget* multiWidget); /** * @brief Method to set the name of a data node. * @param labledSegmentation Name of the labeled segmentation * @param binaryImage Name of the binary image * @param surface Name of the surface */ void SetDataNodeNames(std::string labledSegmentation, std::string binaryImage, /*std::string vesselTree,*/ std::string surface); /** * @brief Method to enable/disable controls for region growing * * This method checks if a seed point is set and a segmentation exists. * @param enable/disable controls */ void EnableControls(bool enable); /** * @brief Method to set the input image node * @param data node */ void SetInputImageNode(mitk::DataNode* node); void Deactivated(); void Activated(); /** * @brief The created GUI from the .ui-File. This Attribute is obligatory */ Ui::QmitkAdaptiveRegionGrowingToolGUIControls m_Controls; protected slots: /** * @brief Method to start the segmentation * * This method is called, when the "Start Segmentation" button is clicked. */ void RunSegmentation(); /** * @brief Method to change the level window * * This method is called, when the level window slider is changed via the slider in the control widget * @param new value */ void ChangeLevelWindow(double newValue); /** * @brief Method to increase the preview slider * * This method is called, when the + button is clicked and increases the value by 1 */ void IncreaseSlider(); /** * @brief Method to decrease the preview slider * * This method is called, when the - button is clicked and decreases the value by 1 */ void DecreaseSlider(); /** * @brief Method to confirm the preview segmentation * * This method is called, when the "Confirm Segmentation" button is clicked. */ void ConfirmSegmentation(); /** * @brief Method to switch the volume rendering on/off * @param on/off */ void UseVolumeRendering(bool on); /** * @brief Method to set the lower threshold * * This method is called, when the minimum threshold slider has changed * @param lower threshold */ void SetLowerThresholdValue(double lowerThreshold); /** * @brief Method to set upper threshold * * This Method is called, when the maximum threshold slider has changed * @param upper threshold */ void SetUpperThresholdValue(double upperThreshold); /** * @brief Method to determine which tool to activate * * This method listens to the tool manager and activates this tool if requested otherwise disables this view */ void OnNewToolAssociated(mitk::Tool*); protected: mitk::AdaptiveRegionGrowingTool::Pointer m_RegionGrow3DTool; /** \brief Destructor. */ virtual ~QmitkAdaptiveRegionGrowingToolGUI(); //Pointer to the main widget to be able to reach the renderer QmitkStdMultiWidget* m_MultiWidget; mitk::DataStorage* m_DataStorage; mitk::DataNode::Pointer m_InputImageNode; /** * @brief Method to calculate parameter settings, when a seed point is set */ void OnPointAdded(); private: std::string m_NAMEFORORGIMAGE; std::string m_NAMEFORLABLEDSEGMENTATIONIMAGE; std::string m_NAMEFORBINARYIMAGE; std::string m_NAMEFORSURFACE; mitk::ScalarType m_LOWERTHRESHOLD; //Hounsfield value mitk::ScalarType m_UPPERTHRESHOLD; //Hounsfield value mitk::ScalarType m_SeedPointValueMean; void RemoveHelperNodes(); int m_DetectedLeakagePoint; bool m_CurrentRGDirectionIsUpwards; // defines fixed threshold (true = LOWERTHRESHOLD fixed, false = UPPERTHRESHOLD fixed) int m_SeedpointValue; bool m_SliderInitialized; bool m_UseVolumeRendering; bool m_UpdateSuggestedThreshold; float m_SuggestedThValue; long m_PointSetAddObserverTag; + long m_PointSetMoveObserverTag; template < typename TPixel, unsigned int VImageDimension > void StartRegionGrowing( itk::Image< TPixel, VImageDimension >* itkImage, mitk::BaseGeometry* imageGeometry, mitk::PointSet::PointType seedPoint ); template < typename TPixel, unsigned int VImageDimension > void ITKThresholding( itk::Image< TPixel, VImageDimension >* inputImage ); void InitializeLevelWindow(); void EnableVolumeRendering(bool enable); void UpdateVolumeRenderingThreshold(int thValue); }; #endif diff --git a/Modules/SegmentationUI/Qmitk/QmitkSlicesInterpolator.cpp b/Modules/SegmentationUI/Qmitk/QmitkSlicesInterpolator.cpp index cd351b7163..d382cf0d7a 100644 --- a/Modules/SegmentationUI/Qmitk/QmitkSlicesInterpolator.cpp +++ b/Modules/SegmentationUI/Qmitk/QmitkSlicesInterpolator.cpp @@ -1,1137 +1,1159 @@ /*=================================================================== 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 "QmitkSlicesInterpolator.h" #include "QmitkStdMultiWidget.h" #include "QmitkSelectableGLWidget.h" #include "mitkToolManager.h" #include "mitkDataNodeFactory.h" #include "mitkLevelWindowProperty.h" #include "mitkColorProperty.h" #include "mitkProperties.h" #include "mitkRenderingManager.h" #include "mitkOverwriteSliceImageFilter.h" #include "mitkProgressBar.h" #include "mitkGlobalInteraction.h" #include "mitkOperationEvent.h" #include "mitkUndoController.h" #include "mitkInteractionConst.h" #include "mitkApplyDiffImageOperation.h" #include "mitkDiffImageApplier.h" #include "mitkSegTool2D.h" #include "mitkCoreObjectFactory.h" #include "mitkSurfaceToImageFilter.h" #include "mitkSliceNavigationController.h" #include #include #include #include #include #include #include #include #include #include #include //#define ROUND(a) ((a)>0 ? (int)((a)+0.5) : -(int)(0.5-(a))) float SURFACE_COLOR_RGB [3] = {0.49f, 1.0f, 0.16f}; const std::map QmitkSlicesInterpolator::createActionToSliceDimension() { std::map actionToSliceDimension; foreach(mitk::SliceNavigationController* slicer, m_ControllerToDeleteObserverTag.keys()) { actionToSliceDimension[new QAction(QString::fromStdString(slicer->GetViewDirectionAsString()),0)] = slicer; } return actionToSliceDimension; } QmitkSlicesInterpolator::QmitkSlicesInterpolator(QWidget* parent, const char* /*name*/) :QWidget(parent), // ACTION_TO_SLICEDIMENSION( createActionToSliceDimension() ), m_Interpolator( mitk::SegmentationInterpolationController::New() ), m_SurfaceInterpolator(mitk::SurfaceInterpolationController::GetInstance()), m_ToolManager(NULL), m_Initialized(false), m_LastSNC(0), m_LastSliceIndex(0), m_2DInterpolationEnabled(false), m_3DInterpolationEnabled(false) { m_GroupBoxEnableExclusiveInterpolationMode = new QGroupBox("Interpolation", this); QVBoxLayout* vboxLayout = new QVBoxLayout(m_GroupBoxEnableExclusiveInterpolationMode); m_CmbInterpolation = new QComboBox(m_GroupBoxEnableExclusiveInterpolationMode); m_CmbInterpolation->addItem("Disabled"); m_CmbInterpolation->addItem("2-Dimensional"); m_CmbInterpolation->addItem("3-Dimensional"); vboxLayout->addWidget(m_CmbInterpolation); m_BtnApply2D = new QPushButton("Confirm for single slice", m_GroupBoxEnableExclusiveInterpolationMode); vboxLayout->addWidget(m_BtnApply2D); m_BtnApplyForAllSlices2D = new QPushButton("Confirm for all slices", m_GroupBoxEnableExclusiveInterpolationMode); vboxLayout->addWidget(m_BtnApplyForAllSlices2D); m_BtnApply3D = new QPushButton("Confirm", m_GroupBoxEnableExclusiveInterpolationMode); vboxLayout->addWidget(m_BtnApply3D); m_BtnReinit3DInterpolation = new QPushButton("Reinit Interpolation", m_GroupBoxEnableExclusiveInterpolationMode); vboxLayout->addWidget(m_BtnReinit3DInterpolation); m_ChkShowPositionNodes = new QCheckBox("Show Position Nodes", m_GroupBoxEnableExclusiveInterpolationMode); vboxLayout->addWidget(m_ChkShowPositionNodes); this->HideAllInterpolationControls(); connect(m_CmbInterpolation, SIGNAL(currentIndexChanged(int)), this, SLOT(OnInterpolationMethodChanged(int))); connect(m_BtnApply2D, SIGNAL(clicked()), this, SLOT(OnAcceptInterpolationClicked())); connect(m_BtnApplyForAllSlices2D, SIGNAL(clicked()), this, SLOT(OnAcceptAllInterpolationsClicked())); connect(m_BtnApply3D, SIGNAL(clicked()), this, SLOT(OnAccept3DInterpolationClicked())); connect(m_BtnReinit3DInterpolation, SIGNAL(clicked()), this, SLOT(OnReinit3DInterpolation())); connect(m_ChkShowPositionNodes, SIGNAL(toggled(bool)), this, SLOT(OnShowMarkers(bool))); connect(m_ChkShowPositionNodes, SIGNAL(toggled(bool)), this, SIGNAL(SignalShowMarkerNodes(bool))); QHBoxLayout* layout = new QHBoxLayout(this); layout->addWidget(m_GroupBoxEnableExclusiveInterpolationMode); this->setLayout(layout); itk::ReceptorMemberCommand::Pointer command = itk::ReceptorMemberCommand::New(); command->SetCallbackFunction( this, &QmitkSlicesInterpolator::OnInterpolationInfoChanged ); InterpolationInfoChangedObserverTag = m_Interpolator->AddObserver( itk::ModifiedEvent(), command ); itk::ReceptorMemberCommand::Pointer command2 = itk::ReceptorMemberCommand::New(); command2->SetCallbackFunction( this, &QmitkSlicesInterpolator::OnSurfaceInterpolationInfoChanged ); SurfaceInterpolationInfoChangedObserverTag = m_SurfaceInterpolator->AddObserver( itk::ModifiedEvent(), command2 ); // feedback node and its visualization properties m_FeedbackNode = mitk::DataNode::New(); mitk::CoreObjectFactory::GetInstance()->SetDefaultProperties( m_FeedbackNode ); m_FeedbackNode->SetProperty( "binary", mitk::BoolProperty::New(true) ); m_FeedbackNode->SetProperty( "outline binary", mitk::BoolProperty::New(true) ); m_FeedbackNode->SetProperty( "color", mitk::ColorProperty::New(255.0, 255.0, 0.0) ); m_FeedbackNode->SetProperty( "texture interpolation", mitk::BoolProperty::New(false) ); m_FeedbackNode->SetProperty( "layer", mitk::IntProperty::New( 20 ) ); m_FeedbackNode->SetProperty( "levelwindow", mitk::LevelWindowProperty::New( mitk::LevelWindow(0, 1) ) ); m_FeedbackNode->SetProperty( "name", mitk::StringProperty::New("Interpolation feedback") ); m_FeedbackNode->SetProperty( "opacity", mitk::FloatProperty::New(0.8) ); m_FeedbackNode->SetProperty( "helper object", mitk::BoolProperty::New(true) ); m_InterpolatedSurfaceNode = mitk::DataNode::New(); m_InterpolatedSurfaceNode->SetProperty( "color", mitk::ColorProperty::New(SURFACE_COLOR_RGB) ); m_InterpolatedSurfaceNode->SetProperty( "name", mitk::StringProperty::New("Surface Interpolation feedback") ); m_InterpolatedSurfaceNode->SetProperty( "opacity", mitk::FloatProperty::New(0.5) ); m_InterpolatedSurfaceNode->SetProperty( "line width", mitk::IntProperty::New(4) ); m_InterpolatedSurfaceNode->SetProperty( "includeInBoundingBox", mitk::BoolProperty::New(false)); m_InterpolatedSurfaceNode->SetProperty( "helper object", mitk::BoolProperty::New(true) ); m_InterpolatedSurfaceNode->SetVisibility(false); m_3DContourNode = mitk::DataNode::New(); m_3DContourNode->SetProperty( "color", mitk::ColorProperty::New(0.0, 0.0, 0.0) ); m_3DContourNode->SetProperty("hidden object", mitk::BoolProperty::New(true)); m_3DContourNode->SetProperty( "name", mitk::StringProperty::New("Drawn Contours") ); m_3DContourNode->SetProperty("material.representation", mitk::VtkRepresentationProperty::New(VTK_WIREFRAME)); m_3DContourNode->SetProperty("material.wireframeLineWidth", mitk::FloatProperty::New(2.0f)); m_3DContourNode->SetProperty("3DContourContainer", mitk::BoolProperty::New(true)); m_3DContourNode->SetProperty( "includeInBoundingBox", mitk::BoolProperty::New(false)); m_3DContourNode->SetVisibility(false, mitk::BaseRenderer::GetInstance( mitk::BaseRenderer::GetRenderWindowByName("stdmulti.widget1"))); m_3DContourNode->SetVisibility(false, mitk::BaseRenderer::GetInstance( mitk::BaseRenderer::GetRenderWindowByName("stdmulti.widget2"))); m_3DContourNode->SetVisibility(false, mitk::BaseRenderer::GetInstance( mitk::BaseRenderer::GetRenderWindowByName("stdmulti.widget3"))); m_3DContourNode->SetVisibility(false, mitk::BaseRenderer::GetInstance( mitk::BaseRenderer::GetRenderWindowByName("stdmulti.widget4"))); QWidget::setContentsMargins(0, 0, 0, 0); if ( QWidget::layout() != NULL ) { QWidget::layout()->setContentsMargins(0, 0, 0, 0); } //For running 3D Interpolation in background // create a QFuture and a QFutureWatcher connect(&m_Watcher, SIGNAL(started()), this, SLOT(StartUpdateInterpolationTimer())); connect(&m_Watcher, SIGNAL(finished()), this, SLOT(OnSurfaceInterpolationFinished())); connect(&m_Watcher, SIGNAL(finished()), this, SLOT(StopUpdateInterpolationTimer())); m_Timer = new QTimer(this); connect(m_Timer, SIGNAL(timeout()), this, SLOT(ChangeSurfaceColor())); } void QmitkSlicesInterpolator::SetDataStorage( mitk::DataStorage::Pointer storage ) { m_DataStorage = storage; m_SurfaceInterpolator->SetDataStorage(storage); } mitk::DataStorage* QmitkSlicesInterpolator::GetDataStorage() { if ( m_DataStorage.IsNotNull() ) { return m_DataStorage; } else { return NULL; } } void QmitkSlicesInterpolator::Initialize(mitk::ToolManager* toolManager, const QList &controllers) { Q_ASSERT(!controllers.empty()); if (m_Initialized) { // remove old observers Uninitialize(); } m_ToolManager = toolManager; if (m_ToolManager) { // set enabled only if a segmentation is selected mitk::DataNode* node = m_ToolManager->GetWorkingData(0); QWidget::setEnabled( node != NULL ); // react whenever the set of selected segmentation changes m_ToolManager->WorkingDataChanged += mitk::MessageDelegate( this, &QmitkSlicesInterpolator::OnToolManagerWorkingDataModified ); m_ToolManager->ReferenceDataChanged += mitk::MessageDelegate( this, &QmitkSlicesInterpolator::OnToolManagerReferenceDataModified ); // connect to the slice navigation controller. after each change, call the interpolator foreach(mitk::SliceNavigationController* slicer, controllers) { //Has to be initialized m_LastSNC = slicer; m_TimeStep.insert(slicer, slicer->GetTime()->GetPos()); itk::MemberCommand::Pointer deleteCommand = itk::MemberCommand::New(); deleteCommand->SetCallbackFunction( this, &QmitkSlicesInterpolator::OnSliceNavigationControllerDeleted); m_ControllerToDeleteObserverTag.insert(slicer, slicer->AddObserver(itk::DeleteEvent(), deleteCommand)); itk::MemberCommand::Pointer timeChangedCommand = itk::MemberCommand::New(); timeChangedCommand->SetCallbackFunction( this, &QmitkSlicesInterpolator::OnTimeChanged); m_ControllerToTimeObserverTag.insert(slicer, slicer->AddObserver(mitk::SliceNavigationController::TimeGeometryEvent(NULL,0), timeChangedCommand)); itk::MemberCommand::Pointer sliceChangedCommand = itk::MemberCommand::New(); sliceChangedCommand->SetCallbackFunction( this, &QmitkSlicesInterpolator::OnSliceChanged); m_ControllerToSliceObserverTag.insert(slicer, slicer->AddObserver(mitk::SliceNavigationController::GeometrySliceEvent(NULL,0), sliceChangedCommand)); } ACTION_TO_SLICEDIMENSION = createActionToSliceDimension(); } m_Initialized = true; } void QmitkSlicesInterpolator::Uninitialize() { if (m_ToolManager.IsNotNull()) { m_ToolManager->WorkingDataChanged -= mitk::MessageDelegate(this, &QmitkSlicesInterpolator::OnToolManagerWorkingDataModified); m_ToolManager->ReferenceDataChanged -= mitk::MessageDelegate(this, &QmitkSlicesInterpolator::OnToolManagerReferenceDataModified); } foreach(mitk::SliceNavigationController* slicer, m_ControllerToSliceObserverTag.keys()) { slicer->RemoveObserver(m_ControllerToDeleteObserverTag.take(slicer)); slicer->RemoveObserver(m_ControllerToTimeObserverTag.take(slicer)); slicer->RemoveObserver(m_ControllerToSliceObserverTag.take(slicer)); } ACTION_TO_SLICEDIMENSION.clear(); m_ToolManager = NULL; m_Initialized = false; } QmitkSlicesInterpolator::~QmitkSlicesInterpolator() { if (m_Initialized) { // remove old observers Uninitialize(); } if(m_DataStorage->Exists(m_3DContourNode)) m_DataStorage->Remove(m_3DContourNode); if(m_DataStorage->Exists(m_InterpolatedSurfaceNode)) m_DataStorage->Remove(m_InterpolatedSurfaceNode); // remove observer m_Interpolator->RemoveObserver( InterpolationInfoChangedObserverTag ); m_SurfaceInterpolator->RemoveObserver( SurfaceInterpolationInfoChangedObserverTag ); delete m_Timer; } /** External enableization... */ void QmitkSlicesInterpolator::setEnabled( bool enable ) { QWidget::setEnabled(enable); //Set the gui elements of the different interpolation modi enabled if (enable) { if (m_2DInterpolationEnabled) { this->Show2DInterpolationControls(true); m_Interpolator->Activate2DInterpolation(true); } else if (m_3DInterpolationEnabled) { this->Show3DInterpolationControls(true); this->Show3DInterpolationResult(true); } } //Set all gui elements of the interpolation disabled else { this->HideAllInterpolationControls(); this->Show3DInterpolationResult(false); } } void QmitkSlicesInterpolator::On2DInterpolationEnabled(bool status) { OnInterpolationActivated(status); m_Interpolator->Activate2DInterpolation(status); } void QmitkSlicesInterpolator::On3DInterpolationEnabled(bool status) { On3DInterpolationActivated(status); } void QmitkSlicesInterpolator::OnInterpolationDisabled(bool status) { if (status) { OnInterpolationActivated(!status); On3DInterpolationActivated(!status); this->Show3DInterpolationResult(false); } } void QmitkSlicesInterpolator::HideAllInterpolationControls() { this->Show2DInterpolationControls(false); this->Show3DInterpolationControls(false); } void QmitkSlicesInterpolator::Show2DInterpolationControls(bool show) { m_BtnApply2D->setVisible(show); m_BtnApplyForAllSlices2D->setVisible(show); } void QmitkSlicesInterpolator::Show3DInterpolationControls(bool show) { m_BtnApply3D->setVisible(show); m_ChkShowPositionNodes->setVisible(show); m_BtnReinit3DInterpolation->setVisible(show); } void QmitkSlicesInterpolator::OnInterpolationMethodChanged(int index) { switch(index) { case 0: // Disabled m_GroupBoxEnableExclusiveInterpolationMode->setTitle("Interpolation"); this->HideAllInterpolationControls(); this->OnInterpolationActivated(false); this->On3DInterpolationActivated(false); this->Show3DInterpolationResult(false); m_Interpolator->Activate2DInterpolation(false); break; case 1: // 2D m_GroupBoxEnableExclusiveInterpolationMode->setTitle("Interpolation (Enabled)"); this->HideAllInterpolationControls(); this->Show2DInterpolationControls(true); this->OnInterpolationActivated(true); this->On3DInterpolationActivated(false); m_Interpolator->Activate2DInterpolation(true); break; case 2: // 3D m_GroupBoxEnableExclusiveInterpolationMode->setTitle("Interpolation (Enabled)"); this->HideAllInterpolationControls(); this->Show3DInterpolationControls(true); this->OnInterpolationActivated(false); this->On3DInterpolationActivated(true); m_Interpolator->Activate2DInterpolation(false); break; default: MITK_ERROR << "Unknown interpolation method!"; m_CmbInterpolation->setCurrentIndex(0); break; } } void QmitkSlicesInterpolator::OnShowMarkers(bool state) { mitk::DataStorage::SetOfObjects::ConstPointer allContourMarkers = m_DataStorage->GetSubset(mitk::NodePredicateProperty::New("isContourMarker" , mitk::BoolProperty::New(true))); for (mitk::DataStorage::SetOfObjects::ConstIterator it = allContourMarkers->Begin(); it != allContourMarkers->End(); ++it) { it->Value()->SetProperty("helper object", mitk::BoolProperty::New(!state)); } } void QmitkSlicesInterpolator::OnToolManagerWorkingDataModified() { if (m_ToolManager->GetWorkingData(0) != 0) { m_Segmentation = dynamic_cast(m_ToolManager->GetWorkingData(0)->GetData()); m_BtnReinit3DInterpolation->setEnabled(true); } else { //If no workingdata is set, remove the interpolation feedback this->GetDataStorage()->Remove(m_FeedbackNode); m_FeedbackNode->SetData(NULL); this->GetDataStorage()->Remove(m_3DContourNode); m_3DContourNode->SetData(NULL); this->GetDataStorage()->Remove(m_InterpolatedSurfaceNode); m_InterpolatedSurfaceNode->SetData(NULL); m_BtnReinit3DInterpolation->setEnabled(false); return; } //Updating the current selected segmentation for the 3D interpolation SetCurrentContourListID(); if (m_2DInterpolationEnabled) { OnInterpolationActivated( true ); // re-initialize if needed } this->CheckSupportedImageDimension(); } void QmitkSlicesInterpolator::OnToolManagerReferenceDataModified() { } void QmitkSlicesInterpolator::OnTimeChanged(itk::Object* sender, const itk::EventObject& e) { //Check if we really have a GeometryTimeEvent if (!dynamic_cast(&e)) return; mitk::SliceNavigationController* slicer = dynamic_cast(sender); Q_ASSERT(slicer); m_TimeStep[slicer]; if (m_LastSNC == slicer) { slicer->SendSlice();//will trigger a new interpolation } } void QmitkSlicesInterpolator::OnSliceChanged(itk::Object *sender, const itk::EventObject &e) { //Check whether we really have a GeometrySliceEvent if (!dynamic_cast(&e)) return; mitk::SliceNavigationController* slicer = dynamic_cast(sender); if (TranslateAndInterpolateChangedSlice(e, slicer)) { slicer->GetRenderer()->RequestUpdate(); } } bool QmitkSlicesInterpolator::TranslateAndInterpolateChangedSlice(const itk::EventObject& e, mitk::SliceNavigationController* slicer) { if (!m_2DInterpolationEnabled) return false; try { const mitk::SliceNavigationController::GeometrySliceEvent& event = dynamic_cast(e); mitk::TimeGeometry* tsg = event.GetTimeGeometry(); if (tsg && m_TimeStep.contains(slicer)) { mitk::SlicedGeometry3D* slicedGeometry = dynamic_cast(tsg->GetGeometryForTimeStep(m_TimeStep[slicer]).GetPointer()); if (slicedGeometry) { m_LastSNC = slicer; mitk::PlaneGeometry* plane = dynamic_cast(slicedGeometry->GetPlaneGeometry( event.GetPos() )); if (plane) Interpolate( plane, m_TimeStep[slicer], slicer ); return true; } } } catch(std::bad_cast) { return false; // so what } return false; } void QmitkSlicesInterpolator::Interpolate( mitk::PlaneGeometry* plane, unsigned int timeStep, mitk::SliceNavigationController* slicer ) { if (m_ToolManager) { mitk::DataNode* node = m_ToolManager->GetWorkingData(0); if (node) { m_Segmentation = dynamic_cast(node->GetData()); if (m_Segmentation) { int clickedSliceDimension(-1); int clickedSliceIndex(-1); // calculate real slice position, i.e. slice of the image and not slice of the TimeSlicedGeometry mitk::SegTool2D::DetermineAffectedImageSlice( m_Segmentation, plane, clickedSliceDimension, clickedSliceIndex ); mitk::Image::Pointer interpolation = m_Interpolator->Interpolate( clickedSliceDimension, clickedSliceIndex, plane, timeStep ); m_FeedbackNode->SetData( interpolation ); m_LastSNC = slicer; m_LastSliceIndex = clickedSliceIndex; } } } } void QmitkSlicesInterpolator::OnSurfaceInterpolationFinished() { mitk::Surface::Pointer interpolatedSurface = m_SurfaceInterpolator->GetInterpolationResult(); mitk::DataNode* workingNode = m_ToolManager->GetWorkingData(0); if(interpolatedSurface.IsNotNull() && workingNode && workingNode->IsVisible(mitk::BaseRenderer::GetInstance( mitk::BaseRenderer::GetRenderWindowByName("stdmulti.widget3")))) { m_BtnApply3D->setEnabled(true); m_InterpolatedSurfaceNode->SetData(interpolatedSurface); m_3DContourNode->SetData(m_SurfaceInterpolator->GetContoursAsSurface()); this->Show3DInterpolationResult(true); if( !m_DataStorage->Exists(m_InterpolatedSurfaceNode) ) { m_DataStorage->Add(m_InterpolatedSurfaceNode); } if (!m_DataStorage->Exists(m_3DContourNode)) { m_DataStorage->Add(m_3DContourNode, workingNode); } } else if (interpolatedSurface.IsNull()) { m_BtnApply3D->setEnabled(false); if (m_DataStorage->Exists(m_InterpolatedSurfaceNode)) { this->Show3DInterpolationResult(false); } } m_BtnReinit3DInterpolation->setEnabled(true); foreach (mitk::SliceNavigationController* slicer, m_ControllerToTimeObserverTag.keys()) { slicer->GetRenderer()->RequestUpdate(); } } void QmitkSlicesInterpolator::OnAcceptInterpolationClicked() { if (m_Segmentation && m_FeedbackNode->GetData()) { //making interpolation separately undoable mitk::UndoStackItem::IncCurrObjectEventId(); mitk::UndoStackItem::IncCurrGroupEventId(); mitk::UndoStackItem::ExecuteIncrement(); //Make sure that for reslicing and overwriting the same alogrithm is used. We can specify the mode of the vtk reslicer vtkSmartPointer reslice = vtkSmartPointer::New(); // Set slice as input mitk::Image::Pointer slice = dynamic_cast(m_FeedbackNode->GetData()); reslice->SetInputSlice(slice->GetSliceData()->GetVtkImageAccessor(slice)->GetVtkImageData()); //set overwrite mode to true to write back to the image volume reslice->SetOverwriteMode(true); reslice->Modified(); mitk::ExtractSliceFilter::Pointer extractor = mitk::ExtractSliceFilter::New(reslice); extractor->SetInput( m_Segmentation ); unsigned int timestep = m_LastSNC->GetTime()->GetPos(); extractor->SetTimeStep( timestep ); extractor->SetWorldGeometry( m_LastSNC->GetCurrentPlaneGeometry() ); extractor->SetVtkOutputRequest(true); extractor->SetResliceTransformByGeometry( m_Segmentation->GetTimeGeometry()->GetGeometryForTimeStep( timestep ) ); extractor->Modified(); extractor->Update(); //the image was modified within the pipeline, but not marked so m_Segmentation->Modified(); m_Segmentation->GetVtkImageData()->Modified(); m_FeedbackNode->SetData(NULL); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } } void QmitkSlicesInterpolator::AcceptAllInterpolations(mitk::SliceNavigationController* slicer) { /* * What exactly is done here: * 1. We create an empty diff image for the current segmentation * 2. All interpolated slices are written into the diff image * 3. Then the diffimage is applied to the original segmentation */ if (m_Segmentation) { //making interpolation separately undoable mitk::UndoStackItem::IncCurrObjectEventId(); mitk::UndoStackItem::IncCurrGroupEventId(); mitk::UndoStackItem::ExecuteIncrement(); mitk::Image::Pointer image3D = m_Segmentation; unsigned int timeStep( slicer->GetTime()->GetPos() ); if (m_Segmentation->GetDimension() == 4) { mitk::ImageTimeSelector::Pointer timeSelector = mitk::ImageTimeSelector::New(); timeSelector->SetInput( m_Segmentation ); timeSelector->SetTimeNr( timeStep ); timeSelector->Update(); image3D = timeSelector->GetOutput(); } // create a empty diff image for the undo operation mitk::Image::Pointer diffImage = mitk::Image::New(); diffImage->Initialize( image3D ); // Create scope for ImageWriteAccessor so that the accessor is destroyed // after the image is initialized. Otherwise later image access will lead to an error { mitk::ImageWriteAccessor imAccess(diffImage); // Set all pixels to zero mitk::PixelType pixelType( mitk::MakeScalarPixelType() ); memset( imAccess.GetData(), 0, (pixelType.GetBpe() >> 3) * diffImage->GetDimension(0) * diffImage->GetDimension(1) * diffImage->GetDimension(2) ); } // Since we need to shift the plane it must be clone so that the original plane isn't altered mitk::PlaneGeometry::Pointer reslicePlane = slicer->GetCurrentPlaneGeometry()->Clone(); int sliceDimension(-1); int sliceIndex(-1); mitk::SegTool2D::DetermineAffectedImageSlice( m_Segmentation, reslicePlane, sliceDimension, sliceIndex ); unsigned int zslices = m_Segmentation->GetDimension( sliceDimension ); mitk::ProgressBar::GetInstance()->AddStepsToDo(zslices); mitk::Point3D origin = reslicePlane->GetOrigin(); unsigned int totalChangedSlices(0); for (unsigned int sliceIndex = 0; sliceIndex < zslices; ++sliceIndex) { // Transforming the current origin of the reslice plane // so that it matches the one of the next slice m_Segmentation->GetSlicedGeometry()->WorldToIndex(origin, origin); origin[sliceDimension] = sliceIndex; m_Segmentation->GetSlicedGeometry()->IndexToWorld(origin, origin); reslicePlane->SetOrigin(origin); //Set the slice as 'input' mitk::Image::Pointer interpolation = m_Interpolator->Interpolate( sliceDimension, sliceIndex, reslicePlane, timeStep ); if (interpolation.IsNotNull()) // we don't check if interpolation is necessary/sensible - but m_Interpolator does { //Setting up the reslicing pipeline which allows us to write the interpolation results back into //the image volume vtkSmartPointer reslice = vtkSmartPointer::New(); //set overwrite mode to true to write back to the image volume reslice->SetInputSlice(interpolation->GetSliceData()->GetVtkImageAccessor(interpolation)->GetVtkImageData()); reslice->SetOverwriteMode(true); reslice->Modified(); mitk::ExtractSliceFilter::Pointer diffslicewriter = mitk::ExtractSliceFilter::New(reslice); diffslicewriter->SetInput( diffImage ); diffslicewriter->SetTimeStep( timeStep ); diffslicewriter->SetWorldGeometry(reslicePlane); diffslicewriter->SetVtkOutputRequest(true); diffslicewriter->SetResliceTransformByGeometry( diffImage->GetTimeGeometry()->GetGeometryForTimeStep( timeStep ) ); diffslicewriter->Modified(); diffslicewriter->Update(); ++totalChangedSlices; } mitk::ProgressBar::GetInstance()->Progress(); } mitk::RenderingManager::GetInstance()->RequestUpdateAll(); if (totalChangedSlices > 0) { // store undo stack items if ( true ) { // create do/undo operations mitk::ApplyDiffImageOperation* doOp = new mitk::ApplyDiffImageOperation( mitk::OpTEST, m_Segmentation, diffImage, timeStep ); mitk::ApplyDiffImageOperation* undoOp = new mitk::ApplyDiffImageOperation( mitk::OpTEST, m_Segmentation, diffImage, timeStep ); undoOp->SetFactor( -1.0 ); std::stringstream comment; comment << "Confirm all interpolations (" << totalChangedSlices << ")"; mitk::OperationEvent* undoStackItem = new mitk::OperationEvent( mitk::DiffImageApplier::GetInstanceForUndo(), doOp, undoOp, comment.str() ); mitk::UndoController::GetCurrentUndoModel()->SetOperationEvent( undoStackItem ); // acutally apply the changes here to the original image mitk::DiffImageApplier::GetInstanceForUndo()->ExecuteOperation( doOp ); } } m_FeedbackNode->SetData(NULL); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } } void QmitkSlicesInterpolator::FinishInterpolation(mitk::SliceNavigationController* slicer) { //this redirect is for calling from outside if (slicer == NULL) OnAcceptAllInterpolationsClicked(); else AcceptAllInterpolations( slicer ); } void QmitkSlicesInterpolator::OnAcceptAllInterpolationsClicked() { QMenu orientationPopup(this); std::map::const_iterator it; for(it = ACTION_TO_SLICEDIMENSION.begin(); it != ACTION_TO_SLICEDIMENSION.end(); it++) orientationPopup.addAction(it->first); connect( &orientationPopup, SIGNAL(triggered(QAction*)), this, SLOT(OnAcceptAllPopupActivated(QAction*)) ); orientationPopup.exec( QCursor::pos() ); } void QmitkSlicesInterpolator::OnAccept3DInterpolationClicked() { if (m_InterpolatedSurfaceNode.IsNotNull() && m_InterpolatedSurfaceNode->GetData()) { mitk::SurfaceToImageFilter::Pointer s2iFilter = mitk::SurfaceToImageFilter::New(); s2iFilter->MakeOutputBinaryOn(); s2iFilter->SetInput(dynamic_cast(m_InterpolatedSurfaceNode->GetData())); // check if ToolManager holds valid ReferenceData if (m_ToolManager->GetReferenceData(0) == NULL || m_ToolManager->GetWorkingData(0) == NULL) { return; } s2iFilter->SetImage(dynamic_cast(m_ToolManager->GetReferenceData(0)->GetData())); s2iFilter->Update(); mitk::DataNode* segmentationNode = m_ToolManager->GetWorkingData(0); - segmentationNode->SetData(s2iFilter->GetOutput()); + mitk::Image* oldSeg = dynamic_cast(segmentationNode->GetData()); + mitk::Image::Pointer newSeg = s2iFilter->GetOutput(); + if (oldSeg) + m_SurfaceInterpolator->ReplaceInterpolationSession(oldSeg, newSeg); + else + return; + + segmentationNode->SetData(newSeg); m_CmbInterpolation->setCurrentIndex(0); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); mitk::DataNode::Pointer segSurface = mitk::DataNode::New(); float rgb[3]; segmentationNode->GetColor(rgb); segSurface->SetColor(rgb); segSurface->SetData(m_InterpolatedSurfaceNode->GetData()); std::stringstream stream; stream << segmentationNode->GetName(); stream << "_"; stream << "3D-interpolation"; segSurface->SetName(stream.str()); segSurface->SetProperty( "opacity", mitk::FloatProperty::New(0.7) ); - segSurface->SetProperty( "includeInBoundingBox", mitk::BoolProperty::New(false)); + segSurface->SetProperty( "includeInBoundingBox", mitk::BoolProperty::New(true)); + segSurface->SetProperty( "3DInterpolationResult", mitk::BoolProperty::New(true)); m_DataStorage->Add(segSurface, segmentationNode); this->Show3DInterpolationResult(false); } } void QmitkSlicesInterpolator::OnReinit3DInterpolation() { mitk::NodePredicateProperty::Pointer pred = mitk::NodePredicateProperty::New("3DContourContainer", mitk::BoolProperty::New(true)); mitk::DataStorage::SetOfObjects::ConstPointer contourNodes = m_DataStorage->GetDerivations( m_ToolManager->GetWorkingData(0), pred); if (contourNodes->Size() != 0) { m_3DContourNode = contourNodes->at(0); } else { QMessageBox errorInfo; errorInfo.setWindowTitle("Reinitialize surface interpolation"); errorInfo.setIcon(QMessageBox::Information); errorInfo.setText("No contours available for the selected segmentation!"); errorInfo.exec(); } mitk::Surface::Pointer contours = dynamic_cast(m_3DContourNode->GetData()); if (contours) mitk::SurfaceInterpolationController::GetInstance()->ReinitializeInterpolation(contours); m_BtnReinit3DInterpolation->setEnabled(false); } void QmitkSlicesInterpolator::OnAcceptAllPopupActivated(QAction* action) { try { std::map::const_iterator iter = ACTION_TO_SLICEDIMENSION.find( action ); if (iter != ACTION_TO_SLICEDIMENSION.end()) { mitk::SliceNavigationController* slicer = iter->second; AcceptAllInterpolations( slicer ); } } catch(...) { /* Showing message box with possible memory error */ QMessageBox errorInfo; errorInfo.setWindowTitle("Interpolation Process"); errorInfo.setIcon(QMessageBox::Critical); errorInfo.setText("An error occurred during interpolation. Possible cause: Not enough memory!"); errorInfo.exec(); //additional error message on std::cerr std::cerr << "Ill construction in " __FILE__ " l. " << __LINE__ << std::endl; } } void QmitkSlicesInterpolator::OnInterpolationActivated(bool on) { m_2DInterpolationEnabled = on; try { if ( m_DataStorage.IsNotNull() ) { if (on && !m_DataStorage->Exists(m_FeedbackNode)) { m_DataStorage->Add( m_FeedbackNode ); } } } catch(...) { // don't care (double add/remove) } if (m_ToolManager) { mitk::DataNode* workingNode = m_ToolManager->GetWorkingData(0); mitk::DataNode* referenceNode = m_ToolManager->GetReferenceData(0); QWidget::setEnabled( workingNode != NULL ); m_BtnApply2D->setEnabled( on ); m_FeedbackNode->SetVisibility( on ); if (!on) { mitk::RenderingManager::GetInstance()->RequestUpdateAll(); return; } if (workingNode) { mitk::Image* segmentation = dynamic_cast(workingNode->GetData()); if (segmentation) { m_Interpolator->SetSegmentationVolume( segmentation ); if (referenceNode) { mitk::Image* referenceImage = dynamic_cast(referenceNode->GetData()); m_Interpolator->SetReferenceVolume( referenceImage ); // may be NULL } } } } UpdateVisibleSuggestion(); } void QmitkSlicesInterpolator::Run3DInterpolation() { m_SurfaceInterpolator->Interpolate(); } void QmitkSlicesInterpolator::StartUpdateInterpolationTimer() { m_Timer->start(500); } void QmitkSlicesInterpolator::StopUpdateInterpolationTimer() { m_Timer->stop(); m_InterpolatedSurfaceNode->SetProperty("color", mitk::ColorProperty::New(SURFACE_COLOR_RGB)); mitk::RenderingManager::GetInstance()->RequestUpdate(mitk::BaseRenderer::GetInstance( mitk::BaseRenderer::GetRenderWindowByName("stdmulti.widget4"))->GetRenderWindow()); } void QmitkSlicesInterpolator::ChangeSurfaceColor() { float currentColor[3]; m_InterpolatedSurfaceNode->GetColor(currentColor); if( currentColor[2] == SURFACE_COLOR_RGB[2]) { m_InterpolatedSurfaceNode->SetProperty("color", mitk::ColorProperty::New(1.0f,1.0f,1.0f)); } else { m_InterpolatedSurfaceNode->SetProperty("color", mitk::ColorProperty::New(SURFACE_COLOR_RGB)); } m_InterpolatedSurfaceNode->Update(); mitk::RenderingManager::GetInstance()->RequestUpdate(mitk::BaseRenderer::GetInstance( mitk::BaseRenderer::GetRenderWindowByName("stdmulti.widget4"))->GetRenderWindow()); } void QmitkSlicesInterpolator::On3DInterpolationActivated(bool on) { m_3DInterpolationEnabled = on; this->CheckSupportedImageDimension(); try { if ( m_DataStorage.IsNotNull() && m_ToolManager && m_3DInterpolationEnabled) { mitk::DataNode* workingNode = m_ToolManager->GetWorkingData(0); if (workingNode) { bool isInterpolationResult(false); workingNode->GetBoolProperty("3DInterpolationResult",isInterpolationResult); + mitk::NodePredicateAnd::Pointer pred = mitk::NodePredicateAnd::New(mitk::NodePredicateProperty::New("3DInterpolationResult", mitk::BoolProperty::New(true)), + mitk::NodePredicateDataType::New("Surface")); + mitk::DataStorage::SetOfObjects::ConstPointer interpolationResults = + m_DataStorage->GetDerivations(workingNode, pred); + + for (unsigned int i = 0; i < interpolationResults->Size(); ++i) + { + mitk::DataNode::Pointer currNode = interpolationResults->at(i); + if (currNode.IsNotNull()) + m_DataStorage->Remove(currNode); + } if ((workingNode->IsVisible(mitk::BaseRenderer::GetInstance( mitk::BaseRenderer::GetRenderWindowByName("stdmulti.widget3")))) && !isInterpolationResult && m_3DInterpolationEnabled) { int ret = QMessageBox::Yes; if (m_SurfaceInterpolator->EstimatePortionOfNeededMemory() > 0.5) { QMessageBox msgBox; msgBox.setText("Due to short handed system memory the 3D interpolation may be very slow!"); msgBox.setInformativeText("Are you sure you want to activate the 3D interpolation?"); msgBox.setStandardButtons(QMessageBox::No | QMessageBox::Yes); ret = msgBox.exec(); } if (m_Watcher.isRunning()) m_Watcher.waitForFinished(); if (ret == QMessageBox::Yes) { m_Future = QtConcurrent::run(this, &QmitkSlicesInterpolator::Run3DInterpolation); m_Watcher.setFuture(m_Future); } else { m_CmbInterpolation->setCurrentIndex(0); } } else if (!m_3DInterpolationEnabled) { this->Show3DInterpolationResult(false); m_BtnApply3D->setEnabled(m_3DInterpolationEnabled); } } else { QWidget::setEnabled( false ); m_ChkShowPositionNodes->setEnabled(m_3DInterpolationEnabled); } } if (!m_3DInterpolationEnabled) { this->Show3DInterpolationResult(false); m_BtnApply3D->setEnabled(m_3DInterpolationEnabled); } } catch(...) { MITK_ERROR<<"Error with 3D surface interpolation!"; } mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } void QmitkSlicesInterpolator::EnableInterpolation(bool on) { // only to be called from the outside world // just a redirection to OnInterpolationActivated OnInterpolationActivated(on); } void QmitkSlicesInterpolator::Enable3DInterpolation(bool on) { // only to be called from the outside world // just a redirection to OnInterpolationActivated On3DInterpolationActivated(on); } void QmitkSlicesInterpolator::UpdateVisibleSuggestion() { if (m_2DInterpolationEnabled && m_LastSNC) { // determine which one is the current view, try to do an initial interpolation mitk::BaseRenderer* renderer = m_LastSNC->GetRenderer(); if (renderer && renderer->GetMapperID() == mitk::BaseRenderer::Standard2D) { const mitk::TimeGeometry* timeGeometry = dynamic_cast( renderer->GetWorldGeometry() ); if (timeGeometry) { mitk::SliceNavigationController::GeometrySliceEvent event( const_cast(timeGeometry), renderer->GetSlice() ); TranslateAndInterpolateChangedSlice(event, m_LastSNC); } } } mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } void QmitkSlicesInterpolator::OnInterpolationInfoChanged(const itk::EventObject& /*e*/) { // something (e.g. undo) changed the interpolation info, we should refresh our display UpdateVisibleSuggestion(); } void QmitkSlicesInterpolator::OnSurfaceInterpolationInfoChanged(const itk::EventObject& /*e*/) { if(m_3DInterpolationEnabled) { if (m_Watcher.isRunning()) m_Watcher.waitForFinished(); m_Future = QtConcurrent::run(this, &QmitkSlicesInterpolator::Run3DInterpolation); m_Watcher.setFuture(m_Future); } } void QmitkSlicesInterpolator:: SetCurrentContourListID() { // New ContourList = hide current interpolation Show3DInterpolationResult(false); if ( m_DataStorage.IsNotNull() && m_ToolManager && m_LastSNC ) { mitk::DataNode* workingNode = m_ToolManager->GetWorkingData(0); if (workingNode) { bool isInterpolationResult(false); workingNode->GetBoolProperty("3DInterpolationResult",isInterpolationResult); if (!isInterpolationResult) { QWidget::setEnabled( true ); //TODO Aufruf hier pruefen! mitk::Vector3D spacing = workingNode->GetData()->GetGeometry( m_LastSNC->GetTime()->GetPos() )->GetSpacing(); double minSpacing (100); double maxSpacing (0); for (int i =0; i < 3; i++) { if (spacing[i] < minSpacing) { minSpacing = spacing[i]; } else if (spacing[i] > maxSpacing) { maxSpacing = spacing[i]; } } m_SurfaceInterpolator->SetMaxSpacing(maxSpacing); m_SurfaceInterpolator->SetMinSpacing(minSpacing); m_SurfaceInterpolator->SetDistanceImageVolume(50000); mitk::Image* segmentationImage = dynamic_cast(workingNode->GetData()); if (segmentationImage->GetDimension() == 3) m_SurfaceInterpolator->SetCurrentInterpolationSession(segmentationImage); else MITK_INFO<<"3D Interpolation is only supported for 3D images at the moment!"; if (m_3DInterpolationEnabled) { if (m_Watcher.isRunning()) m_Watcher.waitForFinished(); m_Future = QtConcurrent::run(this, &QmitkSlicesInterpolator::Run3DInterpolation); m_Watcher.setFuture(m_Future); } } } else { QWidget::setEnabled(false); } } } void QmitkSlicesInterpolator::Show3DInterpolationResult(bool status) { if (m_InterpolatedSurfaceNode.IsNotNull()) m_InterpolatedSurfaceNode->SetVisibility(status); if (m_3DContourNode.IsNotNull()) m_3DContourNode->SetVisibility(status, mitk::BaseRenderer::GetInstance( mitk::BaseRenderer::GetRenderWindowByName("stdmulti.widget4"))); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } void QmitkSlicesInterpolator::CheckSupportedImageDimension() { - if (m_3DInterpolationEnabled && m_Segmentation->GetDimension() != 3) + if (m_ToolManager->GetWorkingData(0)) + m_Segmentation = dynamic_cast(m_ToolManager->GetWorkingData(0)->GetData()); + + if (m_3DInterpolationEnabled && m_Segmentation && m_Segmentation->GetDimension() != 3) { QMessageBox info; info.setWindowTitle("3D Interpolation Process"); info.setIcon(QMessageBox::Information); info.setText("3D Interpolation is only supported for 3D images at the moment!"); info.exec(); m_CmbInterpolation->setCurrentIndex(0); } } void QmitkSlicesInterpolator::OnSliceNavigationControllerDeleted(const itk::Object *sender, const itk::EventObject& /*e*/) { //Don't know how to avoid const_cast here?! mitk::SliceNavigationController* slicer = dynamic_cast(const_cast(sender)); if (slicer) { m_ControllerToTimeObserverTag.remove(slicer); m_ControllerToSliceObserverTag.remove(slicer); m_ControllerToDeleteObserverTag.remove(slicer); } } diff --git a/Modules/SegmentationUI/Qmitk/QmitkToolGUIArea.cpp b/Modules/SegmentationUI/Qmitk/QmitkToolGUIArea.cpp index 08fffdd694..2c3b98cc90 100644 --- a/Modules/SegmentationUI/Qmitk/QmitkToolGUIArea.cpp +++ b/Modules/SegmentationUI/Qmitk/QmitkToolGUIArea.cpp @@ -1,28 +1,32 @@ /*=================================================================== 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 "QmitkToolGUIArea.h" +#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) QmitkToolGUIArea::QmitkToolGUIArea( QWidget* parent, Qt::WFlags f ) +#else +QmitkToolGUIArea::QmitkToolGUIArea( QWidget* parent, Qt::WindowFlags f ) +#endif :QWidget(parent,f) { QWidget::setContentsMargins(0, 0, 0, 0); } QmitkToolGUIArea::~QmitkToolGUIArea() { } diff --git a/Modules/SegmentationUI/Qmitk/QmitkToolGUIArea.h b/Modules/SegmentationUI/Qmitk/QmitkToolGUIArea.h index 658ca80b86..c54224c3d8 100644 --- a/Modules/SegmentationUI/Qmitk/QmitkToolGUIArea.h +++ b/Modules/SegmentationUI/Qmitk/QmitkToolGUIArea.h @@ -1,51 +1,54 @@ /*=================================================================== 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 QmitkToolGUIArea_h_Included #define QmitkToolGUIArea_h_Included #include "mitkCommon.h" #include #include /** \brief Dummy class for putting into a GUI (mainly using Qt Designer). This class is nothing more than a QWidget. It is good for use with QmitkToolSelectionBox as a place to display GUIs for active tools. Last contributor: $Author$ */ class MitkSegmentationUI_EXPORT QmitkToolGUIArea : public QWidget { Q_OBJECT public: - +#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) QmitkToolGUIArea( QWidget* parent = 0, Qt::WFlags f = 0 ); +#else + QmitkToolGUIArea( QWidget* parent = 0, Qt::WindowFlags f = 0 ); +#endif virtual ~QmitkToolGUIArea(); signals: public slots: protected slots: protected: }; #endif diff --git a/Modules/SurfaceInterpolation/Testing/mitkSurfaceInterpolationControllerTest.cpp b/Modules/SurfaceInterpolation/Testing/mitkSurfaceInterpolationControllerTest.cpp index 3c8977830f..b22d421a5a 100644 --- a/Modules/SurfaceInterpolation/Testing/mitkSurfaceInterpolationControllerTest.cpp +++ b/Modules/SurfaceInterpolation/Testing/mitkSurfaceInterpolationControllerTest.cpp @@ -1,398 +1,465 @@ /*=================================================================== 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 #include #include #include #include class mitkSurfaceInterpolationControllerTestSuite : public mitk::TestFixture { CPPUNIT_TEST_SUITE(mitkSurfaceInterpolationControllerTestSuite); MITK_TEST(TestSingleton); MITK_TEST(TestSetCurrentInterpolationSession); + MITK_TEST(TestReplaceInterpolationSession); MITK_TEST(TestRemoveAllInterpolationSessions); MITK_TEST(TestRemoveInterpolationSession); MITK_TEST(TestOnSegmentationDeleted); /// \todo Workaround for memory leak in TestAddNewContour. Bug 18096. vtkDebugLeaks::SetExitError(0); MITK_TEST(TestAddNewContour); MITK_TEST(TestRemoveContour); CPPUNIT_TEST_SUITE_END(); private: mitk::SurfaceInterpolationController::Pointer m_Controller; public: mitk::Image::Pointer createImage(unsigned int *dimensions) { mitk::Image::Pointer newImage = mitk::Image::New(); mitk::PixelType p_type = mitk::MakeScalarPixelType(); newImage->Initialize(p_type, 3, dimensions); return newImage; } void setUp() { m_Controller = mitk::SurfaceInterpolationController::GetInstance(); vtkSmartPointer polygonSource = vtkSmartPointer::New(); polygonSource->SetRadius(100); polygonSource->SetNumberOfSides(7); polygonSource->Update(); mitk::Surface::Pointer surface = mitk::Surface::New(); surface->SetVtkPolyData(polygonSource->GetOutput()); } void TestSingleton() { mitk::SurfaceInterpolationController::Pointer controller2 = mitk::SurfaceInterpolationController::GetInstance(); CPPUNIT_ASSERT_MESSAGE("SurfaceInterpolationController pointers are not equal!", m_Controller.GetPointer() == controller2.GetPointer()); } void TestSetCurrentInterpolationSession() { // Create image for testing unsigned int dimensions1[] = {10, 10, 10}; mitk::Image::Pointer segmentation_1 = createImage(dimensions1); unsigned int dimensions2[] = {20, 10, 30}; mitk::Image::Pointer segmentation_2 = createImage(dimensions2); // Test 1 m_Controller->SetCurrentInterpolationSession(segmentation_1); MITK_ASSERT_EQUAL(m_Controller->GetCurrentSegmentation(), segmentation_1->Clone(), "Segmentation images are not equal"); CPPUNIT_ASSERT_MESSAGE("Segmentation images are not equal", m_Controller->GetCurrentSegmentation().GetPointer() == segmentation_1.GetPointer()); CPPUNIT_ASSERT_MESSAGE("Number of interpolation session not 1", m_Controller->GetNumberOfInterpolationSessions() == 1); // Test 2 m_Controller->SetCurrentInterpolationSession(segmentation_2); MITK_ASSERT_EQUAL(m_Controller->GetCurrentSegmentation(), segmentation_2->Clone(), "Segmentation images are not equal"); CPPUNIT_ASSERT_MESSAGE("Segmentation images are not equal", m_Controller->GetCurrentSegmentation().GetPointer() == segmentation_2.GetPointer()); CPPUNIT_ASSERT_MESSAGE("Number of interpolation session not 2", m_Controller->GetNumberOfInterpolationSessions() == 2); // Test 3 m_Controller->SetCurrentInterpolationSession(segmentation_1); MITK_ASSERT_EQUAL(m_Controller->GetCurrentSegmentation(), segmentation_1->Clone(), "Segmentation images are not equal"); CPPUNIT_ASSERT_MESSAGE("Segmentation images are not equal", m_Controller->GetCurrentSegmentation().GetPointer() == segmentation_1.GetPointer()); CPPUNIT_ASSERT_MESSAGE("Number of interpolation session not 2", m_Controller->GetNumberOfInterpolationSessions() == 2); // Test 4 m_Controller->SetCurrentInterpolationSession(segmentation_1); MITK_ASSERT_EQUAL(m_Controller->GetCurrentSegmentation(), segmentation_1->Clone(), "Segmentation images are not equal"); CPPUNIT_ASSERT_MESSAGE("Segmentation images are not equal", m_Controller->GetCurrentSegmentation().GetPointer() == segmentation_1.GetPointer()); CPPUNIT_ASSERT_MESSAGE("Number of interpolation session not 2", m_Controller->GetNumberOfInterpolationSessions() == 2); // Test 5 m_Controller->SetCurrentInterpolationSession(0); CPPUNIT_ASSERT_MESSAGE("Segmentation images are not equal", m_Controller->GetCurrentSegmentation().IsNull()); CPPUNIT_ASSERT_MESSAGE("Number of interpolation session not 2", m_Controller->GetNumberOfInterpolationSessions() == 2); } + void TestReplaceInterpolationSession() + { + // Create segmentation image + unsigned int dimensions1[] = {10, 10, 10}; + mitk::Image::Pointer segmentation_1 = createImage(dimensions1); + m_Controller->SetCurrentInterpolationSession(segmentation_1); + + // Create some contours + double center_1[3] = {1.25f ,3.43f ,4.44f}; + double normal_1[3] = {0.25f ,1.76f, 0.93f}; + vtkSmartPointer p_source = vtkSmartPointer::New(); + p_source->SetNumberOfSides(20); + p_source->SetCenter(center_1); + p_source->SetRadius(4); + p_source->SetNormal(normal_1); + p_source->Update(); + vtkPolyData* poly_1 = p_source->GetOutput(); + mitk::Surface::Pointer surf_1 = mitk::Surface::New(); + surf_1->SetVtkPolyData(poly_1); + + double center_2[3] = {4.0f ,4.0f ,4.0f}; + double normal_2[3] = {1.0f ,0.0f, 0.0f}; + vtkSmartPointer p_source_2 = vtkSmartPointer::New(); + p_source_2->SetNumberOfSides(80); + p_source_2->SetCenter(center_2); + p_source_2->SetRadius(4); + p_source_2->SetNormal(normal_2); + p_source_2->Update(); + vtkPolyData* poly_2 = p_source_2->GetOutput(); + mitk::Surface::Pointer surf_2 = mitk::Surface::New(); + surf_2->SetVtkPolyData(poly_2); + + // Add contours + m_Controller->AddNewContour(surf_1); + m_Controller->AddNewContour(surf_2); + + // Check if all contours are there + mitk::SurfaceInterpolationController::ContourPositionInformation contourInfo1; + contourInfo1.contourNormal = normal_1; + contourInfo1.contourPoint = center_1; + + mitk::SurfaceInterpolationController::ContourPositionInformation contourInfo2; + contourInfo2.contourNormal = normal_2; + contourInfo2.contourPoint = center_2; + + mitk::Image::Pointer segmentation_2 = createImage(dimensions1); + bool success = m_Controller->ReplaceInterpolationSession(segmentation_1, segmentation_2); + const mitk::Surface* contour_1 = m_Controller->GetContour(contourInfo1); + const mitk::Surface* contour_2 = m_Controller->GetContour(contourInfo2); + + CPPUNIT_ASSERT_MESSAGE("Replace session failed!", success == true); + CPPUNIT_ASSERT_MESSAGE("Wrong number of contours!", m_Controller->GetNumberOfContours() == 2); + CPPUNIT_ASSERT_MESSAGE("Contours not equal!", mitk::Equal(*(surf_1->GetVtkPolyData()), *(contour_1->GetVtkPolyData()), 0.000001, true)); + CPPUNIT_ASSERT_MESSAGE("Contours not equal!", mitk::Equal(*(surf_2->GetVtkPolyData()), *(contour_2->GetVtkPolyData()), 0.000001, true)); + CPPUNIT_ASSERT_MESSAGE("Number of interpolation session not 1", m_Controller->GetNumberOfInterpolationSessions() == 1); + CPPUNIT_ASSERT_MESSAGE("Segmentation images are not equal", m_Controller->GetCurrentSegmentation().GetPointer() == segmentation_2.GetPointer()); + + unsigned int dimensions2[] = {10, 20, 10}; + mitk::Image::Pointer segmentation_3 = createImage(dimensions2); + success = m_Controller->ReplaceInterpolationSession(segmentation_2, segmentation_3); + CPPUNIT_ASSERT_MESSAGE("Replace session failed!", success == false); + CPPUNIT_ASSERT_MESSAGE("Wrong number of contours!", m_Controller->GetNumberOfContours() == 2); + CPPUNIT_ASSERT_MESSAGE("Number of interpolation session not 1", m_Controller->GetNumberOfInterpolationSessions() == 1); + CPPUNIT_ASSERT_MESSAGE("Segmentation images are not equal", m_Controller->GetCurrentSegmentation().GetPointer() == segmentation_2.GetPointer()); + } + void TestRemoveAllInterpolationSessions() { // Create image for testing unsigned int dimensions1[] = {10, 10, 10}; mitk::Image::Pointer segmentation_1 = createImage(dimensions1); unsigned int dimensions2[] = {20, 10, 30}; mitk::Image::Pointer segmentation_2 = createImage(dimensions2); // Test 1 m_Controller->SetCurrentInterpolationSession(segmentation_1); m_Controller->SetCurrentInterpolationSession(segmentation_2); m_Controller->RemoveAllInterpolationSessions(); CPPUNIT_ASSERT_MESSAGE("Number of interpolation session not 0", m_Controller->GetNumberOfInterpolationSessions() == 0); } void TestRemoveInterpolationSession() { // Create image for testing unsigned int dimensions1[] = {10, 10, 10}; mitk::Image::Pointer segmentation_1 = createImage(dimensions1); unsigned int dimensions2[] = {20, 10, 30}; mitk::Image::Pointer segmentation_2 = createImage(dimensions2); // Test 1 m_Controller->SetCurrentInterpolationSession(segmentation_1); m_Controller->SetCurrentInterpolationSession(segmentation_2); CPPUNIT_ASSERT_MESSAGE("Number of interpolation session not 2", m_Controller->GetNumberOfInterpolationSessions() == 2); // Test current segmentation should not be null if another one was removed m_Controller->RemoveInterpolationSession(segmentation_1); CPPUNIT_ASSERT_MESSAGE("Number of interpolation session not 1", m_Controller->GetNumberOfInterpolationSessions() == 1); CPPUNIT_ASSERT_MESSAGE("Segmentation images are not equal", m_Controller->GetCurrentSegmentation().GetPointer() == segmentation_2.GetPointer()); CPPUNIT_ASSERT_MESSAGE("Current segmentation is null after another one was removed", m_Controller->GetCurrentSegmentation().IsNotNull()); m_Controller->SetCurrentInterpolationSession(segmentation_1); CPPUNIT_ASSERT_MESSAGE("Number of interpolation session not 2", m_Controller->GetNumberOfInterpolationSessions() == 2); // Test current segmentation should not be null if another one was removed m_Controller->RemoveInterpolationSession(segmentation_1); CPPUNIT_ASSERT_MESSAGE("Number of interpolation session not 1", m_Controller->GetNumberOfInterpolationSessions() == 1); CPPUNIT_ASSERT_MESSAGE("Current segmentation is not null after session was removed", m_Controller->GetCurrentSegmentation().IsNull()); } void TestOnSegmentationDeleted() { { // Create image for testing unsigned int dimensions1[] = {10, 10, 10}; mitk::Image::Pointer segmentation_1 = createImage(dimensions1); m_Controller->SetCurrentInterpolationSession(segmentation_1); } CPPUNIT_ASSERT_MESSAGE("Number of interpolation session not 0", m_Controller->GetNumberOfInterpolationSessions() == 0); } void TestAddNewContour() { // Create segmentation image unsigned int dimensions1[] = {10, 10, 10}; mitk::Image::Pointer segmentation_1 = createImage(dimensions1); m_Controller->SetCurrentInterpolationSession(segmentation_1); // Create some contours double center_1[3] = {1.25f ,3.43f ,4.44f}; double normal_1[3] = {0.25f ,1.76f, 0.93f}; vtkSmartPointer p_source = vtkSmartPointer::New(); p_source->SetNumberOfSides(20); p_source->SetCenter(center_1); p_source->SetRadius(4); p_source->SetNormal(normal_1); p_source->Update(); vtkPolyData* poly_1 = p_source->GetOutput(); mitk::Surface::Pointer surf_1 = mitk::Surface::New(); surf_1->SetVtkPolyData(poly_1); double center_2[3] = {4.0f ,4.0f ,4.0f}; double normal_2[3] = {1.0f ,0.0f, 0.0f}; vtkSmartPointer p_source_2 = vtkSmartPointer::New(); p_source_2->SetNumberOfSides(80); p_source_2->SetCenter(center_2); p_source_2->SetRadius(4); p_source_2->SetNormal(normal_2); p_source_2->Update(); vtkPolyData* poly_2 = p_source_2->GetOutput(); mitk::Surface::Pointer surf_2 = mitk::Surface::New(); surf_2->SetVtkPolyData(poly_2); double center_3[3] = {4.0f ,4.0f ,3.0f}; double normal_3[3] = {0.0f ,0.0f, 1.0f}; vtkSmartPointer p_source_3 = vtkSmartPointer::New(); p_source_3->SetNumberOfSides(10); p_source_3->SetCenter(center_3); p_source_3->SetRadius(4); p_source_3->SetNormal(normal_3); p_source_3->Update(); vtkPolyData* poly_3 = p_source_3->GetOutput(); mitk::Surface::Pointer surf_3 = mitk::Surface::New(); surf_3->SetVtkPolyData(poly_3); // Add contours m_Controller->AddNewContour(surf_1); m_Controller->AddNewContour(surf_2); m_Controller->AddNewContour(surf_3); // Check if all contours are there mitk::SurfaceInterpolationController::ContourPositionInformation contourInfo1; contourInfo1.contourNormal = normal_1; contourInfo1.contourPoint = center_1; mitk::SurfaceInterpolationController::ContourPositionInformation contourInfo2; contourInfo2.contourNormal = normal_2; contourInfo2.contourPoint = center_2; mitk::SurfaceInterpolationController::ContourPositionInformation contourInfo3; contourInfo3.contourNormal = normal_3; contourInfo3.contourPoint = center_3; const mitk::Surface* contour_1 = m_Controller->GetContour(contourInfo1); const mitk::Surface* contour_2 = m_Controller->GetContour(contourInfo2); const mitk::Surface* contour_3 = m_Controller->GetContour(contourInfo3); CPPUNIT_ASSERT_MESSAGE("Wrong number of contours!", m_Controller->GetNumberOfContours() == 3); CPPUNIT_ASSERT_MESSAGE("Contours not equal!", mitk::Equal(*(surf_1->GetVtkPolyData()), *(contour_1->GetVtkPolyData()), 0.000001, true)); CPPUNIT_ASSERT_MESSAGE("Contours not equal!", mitk::Equal(*(surf_2->GetVtkPolyData()), *(contour_2->GetVtkPolyData()), 0.000001, true)); CPPUNIT_ASSERT_MESSAGE("Contours not equal!", mitk::Equal(*(surf_3->GetVtkPolyData()), *(contour_3->GetVtkPolyData()), 0.000001, true)); // Create another segmentation image unsigned int dimensions2[] = {20, 20, 20}; mitk::Image::Pointer segmentation_2 = createImage(dimensions2); m_Controller->SetCurrentInterpolationSession(segmentation_2); // Create some contours double center_4[3] = {10.0f ,10.0f ,10.0f}; double normal_4[3] = {0.0f ,1.0f, 0.0f}; vtkSmartPointer p_source_4 = vtkSmartPointer::New(); p_source_4->SetNumberOfSides(8); p_source_4->SetCenter(center_4); p_source_4->SetRadius(5); p_source_4->SetNormal(normal_4); p_source_4->Update(); vtkPolyData* poly_4 = p_source_4->GetOutput(); mitk::Surface::Pointer surf_4 = mitk::Surface::New(); surf_4->SetVtkPolyData(poly_4); double center_5[3] = {3.0f ,10.0f ,10.0f}; double normal_5[3] = {1.0f ,0.0f, 0.0f}; vtkSmartPointer p_source_5 = vtkSmartPointer::New(); p_source_5->SetNumberOfSides(16); p_source_5->SetCenter(center_5); p_source_5->SetRadius(8); p_source_5->SetNormal(normal_5); p_source_5->Update(); vtkPolyData* poly_5 = p_source_5->GetOutput(); mitk::Surface::Pointer surf_5 = mitk::Surface::New(); surf_5->SetVtkPolyData(poly_5); double center_6[3] = {10.0f ,10.0f ,3.0f}; double normal_6[3] = {0.0f ,0.0f, 1.0f}; vtkSmartPointer p_source_6 = vtkSmartPointer::New(); p_source_6->SetNumberOfSides(100); p_source_6->SetCenter(center_6); p_source_6->SetRadius(5); p_source_6->SetNormal(normal_6); p_source_6->Update(); vtkPolyData* poly_6 = p_source_6->GetOutput(); mitk::Surface::Pointer surf_6 = mitk::Surface::New(); surf_6->SetVtkPolyData(poly_6); mitk::SurfaceInterpolationController::ContourPositionInformation contourInfo4; contourInfo4.contourNormal = normal_4; contourInfo4.contourPoint = center_4; mitk::SurfaceInterpolationController::ContourPositionInformation contourInfo5; contourInfo5.contourNormal = normal_5; contourInfo5.contourPoint = center_5; mitk::SurfaceInterpolationController::ContourPositionInformation contourInfo6; contourInfo6.contourNormal = normal_6; contourInfo6.contourPoint = center_6; // Add contours m_Controller->AddNewContour(surf_4); m_Controller->AddNewContour(surf_5); m_Controller->AddNewContour(surf_6); // Check if all contours are there mitk::Surface* contour_4 = const_cast(m_Controller->GetContour(contourInfo4)); mitk::Surface* contour_5 = const_cast(m_Controller->GetContour(contourInfo5)); mitk::Surface* contour_6 = const_cast(m_Controller->GetContour(contourInfo6)); CPPUNIT_ASSERT_MESSAGE("Wrong number of contours!", m_Controller->GetNumberOfContours() == 3); CPPUNIT_ASSERT_MESSAGE("Contours not equal!", mitk::Equal(*(surf_4->GetVtkPolyData()), *(contour_4->GetVtkPolyData()), 0.000001, true)); CPPUNIT_ASSERT_MESSAGE("Contours not equal!", mitk::Equal(*(surf_5->GetVtkPolyData()), *(contour_5->GetVtkPolyData()), 0.000001, true)); CPPUNIT_ASSERT_MESSAGE("Contours not equal!", mitk::Equal(*(surf_6->GetVtkPolyData()), *(contour_6->GetVtkPolyData()), 0.000001, true)); // Modify some contours vtkSmartPointer p_source_7 = vtkSmartPointer::New(); p_source_7->SetNumberOfSides(200); p_source_7->SetCenter(3.0,10.0,10.0); p_source_7->SetRadius(5); p_source_7->SetNormal(1, 0, 0); p_source_7->Update(); vtkPolyData* poly_7 = p_source_7->GetOutput(); mitk::Surface::Pointer surf_7 = mitk::Surface::New(); surf_7->SetVtkPolyData(poly_7); m_Controller->AddNewContour(surf_7); mitk::Surface* contour_7 = const_cast(m_Controller->GetContour(contourInfo5)); CPPUNIT_ASSERT_MESSAGE("Contours not equal!", mitk::Equal(*(surf_7->GetVtkPolyData()), *(contour_7->GetVtkPolyData()), 0.000001, true)); // Change session and test if all contours are available m_Controller->SetCurrentInterpolationSession(segmentation_1); mitk::Surface* contour_8 = const_cast(m_Controller->GetContour(contourInfo1)); mitk::Surface* contour_9 = const_cast(m_Controller->GetContour(contourInfo2)); mitk::Surface* contour_10 = const_cast(m_Controller->GetContour(contourInfo3)); CPPUNIT_ASSERT_MESSAGE("Wrong number of contours!", m_Controller->GetNumberOfContours() == 3); CPPUNIT_ASSERT_MESSAGE("Contours not equal!", mitk::Equal(*(surf_1->GetVtkPolyData()), *(contour_8->GetVtkPolyData()), 0.000001, true)); CPPUNIT_ASSERT_MESSAGE("Contours not equal!", mitk::Equal(*(surf_2->GetVtkPolyData()), *(contour_9->GetVtkPolyData()), 0.000001, true)); CPPUNIT_ASSERT_MESSAGE("Contours not equal!", mitk::Equal(*(surf_3->GetVtkPolyData()), *(contour_10->GetVtkPolyData()), 0.000001, true)); } void TestRemoveContour() { // Create segmentation image unsigned int dimensions1[] = {10, 10, 10}; mitk::Image::Pointer segmentation_1 = createImage(dimensions1); m_Controller->SetCurrentInterpolationSession(segmentation_1); // Create some contours double center_1[3] = {4.0f ,4.0f ,4.0f}; double normal_1[3] = {0.0f ,1.0f, 0.0f}; vtkSmartPointer p_source = vtkSmartPointer::New(); p_source->SetNumberOfSides(20); p_source->SetCenter(center_1); p_source->SetRadius(4); p_source->SetNormal(normal_1); p_source->Update(); vtkPolyData* poly_1 = p_source->GetOutput(); mitk::Surface::Pointer surf_1 = mitk::Surface::New(); surf_1->SetVtkPolyData(poly_1); double center_2[3] = {4.0f ,4.0f ,4.0f}; double normal_2[3] = {1.0f ,0.0f, 0.0f}; vtkSmartPointer p_source_2 = vtkSmartPointer::New(); p_source_2->SetNumberOfSides(80); p_source_2->SetCenter(center_2); p_source_2->SetRadius(4); p_source_2->SetNormal(normal_2); p_source_2->Update(); vtkPolyData* poly_2 = p_source_2->GetOutput(); mitk::Surface::Pointer surf_2 = mitk::Surface::New(); surf_2->SetVtkPolyData(poly_2); // Add contours m_Controller->AddNewContour(surf_1); m_Controller->AddNewContour(surf_2); CPPUNIT_ASSERT_MESSAGE("Wrong number of contours!", m_Controller->GetNumberOfContours() == 2); mitk::SurfaceInterpolationController::ContourPositionInformation contourInfo3; contourInfo3.contour = surf_1->Clone(); contourInfo3.contourNormal = normal_1; contourInfo3.contourPoint = center_1; // Shift the new contour so that it is different contourInfo3.contourPoint += 0.5; bool success = m_Controller->RemoveContour(contourInfo3); CPPUNIT_ASSERT_MESSAGE("Remove failed - contour was unintentionally removed!", (m_Controller->GetNumberOfContours() == 2) && !success); mitk::SurfaceInterpolationController::ContourPositionInformation contourInfo2; contourInfo2.contourNormal = normal_2; contourInfo2.contourPoint = center_2; contourInfo2.contour = surf_2; success = m_Controller->RemoveContour(contourInfo2); CPPUNIT_ASSERT_MESSAGE("Remove failed - contour was not removed!", (m_Controller->GetNumberOfContours() == 1) && success); // Let's see if the other contour No. 1 is still there contourInfo3.contourPoint -= 0.5; const mitk::Surface* remainingContour = m_Controller->GetContour(contourInfo3); CPPUNIT_ASSERT_MESSAGE("Remove failed - contour was accidentally removed!", (m_Controller->GetNumberOfContours() == 1) && mitk::Equal(*(surf_1->GetVtkPolyData()), *(remainingContour->GetVtkPolyData()), 0.000001, true) &&success); } }; MITK_TEST_SUITE_REGISTRATION(mitkSurfaceInterpolationController) diff --git a/Modules/SurfaceInterpolation/mitkSurfaceInterpolationController.cpp b/Modules/SurfaceInterpolation/mitkSurfaceInterpolationController.cpp index 036348812c..dc6a5fc40d 100644 --- a/Modules/SurfaceInterpolation/mitkSurfaceInterpolationController.cpp +++ b/Modules/SurfaceInterpolation/mitkSurfaceInterpolationController.cpp @@ -1,547 +1,577 @@ /*=================================================================== 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 "mitkSurfaceInterpolationController.h" #include "mitkMemoryUtilities.h" #include "mitkImageAccessByItk.h" #include "mitkImageCast.h" #include "mitkImageToSurfaceFilter.h" // Check whether the given contours are coplanar bool ContoursCoplanar(mitk::SurfaceInterpolationController::ContourPositionInformation leftHandSide, mitk::SurfaceInterpolationController::ContourPositionInformation rightHandSide) { // Here we check two things: // 1. Whether the normals of both contours are at least parallel // 2. Whether both contours lie in the same plane // Check for coplanarity: // a. Span a vector between two points one from each contour // b. Calculate dot product for the vector and one of the normals // c. If the dot is zero the two vectors are orthogonal and the contours are coplanar double vec[3]; vec[0] = leftHandSide.contourPoint[0] - rightHandSide.contourPoint[0]; vec[1] = leftHandSide.contourPoint[1] - rightHandSide.contourPoint[1]; vec[2] = leftHandSide.contourPoint[2] - rightHandSide.contourPoint[2]; double n[3]; n[0] = rightHandSide.contourNormal[0]; n[1] = rightHandSide.contourNormal[1]; n[2] = rightHandSide.contourNormal[2]; double dot = vtkMath::Dot(n, vec); double n2[3]; n2[0] = leftHandSide.contourNormal[0]; n2[1] = leftHandSide.contourNormal[1]; n2[2] = leftHandSide.contourNormal[2]; // The normals of both contours have to be parallel but not of the same orientation double lengthLHS = leftHandSide.contourNormal.GetNorm(); double lengthRHS = rightHandSide.contourNormal.GetNorm(); double dot2 = vtkMath::Dot(n, n2); bool contoursParallel = mitk::Equal(fabs(lengthLHS*lengthRHS), fabs(dot2), 0.001); if (mitk::Equal(dot, 0.0, 0.001) && contoursParallel) return true; else return false; } mitk::SurfaceInterpolationController::ContourPositionInformation CreateContourPositionInformation(mitk::Surface::Pointer contour) { mitk::SurfaceInterpolationController::ContourPositionInformation contourInfo; contourInfo.contour = contour; double n[3]; double p[3]; contour->GetVtkPolyData()->GetPoints()->GetPoint(0, p); vtkPolygon::ComputeNormal(contour->GetVtkPolyData()->GetPoints(), n); contourInfo.contourNormal = n; contourInfo.contourPoint = p; return contourInfo; } mitk::SurfaceInterpolationController::SurfaceInterpolationController() :m_SelectedSegmentation(0) { m_ReduceFilter = ReduceContourSetFilter::New(); m_NormalsFilter = ComputeContourSetNormalsFilter::New(); m_InterpolateSurfaceFilter = CreateDistanceImageFromSurfaceFilter::New(); m_ReduceFilter->SetUseProgressBar(false); // m_ReduceFilter->SetProgressStepSize(1); m_NormalsFilter->SetUseProgressBar(true); m_NormalsFilter->SetProgressStepSize(1); m_InterpolateSurfaceFilter->SetUseProgressBar(true); m_InterpolateSurfaceFilter->SetProgressStepSize(7); m_Contours = Surface::New(); m_PolyData = vtkSmartPointer::New(); vtkSmartPointer points = vtkSmartPointer::New(); m_PolyData->SetPoints(points); m_InterpolationResult = 0; m_CurrentNumberOfReducedContours = 0; } mitk::SurfaceInterpolationController::~SurfaceInterpolationController() { //Removing all observers std::map::iterator dataIter = m_SegmentationObserverTags.begin(); for (; dataIter != m_SegmentationObserverTags.end(); ++dataIter ) { (*dataIter).first->RemoveObserver( (*dataIter).second ); } m_SegmentationObserverTags.clear(); } mitk::SurfaceInterpolationController* mitk::SurfaceInterpolationController::GetInstance() { static mitk::SurfaceInterpolationController::Pointer m_Instance; if ( m_Instance.IsNull() ) { m_Instance = SurfaceInterpolationController::New(); } return m_Instance; } void mitk::SurfaceInterpolationController::AddNewContour (mitk::Surface::Pointer newContour) { if( newContour->GetVtkPolyData()->GetNumberOfPoints() > 0) { ContourPositionInformation contourInfo = CreateContourPositionInformation(newContour); this->AddToInterpolationPipeline(contourInfo); this->Modified(); } } void mitk::SurfaceInterpolationController::AddNewContours(std::vector newContours) { for (unsigned int i = 0; i < newContours.size(); ++i) { if( newContours.at(i)->GetVtkPolyData()->GetNumberOfPoints() > 0) { ContourPositionInformation contourInfo = CreateContourPositionInformation(newContours.at(i)); this->AddToInterpolationPipeline(contourInfo); } } this->Modified(); } void mitk::SurfaceInterpolationController::AddToInterpolationPipeline(ContourPositionInformation contourInfo) { int pos (-1); ContourPositionInformationList currentContourList = m_ListOfInterpolationSessions[m_SelectedSegmentation]; mitk::Surface* newContour = contourInfo.contour; for (unsigned int i = 0; i < currentContourList.size(); i++) { ContourPositionInformation contourFromList = currentContourList.at(i); if (ContoursCoplanar(contourInfo, contourFromList)) { pos = i; break; } } //Don't save a new empty contour if (pos == -1 && newContour->GetVtkPolyData()->GetNumberOfPoints() > 0) { m_ReduceFilter->SetInput(m_ListOfInterpolationSessions[m_SelectedSegmentation].size(), newContour); m_ListOfInterpolationSessions[m_SelectedSegmentation].push_back(contourInfo); } else if (pos != -1 && newContour->GetVtkPolyData()->GetNumberOfPoints() > 0) { m_ListOfInterpolationSessions[m_SelectedSegmentation].at(pos) = contourInfo; m_ReduceFilter->SetInput(pos, newContour); } else if (newContour->GetVtkPolyData()->GetNumberOfPoints() == 0) { this->RemoveContour(contourInfo); } m_ReduceFilter->Update(); m_CurrentNumberOfReducedContours = m_ReduceFilter->GetNumberOfOutputs(); for (unsigned int i = 0; i < m_CurrentNumberOfReducedContours; i++) { m_NormalsFilter->SetInput(i, m_ReduceFilter->GetOutput(i)); m_InterpolateSurfaceFilter->SetInput(i, m_NormalsFilter->GetOutput(i)); } } bool mitk::SurfaceInterpolationController::RemoveContour(ContourPositionInformation contourInfo) { if(!m_SelectedSegmentation) return false; ContourPositionInformationList::iterator it = m_ListOfInterpolationSessions[m_SelectedSegmentation].begin(); while (it != m_ListOfInterpolationSessions[m_SelectedSegmentation].end()) { ContourPositionInformation currentContour = (*it); if (ContoursCoplanar(currentContour, contourInfo)) { m_ListOfInterpolationSessions[m_SelectedSegmentation].erase(it); this->ReinitializeInterpolation(); return true; } ++it; } return false; } const mitk::Surface* mitk::SurfaceInterpolationController::GetContour(ContourPositionInformation contourInfo) { ContourPositionInformationList contourList = m_ListOfInterpolationSessions[m_SelectedSegmentation]; for (unsigned int i = 0; i < contourList.size(); ++i) { ContourPositionInformation currentContour = contourList.at(i); if (ContoursCoplanar(contourInfo, currentContour)) return currentContour.contour; } return 0; } unsigned int mitk::SurfaceInterpolationController::GetNumberOfContours() { return m_ListOfInterpolationSessions[m_SelectedSegmentation].size(); } void mitk::SurfaceInterpolationController::Interpolate() { if (m_CurrentNumberOfReducedContours< 2) { //If no interpolation is possible reset the interpolation result m_InterpolationResult = 0; return; } //Setting up progress bar mitk::ProgressBar::GetInstance()->AddStepsToDo(10); // create a surface from the distance-image mitk::ImageToSurfaceFilter::Pointer imageToSurfaceFilter = mitk::ImageToSurfaceFilter::New(); imageToSurfaceFilter->SetInput( m_InterpolateSurfaceFilter->GetOutput() ); imageToSurfaceFilter->SetThreshold( 0 ); imageToSurfaceFilter->SetSmooth(true); imageToSurfaceFilter->SetSmoothIteration(20); imageToSurfaceFilter->Update(); m_InterpolationResult = imageToSurfaceFilter->GetOutput(); vtkSmartPointer polyDataAppender = vtkSmartPointer::New(); for (unsigned int i = 0; i < m_ListOfInterpolationSessions[m_SelectedSegmentation].size(); i++) { polyDataAppender->AddInputData(m_ListOfInterpolationSessions[m_SelectedSegmentation].at(i).contour->GetVtkPolyData()); } polyDataAppender->Update(); m_Contours->SetVtkPolyData(polyDataAppender->GetOutput()); //Last progress step mitk::ProgressBar::GetInstance()->Progress(20); m_InterpolationResult->DisconnectPipeline(); } mitk::Surface::Pointer mitk::SurfaceInterpolationController::GetInterpolationResult() { return m_InterpolationResult; } mitk::Surface* mitk::SurfaceInterpolationController::GetContoursAsSurface() { return m_Contours; } void mitk::SurfaceInterpolationController::SetDataStorage(DataStorage::Pointer ds) { m_DataStorage = ds; } void mitk::SurfaceInterpolationController::SetMinSpacing(double minSpacing) { m_ReduceFilter->SetMinSpacing(minSpacing); } void mitk::SurfaceInterpolationController::SetMaxSpacing(double maxSpacing) { m_ReduceFilter->SetMaxSpacing(maxSpacing); m_NormalsFilter->SetMaxSpacing(maxSpacing); } void mitk::SurfaceInterpolationController::SetDistanceImageVolume(unsigned int distImgVolume) { m_InterpolateSurfaceFilter->SetDistanceImageVolume(distImgVolume); } mitk::Image::Pointer mitk::SurfaceInterpolationController::GetCurrentSegmentation() { return m_SelectedSegmentation; } mitk::Image* mitk::SurfaceInterpolationController::GetImage() { return m_InterpolateSurfaceFilter->GetOutput(); } double mitk::SurfaceInterpolationController::EstimatePortionOfNeededMemory() { double numberOfPointsAfterReduction = m_ReduceFilter->GetNumberOfPointsAfterReduction()*3; double sizeOfPoints = pow(numberOfPointsAfterReduction,2)*sizeof(double); double totalMem = mitk::MemoryUtilities::GetTotalSizeOfPhysicalRam(); double percentage = sizeOfPoints/totalMem; return percentage; } unsigned int mitk::SurfaceInterpolationController::GetNumberOfInterpolationSessions() { return m_ListOfInterpolationSessions.size(); } template void mitk::SurfaceInterpolationController::GetImageBase(itk::Image* input, itk::ImageBase<3>::Pointer& result) { result->Graft(input); } void mitk::SurfaceInterpolationController::SetCurrentSegmentationInterpolationList(mitk::Image::Pointer segmentation) { this->SetCurrentInterpolationSession(segmentation); } void mitk::SurfaceInterpolationController::SetCurrentInterpolationSession(mitk::Image::Pointer currentSegmentationImage) { if (currentSegmentationImage.GetPointer() == m_SelectedSegmentation) return; if (currentSegmentationImage.IsNull()) { m_SelectedSegmentation = 0; return; } m_SelectedSegmentation = currentSegmentationImage.GetPointer(); ContourListMap::iterator it = m_ListOfInterpolationSessions.find(currentSegmentationImage.GetPointer()); // If the session does not exist yet create a new ContourPositionPairList otherwise reinitialize the interpolation pipeline if (it == m_ListOfInterpolationSessions.end()) { ContourPositionInformationList newList; m_ListOfInterpolationSessions.insert(std::pair(m_SelectedSegmentation, newList)); m_InterpolationResult = 0; m_CurrentNumberOfReducedContours = 0; itk::MemberCommand::Pointer command = itk::MemberCommand::New(); command->SetCallbackFunction(this, &SurfaceInterpolationController::OnSegmentationDeleted); m_SegmentationObserverTags.insert( std::pair( m_SelectedSegmentation, m_SelectedSegmentation->AddObserver( itk::DeleteEvent(), command ) ) ); } this->ReinitializeInterpolation(); } +bool mitk::SurfaceInterpolationController::ReplaceInterpolationSession(mitk::Image::Pointer oldSession, mitk::Image::Pointer newSession) +{ + if (oldSession.IsNull() || newSession.IsNull()) + return false; + + if (oldSession.GetPointer() == newSession.GetPointer()) + return false; + + if (!mitk::Equal(*(oldSession->GetGeometry()), *(newSession->GetGeometry()), mitk::eps, false)) + return false; + + ContourListMap::iterator it = m_ListOfInterpolationSessions.find(oldSession.GetPointer()); + + if (it == m_ListOfInterpolationSessions.end()) + return false; + + ContourPositionInformationList oldList = (*it).second; + m_ListOfInterpolationSessions.insert(std::pair(newSession.GetPointer(), oldList)); + itk::MemberCommand::Pointer command = itk::MemberCommand::New(); + command->SetCallbackFunction(this, &SurfaceInterpolationController::OnSegmentationDeleted); + m_SegmentationObserverTags.insert( std::pair( newSession, newSession->AddObserver( itk::DeleteEvent(), command ) ) ); + + if (m_SelectedSegmentation == oldSession) + m_SelectedSegmentation = newSession; + m_NormalsFilter->SetSegmentationBinaryImage(m_SelectedSegmentation); + + this->RemoveInterpolationSession(oldSession); + return true; +} + void mitk::SurfaceInterpolationController::RemoveSegmentationFromContourList(mitk::Image *segmentation) { this->RemoveInterpolationSession(segmentation); } void mitk::SurfaceInterpolationController::RemoveInterpolationSession(mitk::Image::Pointer segmentationImage) { if (segmentationImage) { if (m_SelectedSegmentation == segmentationImage) { m_NormalsFilter->SetSegmentationBinaryImage(NULL); m_SelectedSegmentation = 0; } m_ListOfInterpolationSessions.erase(segmentationImage); // Remove observer std::map::iterator pos = m_SegmentationObserverTags.find(segmentationImage); if (pos != m_SegmentationObserverTags.end()) { segmentationImage->RemoveObserver((*pos).second); m_SegmentationObserverTags.erase(pos); } } } void mitk::SurfaceInterpolationController::RemoveAllInterpolationSessions() { //Removing all observers std::map::iterator dataIter = m_SegmentationObserverTags.begin(); while (dataIter != m_SegmentationObserverTags.end()) { mitk::Image* image = (*dataIter).first; image->RemoveObserver((*dataIter).second); ++dataIter; } m_SegmentationObserverTags.clear(); m_SelectedSegmentation = 0; m_ListOfInterpolationSessions.clear(); } void mitk::SurfaceInterpolationController::ReinitializeInterpolation(mitk::Surface::Pointer contours) { // 1. detect coplanar contours // 2. merge coplanar contours into a single surface // 4. add contour to pipeline // Split the surface into separate polygons vtkSmartPointer existingPolys; vtkSmartPointer existingPoints; existingPolys = contours->GetVtkPolyData()->GetPolys(); existingPoints = contours->GetVtkPolyData()->GetPoints(); existingPolys->InitTraversal(); vtkSmartPointer ids = vtkSmartPointer::New(); typedef std::pair PointNormalPair; std::vector list; std::vector > pointsList; int count (0); for( existingPolys->InitTraversal(); existingPolys->GetNextCell(ids);) { // Get the points vtkSmartPointer points = vtkSmartPointer::New(); existingPoints->GetPoints(ids, points); ++count; pointsList.push_back(points); PointNormalPair p_n; double n[3]; vtkPolygon::ComputeNormal(points, n); p_n.first = n; double p[3]; existingPoints->GetPoint(ids->GetId(0), p); p_n.second = p; ContourPositionInformation p_info; p_info.contourNormal = n; p_info.contourPoint = p; list.push_back(p_info); continue; } // Detect and sort coplanar polygons std::vector::iterator outer = list.begin(); std::vector< std::vector< vtkSmartPointer > > relatedPoints; while (outer != list.end()) { std::vector::iterator inner = outer; ++inner; std::vector< vtkSmartPointer > rel; std::vector< vtkSmartPointer >::iterator pointsIter = pointsList.begin(); rel.push_back((*pointsIter)); pointsIter = pointsList.erase(pointsIter); while (inner != list.end()) { if(ContoursCoplanar((*outer),(*inner))) { inner = list.erase(inner); rel.push_back((*pointsIter)); pointsIter = pointsList.erase(pointsIter); } else { ++inner; ++pointsIter; } } relatedPoints.push_back(rel); ++outer; } // Build the separate surfaces again std::vector finalSurfaces; for (unsigned int i = 0; i < relatedPoints.size(); ++i) { vtkSmartPointer contourSurface = vtkSmartPointer::New(); vtkSmartPointer points = vtkSmartPointer::New(); vtkSmartPointer polygons = vtkSmartPointer::New(); unsigned int pointId (0); for (unsigned int j = 0; j < relatedPoints.at(i).size(); ++j) { unsigned int numPoints = relatedPoints.at(i).at(j)->GetNumberOfPoints(); vtkSmartPointer polygon = vtkSmartPointer::New(); polygon->GetPointIds()->SetNumberOfIds(numPoints); polygon->GetPoints()->SetNumberOfPoints(numPoints); vtkSmartPointer currentPoints = relatedPoints.at(i).at(j); for (unsigned k = 0; k < numPoints; ++k) { points->InsertPoint(pointId, currentPoints->GetPoint(k)); polygon->GetPointIds()->SetId(k, pointId); ++pointId; } polygons->InsertNextCell(polygon); } contourSurface->SetPoints(points); contourSurface->SetPolys(polygons); contourSurface->BuildLinks(); mitk::Surface::Pointer surface = mitk::Surface::New(); surface->SetVtkPolyData(contourSurface); finalSurfaces.push_back(surface); } // Add detected contours to interpolation pipeline this->AddNewContours(finalSurfaces); } void mitk::SurfaceInterpolationController::OnSegmentationDeleted(const itk::Object *caller, const itk::EventObject &/*event*/) { mitk::Image* tempImage = dynamic_cast(const_cast(caller)); if (tempImage) { if (m_SelectedSegmentation == tempImage) { m_NormalsFilter->SetSegmentationBinaryImage(NULL); m_SelectedSegmentation = 0; } m_SegmentationObserverTags.erase(tempImage); m_ListOfInterpolationSessions.erase(tempImage); } } void mitk::SurfaceInterpolationController::ReinitializeInterpolation() { m_NormalsFilter->SetSegmentationBinaryImage(m_SelectedSegmentation); // If session has changed reset the pipeline m_ReduceFilter->Reset(); m_NormalsFilter->Reset(); m_InterpolateSurfaceFilter->Reset(); itk::ImageBase<3>::Pointer itkImage = itk::ImageBase<3>::New(); AccessFixedDimensionByItk_1( m_SelectedSegmentation, GetImageBase, 3, itkImage ); m_InterpolateSurfaceFilter->SetReferenceImage(itkImage.GetPointer()); for (unsigned int i = 0; i < m_ListOfInterpolationSessions[m_SelectedSegmentation].size(); i++) { m_ReduceFilter->SetInput(i, m_ListOfInterpolationSessions[m_SelectedSegmentation].at(i).contour); } m_ReduceFilter->Update(); m_CurrentNumberOfReducedContours = m_ReduceFilter->GetNumberOfOutputs(); for (unsigned int i = 0; i < m_CurrentNumberOfReducedContours; i++) { m_NormalsFilter->SetInput(i, m_ReduceFilter->GetOutput(i)); m_InterpolateSurfaceFilter->SetInput(i, m_NormalsFilter->GetOutput(i)); } Modified(); } diff --git a/Modules/SurfaceInterpolation/mitkSurfaceInterpolationController.h b/Modules/SurfaceInterpolation/mitkSurfaceInterpolationController.h index 12285d0361..50654d7785 100644 --- a/Modules/SurfaceInterpolation/mitkSurfaceInterpolationController.h +++ b/Modules/SurfaceInterpolation/mitkSurfaceInterpolationController.h @@ -1,226 +1,236 @@ /*=================================================================== 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 mitkSurfaceInterpolationController_h_Included #define mitkSurfaceInterpolationController_h_Included #include "mitkCommon.h" #include #include "mitkRestorePlanePositionOperation.h" #include "mitkSurface.h" #include "mitkInteractionConst.h" #include "mitkColorProperty.h" #include "mitkProperties.h" #include "mitkCreateDistanceImageFromSurfaceFilter.h" #include "mitkReduceContourSetFilter.h" #include "mitkComputeContourSetNormalsFilter.h" #include "mitkDataNode.h" #include "mitkDataStorage.h" #include "mitkWeakPointer.h" #include "vtkPolygon.h" #include "vtkPoints.h" #include "vtkCellArray.h" #include "vtkPolyData.h" #include "vtkSmartPointer.h" #include "vtkAppendPolyData.h" #include "vtkMarchingCubes.h" #include "vtkImageData.h" #include "mitkVtkRepresentationProperty.h" #include "vtkProperty.h" #include "mitkProgressBar.h" namespace mitk { class MitkSurfaceInterpolation_EXPORT SurfaceInterpolationController : public itk::Object { public: mitkClassMacro(SurfaceInterpolationController, itk::Object) itkFactorylessNewMacro(Self) itkCloneMacro(Self) struct ContourPositionInformation { Surface::Pointer contour; Vector3D contourNormal; Point3D contourPoint; }; typedef std::vector ContourPositionInformationList; typedef std::map ContourListMap; static SurfaceInterpolationController* GetInstance(); /** * @brief Adds a new extracted contour to the list * @param newContour the contour to be added. If a contour at that position * already exists the related contour will be updated */ void AddNewContour (Surface::Pointer newContour); /** * @brief Removes the contour for a given plane for the current selected segmenation * @param contourInfo the contour which should be removed * @return true if a contour was found and removed, false if no contour was found */ bool RemoveContour (ContourPositionInformation contourInfo); /** * @brief Adds new extracted contours to the list. If one or more contours at a given position * already exist they will be updated respectively * @param newContours the list of the contours */ void AddNewContours (std::vector newContours); /** * @brief Returns the contour for a given plane for the current selected segmenation * @param ontourInfo the contour which should be returned * @return the contour as an mitk::Surface. If no contour is available at the give position NULL is returned */ const mitk::Surface* GetContour (ContourPositionInformation contourInfo); /** * @brief Returns the number of available contours for the current selected segmentation * @return the number of contours */ unsigned int GetNumberOfContours(); /** * Interpolates the 3D surface from the given extracted contours */ void Interpolate (); mitk::Surface::Pointer GetInterpolationResult(); /** * Sets the minimum spacing of the current selected segmentation * This is needed since the contour points we reduced before they are used to interpolate the surface */ void SetMinSpacing(double minSpacing); /** * Sets the minimum spacing of the current selected segmentation * This is needed since the contour points we reduced before they are used to interpolate the surface */ void SetMaxSpacing(double maxSpacing); /** * Sets the volume i.e. the number of pixels that the distance image should have * By evaluation we found out that 50.000 pixel delivers a good result */ void SetDistanceImageVolume(unsigned int distImageVolume); /** * @brief Get the current selected segmentation for which the interpolation is performed * @return the current segmentation image */ mitk::Image::Pointer GetCurrentSegmentation(); Surface* GetContoursAsSurface(); void SetDataStorage(DataStorage::Pointer ds); /** * Sets the current list of contourpoints which is used for the surface interpolation * @param segmentation The current selected segmentation * \deprecatedSince{2014_03} */ DEPRECATED (void SetCurrentSegmentationInterpolationList(mitk::Image::Pointer segmentation)); /** * Sets the current list of contourpoints which is used for the surface interpolation * @param segmentation The current selected segmentation */ void SetCurrentInterpolationSession(mitk::Image::Pointer currentSegmentationImage); /** * Removes the segmentation and all its contours from the list * @param segmentation The segmentation to be removed * \deprecatedSince{2014_03} */ DEPRECATED (void RemoveSegmentationFromContourList(mitk::Image* segmentation)); /** * @brief Remove interpolation session * @param segmentationImage the session to be removed */ void RemoveInterpolationSession(mitk::Image::Pointer segmentationImage); + /** + * Replaces the current interpolation session with a new one. All contours form the old + * session will be applied to the new session. This only works if the two images have the + * geometry + * @param oldSession the session which should be replaced + * @param newSession the new session which replaces the old one + * @return true it the the replacement was successful, false if not (e.g. the image's geometry differs) + */ + bool ReplaceInterpolationSession(mitk::Image::Pointer oldSession, mitk::Image::Pointer newSession); + /** * @brief Removes all sessions */ void RemoveAllInterpolationSessions(); /** * @brief Reinitializes the interpolation using the provided contour data * @param contours a mitk::Surface which contains the contours as polys in the vtkPolyData */ void ReinitializeInterpolation(mitk::Surface::Pointer contours); mitk::Image* GetImage(); /** * Estimates the memory which is needed to build up the equationsystem for the interpolation. * \returns The percentage of the real memory which will be used by the interpolation */ double EstimatePortionOfNeededMemory(); unsigned int GetNumberOfInterpolationSessions(); protected: SurfaceInterpolationController(); ~SurfaceInterpolationController(); template void GetImageBase(itk::Image* input, itk::ImageBase<3>::Pointer& result); private: void OnSegmentationDeleted(const itk::Object *caller, const itk::EventObject &event); void ReinitializeInterpolation(); void AddToInterpolationPipeline(ContourPositionInformation contourInfo); ReduceContourSetFilter::Pointer m_ReduceFilter; ComputeContourSetNormalsFilter::Pointer m_NormalsFilter; CreateDistanceImageFromSurfaceFilter::Pointer m_InterpolateSurfaceFilter; Surface::Pointer m_Contours; vtkSmartPointer m_PolyData; mitk::DataStorage::Pointer m_DataStorage; ContourListMap m_ListOfInterpolationSessions; mitk::Surface::Pointer m_InterpolationResult; unsigned int m_CurrentNumberOfReducedContours; mitk::Image* m_SelectedSegmentation; std::map m_SegmentationObserverTags; }; } #endif diff --git a/Modules/ToFHardware/Testing/mitkToFImageRecorderTest.cpp b/Modules/ToFHardware/Testing/mitkToFImageRecorderTest.cpp index 2623414640..2755ea5ce2 100644 --- a/Modules/ToFHardware/Testing/mitkToFImageRecorderTest.cpp +++ b/Modules/ToFHardware/Testing/mitkToFImageRecorderTest.cpp @@ -1,151 +1,155 @@ /*=================================================================== 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 #include #include #include #include #include #include #include class mitkToFImageRecorderTestSuite : public mitk::TestFixture { CPPUNIT_TEST_SUITE(mitkToFImageRecorderTestSuite); //Removed due to random fails on linux continuous bug #12977 -// MITK_TEST(StartRecording_ValidDepthImage_WritesImageToFile); -// MITK_TEST(StartRecording_ValidAmplitudeImage_WritesImageToFile); -// MITK_TEST(StartRecording_ValidIntensityImage_WritesImageToFile); + MITK_TEST(StartRecording_ValidDepthImage_WritesImageToFile); + MITK_TEST(StartRecording_ValidAmplitudeImage_WritesImageToFile); + MITK_TEST(StartRecording_ValidIntensityImage_WritesImageToFile); CPPUNIT_TEST_SUITE_END(); private: /** Members used inside the different (sub-)tests. All members are initialized via setUp(). * Every recorder needs a device. Here we use a player device. * The player device needs data to load. The ground truth is loaded via IOUtil. */ mitk::ToFImageRecorder::Pointer m_ToFImageRecorder; mitk::ToFCameraMITKPlayerDevice::Pointer m_PlayerDevice; std::string m_DistanceImageName; std::string m_AmplitudeImageName; std::string m_IntensityImageName; mitk::Image::Pointer m_GroundTruthDepthImage; mitk::Image::Pointer m_GroundTruthIntensityImage; mitk::Image::Pointer m_GroundTruthAmplitudeImage; public: /** * @brief Setup a recorder including a device. Here, we use a player, because in an automatic test * hardware is not useful. */ void setUp() { m_ToFImageRecorder = mitk::ToFImageRecorder::New(); - m_DistanceImageName = "test_DistanceImage.nrrd"; - m_AmplitudeImageName = "test_AmplitudeImage.nrrd"; - m_IntensityImageName = "test_IntensityImage.nrrd"; + m_DistanceImageName = mitk::IOUtil::CreateTemporaryFile();//"test_DistanceImage.nrrd"; + m_AmplitudeImageName = mitk::IOUtil::CreateTemporaryFile();//"test_AmplitudeImage.nrrd"; + m_IntensityImageName = mitk::IOUtil::CreateTemporaryFile();//"test_IntensityImage.nrrd"; + + m_DistanceImageName.append(".nrrd"); + m_AmplitudeImageName.append(".nrrd"); + m_IntensityImageName.append(".nrrd"); m_PlayerDevice = mitk::ToFCameraMITKPlayerDevice::New(); m_ToFImageRecorder->SetCameraDevice(m_PlayerDevice); //the test data set has 20 frames, so we record 20 per default m_ToFImageRecorder->SetNumOfFrames(20); m_ToFImageRecorder->SetRecordMode(mitk::ToFImageRecorder::PerFrames); std::string dirName = MITK_TOF_DATA_DIR; std::string distanceFileName = dirName + "/PMDCamCube2_MF0_IT0_20Images_DistanceImage.pic"; std::string amplitudeFileName = dirName + "/PMDCamCube2_MF0_IT0_20Images_AmplitudeImage.pic"; std::string intensityFileName = dirName + "/PMDCamCube2_MF0_IT0_20Images_IntensityImage.pic"; m_PlayerDevice->SetProperty("DistanceImageFileName",mitk::StringProperty::New(distanceFileName)); m_PlayerDevice->SetProperty("AmplitudeImageFileName",mitk::StringProperty::New(amplitudeFileName)); m_PlayerDevice->SetProperty("IntensityImageFileName",mitk::StringProperty::New(intensityFileName)); //comparing against IOUtil seems fair enough m_GroundTruthDepthImage = mitk::IOUtil::LoadImage(distanceFileName); m_GroundTruthAmplitudeImage = mitk::IOUtil::LoadImage(amplitudeFileName); m_GroundTruthIntensityImage = mitk::IOUtil::LoadImage(intensityFileName); m_PlayerDevice->ConnectCamera(); m_PlayerDevice->StartCamera(); } void tearDown() { m_PlayerDevice->StopCamera(); m_PlayerDevice->DisconnectCamera(); } void StartRecording_ValidDepthImage_WritesImageToFile() { m_ToFImageRecorder->SetDistanceImageFileName(m_DistanceImageName); m_ToFImageRecorder->StartRecording(); m_ToFImageRecorder->WaitForThreadBeingTerminated(); // wait to allow recording m_ToFImageRecorder->StopRecording(); mitk::Image::Pointer recordedImage = mitk::IOUtil::LoadImage(m_DistanceImageName); MITK_ASSERT_EQUAL( m_GroundTruthDepthImage, recordedImage, "Recorded image should be equal to the test data."); if( remove( m_DistanceImageName.c_str() ) != 0 ) { - MITK_ERROR<<"File: test_distance.nrrd not successfully deleted!"; + MITK_ERROR<<"File: "<< m_DistanceImageName << " not successfully deleted!"; } } void StartRecording_ValidAmplitudeImage_WritesImageToFile() { m_ToFImageRecorder->SetAmplitudeImageFileName(m_AmplitudeImageName); m_ToFImageRecorder->SetAmplitudeImageSelected(true); m_ToFImageRecorder->SetDistanceImageSelected(false); m_ToFImageRecorder->StartRecording(); m_ToFImageRecorder->WaitForThreadBeingTerminated(); // wait to allow recording m_ToFImageRecorder->StopRecording(); mitk::Image::Pointer recordedImage = mitk::IOUtil::LoadImage(m_AmplitudeImageName); MITK_ASSERT_EQUAL( m_GroundTruthAmplitudeImage, recordedImage, "Recorded image should be equal to the test data."); if( remove( m_AmplitudeImageName.c_str() ) != 0 ) { - MITK_ERROR<<"File: test_amplitude.nrrd not successfully deleted!"; + MITK_ERROR<<"File: "<< m_AmplitudeImageName << " not successfully deleted!"; } } void StartRecording_ValidIntensityImage_WritesImageToFile() { m_ToFImageRecorder->SetIntensityImageFileName(m_IntensityImageName); m_ToFImageRecorder->SetIntensityImageSelected(true); m_ToFImageRecorder->SetDistanceImageSelected(false); m_ToFImageRecorder->StartRecording(); m_ToFImageRecorder->WaitForThreadBeingTerminated(); // wait to allow recording m_ToFImageRecorder->StopRecording(); mitk::Image::Pointer recordedImage = mitk::IOUtil::LoadImage(m_IntensityImageName); MITK_ASSERT_EQUAL( m_GroundTruthIntensityImage, recordedImage, "Recorded image should be equal to the test data."); if( remove( m_IntensityImageName.c_str() ) != 0 ) { - MITK_ERROR<<"File: test_intensity.nrrd not successfully deleted!"; + MITK_ERROR<<"File: "<< m_IntensityImageName << " not successfully deleted!"; } } }; MITK_TEST_SUITE_REGISTRATION(mitkToFImageRecorder) diff --git a/Modules/ToFHardware/mitkToFImageRecorder.cpp b/Modules/ToFHardware/mitkToFImageRecorder.cpp index 7eb8605e30..3ad365601b 100644 --- a/Modules/ToFHardware/mitkToFImageRecorder.cpp +++ b/Modules/ToFHardware/mitkToFImageRecorder.cpp @@ -1,268 +1,316 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "mitkToFImageRecorder.h" #include "mitkRealTimeClock.h" #include "itkMultiThreader.h" #include #pragma GCC visibility push(default) #include #pragma GCC visibility pop namespace mitk { ToFImageRecorder::ToFImageRecorder() { this->m_ToFCameraDevice = NULL; this->m_MultiThreader = itk::MultiThreader::New(); this->m_AbortMutex = itk::FastMutexLock::New(); this->m_ThreadID = 0; this->m_NumOfFrames = 1; //lets record one frame per default this->m_ToFImageWriter = NULL; this->m_DistanceImageSelected = true; //lets assume a device only has depth data by default this->m_AmplitudeImageSelected = false; this->m_IntensityImageSelected = false; this->m_RGBImageSelected = false; this->m_Abort = false; this->m_ToFCaptureWidth = 0; this->m_ToFCaptureHeight = 0; this->m_RGBCaptureWidth = 0; this->m_RGBCaptureHeight = 0; this->m_FileFormat = ".nrrd"; //lets make nrrd the default this->m_ToFPixelNumber = 0; this->m_RGBPixelNumber = 0; this->m_SourceDataSize = 0; this->m_ToFImageType = ToFImageWriter::ToFImageType3D; this->m_RecordMode = ToFImageRecorder::PerFrames; this->m_DistanceImageFileName = ""; this->m_AmplitudeImageFileName = ""; this->m_IntensityImageFileName = ""; this->m_RGBImageFileName = ""; this->m_ImageSequence = 0; this->m_DistanceArray = NULL; this->m_AmplitudeArray = NULL; this->m_IntensityArray = NULL; this->m_RGBArray = NULL; this->m_SourceDataArray = NULL; } ToFImageRecorder::~ToFImageRecorder() { delete[] m_DistanceArray; delete[] m_AmplitudeArray; delete[] m_IntensityArray; delete[] m_RGBArray; delete[] m_SourceDataArray; } void ToFImageRecorder::StopRecording() { this->m_AbortMutex->Lock(); this->m_Abort = true; this->m_AbortMutex->Unlock(); } void ToFImageRecorder::StartRecording() { if (this->m_ToFCameraDevice.IsNull()) { throw std::invalid_argument("ToFCameraDevice is NULL."); return; } if (this->m_FileFormat.compare(".csv") == 0) { this->m_ToFImageWriter = ToFImageCsvWriter::New(); } else if(this->m_FileFormat.compare(".nrrd") == 0) { this->m_ToFImageWriter = ToFNrrdImageWriter::New(); this->m_ToFImageWriter->SetExtension(m_FileFormat); } else { throw std::logic_error("No file format specified!"); } this->m_RGBCaptureWidth = this->m_ToFCameraDevice->GetRGBCaptureWidth(); this->m_RGBCaptureHeight = this->m_ToFCameraDevice->GetRGBCaptureHeight(); this->m_RGBPixelNumber = this->m_RGBCaptureWidth * this->m_RGBCaptureHeight; this->m_ToFCaptureWidth = this->m_ToFCameraDevice->GetCaptureWidth(); this->m_ToFCaptureHeight = this->m_ToFCameraDevice->GetCaptureHeight(); this->m_ToFPixelNumber = this->m_ToFCaptureWidth * this->m_ToFCaptureHeight; this->m_SourceDataSize = this->m_ToFCameraDevice->GetSourceDataSize(); // allocate buffer if(m_IntensityArray == NULL) { this->m_IntensityArray = new float[m_ToFPixelNumber]; } if(this->m_DistanceArray == NULL) { this->m_DistanceArray = new float[m_ToFPixelNumber]; } if(this->m_AmplitudeArray == NULL) { this->m_AmplitudeArray = new float[m_ToFPixelNumber]; } if(this->m_RGBArray == NULL) { this->m_RGBArray = new unsigned char[m_RGBPixelNumber*3]; } if(this->m_SourceDataArray == NULL) { this->m_SourceDataArray = new char[m_SourceDataSize]; } this->m_ToFImageWriter->SetDistanceImageFileName(this->m_DistanceImageFileName); this->m_ToFImageWriter->SetAmplitudeImageFileName(this->m_AmplitudeImageFileName); this->m_ToFImageWriter->SetIntensityImageFileName(this->m_IntensityImageFileName); this->m_ToFImageWriter->SetRGBImageFileName(this->m_RGBImageFileName); this->m_ToFImageWriter->SetRGBCaptureWidth(this->m_RGBCaptureWidth); this->m_ToFImageWriter->SetRGBCaptureHeight(this->m_RGBCaptureHeight); //this->m_ToFImageWriter->SetToFCaptureHeight(this->m_ToFCaptureHeight); this->m_ToFImageWriter->SetToFCaptureWidth(this->m_ToFCaptureWidth); this->m_ToFImageWriter->SetToFCaptureHeight(this->m_ToFCaptureHeight); this->m_ToFImageWriter->SetToFImageType(this->m_ToFImageType); this->m_ToFImageWriter->SetDistanceImageSelected(this->m_DistanceImageSelected); this->m_ToFImageWriter->SetAmplitudeImageSelected(this->m_AmplitudeImageSelected); this->m_ToFImageWriter->SetIntensityImageSelected(this->m_IntensityImageSelected); this->m_ToFImageWriter->SetRGBImageSelected(this->m_RGBImageSelected); this->m_ToFImageWriter->Open(); this->m_AbortMutex->Lock(); this->m_Abort = false; this->m_AbortMutex->Unlock(); - this->m_ThreadID = this->m_MultiThreader->SpawnThread(this->RecordData, this); +// this->m_ThreadID = this->m_MultiThreader->SpawnThread(this->RecordData, this); + + ToFCameraDevice::Pointer toFCameraDevice = this->GetCameraDevice(); + + mitk::RealTimeClock::Pointer realTimeClock; + realTimeClock = mitk::RealTimeClock::New(); + double t1 = 0; + t1 = realTimeClock->GetCurrentStamp(); + int requiredImageSequence = 0; + int numOfFramesRecorded = 0; + + bool abort = false; + this->m_AbortMutex->Lock(); + abort = this->m_Abort; + this->m_AbortMutex->Unlock(); + + while ( !abort ) + { + if ( ((this->m_RecordMode == ToFImageRecorder::PerFrames) && (numOfFramesRecorded < this->m_NumOfFrames)) || + (this->m_RecordMode == ToFImageRecorder::Infinite) ) + { + + toFCameraDevice->GetAllImages(this->m_DistanceArray, this->m_AmplitudeArray, + this->m_IntensityArray, this->m_SourceDataArray, requiredImageSequence, this->m_ImageSequence, this->m_RGBArray ); + + if (this->m_ImageSequence >= requiredImageSequence) + { + if (this->m_ImageSequence > requiredImageSequence) + { + MITK_INFO << "Problem! required: " << requiredImageSequence << " captured: " << this->m_ImageSequence; + } + requiredImageSequence = this->m_ImageSequence + 1; + this->m_ToFImageWriter->Add( this->m_DistanceArray, + this->m_AmplitudeArray, this->m_IntensityArray, this->m_RGBArray ); + numOfFramesRecorded++; + } + this->m_AbortMutex->Lock(); + abort = this->m_Abort; + this->m_AbortMutex->Unlock(); + } + else + { + abort = true; + } + } // end of while loop + + this->InvokeEvent(itk::AbortEvent()); + + this->m_ToFImageWriter->Close(); } void ToFImageRecorder::WaitForThreadBeingTerminated() { this->m_MultiThreader->TerminateThread(this->m_ThreadID); } ITK_THREAD_RETURN_TYPE ToFImageRecorder::RecordData(void* pInfoStruct) { struct itk::MultiThreader::ThreadInfoStruct * pInfo = (struct itk::MultiThreader::ThreadInfoStruct*)pInfoStruct; if (pInfo == NULL) { return ITK_THREAD_RETURN_VALUE; } if (pInfo->UserData == NULL) { return ITK_THREAD_RETURN_VALUE; } ToFImageRecorder* toFImageRecorder = (ToFImageRecorder*)pInfo->UserData; if (toFImageRecorder!=NULL) { ToFCameraDevice::Pointer toFCameraDevice = toFImageRecorder->GetCameraDevice(); mitk::RealTimeClock::Pointer realTimeClock; realTimeClock = mitk::RealTimeClock::New(); int n = 100; double t1 = 0; double t2 = 0; t1 = realTimeClock->GetCurrentStamp(); bool overflow = false; bool printStatus = false; int requiredImageSequence = 0; int numOfFramesRecorded = 0; bool abort = false; toFImageRecorder->m_AbortMutex->Lock(); abort = toFImageRecorder->m_Abort; toFImageRecorder->m_AbortMutex->Unlock(); while ( !abort ) { if ( ((toFImageRecorder->m_RecordMode == ToFImageRecorder::PerFrames) && (numOfFramesRecorded < toFImageRecorder->m_NumOfFrames)) || (toFImageRecorder->m_RecordMode == ToFImageRecorder::Infinite) ) { toFCameraDevice->GetAllImages(toFImageRecorder->m_DistanceArray, toFImageRecorder->m_AmplitudeArray, toFImageRecorder->m_IntensityArray, toFImageRecorder->m_SourceDataArray, requiredImageSequence, toFImageRecorder->m_ImageSequence, toFImageRecorder->m_RGBArray ); if (toFImageRecorder->m_ImageSequence >= requiredImageSequence) { if (toFImageRecorder->m_ImageSequence > requiredImageSequence) { MITK_INFO << "Problem! required: " << requiredImageSequence << " captured: " << toFImageRecorder->m_ImageSequence; } requiredImageSequence = toFImageRecorder->m_ImageSequence + 1; toFImageRecorder->m_ToFImageWriter->Add( toFImageRecorder->m_DistanceArray, toFImageRecorder->m_AmplitudeArray, toFImageRecorder->m_IntensityArray, toFImageRecorder->m_RGBArray ); numOfFramesRecorded++; if (numOfFramesRecorded % n == 0) { printStatus = true; } if (printStatus) { t2 = realTimeClock->GetCurrentStamp() - t1; MITK_INFO << " Framerate (fps): " << n / (t2/1000) << " Sequence: " << toFImageRecorder->m_ImageSequence; t1 = realTimeClock->GetCurrentStamp(); printStatus = false; } } toFImageRecorder->m_AbortMutex->Lock(); abort = toFImageRecorder->m_Abort; toFImageRecorder->m_AbortMutex->Unlock(); } else { abort = true; } } // end of while loop toFImageRecorder->InvokeEvent(itk::AbortEvent()); toFImageRecorder->m_ToFImageWriter->Close(); } return ITK_THREAD_RETURN_VALUE; } void ToFImageRecorder::SetCameraDevice(ToFCameraDevice* aToFCameraDevice) { this->m_ToFCameraDevice = aToFCameraDevice; } ToFCameraDevice* ToFImageRecorder::GetCameraDevice() { return this->m_ToFCameraDevice; } ToFImageWriter::ToFImageType ToFImageRecorder::GetToFImageType() { return this->m_ToFImageType; } void ToFImageRecorder::SetToFImageType(ToFImageWriter::ToFImageType toFImageType) { this->m_ToFImageType = toFImageType; } ToFImageRecorder::RecordMode ToFImageRecorder::GetRecordMode() { return this->m_RecordMode; } void ToFImageRecorder::SetRecordMode(ToFImageRecorder::RecordMode recordMode) { this->m_RecordMode = recordMode; } } diff --git a/Modules/ToFUI/Qmitk/QmitkToFCompositeFilterWidget.cpp b/Modules/ToFUI/Qmitk/QmitkToFCompositeFilterWidget.cpp index 5e5caf3514..8727b078df 100644 --- a/Modules/ToFUI/Qmitk/QmitkToFCompositeFilterWidget.cpp +++ b/Modules/ToFUI/Qmitk/QmitkToFCompositeFilterWidget.cpp @@ -1,290 +1,283 @@ /*=================================================================== 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 -//QT headers -#include - #include #include #include #include const std::string QmitkToFCompositeFilterWidget::VIEW_ID = "org.mitk.views.qmitktofcompositefilterwidget"; QmitkToFCompositeFilterWidget::QmitkToFCompositeFilterWidget(QWidget* parent, Qt::WindowFlags f): QWidget(parent, f) { this->m_ToFCompositeFilter = NULL; m_Controls = NULL; CreateQtPartControl(this); } QmitkToFCompositeFilterWidget::~QmitkToFCompositeFilterWidget() { } void QmitkToFCompositeFilterWidget::CreateQtPartControl(QWidget *parent) { if (!m_Controls) { // create GUI widgets m_Controls = new Ui::QmitkToFCompositeFilterWidgetControls; m_Controls->setupUi(parent); - QPlastiqueStyle *sliderStyle = new QPlastiqueStyle(); - int min = m_Controls->m_ThresholdFilterMinValueSpinBox->value(); int max = m_Controls->m_ThresholdFilterMaxValueSpinBox->value(); m_Controls->m_ThresholdFilterRangeSlider->setMinimum(min); m_Controls->m_ThresholdFilterRangeSlider->setMaximum(max); - m_Controls->m_ThresholdFilterRangeSlider->setLowerValue(min); - m_Controls->m_ThresholdFilterRangeSlider->setUpperValue(max); - m_Controls->m_ThresholdFilterRangeSlider->setHandleMovementMode(QxtSpanSlider::NoOverlapping); - m_Controls->m_ThresholdFilterRangeSlider->setStyle(sliderStyle); + m_Controls->m_ThresholdFilterRangeSlider->setMinimumValue(min); + m_Controls->m_ThresholdFilterRangeSlider->setMaximumValue(max); this->CreateConnections(); this->OnShowAdvancedOptionsCheckboxChecked(false); } } void QmitkToFCompositeFilterWidget::CreateConnections() { if ( m_Controls ) { connect(m_Controls->m_TemporalMedianFilterNumOfFramesSpinBox, SIGNAL(valueChanged(int)), this, SLOT(OnTemporalMedianFilterNumOfFramesSpinBoxValueChanged(int))); connect(m_Controls->m_BilateralFilterDomainSigmaSpinBox, SIGNAL(valueChanged(double)), this, SLOT(OnBilateralFilterDomainSigmaSpinBoxValueChanged(double))); connect(m_Controls->m_BilateralFilterRangeSigmaSpinBox, SIGNAL(valueChanged(double)), this, SLOT(OnBilateralFilterRangeSigmaSpinBoxValueChanged(double))); connect(m_Controls->m_BilateralFilterKernelRadiusSpinBox, SIGNAL(valueChanged(int)), this, SLOT(OnBilateralFilterKernelRadiusSpinBoxValueChanged(int))); connect(m_Controls->m_ThresholdFilterMinValueSpinBox, SIGNAL(valueChanged(int)), this, SLOT(OnThresholdFilterMinValueChanged(int))); connect(m_Controls->m_ThresholdFilterMaxValueSpinBox, SIGNAL(valueChanged(int)), this, SLOT(OnThresholdFilterMaxValueChanged(int))); connect( (QObject*)(m_Controls->m_TemporalMedianFilterCheckBox), SIGNAL(toggled(bool)), this, SLOT(OnTemporalMedianFilterCheckBoxChecked(bool)) ); connect( (QObject*)(m_Controls->m_AverageFilterCheckBox), SIGNAL(toggled(bool)), this, SLOT(OnAverageFilterCheckBoxChecked(bool)) ); connect( (QObject*)(m_Controls->m_ThresholdFilterCheckBox), SIGNAL(toggled(bool)), this, SLOT(OnThresholdFilterCheckBoxChecked(bool)) ); connect( (QObject*)(m_Controls->maskSegmentationCheckBox), SIGNAL(toggled(bool)), this, SLOT(OnMaskSegmentationCheckBoxChecked(bool)) ); connect( (QObject*)(m_Controls->m_BilateralFilterCheckBox), SIGNAL(toggled(bool)), this, SLOT(OnBilateralFilterCheckBoxChecked(bool)) ); connect( (QObject*)(m_Controls->m_MedianFilterCheckBox), SIGNAL(toggled(bool)), this, SLOT(OnMedianFilterCheckBoxChecked(bool)) ); connect( (QObject*)(m_Controls->m_ShowAdvancedOptionsCheckbox), SIGNAL(toggled(bool)), this, SLOT(OnShowAdvancedOptionsCheckboxChecked(bool)) ); connect(m_Controls->m_ThresholdFilterRangeSlider, SIGNAL(spanChanged(int, int) ),this, SLOT( OnSpanChanged(int , int ) )); //reset button connect(m_Controls->m_ThresholdFilterRangeSliderReset, SIGNAL(pressed()), this, SLOT(OnResetThresholdFilterRangeSlider())); } } void QmitkToFCompositeFilterWidget::SetToFCompositeFilter(mitk::ToFCompositeFilter* toFCompositeFilter) { this->m_ToFCompositeFilter = toFCompositeFilter; } mitk::ToFCompositeFilter* QmitkToFCompositeFilterWidget::GetToFCompositeFilter() { if (this->m_ToFCompositeFilter.IsNull()) { this->m_ToFCompositeFilter = mitk::ToFCompositeFilter::New(); } return this->m_ToFCompositeFilter; } void QmitkToFCompositeFilterWidget::SetDataStorage(mitk::DataStorage::Pointer dataStorage) { m_DataStorage = dataStorage; m_Controls->maskImageComboBox->SetDataStorage(dataStorage); m_Controls->maskImageComboBox->SetPredicate(mitk::NodePredicateAnd::New(mitk::NodePredicateDataType::New("Image"),mitk::NodePredicateProperty::New("binary", mitk::BoolProperty::New(true)))); } void QmitkToFCompositeFilterWidget::UpdateFilterParameter() { OnTemporalMedianFilterCheckBoxChecked(m_Controls->m_TemporalMedianFilterCheckBox->isChecked()); OnAverageFilterCheckBoxChecked(m_Controls->m_AverageFilterCheckBox->isChecked()); OnMedianFilterCheckBoxChecked(m_Controls->m_MedianFilterCheckBox->isChecked()); OnThresholdFilterCheckBoxChecked(m_Controls->m_ThresholdFilterCheckBox->isChecked()); OnBilateralFilterCheckBoxChecked(m_Controls->m_BilateralFilterCheckBox->isChecked()); } void QmitkToFCompositeFilterWidget::SetWidgetConfiguration(bool threshold, bool mask, bool tempMedian, bool tempAverage, bool median, bool bilateral ) { m_Controls->m_ThresholdFilterCheckBox->setChecked(threshold); m_Controls->maskSegmentationCheckBox->setChecked(mask); m_Controls->m_TemporalMedianFilterCheckBox->setChecked(tempMedian); m_Controls->m_AverageFilterCheckBox->setChecked(tempAverage); m_Controls->m_MedianFilterCheckBox->setChecked(median); m_Controls->m_BilateralFilterCheckBox->setChecked(bilateral); } void QmitkToFCompositeFilterWidget::SetStandardParametersBilateralFilter(double domainSigma, double rangeSigma, int kernelRadius) { m_Controls->m_BilateralFilterDomainSigmaSpinBox->setValue(domainSigma); m_Controls->m_BilateralFilterRangeSigmaSpinBox->setValue(rangeSigma); m_Controls->m_BilateralFilterKernelRadiusSpinBox->setValue(kernelRadius); } void QmitkToFCompositeFilterWidget::SetStandardParametersThresholdFilter(int min, int max) { m_Controls->m_ThresholdFilterMinValueSpinBox->setValue(min); m_Controls->m_ThresholdFilterMaxValueSpinBox->setValue(max); } void QmitkToFCompositeFilterWidget::SetStandardParameterTemporalAveraging(int nImages) { m_Controls->m_TemporalMedianFilterNumOfFramesSpinBox->setValue(nImages); } void QmitkToFCompositeFilterWidget::OnTemporalMedianFilterCheckBoxChecked(bool checked) { this->m_ToFCompositeFilter->SetApplyTemporalMedianFilter(checked); // disable average filter if temporal median filter is enabled if (checked) { m_Controls->m_AverageFilterCheckBox->setChecked(false); this->m_ToFCompositeFilter->SetApplyAverageFilter(false); } } void QmitkToFCompositeFilterWidget::OnAverageFilterCheckBoxChecked(bool checked) { this->m_ToFCompositeFilter->SetApplyAverageFilter(checked); // disable temporal median filter if average filter is enabled if (checked) { m_Controls->m_TemporalMedianFilterCheckBox->setChecked(false); this->m_ToFCompositeFilter->SetApplyTemporalMedianFilter(false); } } void QmitkToFCompositeFilterWidget::OnShowAdvancedOptionsCheckboxChecked(bool checked) { - this->m_Controls->m_AverageFilterCheckBox->setShown(checked); - this->m_Controls->m_BilateralFilterCheckBox->setShown(checked); - this->m_Controls->m_BilateralFilterDomainSigmaSpinBox->setShown(checked); - this->m_Controls->m_BilateralFilterKernelRadiusSpinBox->setShown(checked); - this->m_Controls->m_BilateralFilterRangeSigmaSpinBox->setShown(checked); - this->m_Controls->m_MedianFilterCheckBox->setShown(checked); - this->m_Controls->m_TemporalMedianFilterCheckBox->setShown(checked); - this->m_Controls->m_TemporalMedianFilterNumOfFramesSpinBox->setShown(checked); - this->m_Controls->m_ThresholdFilterCheckBox->setShown(checked); - this->m_Controls->m_ThresholdFilterMaxValueSpinBox->setShown(checked); - this->m_Controls->m_ThresholdFilterMinValueSpinBox->setShown(checked); - this->m_Controls->m_ThresholdFilterRangeSlider->setShown(checked); - this->m_Controls->m_ThresholdFilterRangeSliderReset->setShown(checked); - this->m_Controls->label_3->setShown(checked); - this->m_Controls->label_4->setShown(checked); - this->m_Controls->label_12->setShown(checked); - this->m_Controls->maskImageComboBox->setShown(checked); - this->m_Controls->maskSegmentationCheckBox->setShown(checked); + this->m_Controls->m_AverageFilterCheckBox->setVisible(checked); + this->m_Controls->m_BilateralFilterCheckBox->setVisible(checked); + this->m_Controls->m_BilateralFilterDomainSigmaSpinBox->setVisible(checked); + this->m_Controls->m_BilateralFilterKernelRadiusSpinBox->setVisible(checked); + this->m_Controls->m_BilateralFilterRangeSigmaSpinBox->setVisible(checked); + this->m_Controls->m_MedianFilterCheckBox->setVisible(checked); + this->m_Controls->m_TemporalMedianFilterCheckBox->setVisible(checked); + this->m_Controls->m_TemporalMedianFilterNumOfFramesSpinBox->setVisible(checked); + this->m_Controls->m_ThresholdFilterCheckBox->setVisible(checked); + this->m_Controls->m_ThresholdFilterMaxValueSpinBox->setVisible(checked); + this->m_Controls->m_ThresholdFilterMinValueSpinBox->setVisible(checked); + this->m_Controls->m_ThresholdFilterRangeSlider->setVisible(checked); + this->m_Controls->m_ThresholdFilterRangeSliderReset->setVisible(checked); + this->m_Controls->label_3->setVisible(checked); + this->m_Controls->label_4->setVisible(checked); + this->m_Controls->label_12->setVisible(checked); + this->m_Controls->maskImageComboBox->setVisible(checked); + this->m_Controls->maskSegmentationCheckBox->setVisible(checked); } void QmitkToFCompositeFilterWidget::OnThresholdFilterCheckBoxChecked(bool checked) { this->m_ToFCompositeFilter->SetApplyThresholdFilter(checked); } void QmitkToFCompositeFilterWidget::OnMaskSegmentationCheckBoxChecked(bool checked) { this->m_ToFCompositeFilter->SetApplyMaskSegmentation(checked); if (checked) { mitk::DataNode::Pointer maskImageNode = m_Controls->maskImageComboBox->GetSelectedNode(); if (maskImageNode.IsNotNull()) { mitk::Image::Pointer maskImage = dynamic_cast(maskImageNode->GetData()); this->m_ToFCompositeFilter->SetSegmentationMask(maskImage); } } } void QmitkToFCompositeFilterWidget::OnMedianFilterCheckBoxChecked(bool checked) { this->m_ToFCompositeFilter->SetApplyMedianFilter(checked); } void QmitkToFCompositeFilterWidget::OnBilateralFilterCheckBoxChecked(bool checked) { this->m_ToFCompositeFilter->SetApplyBilateralFilter(checked); } void QmitkToFCompositeFilterWidget::OnTemporalMedianFilterNumOfFramesSpinBoxValueChanged(int value) { this->m_ToFCompositeFilter->SetTemporalMedianFilterParameter(value); } void QmitkToFCompositeFilterWidget::OnBilateralFilterDomainSigmaSpinBoxValueChanged(double value) { SetBilateralFilterParameter(); } void QmitkToFCompositeFilterWidget::OnBilateralFilterRangeSigmaSpinBoxValueChanged(double value) { SetBilateralFilterParameter(); } void QmitkToFCompositeFilterWidget::OnBilateralFilterKernelRadiusSpinBoxValueChanged(int value) { SetBilateralFilterParameter(); } void QmitkToFCompositeFilterWidget::OnThresholdFilterMinValueChanged(int value) { - m_Controls->m_ThresholdFilterRangeSlider->setLowerValue(value); + m_Controls->m_ThresholdFilterRangeSlider->setMinimumValue(value); SetThresholdFilterParameter(); } void QmitkToFCompositeFilterWidget::OnThresholdFilterMaxValueChanged(int value) { - m_Controls->m_ThresholdFilterRangeSlider->setUpperValue(value); + m_Controls->m_ThresholdFilterRangeSlider->setMaximumValue(value); SetThresholdFilterParameter(); } void QmitkToFCompositeFilterWidget::SetThresholdFilterParameter() { int min = m_Controls->m_ThresholdFilterMinValueSpinBox->value(); int max = m_Controls->m_ThresholdFilterMaxValueSpinBox->value(); this->m_ToFCompositeFilter->SetThresholdFilterParameter(min, max); } void QmitkToFCompositeFilterWidget::SetBilateralFilterParameter() { double domainSigma = m_Controls->m_BilateralFilterDomainSigmaSpinBox->value(); double rangeSigma = m_Controls->m_BilateralFilterRangeSigmaSpinBox->value(); int kernelRadius = m_Controls->m_BilateralFilterKernelRadiusSpinBox->value(); this->m_ToFCompositeFilter->SetBilateralFilterParameter(domainSigma, rangeSigma, kernelRadius); } void QmitkToFCompositeFilterWidget::OnSpanChanged(int lower, int upper) { - int lowerVal = m_Controls->m_ThresholdFilterRangeSlider->lowerValue(); - int upperVal = m_Controls->m_ThresholdFilterRangeSlider->upperValue(); + int lowerVal = m_Controls->m_ThresholdFilterRangeSlider->minimumValue(); + int upperVal = m_Controls->m_ThresholdFilterRangeSlider->maximumValue(); m_Controls->m_ThresholdFilterMinValueSpinBox->setValue(lowerVal); m_Controls->m_ThresholdFilterMaxValueSpinBox->setValue(upperVal); } void QmitkToFCompositeFilterWidget::OnResetThresholdFilterRangeSlider() { int lower = 1; int upper = 7000; - m_Controls->m_ThresholdFilterRangeSlider->setLowerValue(lower); - m_Controls->m_ThresholdFilterRangeSlider->setUpperValue(upper); + m_Controls->m_ThresholdFilterRangeSlider->setMinimumValue(lower); + m_Controls->m_ThresholdFilterRangeSlider->setMaximumValue(upper); m_Controls->m_ThresholdFilterMinValueSpinBox->setValue(lower); m_Controls->m_ThresholdFilterMaxValueSpinBox->setValue(upper); } diff --git a/Modules/ToFUI/Qmitk/QmitkToFCompositeFilterWidgetControls.ui b/Modules/ToFUI/Qmitk/QmitkToFCompositeFilterWidgetControls.ui index 672e5a8e6e..81ff4de855 100644 --- a/Modules/ToFUI/Qmitk/QmitkToFCompositeFilterWidgetControls.ui +++ b/Modules/ToFUI/Qmitk/QmitkToFCompositeFilterWidgetControls.ui @@ -1,244 +1,244 @@ QmitkToFCompositeFilterWidgetControls 0 0 467 210 0 0 QmitkToFCompositeFilter 11 ToF Preprocessing Show Advanced Options Threshold Filter 7000 0 QFrame::StyledPanel QFrame::Raised 0 0 - + modify actual seen window by dragging left and right slider. Qt::Horizontal 0 0 48 16777215 Resets range to histogram minimum and maximum. Reset 7000 7000 Mask segmentation true Median Filter (t) Average Filter 100 10 true Median Filter Bilateral Filter σ_d: 2.000000000000000 σ_r: 60.000000000000000 radius: - QxtSpanSlider - QSlider -
qxtspanslider.h
+ ctkRangeSlider + QWidget +
ctkRangeSlider.h
QmitkDataStorageComboBox QComboBox
QmitkDataStorageComboBox.h
diff --git a/Modules/ToFUI/Qmitk/QmitkToFRecorderWidget.cpp b/Modules/ToFUI/Qmitk/QmitkToFRecorderWidget.cpp index 7124eaa534..9cc3aa692d 100644 --- a/Modules/ToFUI/Qmitk/QmitkToFRecorderWidget.cpp +++ b/Modules/ToFUI/Qmitk/QmitkToFRecorderWidget.cpp @@ -1,426 +1,427 @@ /*=================================================================== 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. ===================================================================*/ #define _USE_MATH_DEFINES #include "QmitkToFRecorderWidget.h" //QT headers -#include +#include #include #include #include #include #include +#include //mitk headers #include //itk headers #pragma GCC visibility push(default) #include #pragma GCC visibility pop #include struct QFileDialogArgs; class QFileDialogPrivate; const std::string QmitkToFRecorderWidget::VIEW_ID = "org.mitk.views.qmitktofrecorderwidget"; QmitkToFRecorderWidget::QmitkToFRecorderWidget(QWidget* parent, Qt::WindowFlags f): QWidget(parent, f) { this->m_ToFImageRecorder = NULL; this->m_ToFImageGrabber = NULL; this->m_RecordMode = mitk::ToFImageRecorder::PerFrames; this-> m_Controls = NULL; CreateQtPartControl(this); } QmitkToFRecorderWidget::~QmitkToFRecorderWidget() { } void QmitkToFRecorderWidget::CreateQtPartControl(QWidget *parent) { if (!m_Controls) { // create GUI widgets this->m_Controls = new Ui::QmitkToFRecorderWidgetControls; this->m_Controls->setupUi(parent); this->CreateConnections(); } } void QmitkToFRecorderWidget::CreateConnections() { if ( m_Controls ) { connect( (QObject*)(m_Controls->m_PlayButton), SIGNAL(clicked()),(QObject*) this, SLOT(OnPlay()) ); connect( (QObject*)(m_Controls->m_StopButton), SIGNAL(clicked()),(QObject*) this, SLOT(OnStop()) ); connect( (QObject*)(m_Controls->m_StartRecordingButton), SIGNAL(clicked()),(QObject*) this, SLOT(OnStartRecorder()) ); connect( (QObject*)(m_Controls->m_RecordModeComboBox), SIGNAL(currentIndexChanged(int)),(QObject*) this, SLOT(OnChangeRecordModeComboBox(int)) ); connect(this, SIGNAL(RecordingStopped()), this, SLOT(OnRecordingStopped()), Qt::BlockingQueuedConnection); } } void QmitkToFRecorderWidget::SetParameter(mitk::ToFImageGrabber* toFImageGrabber, mitk::ToFImageRecorder* toFImageRecorder) { this->m_ToFImageGrabber = toFImageGrabber; this->m_ToFImageRecorder = toFImageRecorder; this->m_StopRecordingCommand = CommandType::New(); this->m_StopRecordingCommand->SetCallbackFunction(this, &QmitkToFRecorderWidget::StopRecordingCallback); this->m_ToFImageRecorder->RemoveAllObservers(); this->m_ToFImageRecorder->AddObserver(itk::AbortEvent(), this->m_StopRecordingCommand); m_Controls->m_PlayButton->setChecked(false); m_Controls->m_PlayButton->setEnabled(true); m_Controls->m_StartRecordingButton->setChecked(false); m_Controls->m_RecorderGroupBox->setEnabled(true); } void QmitkToFRecorderWidget::StopRecordingCallback() { emit RecordingStopped(); } void QmitkToFRecorderWidget::ResetGUIToInitial() { m_Controls->m_PlayButton->setChecked(false); m_Controls->m_PlayButton->setEnabled(true); m_Controls->m_RecorderGroupBox->setEnabled(false); } void QmitkToFRecorderWidget::OnRecordingStopped() { m_Controls->m_StartRecordingButton->setChecked(false); m_Controls->m_RecorderGroupBox->setEnabled(true); } void QmitkToFRecorderWidget::OnStop() { StopCamera(); StopRecorder(); ResetGUIToInitial(); emit ToFCameraStopped(); } void QmitkToFRecorderWidget::OnPlay() { m_Controls->m_PlayButton->setChecked(true); m_Controls->m_PlayButton->setEnabled(false); m_Controls->m_RecorderGroupBox->setEnabled(true); this->repaint(); StartCamera(); emit ToFCameraStarted(); } void QmitkToFRecorderWidget::StartCamera() { if (!m_ToFImageGrabber->IsCameraActive()) { m_ToFImageGrabber->StartCamera(); } } void QmitkToFRecorderWidget::StopCamera() { if( m_ToFImageGrabber.IsNotNull() ) m_ToFImageGrabber->StopCamera(); } void QmitkToFRecorderWidget::StopRecorder() { if( m_ToFImageRecorder.IsNotNull() ) { this->m_ToFImageRecorder->StopRecording(); } } void QmitkToFRecorderWidget::OnStartRecorder() { m_Controls->m_StartRecordingButton->setChecked(true); m_Controls->m_RecorderGroupBox->setEnabled(false); this->repaint(); int numOfFrames = m_Controls->m_NumOfFramesSpinBox->value(); try { bool fileOK = true; bool distanceImageSelected = true; bool amplitudeImageSelected = false; bool intensityImageSelected = false; bool rgbImageSelected = false; bool rawDataSelected = false; //Set check boxes in dialog according to device properties m_ToFImageGrabber->GetCameraDevice()->GetBoolProperty("HasAmplitudeImage",amplitudeImageSelected); m_ToFImageGrabber->GetCameraDevice()->GetBoolProperty("HasIntensityImage",intensityImageSelected); m_ToFImageGrabber->GetCameraDevice()->GetBoolProperty("HasRGBImage",rgbImageSelected); QString tmpFileName(""); QString selectedFilter(""); QString imageFileName(""); mitk::ToFImageWriter::ToFImageType tofImageType; tmpFileName = QmitkToFRecorderWidget::getSaveFileName(tofImageType, distanceImageSelected, amplitudeImageSelected, intensityImageSelected, rgbImageSelected, rawDataSelected, NULL, "Save Image To...", imageFileName, "NRRD Images (*.nrrd);;PIC Images - deprecated (*.pic);;Text (*.csv)", &selectedFilter); if (tmpFileName.isEmpty()) { fileOK = false; } else { imageFileName = tmpFileName; } if (fileOK) { std::string dir = itksys::SystemTools::GetFilenamePath( imageFileName.toStdString() ); std::string baseFilename = itksys::SystemTools::GetFilenameWithoutLastExtension( imageFileName.toStdString() ); std::string extension = itksys::SystemTools::GetFilenameLastExtension( imageFileName.toStdString() ); int integrationTime = this->m_ToFImageGrabber->GetIntegrationTime(); int modulationFreq = this->m_ToFImageGrabber->GetModulationFrequency(); QString integrationTimeStr; integrationTimeStr.setNum(integrationTime); QString modulationFreqStr; modulationFreqStr.setNum(modulationFreq); QString numOfFramesStr(""); if (this->m_RecordMode == mitk::ToFImageRecorder::PerFrames) { numOfFramesStr.setNum(numOfFrames); } std::string distImageFileName = prepareFilename(dir, baseFilename, modulationFreqStr.toStdString(), integrationTimeStr.toStdString(), numOfFramesStr.toStdString(), extension, "_DistanceImage"); MITK_INFO << "Save distance data to: " << distImageFileName; std::string amplImageFileName = prepareFilename(dir, baseFilename, modulationFreqStr.toStdString(), integrationTimeStr.toStdString(), numOfFramesStr.toStdString(), extension, "_AmplitudeImage"); MITK_INFO << "Save amplitude data to: " << amplImageFileName; std::string intenImageFileName = prepareFilename(dir, baseFilename, modulationFreqStr.toStdString(), integrationTimeStr.toStdString(), numOfFramesStr.toStdString(), extension, "_IntensityImage"); MITK_INFO << "Save intensity data to: " << intenImageFileName; std::string rgbImageFileName = prepareFilename(dir, baseFilename, modulationFreqStr.toStdString(), integrationTimeStr.toStdString(), numOfFramesStr.toStdString(), extension, "_RGBImage"); MITK_INFO << "Save intensity data to: " << rgbImageFileName; if (selectedFilter.compare("Text (*.csv)") == 0) { this->m_ToFImageRecorder->SetFileFormat(".csv"); } else if (selectedFilter.compare("PIC Images - deprecated (*.pic)") == 0) { //default this->m_ToFImageRecorder->SetFileFormat(".pic"); QMessageBox::warning(NULL, "Deprecated File Format!", "Please note that *.pic file format is deprecated and not longer supported! The suggested file format for images is *.nrrd!"); } else if (selectedFilter.compare("NRRD Images (*.nrrd)") == 0) { this->m_ToFImageRecorder->SetFileFormat(".nrrd"); } else { QMessageBox::warning(NULL, "Unsupported file format!", "Please specify one of the supported file formats *.nrrd, *.csv!"); return; } numOfFrames = m_Controls->m_NumOfFramesSpinBox->value(); this->m_ToFImageRecorder->SetDistanceImageFileName(distImageFileName); this->m_ToFImageRecorder->SetAmplitudeImageFileName(amplImageFileName); this->m_ToFImageRecorder->SetIntensityImageFileName(intenImageFileName); this->m_ToFImageRecorder->SetRGBImageFileName(rgbImageFileName); this->m_ToFImageRecorder->SetToFImageType(tofImageType); this->m_ToFImageRecorder->SetDistanceImageSelected(distanceImageSelected); this->m_ToFImageRecorder->SetAmplitudeImageSelected(amplitudeImageSelected); this->m_ToFImageRecorder->SetIntensityImageSelected(intensityImageSelected); this->m_ToFImageRecorder->SetRGBImageSelected(rgbImageSelected); this->m_ToFImageRecorder->SetRecordMode(this->m_RecordMode); this->m_ToFImageRecorder->SetNumOfFrames(numOfFrames); emit RecordingStarted(); this->m_ToFImageRecorder->StartRecording(); } else { this->OnRecordingStopped(); } } catch(std::exception& e) { QMessageBox::critical(NULL, "Error", QString(e.what())); this->OnRecordingStopped(); } } QString QmitkToFRecorderWidget::getSaveFileName(mitk::ToFImageWriter::ToFImageType& tofImageType, bool& distanceImageSelected, bool& amplitudeImageSelected, bool& intensityImageSelected, bool& rgbImageSelected, bool& rawDataSelected, QWidget *parent, const QString &caption, const QString &dir, const QString &filter, QString *selectedFilter, QFileDialog::Options options ) { QString selectedFileName = ""; QComboBox* combo = new QComboBox; combo->addItem("3D"); combo->addItem("2D + t"); QHBoxLayout* checkBoxGroup = new QHBoxLayout(); QCheckBox* distanceImageCheckBox = new QCheckBox; distanceImageCheckBox->setText("Distance image"); distanceImageCheckBox->setChecked(distanceImageSelected); QCheckBox* amplitudeImageCheckBox = new QCheckBox; amplitudeImageCheckBox->setText("Amplitude image"); amplitudeImageCheckBox->setChecked(amplitudeImageSelected); amplitudeImageCheckBox->setEnabled(amplitudeImageSelected); if(!amplitudeImageSelected) amplitudeImageCheckBox->setToolTip(QString("This device does not provide amplitude data.")); QCheckBox* intensityImageCheckBox = new QCheckBox; intensityImageCheckBox->setText("Intensity image"); intensityImageCheckBox->setChecked(intensityImageSelected); intensityImageCheckBox->setEnabled(intensityImageSelected); if(!intensityImageSelected) intensityImageCheckBox->setToolTip(QString("This device does not provide intensity data.")); QCheckBox* rgbImageCheckBox = new QCheckBox; rgbImageCheckBox->setText("RGB image"); rgbImageCheckBox->setChecked(rgbImageSelected); rgbImageCheckBox->setEnabled(rgbImageSelected); if(!rgbImageSelected) rgbImageCheckBox->setToolTip(QString("This device does not provide RGB data.")); QCheckBox* rawDataCheckBox = new QCheckBox; rawDataCheckBox->setText("Raw data"); rawDataCheckBox->setChecked(false); rawDataCheckBox->setEnabled(false); checkBoxGroup->addWidget(distanceImageCheckBox); checkBoxGroup->addWidget(amplitudeImageCheckBox); checkBoxGroup->addWidget(intensityImageCheckBox); checkBoxGroup->addWidget(rgbImageCheckBox); checkBoxGroup->addWidget(rawDataCheckBox); QFileDialog* fileDialog = new QFileDialog(parent, caption, dir, filter); QLayout* layout = fileDialog->layout(); QGridLayout* gridbox = qobject_cast(layout); if (gridbox) { gridbox->addWidget(new QLabel("ToF-Image type:")); gridbox->addWidget(combo); int lastRow = gridbox->rowCount(); gridbox->addLayout(checkBoxGroup, lastRow, 0, 1, -1); } fileDialog->setLayout(gridbox); fileDialog->setAcceptMode(QFileDialog::AcceptSave); if (selectedFilter) { fileDialog->selectNameFilter(*selectedFilter); } if (fileDialog->exec() == QDialog::Accepted) { if (selectedFilter) { - *selectedFilter = fileDialog->selectedFilter(); + *selectedFilter = fileDialog->selectedNameFilter(); } if (combo->currentIndex() == 0) { tofImageType = mitk::ToFImageWriter::ToFImageType3D; } else { tofImageType = mitk::ToFImageWriter::ToFImageType2DPlusT; } distanceImageSelected = distanceImageCheckBox->isChecked(); amplitudeImageSelected = amplitudeImageCheckBox->isChecked(); intensityImageSelected = intensityImageCheckBox->isChecked(); rgbImageSelected = rgbImageCheckBox->isChecked(); rawDataSelected = rawDataCheckBox->isChecked(); selectedFileName = fileDialog->selectedFiles().value(0); } delete fileDialog; return selectedFileName; } std::string QmitkToFRecorderWidget::prepareFilename(std::string dir, std::string baseFilename, std::string modulationFreq, std::string integrationTime, std::string numOfFrames, std::string extension, std::string imageType) { std::string filenName(""); filenName.append(dir); filenName.append("/"); filenName.append(baseFilename); filenName.append("_MF"); filenName.append(modulationFreq); filenName.append("_IT"); filenName.append(integrationTime); filenName.append("_"); filenName.append(numOfFrames); filenName.append("Images"); filenName.append(imageType); filenName.append(extension); return filenName; } void QmitkToFRecorderWidget::OnChangeRecordModeComboBox(int index) { if (index == 0) { this->m_RecordMode = mitk::ToFImageRecorder::PerFrames; m_Controls->m_NumOfFramesSpinBox->setEnabled(true); } else { this->m_RecordMode = mitk::ToFImageRecorder::Infinite; m_Controls->m_NumOfFramesSpinBox->setEnabled(false); } } diff --git a/Modules/ToFUI/Qmitk/QmitkToFRecorderWidget.h b/Modules/ToFUI/Qmitk/QmitkToFRecorderWidget.h index a1372a1378..0972499787 100644 --- a/Modules/ToFUI/Qmitk/QmitkToFRecorderWidget.h +++ b/Modules/ToFUI/Qmitk/QmitkToFRecorderWidget.h @@ -1,189 +1,189 @@ /*=================================================================== 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 _QMITKTOFRECORDERWIDGET_H_INCLUDED #define _QMITKTOFRECORDERWIDGET_H_INCLUDED #include #include //QT headers #include #include -#include -#include +#include +#include //itk headers #include "itkCommand.h" //mitk headers #include #include class QmitkStdMultiWidget; struct QFileDialogArgs; class QFileIconProvider; class QFileDialogPrivate; /** * @brief Widget allowing to play / record ToF data * * @ingroup ToFUI */ class MitkToFUI_EXPORT QmitkToFRecorderWidget :public QWidget { //this is needed for all Qt objects that should have a MOC object (everything that derives from QObject) Q_OBJECT public: static const std::string VIEW_ID; QmitkToFRecorderWidget(QWidget* p = 0, Qt::WindowFlags f1 = 0); virtual ~QmitkToFRecorderWidget(); /* @brief This method is part of the widget an needs not to be called seperately. */ virtual void CreateQtPartControl(QWidget *parent); /* @brief This method is part of the widget an needs not to be called seperately. (Creation of the connections of main and control widget.)*/ virtual void CreateConnections(); /*! \brief Set the parameters used for this widget \param ToFImageGrabber image grabber providing images from a ToF device \param tofImageRecorder image recorder allowing to record ToF images */ void SetParameter(mitk::ToFImageGrabber* ToFImageGrabber, mitk::ToFImageRecorder* toFImageRecorder); /*! \brief resets the GUI elements to the initial state. Play button: enabled, Stop button: disabled, Recording box: disabled */ void ResetGUIToInitial(); signals: /*! \brief signal emitted when "Play" button is pressed */ void ToFCameraStarted(); /*! \brief signal emitted when "Stop" button is pressed */ void ToFCameraStopped(); /*! \brief signal emitted when recording is started */ void RecordingStarted(); /*! \brief signal emitted AbortEvent() in ToFImageRecorder is observed */ void RecordingStopped(); public slots: /*! \brief slot invoking to start the camera. Calls StartCamera() and emits ToFCameraStarted signal */ void OnPlay(); /*! \brief slot invoking to stop the camera and the recorder. Calls StopCamera() and StopRecorder and emits ToFCameraStarted signal. Resets GUI to initial state. */ void OnStop(); /*! \brief slot invoking to start the recording After letting the user chose a file location for the record, m_ImageRecorder->StartRecording() is inoved. */ void OnStartRecorder(); /*! \brief slot resetting the GUI elements of the recording box */ void OnRecordingStopped(); /*! \brief slot activating/deactivating "number of frames" spin box dependent on recording mode (PerFrame / Infinite) */ void OnChangeRecordModeComboBox(int index); protected: /*! \brief starts the camera by calling ToFImageGrabber::StartCamera() */ void StartCamera(); /*! \brief stops the camera by calling ToFImageGrabber::StopCamera() */ void StopCamera(); /*! \brief stops the recording by calling ToFImageRecorder::StopRecording() */ void StopRecorder(); /*! \brief emits RecordingStopped signal. */ void StopRecordingCallback(); /*! \brief adapted version of QFileDialog::getSaveFileName() The user is now asked to choose which images he wants to save (Distance and/or Intensity and/or Amplitude image) and which type the saved image should have (3D, 2D+t). */ static QString getSaveFileName(mitk::ToFImageWriter::ToFImageType& tofImageType, bool& distanceImageSelected, bool& amplitudeImageSelected, bool& intensityImageSelected, bool& rgbImageSelected, bool& rawDataSelected, QWidget *parent = 0, const QString &caption = QString(), const QString &dir = QString(), const QString &filter = QString(), QString *selectedFilter = 0, QFileDialog::Options options = 0 ); /*! \brief method creating a filename from the given information \param dir directory to save the file \param baseFilename base file name entered by the user \param modulationFreq modulation frequency of the camera \param integrationTime integration time of the camera \param numOfFrames number of frames recorded \param extension file extension \param imageType type of image (DistanceImage, IntensityImage, AmplitudeImage) \return dir+"/"+baseFilename+"_MF"+modulationFreq+"_IT"+integrationTime+"_"+numOfFrames+"Images"+imageType+extension */ std::string prepareFilename(std::string dir, std::string baseFilename, std::string modulationFreq, std::string integrationTime, std::string numOfFrames, std::string extension, std::string imageType); Ui::QmitkToFRecorderWidgetControls* m_Controls; ///< member holding the UI elements of this widget mitk::ToFImageGrabber::Pointer m_ToFImageGrabber; ///< member holding the ToFImageGrabber for acquiring ToF images mitk::ToFImageRecorder::Pointer m_ToFImageRecorder; ///< member holding the recorder for ToF images mitk::ToFImageRecorder::RecordMode m_RecordMode; ///< member holding the RecordMode of the recorder (PerFrame / Infinite) typedef itk::SimpleMemberCommand CommandType; CommandType::Pointer m_StopRecordingCommand; ///< itkCommand for abort of recording private: }; #endif // _QMITKTOFRECORDERWIDGET_H_INCLUDED diff --git a/Modules/ToFUI/Qmitk/QmitkToFSurfaceGenerationWidget.cpp b/Modules/ToFUI/Qmitk/QmitkToFSurfaceGenerationWidget.cpp index 411703ab1a..611bf9fd82 100644 --- a/Modules/ToFUI/Qmitk/QmitkToFSurfaceGenerationWidget.cpp +++ b/Modules/ToFUI/Qmitk/QmitkToFSurfaceGenerationWidget.cpp @@ -1,294 +1,294 @@ /*=================================================================== 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 "QmitkToFSurfaceGenerationWidget.h" #include #include //QT headers #include #include #include #include const std::string QmitkToFSurfaceGenerationWidget::VIEW_ID = "org.mitk.views.qmitktofsurfacegenerationwidget"; QmitkToFSurfaceGenerationWidget::QmitkToFSurfaceGenerationWidget(QWidget* parent, Qt::WindowFlags f): QWidget(parent, f) , m_Controls(NULL), m_ToFDistanceImageToSurfaceFilter(NULL), m_ToFImageGrabber(NULL), m_CameraIntrinsics(NULL), m_Active(false) { CreateQtPartControl(this); } QmitkToFSurfaceGenerationWidget::~QmitkToFSurfaceGenerationWidget() { } void QmitkToFSurfaceGenerationWidget::CreateQtPartControl(QWidget *parent) { if (!m_Controls) { // create GUI widgets m_Controls = new Ui::QmitkToFSurfaceGenerationWidgetControls; m_Controls->setupUi(parent); this->CreateConnections(); this->OnShowAdvancedOptionsCheckboxChecked(false); } } void QmitkToFSurfaceGenerationWidget::CreateConnections() { if ( m_Controls ) { connect( (QObject*)(m_Controls->m_Compute3DDataCheckbox), SIGNAL(toggled(bool)), this, SLOT(OnCompute3DDataCheckboxChecked(bool)) ); connect( (QObject*)(m_Controls->m_DistanceColorMapCheckbox), SIGNAL(toggled(bool)), this, SLOT(OnDistanceColorMapCheckBoxChecked(bool)) ); connect( (QObject*)(m_Controls->m_RGBTextureCheckbox), SIGNAL(toggled(bool)), this, SLOT(OnRGBTextureCheckBoxChecked(bool)) ); connect( (QObject*)(m_Controls->m_TriangulationThresholdSpinbox), SIGNAL(valueChanged(double)), this, SLOT(OnTriangulationThresholdSpinBoxChanged()) ); connect( (QObject*)(m_Controls->m_ShowAdvancedOptionsCheckbox), SIGNAL(toggled(bool)), this, SLOT(OnShowAdvancedOptionsCheckboxChecked(bool)) ); connect( (QObject*)(m_Controls->m_RepresentationCombobox), SIGNAL(currentIndexChanged(int)),(QObject*) this, SLOT(OnRepresentationChanged(int)) ); connect( (QObject*)(m_Controls->m_ReconstructionCombobox), SIGNAL(currentIndexChanged(int)),(QObject*) this, SLOT(OnReconstructionChanged(int)) ); } } mitk::ToFDistanceImageToSurfaceFilter::Pointer QmitkToFSurfaceGenerationWidget::GetToFDistanceImageToSurfaceFilter() { return m_ToFDistanceImageToSurfaceFilter; } void QmitkToFSurfaceGenerationWidget::OnShowAdvancedOptionsCheckboxChecked(bool checked) { - this->m_Controls->m_TextureGroupBox->setShown(checked); - this->m_Controls->m_TriangulationThresholdSpinbox->setShown(checked); - this->m_Controls->m_ReconstructionCombobox->setShown(checked); - this->m_Controls->m_RepresentationCombobox->setShown(checked); - this->m_Controls->label->setShown(checked); - this->m_Controls->label_2->setShown(checked); - this->m_Controls->label_3->setShown(checked); + this->m_Controls->m_TextureGroupBox->setVisible(checked); + this->m_Controls->m_TriangulationThresholdSpinbox->setVisible(checked); + this->m_Controls->m_ReconstructionCombobox->setVisible(checked); + this->m_Controls->m_RepresentationCombobox->setVisible(checked); + this->m_Controls->label->setVisible(checked); + this->m_Controls->label_2->setVisible(checked); + this->m_Controls->label_3->setVisible(checked); } void QmitkToFSurfaceGenerationWidget::Initialize(mitk::ToFDistanceImageToSurfaceFilter::Pointer filter, mitk::ToFImageGrabber::Pointer grabber, mitk::CameraIntrinsics::Pointer intrinsics, mitk::DataNode::Pointer surface, vtkSmartPointer camera, bool generateSurface, bool showAdvancedOptions) { m_ToFDistanceImageToSurfaceFilter = filter; m_ToFImageGrabber = grabber; m_CameraIntrinsics = intrinsics; m_Active = true; m_Camera3d = camera; bool hasSurface = false; m_ToFImageGrabber->GetCameraDevice()->GetBoolProperty("HasSurface", hasSurface); if(hasSurface) { this->m_Surface = mitk::Surface::New(); } else { this->m_Surface = this->m_ToFDistanceImageToSurfaceFilter->GetOutput(0); } m_SurfaceNode = surface; m_SurfaceNode->SetData(m_Surface); this->FindReconstructionModeProperty(); m_Controls->m_ShowAdvancedOptionsCheckbox->setChecked(showAdvancedOptions); this->OnShowAdvancedOptionsCheckboxChecked(showAdvancedOptions); m_Controls->m_Compute3DDataCheckbox->setChecked(generateSurface); } bool QmitkToFSurfaceGenerationWidget::IsActive() { if(!m_Active) { MITK_ERROR << "QmitkToFSurfaceGenerationWidget is not active - please call QmitkToFSurfaceGenerationWidget::Initialize() first"; } return m_Active; } void QmitkToFSurfaceGenerationWidget::OnTriangulationThresholdSpinBoxChanged() { if(IsActive()) { this->m_ToFDistanceImageToSurfaceFilter->SetTriangulationThreshold( this->m_Controls->m_TriangulationThresholdSpinbox->value() ); this->m_ToFImageGrabber->GetCameraDevice()->SetFloatProperty("TriangulationThreshold", this->m_Controls->m_TriangulationThresholdSpinbox->value()); } } void QmitkToFSurfaceGenerationWidget::OnReconstructionChanged(int index) { if(IsActive()) { mitk::ToFDistanceImageToSurfaceFilter::ReconstructionModeType type = mitk::ToFDistanceImageToSurfaceFilter::WithInterPixelDistance; switch (index) { case 0: { type = mitk::ToFDistanceImageToSurfaceFilter::WithInterPixelDistance; break; } case 1: { type = mitk::ToFDistanceImageToSurfaceFilter::WithOutInterPixelDistance; break; } case 2: { type = mitk::ToFDistanceImageToSurfaceFilter::Kinect; break; } default: { MITK_ERROR << "ReconstructionModeType does not exist or is not known in QmitkToFSurfaceGenerationWidget."; break; } } this->m_ToFDistanceImageToSurfaceFilter->SetReconstructionMode( type ); } } void QmitkToFSurfaceGenerationWidget::OnRepresentationChanged(int index) { if(IsActive()) { bool generateTriangularMesh = false; //PointCloud case if( index == 0) //Surface case { generateTriangularMesh = true; } this->m_ToFDistanceImageToSurfaceFilter->SetGenerateTriangularMesh(generateTriangularMesh); this->m_ToFImageGrabber->GetCameraDevice()->SetBoolProperty("GenerateTriangularMesh", generateTriangularMesh); this->m_ToFDistanceImageToSurfaceFilter->SetTriangulationThreshold( this->m_Controls->m_TriangulationThresholdSpinbox->value() ); this->m_ToFImageGrabber->GetCameraDevice()->SetFloatProperty("TriangulationThreshold", this->m_Controls->m_TriangulationThresholdSpinbox->value()); this->m_Controls->m_TriangulationThresholdSpinbox->setEnabled(generateTriangularMesh); } } void QmitkToFSurfaceGenerationWidget::OnRGBTextureCheckBoxChecked(bool checked) { if(IsActive()) { if(m_ToFImageGrabber->GetBoolProperty("HasRGBImage")) { if (checked) { // enable texture this->m_SurfaceNode->SetProperty("Surface.Texture",mitk::SmartPointerProperty::New(this->m_ToFImageGrabber->GetOutput(3))); } else { // disable texture this->m_SurfaceNode->GetPropertyList()->DeleteProperty("Surface.Texture"); } } } } void QmitkToFSurfaceGenerationWidget::OnDistanceColorMapCheckBoxChecked(bool checked) { if(m_SurfaceNode.IsNotNull()) { this->m_SurfaceNode->SetBoolProperty("scalar visibility", checked); } } bool QmitkToFSurfaceGenerationWidget::UpdateSurface() { if(IsActive()) { //##### Code for surface ##### if (m_Controls->m_Compute3DDataCheckbox->isChecked()) { bool hasSurface = false; this->m_ToFImageGrabber->GetCameraDevice()->GetBoolProperty("HasSurface", hasSurface); if(hasSurface) { mitk::SmartPointerProperty::Pointer surfaceProp = dynamic_cast< mitk::SmartPointerProperty * >(this->m_ToFImageGrabber->GetCameraDevice()->GetProperty("ToFSurface")); this->m_Surface->SetVtkPolyData( dynamic_cast< mitk::Surface* >( surfaceProp->GetSmartPointer().GetPointer() )->GetVtkPolyData() ); } else { this->m_Surface = m_ToFDistanceImageToSurfaceFilter->GetOutput(0); } //update pipeline this->m_Surface->Update(); return true; } //##### End code for surface ##### } return false; } void QmitkToFSurfaceGenerationWidget::OnCompute3DDataCheckboxChecked(bool checked) { if(checked) { //initialize the surface once MITK_DEBUG << "OnSurfaceCheckboxChecked true"; this->m_SurfaceNode->SetData(this->m_Surface); this->OnRepresentationChanged(m_Controls->m_RepresentationCombobox->currentIndex()); //we need to initialize (reinit) the surface, to make it fit into the renderwindow mitk::RenderingManager::GetInstance()->InitializeViews( this->m_Surface->GetTimeGeometry(), mitk::RenderingManager::REQUEST_UPDATE_3DWINDOWS, true); // correctly place the vtk camera for appropriate surface rendering //1m distance to camera should be a nice default value for most cameras m_Camera3d->SetPosition(0,0,0); m_Camera3d->SetViewUp(0,-1,0); m_Camera3d->SetFocalPoint(0,0,1); if (this->m_CameraIntrinsics.IsNotNull()) { // compute view angle from camera intrinsics m_Camera3d->SetViewAngle(mitk::ToFProcessingCommon::CalculateViewAngle(m_CameraIntrinsics,m_ToFImageGrabber->GetCaptureWidth())); } else { m_Camera3d->SetViewAngle(45); } m_Camera3d->SetClippingRange(1, 10000); } } void QmitkToFSurfaceGenerationWidget::FindReconstructionModeProperty() { bool KinectReconstructionMode = false; m_ToFImageGrabber->GetCameraDevice()->GetBoolProperty("KinectReconstructionMode",KinectReconstructionMode); if(KinectReconstructionMode) { //set the reconstruction mode for kinect this->m_ToFDistanceImageToSurfaceFilter->SetReconstructionMode(mitk::ToFDistanceImageToSurfaceFilter::Kinect); m_Controls->m_ReconstructionCombobox->setDisabled(true); m_Controls->m_ReconstructionCombobox->setCurrentIndex(2); } else { m_Controls->m_ReconstructionCombobox->setEnabled(true); } } mitk::Surface::Pointer QmitkToFSurfaceGenerationWidget::GetSurface() { return m_Surface; } diff --git a/Modules/ToFUI/Qmitk/QmitkToFVisualisationSettingsWidget.cpp b/Modules/ToFUI/Qmitk/QmitkToFVisualisationSettingsWidget.cpp index f98ed5e916..cca32ec016 100644 --- a/Modules/ToFUI/Qmitk/QmitkToFVisualisationSettingsWidget.cpp +++ b/Modules/ToFUI/Qmitk/QmitkToFVisualisationSettingsWidget.cpp @@ -1,423 +1,419 @@ /*=================================================================== 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 "QmitkToFVisualisationSettingsWidget.h" #include #include #include //QT headers -#include #include #include #include const std::string QmitkToFVisualisationSettingsWidget::VIEW_ID = "org.mitk.views.qmitktofvisualisationsettingswidget"; QmitkToFVisualisationSettingsWidget::QmitkToFVisualisationSettingsWidget(QWidget* parent, Qt::WindowFlags f): QWidget(parent, f) , m_Controls(NULL) , m_RangeSliderMin(0) , m_RangeSliderMax(0) , m_MitkDistanceImageNode(NULL) , m_MitkAmplitudeImageNode(NULL) , m_MitkIntensityImageNode(NULL) , m_Widget1ColorTransferFunction(NULL) , m_Widget2ColorTransferFunction(NULL) , m_Widget3ColorTransferFunction(NULL) , m_Widget1TransferFunctionType(1) , m_Widget2TransferFunctionType(0) , m_Widget3TransferFunctionType(0) { CreateQtPartControl(this); } QmitkToFVisualisationSettingsWidget::~QmitkToFVisualisationSettingsWidget() { } void QmitkToFVisualisationSettingsWidget::CreateQtPartControl(QWidget *parent) { if (!m_Controls) { // create GUI widgets m_Controls = new Ui::QmitkToFVisualisationSettingsWidgetControls; m_Controls->setupUi(parent); this->CreateConnections(); } } void QmitkToFVisualisationSettingsWidget::CreateConnections() { if ( m_Controls ) { connect( (QObject*)(m_Controls->m_SelectWidgetCombobox), SIGNAL(currentIndexChanged(int)),(QObject*) this, SLOT(OnWidgetSelected(int)) ); connect( (QObject*)(m_Controls->m_SelectTransferFunctionTypeCombobox), SIGNAL(currentIndexChanged(int)),(QObject*) this, SLOT(OnTransferFunctionTypeSelected(int)) ); connect( (QObject*)(m_Controls->m_TransferFunctionResetButton), SIGNAL(clicked()),(QObject*) this, SLOT(OnTransferFunctionReset()) ); connect(m_Controls->m_XEditColor, SIGNAL(returnPressed()), this, SLOT(OnSetXValueColor())); connect(m_Controls->m_RangeSliderMaxEdit, SIGNAL(returnPressed()), this, SLOT(OnRangeSliderMaxChanged())); connect(m_Controls->m_RangeSliderMinEdit, SIGNAL(returnPressed()), this, SLOT(OnRangeSliderMinChanged())); connect(m_Controls->m_RangeSliderReset, SIGNAL(pressed()), this, SLOT(OnResetSlider())); connect(m_Controls->m_RangeSlider, SIGNAL(spanChanged(int, int) ),this, SLOT( OnSpanChanged(int , int ) )); connect(m_Controls->m_AdvancedOptionsCheckbox, SIGNAL(toggled(bool) ),this, SLOT( OnShowAdvancedOptionsCheckboxChecked(bool) )); - QPlastiqueStyle *sliderStyle = new QPlastiqueStyle(); m_Controls->m_RangeSlider->setMaximum(2048); m_Controls->m_RangeSlider->setMinimum(-2048); - m_Controls->m_RangeSlider->setHandleMovementMode(QxtSpanSlider::NoOverlapping); - m_Controls->m_RangeSlider->setStyle(sliderStyle); m_Controls->m_ColorTransferFunctionCanvas->SetQLineEdits(m_Controls->m_XEditColor, 0); m_Controls->m_ColorTransferFunctionCanvas->SetTitle(""/*"Value -> Grayscale/Color"*/); this->OnShowAdvancedOptionsCheckboxChecked(false); } } void QmitkToFVisualisationSettingsWidget::OnSetXValueColor() { m_Controls->m_ColorTransferFunctionCanvas->SetX(m_Controls->m_XEditColor->text().toFloat()); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } void QmitkToFVisualisationSettingsWidget::OnRangeSliderMaxChanged() { m_Controls->m_RangeSlider->setMaximum(m_Controls->m_RangeSliderMaxEdit->text().toInt()); UpdateRanges(); m_Controls->m_ColorTransferFunctionCanvas->update(); } void QmitkToFVisualisationSettingsWidget::OnRangeSliderMinChanged() { m_Controls->m_RangeSlider->setMinimum(m_Controls->m_RangeSliderMinEdit->text().toInt()); UpdateRanges(); m_Controls->m_ColorTransferFunctionCanvas->update(); } void QmitkToFVisualisationSettingsWidget::OnSpanChanged(int /*lower*/, int /*upper*/) { UpdateRanges(); m_Controls->m_ColorTransferFunctionCanvas->update(); } void QmitkToFVisualisationSettingsWidget::OnResetSlider() { - m_Controls->m_RangeSlider->setUpperValue(m_RangeSliderMax); - m_Controls->m_RangeSlider->setLowerValue(m_RangeSliderMin); + m_Controls->m_RangeSlider->setMaximumValue(m_RangeSliderMax); + m_Controls->m_RangeSlider->setMinimumValue(m_RangeSliderMin); UpdateRanges(); m_Controls->m_ColorTransferFunctionCanvas->update(); } void QmitkToFVisualisationSettingsWidget::UpdateRanges() { - int lower = m_Controls->m_RangeSlider->lowerValue(); - int upper = m_Controls->m_RangeSlider->upperValue(); + int lower = m_Controls->m_RangeSlider->minimumValue(); + int upper = m_Controls->m_RangeSlider->maximumValue(); m_Controls->m_ColorTransferFunctionCanvas->SetMin(lower); m_Controls->m_ColorTransferFunctionCanvas->SetMax(upper); } void QmitkToFVisualisationSettingsWidget::UpdateSurfaceProperty() { if(this->m_MitkSurfaceNode.IsNotNull()) { mitk::TransferFunction::Pointer transferFunction = mitk::TransferFunction::New(); transferFunction->SetColorTransferFunction(this->GetSelectedColorTransferFunction()); this->m_MitkSurfaceNode->SetProperty("Surface.TransferFunction", mitk::TransferFunctionProperty::New(transferFunction)); } } void QmitkToFVisualisationSettingsWidget::Initialize(mitk::DataNode* distanceImageNode, mitk::DataNode* amplitudeImageNode, mitk::DataNode* intensityImageNode, mitk::DataNode* surfaceNode) { this->m_MitkDistanceImageNode = distanceImageNode; this->m_MitkAmplitudeImageNode = amplitudeImageNode; this->m_MitkIntensityImageNode = intensityImageNode; this->m_MitkSurfaceNode = surfaceNode; // Initialize transfer functions for image DataNodes such that: // Widget1 (Distance): color from red (2nd min) to blue (max) // Widget2 (Amplitude): grey value from black (2nd min) to white (max) // Widget3 (Intensity): grey value from black (2nd min) to white (max) if (!m_MitkDistanceImageNode && !m_MitkAmplitudeImageNode && !m_MitkIntensityImageNode) { m_Controls->m_ColorTransferFunctionCanvas->setEnabled(false); } else { m_Controls->m_ColorTransferFunctionCanvas->setEnabled(true); int numberOfImages = 0; if (m_MitkDistanceImageNode) { m_Widget1ColorTransferFunction = vtkColorTransferFunction::New(); this->m_Widget1TransferFunctionType = 1; m_Controls->m_SelectTransferFunctionTypeCombobox->setCurrentIndex(this->m_Widget1TransferFunctionType); numberOfImages++; } if (m_MitkAmplitudeImageNode) { m_Widget2ColorTransferFunction = vtkColorTransferFunction::New(); this->m_Widget2TransferFunctionType = 0; numberOfImages++; } if (m_MitkIntensityImageNode) { m_Widget3ColorTransferFunction = vtkColorTransferFunction::New(); this->m_Widget3TransferFunctionType = 0; numberOfImages++; } m_Controls->m_SelectWidgetCombobox->setMaxCount(numberOfImages); } this->ReinitTransferFunction(0,1); this->ReinitTransferFunction(1,0); this->ReinitTransferFunction(2,0); } void QmitkToFVisualisationSettingsWidget::UpdateCanvas() { m_Controls->m_ColorTransferFunctionCanvas->SetColorTransferFunction( this->GetSelectedColorTransferFunction() ); UpdateRanges(); m_Controls->m_ColorTransferFunctionCanvas->update(); } void QmitkToFVisualisationSettingsWidget::OnTransferFunctionTypeSelected(int index) { int currentWidgetIndex = m_Controls->m_SelectWidgetCombobox->currentIndex(); if (currentWidgetIndex == 0) { this->m_Widget1TransferFunctionType = index; } else if (currentWidgetIndex == 1) { this->m_Widget2TransferFunctionType = index; } else if (currentWidgetIndex == 2) { this->m_Widget3TransferFunctionType = index; } else { return; } this->UpdateSurfaceProperty(); } void QmitkToFVisualisationSettingsWidget::OnShowAdvancedOptionsCheckboxChecked(bool checked) { - this->m_Controls->m_MappingGroupBox->setShown(checked); - this->m_Controls->m_SelectTransferFunctionTypeCombobox->setShown(checked); - this->m_Controls->m_SelectWidgetCombobox->setShown(checked); - this->m_Controls->m_TransferFunctionResetButton->setShown(checked); + this->m_Controls->m_MappingGroupBox->setVisible(checked); + this->m_Controls->m_SelectTransferFunctionTypeCombobox->setVisible(checked); + this->m_Controls->m_SelectWidgetCombobox->setVisible(checked); + this->m_Controls->m_TransferFunctionResetButton->setVisible(checked); } void QmitkToFVisualisationSettingsWidget::OnWidgetSelected(int index) { int currentWidgetIndex = index; double valMin[6]; double valMax[6]; int numPoints; if (currentWidgetIndex == 0) { m_Controls->m_SelectTransferFunctionTypeCombobox->setCurrentIndex(this->m_Widget1TransferFunctionType); numPoints = this->m_Widget1ColorTransferFunction->GetSize(); this->m_Widget1ColorTransferFunction->GetNodeValue( 0, valMin ); this->m_Widget1ColorTransferFunction->GetNodeValue( numPoints-1, valMax ); m_Controls->m_ColorTransferFunctionCanvas->SetColorTransferFunction( this->m_Widget1ColorTransferFunction ); } else if (currentWidgetIndex == 1) { m_Controls->m_SelectTransferFunctionTypeCombobox->setCurrentIndex(this->m_Widget2TransferFunctionType); numPoints = this->m_Widget2ColorTransferFunction->GetSize(); this->m_Widget2ColorTransferFunction->GetNodeValue( 0, valMin ); this->m_Widget2ColorTransferFunction->GetNodeValue( numPoints-1, valMax ); m_Controls->m_ColorTransferFunctionCanvas->SetColorTransferFunction( this->m_Widget2ColorTransferFunction ); } else if (currentWidgetIndex == 2) { m_Controls->m_SelectTransferFunctionTypeCombobox->setCurrentIndex(this->m_Widget3TransferFunctionType); numPoints = this->m_Widget3ColorTransferFunction->GetSize(); this->m_Widget3ColorTransferFunction->GetNodeValue( 0, valMin ); this->m_Widget3ColorTransferFunction->GetNodeValue( numPoints-1, valMax ); m_Controls->m_ColorTransferFunctionCanvas->SetColorTransferFunction( this->m_Widget3ColorTransferFunction ); } else if (currentWidgetIndex == 3) { } else { return; } m_RangeSliderMin = valMin[0]; m_RangeSliderMax = valMax[0]; int border = (m_RangeSliderMax - m_RangeSliderMin) * 0.1; m_Controls->m_RangeSlider->setMinimum(m_RangeSliderMin - border); m_Controls->m_RangeSlider->setMaximum(m_RangeSliderMax + border); m_Controls->m_RangeSliderMinEdit->setText(QString("").setNum(m_RangeSliderMin - border)); m_Controls->m_RangeSliderMaxEdit->setText(QString("").setNum(m_RangeSliderMax + border)); - m_Controls->m_RangeSlider->setSpan( m_RangeSliderMin, m_RangeSliderMax); + m_Controls->m_RangeSlider->setRange( m_RangeSliderMin, m_RangeSliderMax); UpdateRanges(); m_Controls->m_ColorTransferFunctionCanvas->update(); this->UpdateSurfaceProperty(); } void QmitkToFVisualisationSettingsWidget::ResetTransferFunction(vtkColorTransferFunction* colorTransferFunction, int type, double min, double max) { colorTransferFunction->RemoveAllPoints(); if (type == 0) { colorTransferFunction->AddRGBPoint(min, 0, 0, 0); colorTransferFunction->AddRGBPoint(max, 1, 1, 1); } else { if (min>0.01) { colorTransferFunction->AddRGBPoint(0.0, 0, 0, 0); colorTransferFunction->AddRGBPoint(min-0.01, 0, 0, 0); } colorTransferFunction->AddRGBPoint(min, 1, 0, 0); colorTransferFunction->AddRGBPoint(min+(max-min)/2, 1, 1, 0); colorTransferFunction->AddRGBPoint(max, 0, 0, 1); } colorTransferFunction->SetColorSpaceToHSV(); } void QmitkToFVisualisationSettingsWidget::ReinitTransferFunction(int widget, int type) { switch (widget) { case 0: { mitk::Image::Pointer distanceImage = dynamic_cast(m_MitkDistanceImageNode->GetData()); // use second minimum to draw 0 values (that are usually segmented) black m_RangeSliderMin = distanceImage->GetStatistics()->GetScalarValue2ndMin(); m_RangeSliderMax = distanceImage->GetStatistics()->GetScalarValueMax(); MITK_INFO<<"Distance Min: "<m_Widget1ColorTransferFunction, type, this->m_RangeSliderMin, this->m_RangeSliderMax); m_Controls->m_ColorTransferFunctionCanvas->SetColorTransferFunction( this->m_Widget1ColorTransferFunction ); mitk::TransferFunction::Pointer tf1 = mitk::TransferFunction::New(); tf1->SetColorTransferFunction( m_Widget1ColorTransferFunction ); m_MitkDistanceImageNode->SetProperty("Image Rendering.Transfer Function",mitk::TransferFunctionProperty::New(tf1)); break; } case 1: { if (m_MitkAmplitudeImageNode) { mitk::Image::Pointer amplitudeImage = dynamic_cast(m_MitkAmplitudeImageNode->GetData()); if (amplitudeImage.IsNotNull()) { m_RangeSliderMin = amplitudeImage->GetStatistics()->GetScalarValueMin(); m_RangeSliderMax = amplitudeImage->GetStatistics()->GetScalarValueMax(); MITK_INFO<<"Amplitude Min: "<m_Widget2ColorTransferFunction, type, this->m_RangeSliderMin, this->m_RangeSliderMax); m_Controls->m_ColorTransferFunctionCanvas->SetColorTransferFunction( this->m_Widget2ColorTransferFunction ); mitk::TransferFunction::Pointer tf2 = mitk::TransferFunction::New(); tf2->SetColorTransferFunction( m_Widget2ColorTransferFunction ); m_MitkAmplitudeImageNode->SetProperty("Image Rendering.Transfer Function",mitk::TransferFunctionProperty::New(tf2)); } } break; } case 2: { if (m_MitkIntensityImageNode) { mitk::Image::Pointer intensityImage = dynamic_cast(m_MitkIntensityImageNode->GetData()); if (intensityImage.IsNotNull()) { m_RangeSliderMin = intensityImage->GetStatistics()->GetScalarValueMin(); m_RangeSliderMax = intensityImage->GetStatistics()->GetScalarValueMax(); MITK_INFO<<"Intensity Min: "<m_Widget3ColorTransferFunction, type, this->m_RangeSliderMin, this->m_RangeSliderMax); m_Controls->m_ColorTransferFunctionCanvas->SetColorTransferFunction( this->m_Widget3ColorTransferFunction ); mitk::TransferFunction::Pointer tf3 = mitk::TransferFunction::New(); tf3->SetColorTransferFunction( m_Widget3ColorTransferFunction ); m_MitkIntensityImageNode->SetProperty("Image Rendering.Transfer Function",mitk::TransferFunctionProperty::New(tf3)); } } break; } default: break; } this->UpdateSurfaceProperty(); } void QmitkToFVisualisationSettingsWidget::OnTransferFunctionReset() { int currentTransferFunctionTypeIndex = m_Controls->m_SelectTransferFunctionTypeCombobox->currentIndex(); int currentWidgetIndex = m_Controls->m_SelectWidgetCombobox->currentIndex(); this->ReinitTransferFunction(currentWidgetIndex,currentTransferFunctionTypeIndex); int border = (m_RangeSliderMax - m_RangeSliderMin) * 0.1; m_Controls->m_RangeSlider->setMinimum(m_RangeSliderMin - border); m_Controls->m_RangeSlider->setMaximum(m_RangeSliderMax + border); m_Controls->m_RangeSliderMinEdit->setText(QString("").setNum(m_RangeSliderMin - border)); m_Controls->m_RangeSliderMaxEdit->setText(QString("").setNum(m_RangeSliderMax + border)); - m_Controls->m_RangeSlider->setSpan( m_RangeSliderMin, m_RangeSliderMax); + m_Controls->m_RangeSlider->setRange( m_RangeSliderMin, m_RangeSliderMax); UpdateRanges(); m_Controls->m_ColorTransferFunctionCanvas->update(); this->UpdateSurfaceProperty(); } vtkColorTransferFunction* QmitkToFVisualisationSettingsWidget::GetWidget1ColorTransferFunction() { return this->m_Widget1ColorTransferFunction; } vtkColorTransferFunction* QmitkToFVisualisationSettingsWidget::GetWidget2ColorTransferFunction() { return this->m_Widget2ColorTransferFunction; } vtkColorTransferFunction* QmitkToFVisualisationSettingsWidget::GetWidget3ColorTransferFunction() { return this->m_Widget3ColorTransferFunction; } vtkColorTransferFunction* QmitkToFVisualisationSettingsWidget::GetSelectedColorTransferFunction() { int currentWidgetIndex = m_Controls->m_SelectWidgetCombobox->currentIndex(); if (currentWidgetIndex==0) { return this->m_Widget1ColorTransferFunction; } else if (currentWidgetIndex==1) { return this->m_Widget2ColorTransferFunction; } else if (currentWidgetIndex==2) { return this->m_Widget3ColorTransferFunction; } else { return this->m_Widget3ColorTransferFunction; } } int QmitkToFVisualisationSettingsWidget::GetSelectedImageIndex() { return this->m_Controls->m_SelectWidgetCombobox->currentIndex(); } diff --git a/Modules/ToFUI/Qmitk/QmitkToFVisualisationSettingsWidgetControls.ui b/Modules/ToFUI/Qmitk/QmitkToFVisualisationSettingsWidgetControls.ui index 9d8aebea7f..dc1e7ca403 100644 --- a/Modules/ToFUI/Qmitk/QmitkToFVisualisationSettingsWidgetControls.ui +++ b/Modules/ToFUI/Qmitk/QmitkToFVisualisationSettingsWidgetControls.ui @@ -1,445 +1,445 @@ QmitkToFVisualisationSettingsWidgetControls 0 0 482 230 0 0 QmitkToFVisualisationSettings 11 ToF Visualization Show advanced options 0 0 200 50 10 0 3 QComboBox::InsertAtBottom QComboBox::AdjustToContents 30 30 true Distance :/images/widget1.png:/images/widget1.png Amplitude :/images/widget2.png:/images/widget2.png Intensity :/images/widget3.png:/images/widget3.png true 0 0 150 50 16777215 50 10 0 3 QComboBox::InsertAtBottom QComboBox::AdjustToContents 100 35 true :/images/grayscale.png:/images/grayscale.png :/images/color.png:/images/color.png 100 50 16777215 50 10 Fit scale Gray value/color mapping QFrame::StyledPanel QFrame::Raised 0 - + modify actual seen window by dragging left and right slider. Qt::Horizontal 0 0 48 16777215 Resets range to histogram minimum and maximum. Reset 1 1 0 28 Left-click to select a point or add a new point. Hold left mouse button to move selected point. Click right mouse button to delete a point. Double-click left mouse button to change color of a point. true 0 0 48 0 48 16777215 7 Edit x-coordinate (grayvalue) of currently selected point. Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter Qt::Horizontal 86 20 0 0 48 0 48 16777215 7 Edit x-coordinate (grayvalue) of currently selected point. Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter Qt::Horizontal 85 20 0 0 48 0 48 16777215 7 Edit x-coordinate (grayvalue) of currently selected point. Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - QxtSpanSlider - QSlider -
qxtspanslider.h
+ ctkRangeSlider + QWidget +
ctkRangeSlider.h
QmitkColorTransferFunctionCanvas QWidget
QmitkColorTransferFunctionCanvas.h
diff --git a/Plugins/PluginList.cmake b/Plugins/PluginList.cmake index 1a6e6ada9d..3bf25ed2aa 100644 --- a/Plugins/PluginList.cmake +++ b/Plugins/PluginList.cmake @@ -1,58 +1,49 @@ # Plug-ins must be ordered according to their dependencies -if (MITK_USE_Qt4) set(MITK_EXT_PLUGINS org.mitk.core.services:ON org.mitk.gui.common:ON org.mitk.planarfigure:ON org.mitk.core.ext:OFF org.mitk.core.jobs:OFF org.mitk.diffusionimaging:OFF org.mitk.simulation:OFF org.mitk.gui.qt.application:ON org.mitk.gui.qt.coreapplication:OFF org.mitk.gui.qt.ext:OFF org.mitk.gui.qt.extapplication:OFF org.mitk.gui.qt.common:ON org.mitk.gui.qt.stdmultiwidgeteditor:ON org.mitk.gui.qt.common.legacy:OFF org.mitk.gui.qt.cmdlinemodules:OFF org.mitk.gui.qt.diffusionimagingapp:OFF org.mitk.gui.qt.datamanager:ON org.mitk.gui.qt.datamanagerlight:OFF org.mitk.gui.qt.properties:ON org.mitk.gui.qt.basicimageprocessing:OFF org.mitk.gui.qt.dicom:OFF org.mitk.gui.qt.diffusionimaging:OFF org.mitk.gui.qt.dtiatlasapp:OFF org.mitk.gui.qt.igtexamples:OFF org.mitk.gui.qt.igttracking:OFF org.mitk.gui.qt.imagecropper:OFF org.mitk.gui.qt.imagenavigator:ON org.mitk.gui.qt.viewnavigator:OFF org.mitk.gui.qt.materialeditor:OFF org.mitk.gui.qt.measurementtoolbox:OFF org.mitk.gui.qt.moviemaker:OFF org.mitk.gui.qt.pointsetinteraction:OFF org.mitk.gui.qt.python:OFF org.mitk.gui.qt.registration:OFF org.mitk.gui.qt.remeshing:OFF org.mitk.gui.qt.segmentation:OFF org.mitk.gui.qt.simulation:OFF org.mitk.gui.qt.toftutorial:OFF org.mitk.gui.qt.tofutil:OFF org.mitk.gui.qt.ugvisualization:OFF org.mitk.gui.qt.ultrasound:OFF org.mitk.gui.qt.volumevisualization:OFF org.mitk.gui.qt.eventrecorder:OFF org.mitk.gui.qt.xnat:OFF ) - -else() - -set(MITK_EXT_PLUGINS - # empty so far -) - -endif() diff --git a/Plugins/org.mitk.core.ext/src/internal/mitkCoreExtActivator.cpp b/Plugins/org.mitk.core.ext/src/internal/mitkCoreExtActivator.cpp index 5ce1bbef45..74dd244710 100755 --- a/Plugins/org.mitk.core.ext/src/internal/mitkCoreExtActivator.cpp +++ b/Plugins/org.mitk.core.ext/src/internal/mitkCoreExtActivator.cpp @@ -1,70 +1,72 @@ /*=================================================================== 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 "mitkCoreExtActivator.h" #include "mitkCoreExtConstants.h" #include "mitkInputDeviceRegistry.h" #include #include #include namespace mitk { void CoreExtActivator::start(ctkPluginContext* context) { Q_UNUSED(context) this->StartInputDeviceModules(); } void CoreExtActivator::stop(ctkPluginContext* context) { Q_UNUSED(context) } void mitk::CoreExtActivator::StartInputDeviceModules() { IInputDeviceRegistry::Pointer inputDeviceRegistry(new mitk::InputDeviceRegistry()); berry::Platform::GetServiceRegistry().RegisterService( mitk::CoreExtConstants::INPUTDEVICE_SERVICE, inputDeviceRegistry); // Gets the last setting of the preferences; if a device was selected, // it will still be activated after a restart berry::IPreferencesService::Pointer prefService = berry::Platform::GetServiceRegistry() .GetServiceById(berry::IPreferencesService::ID); berry::IPreferences::Pointer extPreferencesNode = prefService->GetSystemPreferences()->Node(CoreExtConstants::INPUTDEVICE_PREFERENCES); // Initializes the modules std::vector descriptors(inputDeviceRegistry->GetInputDevices()); for (std::vector::const_iterator it = descriptors.begin(); it != descriptors.end(); ++it) { if (extPreferencesNode->GetBool((*it)->GetID(), false)) { IInputDevice::Pointer temp = (*it)->CreateInputDevice(); temp->RegisterInputDevice(); } } } // end method StartInputDeviceModules } // end namespace mitk -Q_EXPORT_PLUGIN2(org_mitk_core_ext, mitk::CoreExtActivator) +#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) + Q_EXPORT_PLUGIN2(org_mitk_core_ext, mitk::CoreExtActivator) +#endif diff --git a/Plugins/org.mitk.core.ext/src/internal/mitkCoreExtActivator.h b/Plugins/org.mitk.core.ext/src/internal/mitkCoreExtActivator.h index 9c9742f32a..bbbf9881a1 100755 --- a/Plugins/org.mitk.core.ext/src/internal/mitkCoreExtActivator.h +++ b/Plugins/org.mitk.core.ext/src/internal/mitkCoreExtActivator.h @@ -1,63 +1,66 @@ /*=================================================================== 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 MITKCOREEXTACTIVATOR_H_ #define MITKCOREEXTACTIVATOR_H_ #include #include #include namespace mitk { /** * @brief The activator class for the org.mitk.core.ext plug-in. * @ingroup org_mitk_core_ext_internal * * When the plug-in is started by the framework, it calls a global function to initialize * the mitkCoreExt module. * */ class MITK_LOCAL CoreExtActivator : public QObject, public ctkPluginActivator { Q_OBJECT +#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) + Q_PLUGIN_METADATA(IID "org_mitk_core_ext") +#endif Q_INTERFACES(ctkPluginActivator) public: /** * Starts this plug-in and registers object factories. * * @param context * The context for the plug-in. */ void start(ctkPluginContext* context); void stop(ctkPluginContext* context); private: /** * Activates the input device modules. */ void StartInputDeviceModules(); }; // end class CoreExtActivator } //end namespace mitk #endif /* MITKCOREEXTACTIVATOR_H_ */ diff --git a/Plugins/org.mitk.core.jobs/src/internal/mitkPluginActivator.cpp b/Plugins/org.mitk.core.jobs/src/internal/mitkPluginActivator.cpp index 0d608ccb5e..785033cfa0 100644 --- a/Plugins/org.mitk.core.jobs/src/internal/mitkPluginActivator.cpp +++ b/Plugins/org.mitk.core.jobs/src/internal/mitkPluginActivator.cpp @@ -1,34 +1,36 @@ /*=================================================================== 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 "mitkPluginActivator.h" #include namespace mitk { void PluginActivator::start(ctkPluginContext* context) { Q_UNUSED(context) } void PluginActivator::stop(ctkPluginContext* context) { Q_UNUSED(context) } } -Q_EXPORT_PLUGIN2(org_mitk_core_jobs, mitk::PluginActivator) +#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) + Q_EXPORT_PLUGIN2(org_mitk_core_jobs, mitk::PluginActivator) +#endif diff --git a/Plugins/org.mitk.core.jobs/src/internal/mitkPluginActivator.h b/Plugins/org.mitk.core.jobs/src/internal/mitkPluginActivator.h index 12053e09e3..bdba95af92 100644 --- a/Plugins/org.mitk.core.jobs/src/internal/mitkPluginActivator.h +++ b/Plugins/org.mitk.core.jobs/src/internal/mitkPluginActivator.h @@ -1,39 +1,42 @@ /*=================================================================== 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 MITKPLUGINACTIVATOR_H #define MITKPLUGINACTIVATOR_H #include #include namespace mitk { class MITK_LOCAL PluginActivator : public QObject, public ctkPluginActivator { Q_OBJECT +#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) + Q_PLUGIN_METADATA(IID "org_mitk_core_jobs") +#endif Q_INTERFACES(ctkPluginActivator) public: void start(ctkPluginContext* context); void stop(ctkPluginContext* context); }; // PluginActivator } #endif // MITKPLUGINACTIVATOR_H diff --git a/Plugins/org.mitk.core.services/src/internal/mitkPluginActivator.cpp b/Plugins/org.mitk.core.services/src/internal/mitkPluginActivator.cpp index a992be822f..84ac6db2e1 100644 --- a/Plugins/org.mitk.core.services/src/internal/mitkPluginActivator.cpp +++ b/Plugins/org.mitk.core.services/src/internal/mitkPluginActivator.cpp @@ -1,284 +1,286 @@ /*=================================================================== 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 "mitkPluginActivator.h" #include "mitkLog.h" #include #include #include "internal/mitkDataStorageService.h" #include #include #include #include #include namespace mitk { class InterfaceMapToQObjectAdapter : public QObject { public: InterfaceMapToQObjectAdapter(const us::InterfaceMap& im) : interfaceMap(im) {} // This method is called by the Qt meta object system. It is usually // generated by the moc, but we create it manually to be able to return // a MITK micro service object (derived from itk::LightObject). It basically // works as if the micro service class had used the Q_INTERFACES macro in // its declaration. Now we can successfully do a // qobject_cast(lightObjectToQObjectAdapter) void* qt_metacast(const char *_clname) { if (!_clname) return 0; if (!strcmp(_clname, "InterfaceMapToQObjectAdapter")) return static_cast(const_cast(this)); us::InterfaceMap::const_iterator iter = interfaceMap.find(_clname); if (iter != interfaceMap.end()) return iter->second; return QObject::qt_metacast(_clname); } private: us::InterfaceMap interfaceMap; }; const std::string org_mitk_core_services_Activator::PLUGIN_ID = "org.mitk.core.services"; void org_mitk_core_services_Activator::start(ctkPluginContext* context) { pluginContext = context; //initialize logging mitk::LoggingBackend::Register(); QString logFilenamePrefix = "mitk"; QFileInfo path = context->getDataFile(logFilenamePrefix); try { mitk::LoggingBackend::RotateLogFiles(path.absoluteFilePath().toStdString()); } catch(mitk::Exception& e) { MITK_ERROR << "Problem during logfile initialization: " << e.GetDescription() << " Caution: Logging to harddisc might be disabled!"; } mitk::VtkLoggingAdapter::Initialize(); mitk::ItkLoggingAdapter::Initialize(); //initialize data storage service DataStorageService* service = new DataStorageService(); dataStorageService = IDataStorageService::Pointer(service); context->registerService(service); // Get the MitkCore Module Context mitkContext = us::ModuleRegistry::GetModule(1)->GetModuleContext(); // Process all already registered services std::vector refs = mitkContext->GetServiceReferences(""); for (std::vector::const_iterator i = refs.begin(); i != refs.end(); ++i) { this->AddMitkService(*i); } mitkContext->AddServiceListener(this, &org_mitk_core_services_Activator::MitkServiceChanged); } void org_mitk_core_services_Activator::stop(ctkPluginContext* /*context*/) { mitkContext->RemoveServiceListener(this, &org_mitk_core_services_Activator::MitkServiceChanged); foreach(ctkServiceRegistration reg, mapMitkIdToRegistration.values()) { reg.unregister(); } mapMitkIdToRegistration.clear(); qDeleteAll(mapMitkIdToAdapter); mapMitkIdToAdapter.clear(); //clean up logging mitk::LoggingBackend::Unregister(); dataStorageService = 0; mitkContext = 0; pluginContext = 0; } void org_mitk_core_services_Activator::MitkServiceChanged(const us::ServiceEvent event) { switch (event.GetType()) { case us::ServiceEvent::REGISTERED: { this->AddMitkService(event.GetServiceReference()); break; } case us::ServiceEvent::UNREGISTERING: { long mitkServiceId = us::any_cast(event.GetServiceReference().GetProperty(us::ServiceConstants::SERVICE_ID())); ctkServiceRegistration reg = mapMitkIdToRegistration.take(mitkServiceId); if (reg) { reg.unregister(); } delete mapMitkIdToAdapter.take(mitkServiceId); break; } case us::ServiceEvent::MODIFIED: { long mitkServiceId = us::any_cast(event.GetServiceReference().GetProperty(us::ServiceConstants::SERVICE_ID())); ctkDictionary newProps = CreateServiceProperties(event.GetServiceReference()); mapMitkIdToRegistration[mitkServiceId].setProperties(newProps); break; } default: break; // do nothing } } void org_mitk_core_services_Activator::AddMitkService(const us::ServiceReferenceU& ref) { // Get the MITK micro service object us::InterfaceMap mitkService = mitkContext->GetService(ref); if (mitkService.empty()) return; // Get the interface names against which the service was registered QStringList qclazzes; for(us::InterfaceMap::const_iterator clazz = mitkService.begin(); clazz != mitkService.end(); ++clazz) { qclazzes << QString::fromStdString(clazz->first); } long mitkServiceId = us::any_cast(ref.GetProperty(us::ServiceConstants::SERVICE_ID())); QObject* adapter = new InterfaceMapToQObjectAdapter(mitkService); mapMitkIdToAdapter[mitkServiceId] = adapter; ctkDictionary props = CreateServiceProperties(ref); mapMitkIdToRegistration[mitkServiceId] = pluginContext->registerService(qclazzes, adapter, props); } ctkDictionary org_mitk_core_services_Activator::CreateServiceProperties(const us::ServiceReferenceU& ref) { ctkDictionary props; long mitkServiceId = us::any_cast(ref.GetProperty(us::ServiceConstants::SERVICE_ID())); props.insert("mitk.serviceid", QVariant::fromValue(mitkServiceId)); // Add all other properties from the MITK micro service std::vector keys; ref.GetPropertyKeys(keys); for (std::vector::const_iterator it = keys.begin(); it != keys.end(); ++it) { QString key = QString::fromStdString(*it); us::Any value = ref.GetProperty(*it); // We cannot add any mitk::Any object, we need to query the type const std::type_info& objType = value.Type(); if (objType == typeid(std::string)) { props.insert(key, QString::fromStdString(us::ref_any_cast(value))); } else if (objType == typeid(std::vector)) { const std::vector& list = us::ref_any_cast >(value); QStringList qlist; for (std::vector::const_iterator str = list.begin(); str != list.end(); ++str) { qlist << QString::fromStdString(*str); } props.insert(key, qlist); } else if (objType == typeid(std::list)) { const std::list& list = us::ref_any_cast >(value); QStringList qlist; for (std::list::const_iterator str = list.begin(); str != list.end(); ++str) { qlist << QString::fromStdString(*str); } props.insert(key, qlist); } else if (objType == typeid(char)) { props.insert(key, QChar(us::ref_any_cast(value))); } else if (objType == typeid(unsigned char)) { props.insert(key, QChar(us::ref_any_cast(value))); } else if (objType == typeid(bool)) { props.insert(key, us::any_cast(value)); } else if (objType == typeid(short)) { props.insert(key, us::any_cast(value)); } else if (objType == typeid(unsigned short)) { props.insert(key, us::any_cast(value)); } else if (objType == typeid(int)) { props.insert(key, us::any_cast(value)); } else if (objType == typeid(unsigned int)) { props.insert(key, us::any_cast(value)); } else if (objType == typeid(float)) { props.insert(key, us::any_cast(value)); } else if (objType == typeid(double)) { props.insert(key, us::any_cast(value)); } else if (objType == typeid(long long int)) { props.insert(key, us::any_cast(value)); } else if (objType == typeid(unsigned long long int)) { props.insert(key, us::any_cast(value)); } } return props; } org_mitk_core_services_Activator::org_mitk_core_services_Activator() : mitkContext(0), pluginContext(0) { } } -Q_EXPORT_PLUGIN2(org_mitk_core_services, mitk::org_mitk_core_services_Activator) +#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) + Q_EXPORT_PLUGIN2(org_mitk_core_services, mitk::org_mitk_core_services_Activator) +#endif diff --git a/Plugins/org.mitk.core.services/src/internal/mitkPluginActivator.h b/Plugins/org.mitk.core.services/src/internal/mitkPluginActivator.h index 770cd816f7..185be7b434 100644 --- a/Plugins/org.mitk.core.services/src/internal/mitkPluginActivator.h +++ b/Plugins/org.mitk.core.services/src/internal/mitkPluginActivator.h @@ -1,67 +1,70 @@ /*=================================================================== 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 MITKCORESERVICESPLUGIN_H_ #define MITKCORESERVICESPLUGIN_H_ #include #include #include "mitkIDataStorageService.h" #include namespace us { class ModuleContext; } namespace mitk { class org_mitk_core_services_Activator : public QObject, public ctkPluginActivator { Q_OBJECT +#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) + Q_PLUGIN_METADATA(IID "org_mitk_core_services") +#endif Q_INTERFACES(ctkPluginActivator) public: static const std::string PLUGIN_ID; org_mitk_core_services_Activator(); void start(ctkPluginContext* context); void stop(ctkPluginContext* context); void MitkServiceChanged(const us::ServiceEvent event); private: mitk::IDataStorageService::Pointer dataStorageService; QMap mapMitkIdToAdapter; QMap mapMitkIdToRegistration; us::ModuleContext* mitkContext; ctkPluginContext* pluginContext; void AddMitkService(const us::ServiceReferenceU& ref); ctkDictionary CreateServiceProperties(const us::ServiceReferenceU& ref); }; typedef org_mitk_core_services_Activator PluginActivator; } #endif /*MITKCORESERVICESPLUGIN_H_*/ diff --git a/Plugins/org.mitk.diffusionimaging/src/internal/mitkDiffusionImagingActivator.cpp b/Plugins/org.mitk.diffusionimaging/src/internal/mitkDiffusionImagingActivator.cpp index 8d979b58d5..40d92b2cdf 100644 --- a/Plugins/org.mitk.diffusionimaging/src/internal/mitkDiffusionImagingActivator.cpp +++ b/Plugins/org.mitk.diffusionimaging/src/internal/mitkDiffusionImagingActivator.cpp @@ -1,59 +1,61 @@ /*=================================================================== 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 "mitkDiffusionImagingActivator.h" #include "QmitkNodeDescriptorManager.h" #include "mitkNodePredicateDataType.h" #include void mitk::DiffusionImagingActivator::start(ctkPluginContext* context) { Q_UNUSED(context) QmitkNodeDescriptorManager* manager = QmitkNodeDescriptorManager::GetInstance(); mitk::NodePredicateDataType::Pointer isDiffusionImage = mitk::NodePredicateDataType::New("DiffusionImage"); QmitkNodeDescriptor* desc = new QmitkNodeDescriptor(QObject::tr("DiffusionImage"), QString(":/QmitkDiffusionImaging/QBallData24.png"), isDiffusionImage, manager); manager->AddDescriptor(desc); mitk::NodePredicateDataType::Pointer isTensorImage = mitk::NodePredicateDataType::New("TensorImage"); manager->AddDescriptor(new QmitkNodeDescriptor(QObject::tr("TensorImage"), QString(":/QmitkDiffusionImaging/recontensor.png"), isTensorImage, manager)); mitk::NodePredicateDataType::Pointer isQBallImage = mitk::NodePredicateDataType::New("QBallImage"); manager->AddDescriptor(new QmitkNodeDescriptor(QObject::tr("QBallImage"), QString(":/QmitkDiffusionImaging/reconodf.png"), isQBallImage, manager)); mitk::NodePredicateDataType::Pointer isFiberBundle = mitk::NodePredicateDataType::New("FiberBundle"); manager->AddDescriptor(new QmitkNodeDescriptor(QObject::tr("FiberBundle"), QString(":/QmitkDiffusionImaging/FiberBundle.png"), isFiberBundle, manager)); mitk::NodePredicateDataType::Pointer isFiberBundleX = mitk::NodePredicateDataType::New("FiberBundleX"); manager->AddDescriptor(new QmitkNodeDescriptor(QObject::tr("FiberBundleX"), QString(":/QmitkDiffusionImaging/FiberBundleX.png"), isFiberBundleX, manager)); mitk::NodePredicateDataType::Pointer isConnectomicsNetwork = mitk::NodePredicateDataType::New("ConnectomicsNetwork"); manager->AddDescriptor(new QmitkNodeDescriptor(QObject::tr("ConnectomicsNetwork"), QString(":/QmitkDiffusionImaging/ConnectomicsNetwork.png"), isConnectomicsNetwork, manager)); } void mitk::DiffusionImagingActivator::stop(ctkPluginContext* context) { Q_UNUSED(context) } -Q_EXPORT_PLUGIN2(org_mitk_diffusionimaging, mitk::DiffusionImagingActivator) +#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) + Q_EXPORT_PLUGIN2(org_mitk_diffusionimaging, mitk::DiffusionImagingActivator) +#endif diff --git a/Plugins/org.mitk.diffusionimaging/src/internal/mitkDiffusionImagingActivator.h b/Plugins/org.mitk.diffusionimaging/src/internal/mitkDiffusionImagingActivator.h index 40dfce9ee3..b17942daf0 100644 --- a/Plugins/org.mitk.diffusionimaging/src/internal/mitkDiffusionImagingActivator.h +++ b/Plugins/org.mitk.diffusionimaging/src/internal/mitkDiffusionImagingActivator.h @@ -1,54 +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 MITKDIFFUSIONIMAGINGACTIVATOR_H_ #define MITKDIFFUSIONIMAGINGACTIVATOR_H_ #include #include namespace mitk { /** * \ingroup org_mitk_diffusionimaging_internal * * \brief The plug-in activator for the diffusion imaging module * * When the plug-in is started by the framework, it initialzes diffusion imaging * specific things. */ class MITK_LOCAL DiffusionImagingActivator : public QObject, public ctkPluginActivator { Q_OBJECT +#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) + Q_PLUGIN_METADATA(IID "org_mitk_diffusionimaging") +#endif Q_INTERFACES(ctkPluginActivator) public: /** * Registers diffusion imaging object factories. */ void start(ctkPluginContext* context); void stop(ctkPluginContext* context); }; } #endif /* MITKDIFFUSIONIMAGINGACTIVATOR_H_ */ diff --git a/Plugins/org.mitk.gui.common/src/internal/org_mitk_gui_common_Activator.cpp b/Plugins/org.mitk.gui.common/src/internal/org_mitk_gui_common_Activator.cpp index 20d00cc540..f2d00c4087 100644 --- a/Plugins/org.mitk.gui.common/src/internal/org_mitk_gui_common_Activator.cpp +++ b/Plugins/org.mitk.gui.common/src/internal/org_mitk_gui_common_Activator.cpp @@ -1,46 +1,46 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "org_mitk_gui_common_Activator.h" #include namespace mitk { ctkPluginContext* org_mitk_gui_common_Activator::m_Context = 0; void org_mitk_gui_common_Activator::start(ctkPluginContext* context) { m_Context = context; } void org_mitk_gui_common_Activator::stop(ctkPluginContext* context) { Q_UNUSED(context) m_Context = 0; } ctkPluginContext *org_mitk_gui_common_Activator::GetContext() { return m_Context; } } -Q_EXPORT_PLUGIN2(org_mitk_gui_common, mitk::org_mitk_gui_common_Activator) - - +#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) + Q_EXPORT_PLUGIN2(org_mitk_gui_common, mitk::org_mitk_gui_common_Activator) +#endif diff --git a/Plugins/org.mitk.gui.common/src/internal/org_mitk_gui_common_Activator.h b/Plugins/org.mitk.gui.common/src/internal/org_mitk_gui_common_Activator.h index 70f690c427..43ce20e790 100644 --- a/Plugins/org.mitk.gui.common/src/internal/org_mitk_gui_common_Activator.h +++ b/Plugins/org.mitk.gui.common/src/internal/org_mitk_gui_common_Activator.h @@ -1,48 +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 MITKPLUGINACTIVATOR_H #define MITKPLUGINACTIVATOR_H #include namespace mitk { class org_mitk_gui_common_Activator : public QObject, public ctkPluginActivator { Q_OBJECT +#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) + Q_PLUGIN_METADATA(IID "org_mitk_gui_common") +#endif Q_INTERFACES(ctkPluginActivator) public: void start(ctkPluginContext* context); void stop(ctkPluginContext* context); static ctkPluginContext* GetContext(); private: static ctkPluginContext* m_Context; }; // org_mitk_gui_common_Activator typedef org_mitk_gui_common_Activator PluginActivator; } #endif // MITKPLUGINACTIVATOR_H diff --git a/Plugins/org.mitk.gui.qt.application/CMakeLists.txt b/Plugins/org.mitk.gui.qt.application/CMakeLists.txt index 7d52d7bed3..6b8916ba8a 100644 --- a/Plugins/org.mitk.gui.qt.application/CMakeLists.txt +++ b/Plugins/org.mitk.gui.qt.application/CMakeLists.txt @@ -1,8 +1,9 @@ project(org_mitk_gui_qt_application) MACRO_CREATE_MITK_CTK_PLUGIN( EXPORT_DIRECTIVE MITK_QT_APP EXPORTED_INCLUDE_SUFFIXES src MODULE_DEPENDS MitkQtWidgets + PACKAGE_DEPENDS Qt4|QtCore Qt5|OpenGL+Xml SUBPROJECTS MITK-CoreUI ) diff --git a/Plugins/org.mitk.gui.qt.application/src/QmitkDefaultDropTargetListener.cpp b/Plugins/org.mitk.gui.qt.application/src/QmitkDefaultDropTargetListener.cpp index 73e6e9a065..c496bb4c6e 100644 --- a/Plugins/org.mitk.gui.qt.application/src/QmitkDefaultDropTargetListener.cpp +++ b/Plugins/org.mitk.gui.qt.application/src/QmitkDefaultDropTargetListener.cpp @@ -1,92 +1,93 @@ /*=================================================================== 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 "QmitkDefaultDropTargetListener.h" #include #include +#include #include #include #include "internal/org_mitk_gui_qt_application_Activator.h" #include #include #include class QmitkDefaultDropTargetListenerPrivate { public: berry::IPreferences::Pointer GetPreferences() const { berry::IPreferencesService::Pointer prefService = mitk::PluginActivator::GetInstance()->GetPreferencesService(); if (prefService) { return prefService->GetSystemPreferences()->Node("/General"); } return berry::IPreferences::Pointer(0); } bool GetOpenEditor() const { berry::IPreferences::Pointer prefs = GetPreferences(); if(prefs.IsNotNull()) { return prefs->GetBool("OpenEditor", true); } return true; } }; QmitkDefaultDropTargetListener::QmitkDefaultDropTargetListener() : berry::IDropTargetListener(), d(new QmitkDefaultDropTargetListenerPrivate()) { } QmitkDefaultDropTargetListener::~QmitkDefaultDropTargetListener() { } berry::IDropTargetListener::Events::Types QmitkDefaultDropTargetListener::GetDropTargetEventTypes() const { return Events::DROP; } void QmitkDefaultDropTargetListener::DropEvent(QDropEvent *event) { qDebug() << event->mimeData()->formats(); qDebug() << event->mimeData()->text(); QList fileNames = event->mimeData()->urls(); if (fileNames.empty()) return; QStringList fileNames2; //TODO Qt 4.7 API //fileNames2.reserve(fileNames.size()); foreach(QUrl url, fileNames) { fileNames2.push_back(url.toLocalFile()); } mitk::WorkbenchUtil::LoadFiles(fileNames2, berry::PlatformUI::GetWorkbench()->GetActiveWorkbenchWindow(), d->GetOpenEditor()); event->accept(); } diff --git a/Plugins/org.mitk.gui.qt.application/src/internal/org_mitk_gui_qt_application_Activator.cpp b/Plugins/org.mitk.gui.qt.application/src/internal/org_mitk_gui_qt_application_Activator.cpp index b9b06decb9..4d3c0aa5cf 100644 --- a/Plugins/org.mitk.gui.qt.application/src/internal/org_mitk_gui_qt_application_Activator.cpp +++ b/Plugins/org.mitk.gui.qt.application/src/internal/org_mitk_gui_qt_application_Activator.cpp @@ -1,73 +1,75 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "org_mitk_gui_qt_application_Activator.h" #include "QmitkGeneralPreferencePage.h" #include "QmitkEditorsPreferencePage.h" #include #include namespace mitk { org_mitk_gui_qt_application_Activator* org_mitk_gui_qt_application_Activator::m_Instance = 0; ctkPluginContext* org_mitk_gui_qt_application_Activator::m_Context = 0; void org_mitk_gui_qt_application_Activator::start(ctkPluginContext* context) { this->m_Instance = this; this->m_Context = context; BERRY_REGISTER_EXTENSION_CLASS(QmitkGeneralPreferencePage, context) BERRY_REGISTER_EXTENSION_CLASS(QmitkEditorsPreferencePage, context) QmitkRegisterClasses(); this->m_PrefServiceTracker.reset(new ctkServiceTracker(context)); this->m_PrefServiceTracker->open(); } void org_mitk_gui_qt_application_Activator::stop(ctkPluginContext* context) { Q_UNUSED(context) this->m_PrefServiceTracker.reset(); this->m_Context = 0; this->m_Instance = 0; } ctkPluginContext* org_mitk_gui_qt_application_Activator::GetContext() { return m_Context; } org_mitk_gui_qt_application_Activator *org_mitk_gui_qt_application_Activator::GetInstance() { return m_Instance; } berry::IPreferencesService::Pointer org_mitk_gui_qt_application_Activator::GetPreferencesService() { return berry::IPreferencesService::Pointer(m_PrefServiceTracker->getService()); } } -Q_EXPORT_PLUGIN2(org_mitk_gui_qt_application, mitk::org_mitk_gui_qt_application_Activator) +#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) + Q_EXPORT_PLUGIN2(org_mitk_gui_qt_application, mitk::org_mitk_gui_qt_application_Activator) +#endif diff --git a/Plugins/org.mitk.gui.qt.application/src/internal/org_mitk_gui_qt_application_Activator.h b/Plugins/org.mitk.gui.qt.application/src/internal/org_mitk_gui_qt_application_Activator.h index 3f9a16243a..4ff5371dc5 100644 --- a/Plugins/org.mitk.gui.qt.application/src/internal/org_mitk_gui_qt_application_Activator.h +++ b/Plugins/org.mitk.gui.qt.application/src/internal/org_mitk_gui_qt_application_Activator.h @@ -1,58 +1,61 @@ /*=================================================================== 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 MITKPLUGINACTIVATOR_H #define MITKPLUGINACTIVATOR_H #include #include #include namespace mitk { class org_mitk_gui_qt_application_Activator : public QObject, public ctkPluginActivator { Q_OBJECT +#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) + Q_PLUGIN_METADATA(IID "org_mitk_gui_qt_application") +#endif Q_INTERFACES(ctkPluginActivator) public: void start(ctkPluginContext* context); void stop(ctkPluginContext* context); static ctkPluginContext* GetContext(); static org_mitk_gui_qt_application_Activator* GetInstance(); berry::IPreferencesService::Pointer GetPreferencesService(); private: static org_mitk_gui_qt_application_Activator* m_Instance; static ctkPluginContext* m_Context; QScopedPointer > m_PrefServiceTracker; }; // org_mitk_gui_common_Activator typedef org_mitk_gui_qt_application_Activator PluginActivator; } #endif // MITKPLUGINACTIVATOR_H diff --git a/Plugins/org.mitk.gui.qt.basicimageprocessing/src/internal/QmitkBasicImageProcessingView.cpp b/Plugins/org.mitk.gui.qt.basicimageprocessing/src/internal/QmitkBasicImageProcessingView.cpp index aff7c6d02b..60d3d933e7 100644 --- a/Plugins/org.mitk.gui.qt.basicimageprocessing/src/internal/QmitkBasicImageProcessingView.cpp +++ b/Plugins/org.mitk.gui.qt.basicimageprocessing/src/internal/QmitkBasicImageProcessingView.cpp @@ -1,1355 +1,1355 @@ /*=================================================================== 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 "QmitkBasicImageProcessingView.h" // QT includes (GUI) #include #include #include #include #include #include #include // Berry includes (selection service) #include #include // MITK includes (GUI) #include "QmitkStdMultiWidget.h" #include "QmitkDataNodeSelectionProvider.h" #include "mitkDataNodeObject.h" // MITK includes (general) #include "mitkNodePredicateDataType.h" #include "mitkNodePredicateDimension.h" #include "mitkNodePredicateAnd.h" #include "mitkImageTimeSelector.h" #include "mitkVectorImageMapper2D.h" #include "mitkProperties.h" // Includes for image casting between ITK and MITK #include "mitkImageCast.h" #include "mitkITKImageImport.h" // ITK includes (general) #include #include // Morphological Operations #include #include #include #include #include // Smoothing #include #include #include // Threshold #include // Inversion #include // Derivatives #include #include #include // Resampling #include #include #include #include // Image Arithmetics #include #include #include #include // Boolean operations #include #include #include // Flip Image #include #include // Convenient Definitions typedef itk::Image ImageType; typedef itk::Image SegmentationImageType; typedef itk::Image FloatImageType; typedef itk::Image, 3> VectorImageType; typedef itk::BinaryBallStructuringElement BallType; typedef itk::GrayscaleDilateImageFilter DilationFilterType; typedef itk::GrayscaleErodeImageFilter ErosionFilterType; typedef itk::GrayscaleMorphologicalOpeningImageFilter OpeningFilterType; typedef itk::GrayscaleMorphologicalClosingImageFilter ClosingFilterType; typedef itk::MedianImageFilter< ImageType, ImageType > MedianFilterType; typedef itk::DiscreteGaussianImageFilter< ImageType, ImageType> GaussianFilterType; typedef itk::TotalVariationDenoisingImageFilter TotalVariationFilterType; typedef itk::TotalVariationDenoisingImageFilter VectorTotalVariationFilterType; typedef itk::BinaryThresholdImageFilter< ImageType, ImageType > ThresholdFilterType; typedef itk::InvertIntensityImageFilter< ImageType, ImageType > InversionFilterType; typedef itk::GradientMagnitudeRecursiveGaussianImageFilter< ImageType, ImageType > GradientFilterType; typedef itk::LaplacianImageFilter< FloatImageType, FloatImageType > LaplacianFilterType; typedef itk::SobelEdgeDetectionImageFilter< FloatImageType, FloatImageType > SobelFilterType; typedef itk::ResampleImageFilter< ImageType, ImageType > ResampleImageFilterType; typedef itk::ResampleImageFilter< ImageType, ImageType > ResampleImageFilterType2; typedef itk::CastImageFilter< ImageType, FloatImageType > ImagePTypeToFloatPTypeCasterType; typedef itk::AddImageFilter< ImageType, ImageType, ImageType > AddFilterType; typedef itk::SubtractImageFilter< ImageType, ImageType, ImageType > SubtractFilterType; typedef itk::MultiplyImageFilter< ImageType, ImageType, ImageType > MultiplyFilterType; typedef itk::DivideImageFilter< ImageType, ImageType, FloatImageType > DivideFilterType; typedef itk::OrImageFilter< ImageType, ImageType > OrImageFilterType; typedef itk::AndImageFilter< ImageType, ImageType > AndImageFilterType; typedef itk::XorImageFilter< ImageType, ImageType > XorImageFilterType; typedef itk::FlipImageFilter< ImageType > FlipImageFilterType; typedef itk::LinearInterpolateImageFunction< ImageType, double > LinearInterpolatorType; typedef itk::NearestNeighborInterpolateImageFunction< ImageType, double > NearestInterpolatorType; QmitkBasicImageProcessing::QmitkBasicImageProcessing() : QmitkFunctionality(), m_Controls(NULL), m_SelectedImageNode(NULL), m_TimeStepperAdapter(NULL), m_SelectionListener(NULL) { } QmitkBasicImageProcessing::~QmitkBasicImageProcessing() { //berry::ISelectionService* s = GetSite()->GetWorkbenchWindow()->GetSelectionService(); //if(s) // s->RemoveSelectionListener(m_SelectionListener); } void QmitkBasicImageProcessing::CreateQtPartControl(QWidget *parent) { if (m_Controls == NULL) { m_Controls = new Ui::QmitkBasicImageProcessingViewControls; m_Controls->setupUi(parent); this->CreateConnections(); //setup predictaes for combobox mitk::NodePredicateDimension::Pointer dimensionPredicate = mitk::NodePredicateDimension::New(3); mitk::NodePredicateDataType::Pointer imagePredicate = mitk::NodePredicateDataType::New("Image"); m_Controls->m_ImageSelector2->SetDataStorage(this->GetDefaultDataStorage()); m_Controls->m_ImageSelector2->SetPredicate(mitk::NodePredicateAnd::New(dimensionPredicate, imagePredicate)); } m_Controls->gbTwoImageOps->hide(); m_SelectedImageNode = mitk::DataStorageSelection::New(this->GetDefaultDataStorage(), false); } void QmitkBasicImageProcessing::CreateConnections() { if ( m_Controls ) { connect( (QObject*)(m_Controls->cbWhat1), SIGNAL( activated(int) ), this, SLOT( SelectAction(int) ) ); connect( (QObject*)(m_Controls->btnDoIt), SIGNAL(clicked()),(QObject*) this, SLOT(StartButtonClicked())); connect( (QObject*)(m_Controls->cbWhat2), SIGNAL( activated(int) ), this, SLOT( SelectAction2(int) ) ); connect( (QObject*)(m_Controls->btnDoIt2), SIGNAL(clicked()),(QObject*) this, SLOT(StartButton2Clicked())); connect( (QObject*)(m_Controls->rBOneImOp), SIGNAL( clicked() ), this, SLOT( ChangeGUI() ) ); connect( (QObject*)(m_Controls->rBTwoImOp), SIGNAL( clicked() ), this, SLOT( ChangeGUI() ) ); connect( (QObject*)(m_Controls->cbParam4), SIGNAL( activated(int) ), this, SLOT( SelectInterpolator(int) ) ); } m_TimeStepperAdapter = new QmitkStepperAdapter((QObject*) m_Controls->sliceNavigatorTime, GetActiveStdMultiWidget()->GetTimeNavigationController()->GetTime(), "sliceNavigatorTimeFromBIP"); } void QmitkBasicImageProcessing::Activated() { QmitkFunctionality::Activated(); this->m_Controls->cbWhat1->clear(); - this->m_Controls->cbWhat1->insertItem( NOACTIONSELECTED, QString( QApplication::translate("QmitkBasicImageProcessingViewControls", "Please select operation", 0, QApplication::UnicodeUTF8) )); - this->m_Controls->cbWhat1->insertItem( CATEGORY_DENOISING, QString( QApplication::translate("QmitkBasicImageProcessingViewControls", "--- Denoising ---", 0, QApplication::UnicodeUTF8) )); - this->m_Controls->cbWhat1->insertItem( GAUSSIAN, QString( QApplication::translate("QmitkBasicImageProcessingViewControls", "Gaussian", 0, QApplication::UnicodeUTF8) )); - this->m_Controls->cbWhat1->insertItem( MEDIAN, QString( QApplication::translate("QmitkBasicImageProcessingViewControls", "Median", 0, QApplication::UnicodeUTF8) )); - this->m_Controls->cbWhat1->insertItem( TOTALVARIATION, QString( QApplication::translate("QmitkBasicImageProcessingViewControls", "Total Variation", 0, QApplication::UnicodeUTF8) )); - this->m_Controls->cbWhat1->insertItem( CATEGORY_MORPHOLOGICAL, QString( QApplication::translate("QmitkBasicImageProcessingViewControls", "--- Morphological ---", 0, QApplication::UnicodeUTF8) )); - this->m_Controls->cbWhat1->insertItem( DILATION, QString( QApplication::translate("QmitkBasicImageProcessingViewControls", "Dilation", 0, QApplication::UnicodeUTF8) )); - this->m_Controls->cbWhat1->insertItem( EROSION, QString( QApplication::translate("QmitkBasicImageProcessingViewControls", "Erosion", 0, QApplication::UnicodeUTF8) )); - this->m_Controls->cbWhat1->insertItem( OPENING, QString( QApplication::translate("QmitkBasicImageProcessingViewControls", "Opening", 0, QApplication::UnicodeUTF8) )); - this->m_Controls->cbWhat1->insertItem( CLOSING, QString( QApplication::translate("QmitkBasicImageProcessingViewControls", "Closing", 0, QApplication::UnicodeUTF8) )); - this->m_Controls->cbWhat1->insertItem( CATEGORY_EDGE_DETECTION, QString( QApplication::translate("QmitkBasicImageProcessingViewControls", "--- Edge Detection ---", 0, QApplication::UnicodeUTF8) )); - this->m_Controls->cbWhat1->insertItem( GRADIENT, QString( QApplication::translate("QmitkBasicImageProcessingViewControls", "Gradient", 0, QApplication::UnicodeUTF8) )); - this->m_Controls->cbWhat1->insertItem( LAPLACIAN, QString( QApplication::translate("QmitkBasicImageProcessingViewControls", "Laplacian (2nd Derivative)", 0, QApplication::UnicodeUTF8) )); - this->m_Controls->cbWhat1->insertItem( SOBEL, QString( QApplication::translate("QmitkBasicImageProcessingViewControls", "Sobel Operator", 0, QApplication::UnicodeUTF8) )); - this->m_Controls->cbWhat1->insertItem( CATEGORY_MISC, QString( QApplication::translate("QmitkBasicImageProcessingViewControls", "--- Misc ---", 0, QApplication::UnicodeUTF8) )); - this->m_Controls->cbWhat1->insertItem( THRESHOLD, QString( QApplication::translate("QmitkBasicImageProcessingViewControls", "Threshold", 0, QApplication::UnicodeUTF8) )); - this->m_Controls->cbWhat1->insertItem( INVERSION, QString( QApplication::translate("QmitkBasicImageProcessingViewControls", "Image Inversion", 0, QApplication::UnicodeUTF8) )); - this->m_Controls->cbWhat1->insertItem( DOWNSAMPLING, QString( QApplication::translate("QmitkBasicImageProcessingViewControls", "Downsampling", 0, QApplication::UnicodeUTF8) )); - this->m_Controls->cbWhat1->insertItem( FLIPPING, QString( QApplication::translate("QmitkBasicImageProcessingViewControls", "Flipping", 0, QApplication::UnicodeUTF8) )); - this->m_Controls->cbWhat1->insertItem( RESAMPLING, QString( QApplication::translate("QmitkBasicImageProcessingViewControls", "Resample to", 0, QApplication::UnicodeUTF8) )); - this->m_Controls->cbWhat1->insertItem( RESCALE, QString( QApplication::translate("QmitkBasicImageProcessingViewControls", "Rescale image values", 0, QApplication::UnicodeUTF8) )); + this->m_Controls->cbWhat1->insertItem( NOACTIONSELECTED, "Please select operation"); + this->m_Controls->cbWhat1->insertItem( CATEGORY_DENOISING, "--- Denoising ---"); + this->m_Controls->cbWhat1->insertItem( GAUSSIAN, "Gaussian"); + this->m_Controls->cbWhat1->insertItem( MEDIAN, "Median"); + this->m_Controls->cbWhat1->insertItem( TOTALVARIATION, "Total Variation"); + this->m_Controls->cbWhat1->insertItem( CATEGORY_MORPHOLOGICAL, "--- Morphological ---"); + this->m_Controls->cbWhat1->insertItem( DILATION, "Dilation"); + this->m_Controls->cbWhat1->insertItem( EROSION, "Erosion"); + this->m_Controls->cbWhat1->insertItem( OPENING, "Opening"); + this->m_Controls->cbWhat1->insertItem( CLOSING, "Closing"); + this->m_Controls->cbWhat1->insertItem( CATEGORY_EDGE_DETECTION, "--- Edge Detection ---"); + this->m_Controls->cbWhat1->insertItem( GRADIENT, "Gradient"); + this->m_Controls->cbWhat1->insertItem( LAPLACIAN, "Laplacian (2nd Derivative)"); + this->m_Controls->cbWhat1->insertItem( SOBEL, "Sobel Operator"); + this->m_Controls->cbWhat1->insertItem( CATEGORY_MISC, "--- Misc ---"); + this->m_Controls->cbWhat1->insertItem( THRESHOLD, "Threshold"); + this->m_Controls->cbWhat1->insertItem( INVERSION, "Image Inversion"); + this->m_Controls->cbWhat1->insertItem( DOWNSAMPLING, "Downsampling"); + this->m_Controls->cbWhat1->insertItem( FLIPPING, "Flipping"); + this->m_Controls->cbWhat1->insertItem( RESAMPLING, "Resample to"); + this->m_Controls->cbWhat1->insertItem( RESCALE, "Rescale image values"); this->m_Controls->cbWhat2->clear(); - this->m_Controls->cbWhat2->insertItem( TWOIMAGESNOACTIONSELECTED, QString( QApplication::translate("QmitkBasicImageProcessingViewControls", "Please select on operation", 0, QApplication::UnicodeUTF8) ) ); - this->m_Controls->cbWhat2->insertItem( CATEGORY_ARITHMETIC, QString( QApplication::translate("QmitkBasicImageProcessingViewControls", "--- Arithmetric operations ---", 0, QApplication::UnicodeUTF8) ) ); - this->m_Controls->cbWhat2->insertItem( ADD, QString( QApplication::translate("QmitkBasicImageProcessingViewControls", "Add to Image 1:", 0, QApplication::UnicodeUTF8) ) ); - this->m_Controls->cbWhat2->insertItem( SUBTRACT, QString( QApplication::translate("QmitkBasicImageProcessingViewControls", "Subtract from Image 1:", 0, QApplication::UnicodeUTF8) ) ); - this->m_Controls->cbWhat2->insertItem( MULTIPLY, QString( QApplication::translate("QmitkBasicImageProcessingViewControls", "Multiply with Image 1:", 0, QApplication::UnicodeUTF8) ) ); - this->m_Controls->cbWhat2->insertItem( RESAMPLE_TO, QString( QApplication::translate("QmitkBasicImageProcessingViewControls", "Resample Image 1 to fit geometry:", 0, QApplication::UnicodeUTF8) ) ); - this->m_Controls->cbWhat2->insertItem( DIVIDE, QString( QApplication::translate("QmitkBasicImageProcessingViewControls", "Divide Image 1 by:", 0, QApplication::UnicodeUTF8) ) ); - this->m_Controls->cbWhat2->insertItem( CATEGORY_BOOLEAN, QString( QApplication::translate("QmitkBasicImageProcessingViewControls", "--- Boolean operations ---", 0, QApplication::UnicodeUTF8) ) ); - this->m_Controls->cbWhat2->insertItem( AND, QString( QApplication::translate("QmitkBasicImageProcessingViewControls", "AND", 0, QApplication::UnicodeUTF8) ) ); - this->m_Controls->cbWhat2->insertItem( OR, QString( QApplication::translate("QmitkBasicImageProcessingViewControls", "OR", 0, QApplication::UnicodeUTF8) ) ); - this->m_Controls->cbWhat2->insertItem( XOR, QString( QApplication::translate("QmitkBasicImageProcessingViewControls", "XOR", 0, QApplication::UnicodeUTF8) ) ); + this->m_Controls->cbWhat2->insertItem( TWOIMAGESNOACTIONSELECTED, "Please select on operation" ); + this->m_Controls->cbWhat2->insertItem( CATEGORY_ARITHMETIC, "--- Arithmetric operations ---" ); + this->m_Controls->cbWhat2->insertItem( ADD, "Add to Image 1:" ); + this->m_Controls->cbWhat2->insertItem( SUBTRACT, "Subtract from Image 1:" ); + this->m_Controls->cbWhat2->insertItem( MULTIPLY, "Multiply with Image 1:" ); + this->m_Controls->cbWhat2->insertItem( RESAMPLE_TO, "Resample Image 1 to fit geometry:" ); + this->m_Controls->cbWhat2->insertItem( DIVIDE, "Divide Image 1 by:" ); + this->m_Controls->cbWhat2->insertItem( CATEGORY_BOOLEAN, "--- Boolean operations ---" ); + this->m_Controls->cbWhat2->insertItem( AND, "AND" ); + this->m_Controls->cbWhat2->insertItem( OR, "OR" ); + this->m_Controls->cbWhat2->insertItem( XOR, "XOR" ); this->m_Controls->cbParam4->clear(); - this->m_Controls->cbParam4->insertItem( LINEAR, QString( QApplication::translate("QmitkBasicImageProcessingViewControls", "Linear", 0, QApplication::UnicodeUTF8) ) ); - this->m_Controls->cbParam4->insertItem( NEAREST, QString( QApplication::translate("QmitkBasicImageProcessingViewControls", "Nearest neighbor", 0, QApplication::UnicodeUTF8) ) ); + this->m_Controls->cbParam4->insertItem( LINEAR, "Linear" ); + this->m_Controls->cbParam4->insertItem( NEAREST, "Nearest neighbor" ); m_Controls->dsbParam1->hide(); m_Controls->dsbParam2->hide(); m_Controls->dsbParam3->hide(); m_Controls->tlParam3->hide(); m_Controls->tlParam4->hide(); m_Controls->cbParam4->hide(); } //datamanager selection changed void QmitkBasicImageProcessing::OnSelectionChanged(std::vector nodes) { //any nodes there? if (!nodes.empty()) { // reset GUI // this->ResetOneImageOpPanel(); m_Controls->sliceNavigatorTime->setEnabled(false); m_Controls->leImage1->setText("Select an Image in Data Manager"); m_Controls->tlWhat1->setEnabled(false); m_Controls->cbWhat1->setEnabled(false); m_Controls->tlWhat2->setEnabled(false); m_Controls->cbWhat2->setEnabled(false); m_SelectedImageNode->RemoveAllNodes(); //get the selected Node mitk::DataNode* _DataNode = nodes.front(); *m_SelectedImageNode = _DataNode; //try to cast to image mitk::Image::Pointer tempImage = dynamic_cast(m_SelectedImageNode->GetNode()->GetData()); //no image if( tempImage.IsNull() || (tempImage->IsInitialized() == false) ) { m_Controls->leImage1->setText("Not an image."); return; } //2D image if( tempImage->GetDimension() < 3) { m_Controls->leImage1->setText("2D images are not supported."); return; } //image m_Controls->leImage1->setText(QString(m_SelectedImageNode->GetNode()->GetName().c_str())); // button coding if ( tempImage->GetDimension() > 3 ) { m_Controls->sliceNavigatorTime->setEnabled(true); m_Controls->tlTime->setEnabled(true); } m_Controls->tlWhat1->setEnabled(true); m_Controls->cbWhat1->setEnabled(true); m_Controls->tlWhat2->setEnabled(true); m_Controls->cbWhat2->setEnabled(true); } } void QmitkBasicImageProcessing::ChangeGUI() { if(m_Controls->rBOneImOp->isChecked()) { m_Controls->gbTwoImageOps->hide(); m_Controls->gbOneImageOps->show(); } else if(m_Controls->rBTwoImOp->isChecked()) { m_Controls->gbOneImageOps->hide(); m_Controls->gbTwoImageOps->show(); } } void QmitkBasicImageProcessing::ResetOneImageOpPanel() { m_Controls->tlParam1->setText("Param1"); m_Controls->tlParam2->setText("Param2"); m_Controls->cbWhat1->setCurrentIndex(0); m_Controls->tlTime->setEnabled(false); this->ResetParameterPanel(); m_Controls->btnDoIt->setEnabled(false); m_Controls->cbHideOrig->setEnabled(false); } void QmitkBasicImageProcessing::ResetParameterPanel() { m_Controls->tlParam->setEnabled(false); m_Controls->tlParam1->setEnabled(false); m_Controls->tlParam2->setEnabled(false); m_Controls->tlParam3->setEnabled(false); m_Controls->tlParam4->setEnabled(false); m_Controls->sbParam1->setEnabled(false); m_Controls->sbParam2->setEnabled(false); m_Controls->dsbParam1->setEnabled(false); m_Controls->dsbParam2->setEnabled(false); m_Controls->dsbParam3->setEnabled(false); m_Controls->cbParam4->setEnabled(false); m_Controls->sbParam1->setValue(0); m_Controls->sbParam2->setValue(0); m_Controls->dsbParam1->setValue(0); m_Controls->dsbParam2->setValue(0); m_Controls->dsbParam3->setValue(0); m_Controls->sbParam1->show(); m_Controls->sbParam2->show(); m_Controls->dsbParam1->hide(); m_Controls->dsbParam2->hide(); m_Controls->dsbParam3->hide(); m_Controls->cbParam4->hide(); m_Controls->tlParam3->hide(); m_Controls->tlParam4->hide(); } void QmitkBasicImageProcessing::ResetTwoImageOpPanel() { m_Controls->cbWhat2->setCurrentIndex(0); m_Controls->tlImage2->setEnabled(false); m_Controls->m_ImageSelector2->setEnabled(false); m_Controls->btnDoIt2->setEnabled(false); } void QmitkBasicImageProcessing::SelectAction(int action) { if ( ! m_SelectedImageNode->GetNode() ) return; // Prepare GUI this->ResetParameterPanel(); m_Controls->btnDoIt->setEnabled(false); m_Controls->cbHideOrig->setEnabled(false); QString text1 = "No Parameters"; QString text2 = "No Parameters"; QString text3 = "No Parameters"; QString text4 = "No Parameters"; if (action != 19) { m_Controls->dsbParam1->hide(); m_Controls->dsbParam2->hide(); m_Controls->dsbParam3->hide(); m_Controls->tlParam3->hide(); m_Controls->tlParam4->hide(); m_Controls->sbParam1->show(); m_Controls->sbParam2->show(); m_Controls->cbParam4->hide(); } // check which operation the user has selected and set parameters and GUI accordingly switch (action) { case 2: { m_SelectedAction = GAUSSIAN; m_Controls->tlParam1->setEnabled(true); m_Controls->sbParam1->setEnabled(true); text1 = "&Variance:"; m_Controls->sbParam1->setMinimum( 0 ); m_Controls->sbParam1->setMaximum( 200 ); m_Controls->sbParam1->setValue( 2 ); break; } case 3: { m_SelectedAction = MEDIAN; m_Controls->tlParam1->setEnabled(true); m_Controls->sbParam1->setEnabled(true); text1 = "&Radius:"; m_Controls->sbParam1->setMinimum( 0 ); m_Controls->sbParam1->setMaximum( 200 ); m_Controls->sbParam1->setValue( 3 ); break; } case 4: { m_SelectedAction = TOTALVARIATION; m_Controls->tlParam1->setEnabled(true); m_Controls->sbParam1->setEnabled(true); m_Controls->tlParam2->setEnabled(true); m_Controls->sbParam2->setEnabled(true); text1 = "Number Iterations:"; text2 = "Regularization\n(Lambda/1000):"; m_Controls->sbParam1->setMinimum( 1 ); m_Controls->sbParam1->setMaximum( 1000 ); m_Controls->sbParam1->setValue( 40 ); m_Controls->sbParam2->setMinimum( 0 ); m_Controls->sbParam2->setMaximum( 100000 ); m_Controls->sbParam2->setValue( 1 ); break; } case 6: { m_SelectedAction = DILATION; m_Controls->tlParam1->setEnabled(true); m_Controls->sbParam1->setEnabled(true); text1 = "&Radius:"; m_Controls->sbParam1->setMinimum( 0 ); m_Controls->sbParam1->setMaximum( 200 ); m_Controls->sbParam1->setValue( 3 ); break; } case 7: { m_SelectedAction = EROSION; m_Controls->tlParam1->setEnabled(true); m_Controls->sbParam1->setEnabled(true); text1 = "&Radius:"; m_Controls->sbParam1->setMinimum( 0 ); m_Controls->sbParam1->setMaximum( 200 ); m_Controls->sbParam1->setValue( 3 ); break; } case 8: { m_SelectedAction = OPENING; m_Controls->tlParam1->setEnabled(true); m_Controls->sbParam1->setEnabled(true); text1 = "&Radius:"; m_Controls->sbParam1->setMinimum( 0 ); m_Controls->sbParam1->setMaximum( 200 ); m_Controls->sbParam1->setValue( 3 ); break; } case 9: { m_SelectedAction = CLOSING; m_Controls->tlParam1->setEnabled(true); m_Controls->sbParam1->setEnabled(true); text1 = "&Radius:"; m_Controls->sbParam1->setMinimum( 0 ); m_Controls->sbParam1->setMaximum( 200 ); m_Controls->sbParam1->setValue( 3 ); break; } case 11: { m_SelectedAction = GRADIENT; m_Controls->tlParam1->setEnabled(true); m_Controls->sbParam1->setEnabled(true); text1 = "Sigma of Gaussian Kernel:\n(in Image Spacing Units)"; m_Controls->sbParam1->setMinimum( 0 ); m_Controls->sbParam1->setMaximum( 200 ); m_Controls->sbParam1->setValue( 2 ); break; } case 12: { m_SelectedAction = LAPLACIAN; break; } case 13: { m_SelectedAction = SOBEL; break; } case 15: { m_SelectedAction = THRESHOLD; m_Controls->tlParam1->setEnabled(true); m_Controls->sbParam1->setEnabled(true); m_Controls->tlParam2->setEnabled(true); m_Controls->sbParam2->setEnabled(true); text1 = "Lower threshold:"; text2 = "Upper threshold:"; m_Controls->sbParam1->setMinimum( -100000 ); m_Controls->sbParam1->setMaximum( 100000 ); m_Controls->sbParam1->setValue( 0 ); m_Controls->sbParam2->setMinimum( -100000 ); m_Controls->sbParam2->setMaximum( 100000 ); m_Controls->sbParam2->setValue( 300 ); break; } case 16: { m_SelectedAction = INVERSION; break; } case 17: { m_SelectedAction = DOWNSAMPLING; m_Controls->tlParam1->setEnabled(true); m_Controls->sbParam1->setEnabled(true); text1 = "Downsampling by Factor:"; m_Controls->sbParam1->setMinimum( 1 ); m_Controls->sbParam1->setMaximum( 100 ); m_Controls->sbParam1->setValue( 2 ); break; } case 18: { m_SelectedAction = FLIPPING; m_Controls->tlParam1->setEnabled(true); m_Controls->sbParam1->setEnabled(true); text1 = "Flip across axis:"; m_Controls->sbParam1->setMinimum( 0 ); m_Controls->sbParam1->setMaximum( 2 ); m_Controls->sbParam1->setValue( 1 ); break; } case 19: { m_SelectedAction = RESAMPLING; m_Controls->tlParam1->setEnabled(true); m_Controls->sbParam1->setEnabled(false); m_Controls->sbParam1->hide(); m_Controls->dsbParam1->show(); m_Controls->dsbParam1->setEnabled(true); m_Controls->tlParam2->setEnabled(true); m_Controls->sbParam2->setEnabled(false); m_Controls->sbParam2->hide(); m_Controls->dsbParam2->show(); m_Controls->dsbParam2->setEnabled(true); m_Controls->tlParam3->show(); m_Controls->tlParam3->setEnabled(true); m_Controls->dsbParam3->show(); m_Controls->dsbParam3->setEnabled(true); m_Controls->tlParam4->show(); m_Controls->tlParam4->setEnabled(true); m_Controls->cbParam4->show(); m_Controls->cbParam4->setEnabled(true); m_Controls->dsbParam1->setMinimum(0.01); m_Controls->dsbParam1->setMaximum(10.0); m_Controls->dsbParam1->setSingleStep(0.1); m_Controls->dsbParam1->setValue(0.3); m_Controls->dsbParam2->setMinimum(0.01); m_Controls->dsbParam2->setMaximum(10.0); m_Controls->dsbParam2->setSingleStep(0.1); m_Controls->dsbParam2->setValue(0.3); m_Controls->dsbParam3->setMinimum(0.01); m_Controls->dsbParam3->setMaximum(10.0); m_Controls->dsbParam3->setSingleStep(0.1); m_Controls->dsbParam3->setValue(1.5); text1 = "x-spacing:"; text2 = "y-spacing:"; text3 = "z-spacing:"; text4 = "Interplation:"; break; } case 20: { m_SelectedAction = RESCALE; m_Controls->dsbParam1->show(); m_Controls->tlParam1->show(); m_Controls->dsbParam1->setEnabled(true); m_Controls->tlParam1->setEnabled(true); m_Controls->dsbParam2->show(); m_Controls->tlParam2->show(); m_Controls->dsbParam2->setEnabled(true); m_Controls->tlParam2->setEnabled(true); text1 = "Output minimum:"; text2 = "Output maximum:"; break; } default: return; } m_Controls->tlParam->setEnabled(true); m_Controls->tlParam1->setText(text1); m_Controls->tlParam2->setText(text2); m_Controls->tlParam3->setText(text3); m_Controls->tlParam4->setText(text4); m_Controls->btnDoIt->setEnabled(true); m_Controls->cbHideOrig->setEnabled(true); } void QmitkBasicImageProcessing::StartButtonClicked() { if(!m_SelectedImageNode->GetNode()) return; this->BusyCursorOn(); mitk::Image::Pointer newImage; try { newImage = dynamic_cast(m_SelectedImageNode->GetNode()->GetData()); } catch ( std::exception &e ) { QString exceptionString = "An error occured during image loading:\n"; exceptionString.append( e.what() ); QMessageBox::warning( NULL, "Basic Image Processing", exceptionString , QMessageBox::Ok, QMessageBox::NoButton ); this->BusyCursorOff(); return; } // check if input image is valid, casting does not throw exception when casting from 'NULL-Object' if ( (! newImage) || (newImage->IsInitialized() == false) ) { this->BusyCursorOff(); QMessageBox::warning( NULL, "Basic Image Processing", "Input image is broken or not initialized. Returning.", QMessageBox::Ok, QMessageBox::NoButton ); return; } // check if operation is done on 4D a image time step if(newImage->GetDimension() > 3) { mitk::ImageTimeSelector::Pointer timeSelector = mitk::ImageTimeSelector::New(); timeSelector->SetInput(newImage); timeSelector->SetTimeNr( ((QmitkSliderNavigatorWidget*)m_Controls->sliceNavigatorTime)->GetPos() ); timeSelector->Update(); newImage = timeSelector->GetOutput(); } // check if image or vector image ImageType::Pointer itkImage = ImageType::New(); VectorImageType::Pointer itkVecImage = VectorImageType::New(); int isVectorImage = newImage->GetPixelType().GetNumberOfComponents(); if(isVectorImage > 1) { CastToItkImage( newImage, itkVecImage ); } else { CastToItkImage( newImage, itkImage ); } std::stringstream nameAddition(""); int param1 = m_Controls->sbParam1->value(); int param2 = m_Controls->sbParam2->value(); double dparam1 = m_Controls->dsbParam1->value(); double dparam2 = m_Controls->dsbParam2->value(); double dparam3 = m_Controls->dsbParam3->value(); try{ switch (m_SelectedAction) { case GAUSSIAN: { GaussianFilterType::Pointer gaussianFilter = GaussianFilterType::New(); gaussianFilter->SetInput( itkImage ); gaussianFilter->SetVariance( param1 ); gaussianFilter->UpdateLargestPossibleRegion(); newImage = mitk::ImportItkImage(gaussianFilter->GetOutput())->Clone(); nameAddition << "_Gaussian_var_" << param1; std::cout << "Gaussian filtering successful." << std::endl; break; } case MEDIAN: { MedianFilterType::Pointer medianFilter = MedianFilterType::New(); MedianFilterType::InputSizeType size; size.Fill(param1); medianFilter->SetRadius( size ); medianFilter->SetInput(itkImage); medianFilter->UpdateLargestPossibleRegion(); newImage = mitk::ImportItkImage(medianFilter->GetOutput())->Clone(); nameAddition << "_Median_radius_" << param1; std::cout << "Median Filtering successful." << std::endl; break; } case TOTALVARIATION: { if(isVectorImage > 1) { VectorTotalVariationFilterType::Pointer TVFilter = VectorTotalVariationFilterType::New(); TVFilter->SetInput( itkVecImage.GetPointer() ); TVFilter->SetNumberIterations(param1); TVFilter->SetLambda(double(param2)/1000.); TVFilter->UpdateLargestPossibleRegion(); newImage = mitk::ImportItkImage(TVFilter->GetOutput())->Clone(); } else { ImagePTypeToFloatPTypeCasterType::Pointer floatCaster = ImagePTypeToFloatPTypeCasterType::New(); floatCaster->SetInput( itkImage ); floatCaster->Update(); FloatImageType::Pointer fImage = floatCaster->GetOutput(); TotalVariationFilterType::Pointer TVFilter = TotalVariationFilterType::New(); TVFilter->SetInput( fImage.GetPointer() ); TVFilter->SetNumberIterations(param1); TVFilter->SetLambda(double(param2)/1000.); TVFilter->UpdateLargestPossibleRegion(); newImage = mitk::ImportItkImage(TVFilter->GetOutput())->Clone(); } nameAddition << "_TV_Iter_" << param1 << "_L_" << param2; std::cout << "Total Variation Filtering successful." << std::endl; break; } case DILATION: { BallType binaryBall; binaryBall.SetRadius( param1 ); binaryBall.CreateStructuringElement(); DilationFilterType::Pointer dilationFilter = DilationFilterType::New(); dilationFilter->SetInput( itkImage ); dilationFilter->SetKernel( binaryBall ); dilationFilter->UpdateLargestPossibleRegion(); newImage = mitk::ImportItkImage(dilationFilter->GetOutput())->Clone(); nameAddition << "_Dilated_by_" << param1; std::cout << "Dilation successful." << std::endl; break; } case EROSION: { BallType binaryBall; binaryBall.SetRadius( param1 ); binaryBall.CreateStructuringElement(); ErosionFilterType::Pointer erosionFilter = ErosionFilterType::New(); erosionFilter->SetInput( itkImage ); erosionFilter->SetKernel( binaryBall ); erosionFilter->UpdateLargestPossibleRegion(); newImage = mitk::ImportItkImage(erosionFilter->GetOutput())->Clone(); nameAddition << "_Eroded_by_" << param1; std::cout << "Erosion successful." << std::endl; break; } case OPENING: { BallType binaryBall; binaryBall.SetRadius( param1 ); binaryBall.CreateStructuringElement(); OpeningFilterType::Pointer openFilter = OpeningFilterType::New(); openFilter->SetInput( itkImage ); openFilter->SetKernel( binaryBall ); openFilter->UpdateLargestPossibleRegion(); newImage = mitk::ImportItkImage(openFilter->GetOutput())->Clone(); nameAddition << "_Opened_by_" << param1; std::cout << "Opening successful." << std::endl; break; } case CLOSING: { BallType binaryBall; binaryBall.SetRadius( param1 ); binaryBall.CreateStructuringElement(); ClosingFilterType::Pointer closeFilter = ClosingFilterType::New(); closeFilter->SetInput( itkImage ); closeFilter->SetKernel( binaryBall ); closeFilter->UpdateLargestPossibleRegion(); newImage = mitk::ImportItkImage(closeFilter->GetOutput())->Clone(); nameAddition << "_Closed_by_" << param1; std::cout << "Closing successful." << std::endl; break; } case GRADIENT: { GradientFilterType::Pointer gradientFilter = GradientFilterType::New(); gradientFilter->SetInput( itkImage ); gradientFilter->SetSigma( param1 ); gradientFilter->UpdateLargestPossibleRegion(); newImage = mitk::ImportItkImage(gradientFilter->GetOutput())->Clone(); nameAddition << "_Gradient_sigma_" << param1; std::cout << "Gradient calculation successful." << std::endl; break; } case LAPLACIAN: { // the laplace filter requires a float type image as input, we need to cast the itkImage // to correct type ImagePTypeToFloatPTypeCasterType::Pointer caster = ImagePTypeToFloatPTypeCasterType::New(); caster->SetInput( itkImage ); caster->Update(); FloatImageType::Pointer fImage = caster->GetOutput(); LaplacianFilterType::Pointer laplacianFilter = LaplacianFilterType::New(); laplacianFilter->SetInput( fImage ); laplacianFilter->UpdateLargestPossibleRegion(); newImage = mitk::ImportItkImage(laplacianFilter->GetOutput())->Clone(); nameAddition << "_Second_Derivative"; std::cout << "Laplacian filtering successful." << std::endl; break; } case SOBEL: { // the sobel filter requires a float type image as input, we need to cast the itkImage // to correct type ImagePTypeToFloatPTypeCasterType::Pointer caster = ImagePTypeToFloatPTypeCasterType::New(); caster->SetInput( itkImage ); caster->Update(); FloatImageType::Pointer fImage = caster->GetOutput(); SobelFilterType::Pointer sobelFilter = SobelFilterType::New(); sobelFilter->SetInput( fImage ); sobelFilter->UpdateLargestPossibleRegion(); newImage = mitk::ImportItkImage(sobelFilter->GetOutput())->Clone(); nameAddition << "_Sobel"; std::cout << "Edge Detection successful." << std::endl; break; } case THRESHOLD: { ThresholdFilterType::Pointer thFilter = ThresholdFilterType::New(); thFilter->SetLowerThreshold(param1 < param2 ? param1 : param2); thFilter->SetUpperThreshold(param2 > param1 ? param2 : param1); thFilter->SetInsideValue(1); thFilter->SetOutsideValue(0); thFilter->SetInput(itkImage); thFilter->UpdateLargestPossibleRegion(); newImage = mitk::ImportItkImage(thFilter->GetOutput())->Clone(); nameAddition << "_Threshold"; std::cout << "Thresholding successful." << std::endl; break; } case INVERSION: { InversionFilterType::Pointer invFilter = InversionFilterType::New(); mitk::ScalarType min = newImage->GetScalarValueMin(); mitk::ScalarType max = newImage->GetScalarValueMax(); invFilter->SetMaximum( max + min ); invFilter->SetInput(itkImage); invFilter->UpdateLargestPossibleRegion(); newImage = mitk::ImportItkImage(invFilter->GetOutput())->Clone(); nameAddition << "_Inverted"; std::cout << "Image inversion successful." << std::endl; break; } case DOWNSAMPLING: { ResampleImageFilterType::Pointer downsampler = ResampleImageFilterType::New(); downsampler->SetInput( itkImage ); NearestInterpolatorType::Pointer interpolator = NearestInterpolatorType::New(); downsampler->SetInterpolator( interpolator ); downsampler->SetDefaultPixelValue( 0 ); ResampleImageFilterType::SpacingType spacing = itkImage->GetSpacing(); spacing *= (double) param1; downsampler->SetOutputSpacing( spacing ); downsampler->SetOutputOrigin( itkImage->GetOrigin() ); downsampler->SetOutputDirection( itkImage->GetDirection() ); ResampleImageFilterType::SizeType size = itkImage->GetLargestPossibleRegion().GetSize(); for ( int i = 0; i < 3; ++i ) { size[i] /= param1; } downsampler->SetSize( size ); downsampler->UpdateLargestPossibleRegion(); newImage = mitk::ImportItkImage(downsampler->GetOutput())->Clone(); nameAddition << "_Downsampled_by_" << param1; std::cout << "Downsampling successful." << std::endl; break; } case FLIPPING: { FlipImageFilterType::Pointer flipper = FlipImageFilterType::New(); flipper->SetInput( itkImage ); itk::FixedArray flipAxes; for(int i=0; i<3; ++i) { if(i == param1) { flipAxes[i] = true; } else { flipAxes[i] = false; } } flipper->SetFlipAxes(flipAxes); flipper->UpdateLargestPossibleRegion(); newImage = mitk::ImportItkImage(flipper->GetOutput())->Clone(); std::cout << "Image flipping successful." << std::endl; break; } case RESAMPLING: { std::string selectedInterpolator; ResampleImageFilterType::Pointer resampler = ResampleImageFilterType::New(); switch (m_SelectedInterpolation) { case LINEAR: { LinearInterpolatorType::Pointer interpolator = LinearInterpolatorType::New(); resampler->SetInterpolator(interpolator); selectedInterpolator = "Linear"; break; } case NEAREST: { NearestInterpolatorType::Pointer interpolator = NearestInterpolatorType::New(); resampler->SetInterpolator(interpolator); selectedInterpolator = "Nearest"; break; } default: { LinearInterpolatorType::Pointer interpolator = LinearInterpolatorType::New(); resampler->SetInterpolator(interpolator); selectedInterpolator = "Linear"; break; } } resampler->SetInput( itkImage ); resampler->SetOutputOrigin( itkImage->GetOrigin() ); ImageType::SizeType input_size = itkImage->GetLargestPossibleRegion().GetSize(); ImageType::SpacingType input_spacing = itkImage->GetSpacing(); ImageType::SizeType output_size; ImageType::SpacingType output_spacing; output_size[0] = input_size[0] * (input_spacing[0] / dparam1); output_size[1] = input_size[1] * (input_spacing[1] / dparam2); output_size[2] = input_size[2] * (input_spacing[2] / dparam3); output_spacing [0] = dparam1; output_spacing [1] = dparam2; output_spacing [2] = dparam3; resampler->SetSize( output_size ); resampler->SetOutputSpacing( output_spacing ); resampler->SetOutputDirection( itkImage->GetDirection() ); resampler->UpdateLargestPossibleRegion(); ImageType::Pointer resampledImage = resampler->GetOutput(); newImage = mitk::ImportItkImage( resampledImage ); nameAddition << "_Resampled_" << selectedInterpolator; std::cout << "Resampling successful." << std::endl; break; } case RESCALE: { FloatImageType::Pointer floatImage = FloatImageType::New(); CastToItkImage( newImage, floatImage ); itk::RescaleIntensityImageFilter::Pointer filter = itk::RescaleIntensityImageFilter::New(); filter->SetInput(0, floatImage); filter->SetOutputMinimum(dparam1); filter->SetOutputMaximum(dparam2); filter->Update(); floatImage = filter->GetOutput(); newImage = mitk::Image::New(); newImage->InitializeByItk(floatImage.GetPointer()); newImage->SetVolume(floatImage->GetBufferPointer()); nameAddition << "_Rescaled"; std::cout << "Rescaling successful." << std::endl; break; } default: this->BusyCursorOff(); return; } } catch (...) { this->BusyCursorOff(); QMessageBox::warning(NULL, "Warning", "Problem when applying filter operation. Check your input..."); return; } newImage->DisconnectPipeline(); // adjust level/window to new image mitk::LevelWindow levelwindow; levelwindow.SetAuto( newImage ); mitk::LevelWindowProperty::Pointer levWinProp = mitk::LevelWindowProperty::New(); levWinProp->SetLevelWindow( levelwindow ); // compose new image name std::string name = m_SelectedImageNode->GetNode()->GetName(); if (name.find(".pic.gz") == name.size() -7 ) { name = name.substr(0,name.size() -7); } name.append( nameAddition.str() ); // create final result MITK data storage node mitk::DataNode::Pointer result = mitk::DataNode::New(); result->SetProperty( "levelwindow", levWinProp ); result->SetProperty( "name", mitk::StringProperty::New( name.c_str() ) ); result->SetData( newImage ); // for vector images, a different mapper is needed if(isVectorImage > 1) { mitk::VectorImageMapper2D::Pointer mapper = mitk::VectorImageMapper2D::New(); result->SetMapper(1,mapper); } // reset GUI to ease further processing // this->ResetOneImageOpPanel(); // add new image to data storage and set as active to ease further processing GetDefaultDataStorage()->Add( result, m_SelectedImageNode->GetNode() ); if ( m_Controls->cbHideOrig->isChecked() == true ) m_SelectedImageNode->GetNode()->SetProperty( "visible", mitk::BoolProperty::New(false) ); // TODO!! m_Controls->m_ImageSelector1->SetSelectedNode(result); // show the results mitk::RenderingManager::GetInstance()->RequestUpdateAll(); this->BusyCursorOff(); } void QmitkBasicImageProcessing::SelectAction2(int operation) { // check which operation the user has selected and set parameters and GUI accordingly switch (operation) { case 2: m_SelectedOperation = ADD; break; case 3: m_SelectedOperation = SUBTRACT; break; case 4: m_SelectedOperation = MULTIPLY; break; case 5: m_SelectedOperation = DIVIDE; break; case 6: m_SelectedOperation = RESAMPLE_TO; break; case 8: m_SelectedOperation = AND; break; case 9: m_SelectedOperation = OR; break; case 10: m_SelectedOperation = XOR; break; default: // this->ResetTwoImageOpPanel(); return; } m_Controls->tlImage2->setEnabled(true); m_Controls->m_ImageSelector2->setEnabled(true); m_Controls->btnDoIt2->setEnabled(true); } void QmitkBasicImageProcessing::StartButton2Clicked() { mitk::Image::Pointer newImage1 = dynamic_cast (m_SelectedImageNode->GetNode()->GetData()); mitk::Image::Pointer newImage2 = dynamic_cast (m_Controls->m_ImageSelector2->GetSelectedNode()->GetData()); // check if images are valid if( (!newImage1) || (!newImage2) || (newImage1->IsInitialized() == false) || (newImage2->IsInitialized() == false) ) { itkGenericExceptionMacro(<< "At least one of the input images are broken or not initialized. Returning"); return; } this->BusyCursorOn(); // this->ResetTwoImageOpPanel(); // check if 4D image and use filter on correct time step int time = ((QmitkSliderNavigatorWidget*)m_Controls->sliceNavigatorTime)->GetPos(); if(newImage1->GetDimension() > 3) { mitk::ImageTimeSelector::Pointer timeSelector = mitk::ImageTimeSelector::New(); timeSelector->SetInput(newImage1); timeSelector->SetTimeNr( time ); timeSelector->UpdateLargestPossibleRegion(); newImage1 = timeSelector->GetOutput(); newImage1->DisconnectPipeline(); timeSelector->SetInput(newImage2); timeSelector->SetTimeNr( time ); timeSelector->UpdateLargestPossibleRegion(); newImage2 = timeSelector->GetOutput(); newImage2->DisconnectPipeline(); } // reset GUI for better usability // this->ResetTwoImageOpPanel(); ImageType::Pointer itkImage1 = ImageType::New(); ImageType::Pointer itkImage2 = ImageType::New(); CastToItkImage( newImage1, itkImage1 ); CastToItkImage( newImage2, itkImage2 ); // Remove temp image newImage2 = NULL; std::string nameAddition = ""; try { switch (m_SelectedOperation) { case ADD: { AddFilterType::Pointer addFilter = AddFilterType::New(); addFilter->SetInput1( itkImage1 ); addFilter->SetInput2( itkImage2 ); addFilter->UpdateLargestPossibleRegion(); newImage1 = mitk::ImportItkImage(addFilter->GetOutput())->Clone(); nameAddition = "_Added"; } break; case SUBTRACT: { SubtractFilterType::Pointer subFilter = SubtractFilterType::New(); subFilter->SetInput1( itkImage1 ); subFilter->SetInput2( itkImage2 ); subFilter->UpdateLargestPossibleRegion(); newImage1 = mitk::ImportItkImage(subFilter->GetOutput())->Clone(); nameAddition = "_Subtracted"; } break; case MULTIPLY: { MultiplyFilterType::Pointer multFilter = MultiplyFilterType::New(); multFilter->SetInput1( itkImage1 ); multFilter->SetInput2( itkImage2 ); multFilter->UpdateLargestPossibleRegion(); newImage1 = mitk::ImportItkImage(multFilter->GetOutput())->Clone(); nameAddition = "_Multiplied"; } break; case DIVIDE: { DivideFilterType::Pointer divFilter = DivideFilterType::New(); divFilter->SetInput1( itkImage1 ); divFilter->SetInput2( itkImage2 ); divFilter->UpdateLargestPossibleRegion(); newImage1 = mitk::ImportItkImage(divFilter->GetOutput())->Clone(); nameAddition = "_Divided"; } break; case AND: { AndImageFilterType::Pointer andFilter = AndImageFilterType::New(); andFilter->SetInput1( itkImage1 ); andFilter->SetInput2( itkImage2 ); andFilter->UpdateLargestPossibleRegion(); newImage1 = mitk::ImportItkImage(andFilter->GetOutput())->Clone(); nameAddition = "_AND"; break; } case OR: { OrImageFilterType::Pointer orFilter = OrImageFilterType::New(); orFilter->SetInput1( itkImage1 ); orFilter->SetInput2( itkImage2 ); orFilter->UpdateLargestPossibleRegion(); newImage1 = mitk::ImportItkImage(orFilter->GetOutput())->Clone(); nameAddition = "_OR"; break; } case XOR: { XorImageFilterType::Pointer xorFilter = XorImageFilterType::New(); xorFilter->SetInput1( itkImage1 ); xorFilter->SetInput2( itkImage2 ); xorFilter->UpdateLargestPossibleRegion(); newImage1 = mitk::ImportItkImage(xorFilter->GetOutput())->Clone(); nameAddition = "_XOR"; break; } case RESAMPLE_TO: { itk::NearestNeighborInterpolateImageFunction::Pointer nn_interpolator = itk::NearestNeighborInterpolateImageFunction::New(); ResampleImageFilterType2::Pointer resampleFilter = ResampleImageFilterType2::New(); resampleFilter->SetInput( itkImage1 ); resampleFilter->SetReferenceImage( itkImage2 ); resampleFilter->SetUseReferenceImage( true ); resampleFilter->SetInterpolator( nn_interpolator ); resampleFilter->SetDefaultPixelValue( 0 ); try { resampleFilter->UpdateLargestPossibleRegion(); } catch( const itk::ExceptionObject &e) { MITK_WARN << "Updating resampling filter failed. "; MITK_WARN << "REASON: " << e.what(); } ImageType::Pointer resampledImage = resampleFilter->GetOutput(); newImage1 = mitk::ImportItkImage( resampledImage )->Clone(); nameAddition = "_Resampled"; break; } default: std::cout << "Something went wrong..." << std::endl; this->BusyCursorOff(); return; } } catch (const itk::ExceptionObject& e ) { this->BusyCursorOff(); QMessageBox::warning(NULL, "ITK Exception", e.what() ); QMessageBox::warning(NULL, "Warning", "Problem when applying arithmetic operation to two images. Check dimensions of input images."); return; } // disconnect pipeline; images will not be reused newImage1->DisconnectPipeline(); itkImage1 = NULL; itkImage2 = NULL; // adjust level/window to new image and compose new image name mitk::LevelWindow levelwindow; levelwindow.SetAuto( newImage1 ); mitk::LevelWindowProperty::Pointer levWinProp = mitk::LevelWindowProperty::New(); levWinProp->SetLevelWindow( levelwindow ); std::string name = m_SelectedImageNode->GetNode()->GetName(); if (name.find(".pic.gz") == name.size() -7 ) { name = name.substr(0,name.size() -7); } // create final result MITK data storage node mitk::DataNode::Pointer result = mitk::DataNode::New(); result->SetProperty( "levelwindow", levWinProp ); result->SetProperty( "name", mitk::StringProperty::New( (name + nameAddition ).c_str() )); result->SetData( newImage1 ); GetDefaultDataStorage()->Add( result, m_SelectedImageNode->GetNode() ); // show only the newly created image m_SelectedImageNode->GetNode()->SetProperty( "visible", mitk::BoolProperty::New(false) ); m_Controls->m_ImageSelector2->GetSelectedNode()->SetProperty( "visible", mitk::BoolProperty::New(false) ); // show the newly created image mitk::RenderingManager::GetInstance()->RequestUpdateAll(); this->BusyCursorOff(); } void QmitkBasicImageProcessing::SelectInterpolator(int interpolator) { switch (interpolator) { case 0: { m_SelectedInterpolation = LINEAR; break; } case 1: { m_SelectedInterpolation = NEAREST; break; } } } diff --git a/Plugins/org.mitk.gui.qt.basicimageprocessing/src/internal/mitkBasicImageProcessingActivator.cpp b/Plugins/org.mitk.gui.qt.basicimageprocessing/src/internal/mitkBasicImageProcessingActivator.cpp index be704411ad..7683d4082e 100644 --- a/Plugins/org.mitk.gui.qt.basicimageprocessing/src/internal/mitkBasicImageProcessingActivator.cpp +++ b/Plugins/org.mitk.gui.qt.basicimageprocessing/src/internal/mitkBasicImageProcessingActivator.cpp @@ -1,35 +1,37 @@ /*=================================================================== 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 "mitkBasicImageProcessingActivator.h" #include "QmitkBasicImageProcessingView.h" #include namespace mitk { void BasicImageProcessingActivator::start(ctkPluginContext* context) { BERRY_REGISTER_EXTENSION_CLASS(QmitkBasicImageProcessing, context) } void BasicImageProcessingActivator::stop(ctkPluginContext* context) { Q_UNUSED(context) } } -Q_EXPORT_PLUGIN2(org_mitk_gui_qt_basicimageprocessing, mitk::BasicImageProcessingActivator) +#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) + Q_EXPORT_PLUGIN2(org_mitk_gui_qt_basicimageprocessing, mitk::BasicImageProcessingActivator) +#endif diff --git a/Plugins/org.mitk.gui.qt.basicimageprocessing/src/internal/mitkBasicImageProcessingActivator.h b/Plugins/org.mitk.gui.qt.basicimageprocessing/src/internal/mitkBasicImageProcessingActivator.h index 062920d5ca..45c6f516f7 100644 --- a/Plugins/org.mitk.gui.qt.basicimageprocessing/src/internal/mitkBasicImageProcessingActivator.h +++ b/Plugins/org.mitk.gui.qt.basicimageprocessing/src/internal/mitkBasicImageProcessingActivator.h @@ -1,39 +1,42 @@ /*=================================================================== 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 MITKBASICIMAGEPROCESSINGACTIVATOR_H #define MITKBASICIMAGEPROCESSINGACTIVATOR_H #include #include namespace mitk { class MITK_LOCAL BasicImageProcessingActivator : public QObject, public ctkPluginActivator { Q_OBJECT +#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) + Q_PLUGIN_METADATA(IID "org_mitk_gui_qt_basicimageprocessing") +#endif Q_INTERFACES(ctkPluginActivator) public: void start(ctkPluginContext* context); void stop(ctkPluginContext* context); }; // basicImageProcessingActivator } #endif // MITKBASICIMAGEPROCESSINGACTIVATOR_H diff --git a/Plugins/org.mitk.gui.qt.cmdlinemodules/CMakeLists.txt b/Plugins/org.mitk.gui.qt.cmdlinemodules/CMakeLists.txt index 7983a10989..55809c14af 100644 --- a/Plugins/org.mitk.gui.qt.cmdlinemodules/CMakeLists.txt +++ b/Plugins/org.mitk.gui.qt.cmdlinemodules/CMakeLists.txt @@ -1,8 +1,8 @@ project(org_mitk_gui_qt_cmdlinemodules) MACRO_CREATE_MITK_CTK_PLUGIN( EXPORT_DIRECTIVE CLI_EXPORT EXPORTED_INCLUDE_SUFFIXES src MODULE_DEPENDS MitkQtWidgetsExt - PACKAGE_DEPENDS CTK Qt4|QtUiTools + PACKAGE_DEPENDS CTK|CTKCommandLineModulesFrontendQtGui+CTKCommandLineModulesBackendLocalProcess Qt4|QtUiTools Qt5|UiTools+XmlPatterns ) diff --git a/Plugins/org.mitk.gui.qt.cmdlinemodules/src/internal/org_mitk_gui_qt_cmdlinemodules_Activator.cpp b/Plugins/org.mitk.gui.qt.cmdlinemodules/src/internal/org_mitk_gui_qt_cmdlinemodules_Activator.cpp index 82cca91141..6ea064a91b 100644 --- a/Plugins/org.mitk.gui.qt.cmdlinemodules/src/internal/org_mitk_gui_qt_cmdlinemodules_Activator.cpp +++ b/Plugins/org.mitk.gui.qt.cmdlinemodules/src/internal/org_mitk_gui_qt_cmdlinemodules_Activator.cpp @@ -1,39 +1,41 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) University College London (UCL). All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "org_mitk_gui_qt_cmdlinemodules_Activator.h" #include #include "CommandLineModulesView.h" #include "CommandLineModulesPreferencesPage.h" namespace mitk { void org_mitk_gui_qt_cmdlinemodules_Activator::start(ctkPluginContext* context) { BERRY_REGISTER_EXTENSION_CLASS(CommandLineModulesView, context) BERRY_REGISTER_EXTENSION_CLASS(CommandLineModulesPreferencesPage, context) } void org_mitk_gui_qt_cmdlinemodules_Activator::stop(ctkPluginContext* context) { Q_UNUSED(context) } } -Q_EXPORT_PLUGIN2(org_mitk_gui_qt_cmdlinemodules, mitk::org_mitk_gui_qt_cmdlinemodules_Activator) +#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) + Q_EXPORT_PLUGIN2(org_mitk_gui_qt_cmdlinemodules, mitk::org_mitk_gui_qt_cmdlinemodules_Activator) +#endif diff --git a/Plugins/org.mitk.gui.qt.cmdlinemodules/src/internal/org_mitk_gui_qt_cmdlinemodules_Activator.h b/Plugins/org.mitk.gui.qt.cmdlinemodules/src/internal/org_mitk_gui_qt_cmdlinemodules_Activator.h index fc5db1913c..cc926ecf91 100644 --- a/Plugins/org.mitk.gui.qt.cmdlinemodules/src/internal/org_mitk_gui_qt_cmdlinemodules_Activator.h +++ b/Plugins/org.mitk.gui.qt.cmdlinemodules/src/internal/org_mitk_gui_qt_cmdlinemodules_Activator.h @@ -1,45 +1,48 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) University College London (UCL). 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 org_mitk_gui_qt_cmdlinemodules_Activator_h #define org_mitk_gui_qt_cmdlinemodules_Activator_h #include namespace mitk { /** * \class org_mitk_gui_qt_cmdlinemodules_Activator * \brief Blueberry plugin activator for CommandLineModulesView. * \author Matt Clarkson (m.clarkson@ucl.ac.uk) * \ingroup org_mitk_gui_qt_cmdlinemodules_internal */ class org_mitk_gui_qt_cmdlinemodules_Activator : public QObject, public ctkPluginActivator { Q_OBJECT +#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) + Q_PLUGIN_METADATA(IID "org_mitk_gui_qt_cmdlinemodules") +#endif Q_INTERFACES(ctkPluginActivator) public: void start(ctkPluginContext* context); void stop(ctkPluginContext* context); }; // org_mitk_gui_qt_cmdlinemodules_Activator } #endif // org_mitk_gui_qt_cmdlinemodules_Activator_h diff --git a/Plugins/org.mitk.gui.qt.common.legacy/src/internal/QmitkCommonLegacyActivator.cpp b/Plugins/org.mitk.gui.qt.common.legacy/src/internal/QmitkCommonLegacyActivator.cpp index bf1b683410..8253eea225 100644 --- a/Plugins/org.mitk.gui.qt.common.legacy/src/internal/QmitkCommonLegacyActivator.cpp +++ b/Plugins/org.mitk.gui.qt.common.legacy/src/internal/QmitkCommonLegacyActivator.cpp @@ -1,50 +1,52 @@ /*=================================================================== 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 "QmitkCommonLegacyActivator.h" #include #include #include void QmitkCommonLegacyActivator::start(ctkPluginContext* context) { Q_UNUSED(context) if(berry::PlatformUI::IsWorkbenchRunning()) { m_FunctionalityCoordinator = QmitkFunctionalityCoordinator::Pointer(new QmitkFunctionalityCoordinator); m_FunctionalityCoordinator->Start(); } else { MITK_ERROR << "BlueBerry Workbench not running!"; } } void QmitkCommonLegacyActivator::stop(ctkPluginContext* context) { Q_UNUSED(context) m_FunctionalityCoordinator->Stop(); m_FunctionalityCoordinator = 0; } -Q_EXPORT_PLUGIN2(org_mitk_gui_qt_common_legacy, QmitkCommonLegacyActivator) +#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) + Q_EXPORT_PLUGIN2(org_mitk_gui_qt_common_legacy, QmitkCommonLegacyActivator) +#endif diff --git a/Plugins/org.mitk.gui.qt.common.legacy/src/internal/QmitkCommonLegacyActivator.h b/Plugins/org.mitk.gui.qt.common.legacy/src/internal/QmitkCommonLegacyActivator.h index b3f8d9040a..859ec03dd1 100644 --- a/Plugins/org.mitk.gui.qt.common.legacy/src/internal/QmitkCommonLegacyActivator.h +++ b/Plugins/org.mitk.gui.qt.common.legacy/src/internal/QmitkCommonLegacyActivator.h @@ -1,48 +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 QMITKCOMMONLEGACYACTIVATOR_H_ #define QMITKCOMMONLEGACYACTIVATOR_H_ #include #include "QmitkFunctionalityCoordinator.h" /** * \ingroup org_mitk_gui_qt_common_legacy_internal */ class QmitkCommonLegacyActivator : public QObject, public ctkPluginActivator { Q_OBJECT +#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) + Q_PLUGIN_METADATA(IID "org_mitk_gui_qt_common_legacy") +#endif Q_INTERFACES(ctkPluginActivator) public: /** * Sets default StateMachine to EventMapper. */ void start(ctkPluginContext* context); void stop(ctkPluginContext* context); private: QmitkFunctionalityCoordinator::Pointer m_FunctionalityCoordinator; }; #endif /* QMITKCOMMONLEGACYACTIVATOR_H_ */ diff --git a/Plugins/org.mitk.gui.qt.common/src/QmitkDnDFrameWidget.cpp b/Plugins/org.mitk.gui.qt.common/src/QmitkDnDFrameWidget.cpp index 71b3d0f9f2..c7cb65fafd 100644 --- a/Plugins/org.mitk.gui.qt.common/src/QmitkDnDFrameWidget.cpp +++ b/Plugins/org.mitk.gui.qt.common/src/QmitkDnDFrameWidget.cpp @@ -1,90 +1,90 @@ /*=================================================================== 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 #include #include #include "internal/QmitkCommonActivator.h" #include #include - +#include class QmitkDnDFrameWidgetPrivate { public: berry::IPreferences::Pointer GetPreferences() const { berry::IPreferencesService::Pointer prefService = QmitkCommonActivator::GetInstance()->GetPreferencesService(); if (prefService.IsNotNull()) { return prefService->GetSystemPreferences()->Node("/General"); } return berry::IPreferences::Pointer(0); } bool GetOpenEditor() const { berry::IPreferences::Pointer prefs = GetPreferences(); if(prefs.IsNotNull()) { return prefs->GetBool("OpenEditor", true); } return true; } }; QmitkDnDFrameWidget::QmitkDnDFrameWidget(QWidget *parent) : QWidget(parent), d(new QmitkDnDFrameWidgetPrivate()) { setAcceptDrops(true); } QmitkDnDFrameWidget::~QmitkDnDFrameWidget() { } void QmitkDnDFrameWidget::dragEnterEvent( QDragEnterEvent *event ) { // accept drags event->acceptProposedAction(); } void QmitkDnDFrameWidget::dropEvent( QDropEvent * event ) { //open dragged files QList fileNames = event->mimeData()->urls(); if (fileNames.empty()) return; QStringList fileNames2; //TODO Qt 4.7 API //fileNames2.reserve(fileNames.size()); foreach(QUrl url, fileNames) { fileNames2.push_back(url.toLocalFile()); } mitk::WorkbenchUtil::LoadFiles(fileNames2, berry::PlatformUI::GetWorkbench()->GetActiveWorkbenchWindow(), d->GetOpenEditor()); event->accept(); } diff --git a/Plugins/org.mitk.gui.qt.common/src/internal/QmitkCommonActivator.cpp b/Plugins/org.mitk.gui.qt.common/src/internal/QmitkCommonActivator.cpp index 404d31559c..43cad98bcc 100644 --- a/Plugins/org.mitk.gui.qt.common/src/internal/QmitkCommonActivator.cpp +++ b/Plugins/org.mitk.gui.qt.common/src/internal/QmitkCommonActivator.cpp @@ -1,72 +1,74 @@ /*=================================================================== 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 "QmitkCommonActivator.h" #include #include QmitkCommonActivator* QmitkCommonActivator::m_Instance = 0; ctkPluginContext* QmitkCommonActivator::m_Context = 0; ctkPluginContext* QmitkCommonActivator::GetContext() { return m_Context; } QmitkCommonActivator* QmitkCommonActivator::GetInstance() { return m_Instance; } berry::IPreferencesService::Pointer QmitkCommonActivator::GetPreferencesService() { return berry::IPreferencesService::Pointer(m_PrefServiceTracker->getService()); } void QmitkCommonActivator::start(ctkPluginContext* context) { this->m_Instance = this; this->m_Context = context; this->m_PrefServiceTracker.reset(new ctkServiceTracker(context)); if(berry::PlatformUI::IsWorkbenchRunning()) { m_ViewCoordinator = QmitkViewCoordinator::Pointer(new QmitkViewCoordinator); m_ViewCoordinator->Start(); } else { MITK_ERROR << "BlueBerry Workbench not running!"; } } void QmitkCommonActivator::stop(ctkPluginContext* context) { Q_UNUSED(context) m_ViewCoordinator->Stop(); m_ViewCoordinator = 0; this->m_PrefServiceTracker.reset(); this->m_Context = 0; this->m_Instance = 0; } -Q_EXPORT_PLUGIN2(org_mitk_gui_qt_common, QmitkCommonActivator) +#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) + Q_EXPORT_PLUGIN2(org_mitk_gui_qt_common, QmitkCommonActivator) +#endif diff --git a/Plugins/org.mitk.gui.qt.common/src/internal/QmitkCommonActivator.h b/Plugins/org.mitk.gui.qt.common/src/internal/QmitkCommonActivator.h index a863bb1a0e..2934c38384 100644 --- a/Plugins/org.mitk.gui.qt.common/src/internal/QmitkCommonActivator.h +++ b/Plugins/org.mitk.gui.qt.common/src/internal/QmitkCommonActivator.h @@ -1,65 +1,68 @@ /*=================================================================== 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 QMITKCOMMONACTIVATOR_H_ #define QMITKCOMMONACTIVATOR_H_ #include #include #include #include "QmitkViewCoordinator.h" /** * \ingroup org_mitk_gui_qt_common_internal * * \brief The plug-in activator for the StateMachine * * When the plug-in is started by the framework, it initializes StateMachine * specific things. */ class QmitkCommonActivator : public QObject, public ctkPluginActivator { Q_OBJECT +#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) + Q_PLUGIN_METADATA(IID "org_mitk_gui_qt_common") +#endif Q_INTERFACES(ctkPluginActivator) public: static ctkPluginContext* GetContext(); static QmitkCommonActivator* GetInstance(); berry::IPreferencesService::Pointer GetPreferencesService(); /** * Sets default StateMachine to EventMapper. */ void start(ctkPluginContext* context); void stop(ctkPluginContext* context); private: static QmitkCommonActivator* m_Instance; static ctkPluginContext* m_Context; QmitkViewCoordinator::Pointer m_ViewCoordinator; QScopedPointer > m_PrefServiceTracker; }; #endif /* QMITKCOMMONACTIVATOR_H_ */ diff --git a/Plugins/org.mitk.gui.qt.coreapplication/src/internal/org_mitk_gui_qt_coreapplication_Activator.cpp b/Plugins/org.mitk.gui.qt.coreapplication/src/internal/org_mitk_gui_qt_coreapplication_Activator.cpp index 4ae0c85594..581e263b88 100644 --- a/Plugins/org.mitk.gui.qt.coreapplication/src/internal/org_mitk_gui_qt_coreapplication_Activator.cpp +++ b/Plugins/org.mitk.gui.qt.coreapplication/src/internal/org_mitk_gui_qt_coreapplication_Activator.cpp @@ -1,42 +1,42 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "org_mitk_gui_qt_coreapplication_Activator.h" #include "QmitkCoreApplication.h" #include "QmitkDefaultPerspective.h" #include namespace mitk { void org_mitk_gui_qt_coreapplication_Activator::start(ctkPluginContext* context) { BERRY_REGISTER_EXTENSION_CLASS(QmitkCoreApplication, context) BERRY_REGISTER_EXTENSION_CLASS(QmitkDefaultPerspective, context) } void org_mitk_gui_qt_coreapplication_Activator::stop(ctkPluginContext* context) { Q_UNUSED(context) } } -Q_EXPORT_PLUGIN2(org_mitk_gui_qt_coreapplication, mitk::org_mitk_gui_qt_coreapplication_Activator) - - +#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) + Q_EXPORT_PLUGIN2(org_mitk_gui_qt_coreapplication, mitk::org_mitk_gui_qt_coreapplication_Activator) +#endif diff --git a/Plugins/org.mitk.gui.qt.coreapplication/src/internal/org_mitk_gui_qt_coreapplication_Activator.h b/Plugins/org.mitk.gui.qt.coreapplication/src/internal/org_mitk_gui_qt_coreapplication_Activator.h index 9ac0220f38..0002eaf3ac 100644 --- a/Plugins/org.mitk.gui.qt.coreapplication/src/internal/org_mitk_gui_qt_coreapplication_Activator.h +++ b/Plugins/org.mitk.gui.qt.coreapplication/src/internal/org_mitk_gui_qt_coreapplication_Activator.h @@ -1,42 +1,45 @@ /*=================================================================== 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 MITKPLUGINACTIVATOR_H #define MITKPLUGINACTIVATOR_H #include namespace mitk { class org_mitk_gui_qt_coreapplication_Activator : public QObject, public ctkPluginActivator { Q_OBJECT +#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) + Q_PLUGIN_METADATA(IID "org_mitk_gui_qt_coreapplication") +#endif Q_INTERFACES(ctkPluginActivator) public: void start(ctkPluginContext* context); void stop(ctkPluginContext* context); }; // org_mitk_gui_common_Activator typedef org_mitk_gui_qt_coreapplication_Activator PluginActivator; } #endif // MITKPLUGINACTIVATOR_H diff --git a/Plugins/org.mitk.gui.qt.datamanager/src/QmitkDataManagerView.cpp b/Plugins/org.mitk.gui.qt.datamanager/src/QmitkDataManagerView.cpp index 3b30a061dc..ad37941c0a 100644 --- a/Plugins/org.mitk.gui.qt.datamanager/src/QmitkDataManagerView.cpp +++ b/Plugins/org.mitk.gui.qt.datamanager/src/QmitkDataManagerView.cpp @@ -1,1060 +1,1059 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "QmitkDataManagerView.h" #include //# Own Includes //## mitk #include "mitkDataStorageEditorInput.h" #include "mitkIDataStorageReference.h" #include "mitkNodePredicateDataType.h" #include "mitkCoreObjectFactory.h" #include "mitkDataNodeFactory.h" #include "mitkColorProperty.h" #include "mitkCommon.h" #include "mitkNodePredicateData.h" #include "mitkNodePredicateNot.h" #include "mitkNodePredicateOr.h" #include "mitkNodePredicateProperty.h" #include "mitkEnumerationProperty.h" #include "mitkLookupTableProperty.h" #include "mitkProperties.h" #include #include #include #include #include //## Qmitk #include #include #include #include #include #include #include #include "src/internal/QmitkNodeTableViewKeyFilter.h" #include "src/internal/QmitkInfoDialog.h" #include "src/internal/QmitkDataManagerItemDelegate.h" //## Berry #include #include #include #include #include #include //# Toolkit Includes #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include -#include #include #include #include #include #include #include #include #include #include #include "mitkDataNodeObject.h" #include "mitkIContextMenuAction.h" #include "berryIExtensionPointService.h" #include "mitkRenderingModeProperty.h" const std::string QmitkDataManagerView::VIEW_ID = "org.mitk.views.datamanager"; QmitkDataManagerView::QmitkDataManagerView() : m_GlobalReinitOnNodeDelete(true), m_ItemDelegate(NULL) { } QmitkDataManagerView::~QmitkDataManagerView() { //Remove all registered actions from each descriptor for (std::vector< std::pair< QmitkNodeDescriptor*, QAction* > >::iterator it = m_DescriptorActionList.begin();it != m_DescriptorActionList.end(); it++) { // first== the NodeDescriptor; second== the registered QAction (it->first)->RemoveAction(it->second); } } void QmitkDataManagerView::CreateQtPartControl(QWidget* parent) { m_CurrentRowCount = 0; m_Parent = parent; //# Preferences berry::IPreferencesService::Pointer prefService = berry::Platform::GetServiceRegistry() .GetServiceById(berry::IPreferencesService::ID); berry::IBerryPreferences::Pointer prefs = (prefService->GetSystemPreferences()->Node(VIEW_ID)) .Cast(); assert( prefs ); prefs->OnChanged.AddListener( berry::MessageDelegate1( this , &QmitkDataManagerView::OnPreferencesChanged ) ); //# GUI m_NodeTreeModel = new QmitkDataStorageTreeModel(this->GetDataStorage()); m_NodeTreeModel->setParent( parent ); m_NodeTreeModel->SetPlaceNewNodesOnTop( prefs->GetBool("Place new nodes on top", true) ); m_SurfaceDecimation = prefs->GetBool("Use surface decimation", false); // Prepare filters m_HelperObjectFilterPredicate = mitk::NodePredicateOr::New( mitk::NodePredicateProperty::New("helper object", mitk::BoolProperty::New(true)), mitk::NodePredicateProperty::New("hidden object", mitk::BoolProperty::New(true))); m_NodeWithNoDataFilterPredicate = mitk::NodePredicateData::New(0); m_FilterModel = new QmitkDataStorageFilterProxyModel(); m_FilterModel->setSourceModel(m_NodeTreeModel); m_FilterModel->AddFilterPredicate(m_HelperObjectFilterPredicate); m_FilterModel->AddFilterPredicate(m_NodeWithNoDataFilterPredicate); //# Tree View (experimental) m_NodeTreeView = new QTreeView; m_NodeTreeView->setHeaderHidden(true); m_NodeTreeView->setSelectionMode( QAbstractItemView::ExtendedSelection ); m_NodeTreeView->setSelectionBehavior( QAbstractItemView::SelectRows ); m_NodeTreeView->setAlternatingRowColors(true); m_NodeTreeView->setDragEnabled(true); m_NodeTreeView->setDropIndicatorShown(true); m_NodeTreeView->setAcceptDrops(true); m_NodeTreeView->setContextMenuPolicy(Qt::CustomContextMenu); m_NodeTreeView->setModel(m_FilterModel); m_NodeTreeView->setTextElideMode(Qt::ElideMiddle); m_NodeTreeView->installEventFilter(new QmitkNodeTableViewKeyFilter(this)); m_ItemDelegate = new QmitkDataManagerItemDelegate(m_NodeTreeView); m_NodeTreeView->setItemDelegate(m_ItemDelegate); QObject::connect( m_NodeTreeView, SIGNAL(customContextMenuRequested(const QPoint&)) , this, SLOT(NodeTableViewContextMenuRequested(const QPoint&)) ); QObject::connect( m_NodeTreeModel, SIGNAL(rowsInserted (const QModelIndex&, int, int)) , this, SLOT(NodeTreeViewRowsInserted ( const QModelIndex&, int, int )) ); QObject::connect( m_NodeTreeModel, SIGNAL(rowsRemoved (const QModelIndex&, int, int)) , this, SLOT(NodeTreeViewRowsRemoved( const QModelIndex&, int, int )) ); QObject::connect( m_NodeTreeView->selectionModel() , SIGNAL( selectionChanged ( const QItemSelection &, const QItemSelection & ) ) , this , SLOT( NodeSelectionChanged ( const QItemSelection &, const QItemSelection & ) ) ); //# m_NodeMenu m_NodeMenu = new QMenu(m_NodeTreeView); // # Actions berry::IEditorRegistry* editorRegistry = berry::PlatformUI::GetWorkbench()->GetEditorRegistry(); std::list editors = editorRegistry->GetEditors("*.mitk"); if (editors.size() > 1) { m_ShowInMapper = new QSignalMapper(this); foreach(berry::IEditorDescriptor::Pointer descriptor, editors) { QAction* action = new QAction(QString::fromStdString(descriptor->GetLabel()), this); m_ShowInActions << action; m_ShowInMapper->connect(action, SIGNAL(triggered()), m_ShowInMapper, SLOT(map())); m_ShowInMapper->setMapping(action, QString::fromStdString(descriptor->GetId())); } connect(m_ShowInMapper, SIGNAL(mapped(QString)), this, SLOT(ShowIn(QString))); } QmitkNodeDescriptor* unknownDataNodeDescriptor = QmitkNodeDescriptorManager::GetInstance()->GetUnknownDataNodeDescriptor(); QmitkNodeDescriptor* imageDataNodeDescriptor = QmitkNodeDescriptorManager::GetInstance()->GetDescriptor("Image"); QmitkNodeDescriptor* diffusionImageDataNodeDescriptor = QmitkNodeDescriptorManager::GetInstance()->GetDescriptor("DiffusionImage"); QmitkNodeDescriptor* surfaceDataNodeDescriptor = QmitkNodeDescriptorManager::GetInstance()->GetDescriptor("Surface"); QAction* globalReinitAction = new QAction(QIcon(":/org.mitk.gui.qt.datamanager/Refresh_48.png"), "Global Reinit", this); QObject::connect( globalReinitAction, SIGNAL( triggered(bool) ) , this, SLOT( GlobalReinit(bool) ) ); unknownDataNodeDescriptor->AddAction(globalReinitAction); m_DescriptorActionList.push_back(std::pair(unknownDataNodeDescriptor, globalReinitAction)); QAction* saveAction = new QmitkFileSaveAction(QIcon(":/org.mitk.gui.qt.datamanager/Save_48.png"), this->GetSite()->GetWorkbenchWindow()); unknownDataNodeDescriptor->AddAction(saveAction); m_DescriptorActionList.push_back(std::pair(unknownDataNodeDescriptor,saveAction)); QAction* removeAction = new QAction(QIcon(":/org.mitk.gui.qt.datamanager/Remove_48.png"), "Remove", this); QObject::connect( removeAction, SIGNAL( triggered(bool) ) , this, SLOT( RemoveSelectedNodes(bool) ) ); unknownDataNodeDescriptor->AddAction(removeAction); m_DescriptorActionList.push_back(std::pair(unknownDataNodeDescriptor,removeAction)); QAction* reinitAction = new QAction(QIcon(":/org.mitk.gui.qt.datamanager/Refresh_48.png"), "Reinit", this); QObject::connect( reinitAction, SIGNAL( triggered(bool) ) , this, SLOT( ReinitSelectedNodes(bool) ) ); unknownDataNodeDescriptor->AddAction(reinitAction); m_DescriptorActionList.push_back(std::pair(unknownDataNodeDescriptor,reinitAction)); // find contextMenuAction extension points and add them to the node descriptor berry::IExtensionPointService::Pointer extensionPointService = berry::Platform::GetExtensionPointService(); berry::IConfigurationElement::vector cmActions( extensionPointService->GetConfigurationElementsFor("org.mitk.gui.qt.datamanager.contextMenuActions") ); berry::IConfigurationElement::vector::iterator cmActionsIt; std::string cmNodeDescriptorName; std::string cmLabel; std::string cmIcon; std::string cmClass; QmitkNodeDescriptor* tmpDescriptor; QAction* contextMenuAction; QVariant cmActionDataIt; m_ConfElements.clear(); int i=1; for (cmActionsIt = cmActions.begin() ; cmActionsIt != cmActions.end() ; ++cmActionsIt) { cmIcon.erase(); if((*cmActionsIt)->GetAttribute("nodeDescriptorName", cmNodeDescriptorName) && (*cmActionsIt)->GetAttribute("label", cmLabel) && (*cmActionsIt)->GetAttribute("class", cmClass)) { // create context menu entry here tmpDescriptor = QmitkNodeDescriptorManager::GetInstance()->GetDescriptor(QString::fromStdString(cmNodeDescriptorName)); if(!tmpDescriptor) { MITK_WARN << "cannot add action \"" << cmLabel << "\" because descriptor " << cmNodeDescriptorName << " does not exist"; continue; } // check if the user specified an icon attribute if ( (*cmActionsIt)->GetAttribute("icon", cmIcon) ) { contextMenuAction = new QAction( QIcon( QString::fromStdString(cmIcon)), QString::fromStdString(cmLabel), parent); } else { contextMenuAction = new QAction( QString::fromStdString(cmLabel), parent); } tmpDescriptor->AddAction(contextMenuAction); m_DescriptorActionList.push_back(std::pair(tmpDescriptor,contextMenuAction)); m_ConfElements[contextMenuAction] = *cmActionsIt; cmActionDataIt.setValue(i); contextMenuAction->setData( cmActionDataIt ); connect( contextMenuAction, SIGNAL( triggered(bool) ) , this, SLOT( ContextMenuActionTriggered(bool) ) ); ++i; } } m_OpacitySlider = new QSlider; m_OpacitySlider->setMinimum(0); m_OpacitySlider->setMaximum(100); m_OpacitySlider->setOrientation(Qt::Horizontal); QObject::connect( m_OpacitySlider, SIGNAL( valueChanged(int) ) , this, SLOT( OpacityChanged(int) ) ); QLabel* _OpacityLabel = new QLabel("Opacity: "); QHBoxLayout* _OpacityWidgetLayout = new QHBoxLayout; _OpacityWidgetLayout->setContentsMargins(4,4,4,4); _OpacityWidgetLayout->addWidget(_OpacityLabel); _OpacityWidgetLayout->addWidget(m_OpacitySlider); QWidget* _OpacityWidget = new QWidget; _OpacityWidget->setLayout(_OpacityWidgetLayout); QWidgetAction* opacityAction = new QWidgetAction(this); opacityAction ->setDefaultWidget(_OpacityWidget); QObject::connect( opacityAction , SIGNAL( changed() ) , this, SLOT( OpacityActionChanged() ) ); unknownDataNodeDescriptor->AddAction(opacityAction , false); m_DescriptorActionList.push_back(std::pair(unknownDataNodeDescriptor,opacityAction)); m_ColorButton = new QPushButton; m_ColorButton->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Minimum); //m_ColorButton->setText("Change color"); QObject::connect( m_ColorButton, SIGNAL( clicked() ) , this, SLOT( ColorChanged() ) ); QLabel* _ColorLabel = new QLabel("Color: "); _ColorLabel->setSizePolicy(QSizePolicy::Minimum,QSizePolicy::Minimum); QHBoxLayout* _ColorWidgetLayout = new QHBoxLayout; _ColorWidgetLayout->setContentsMargins(4,4,4,4); _ColorWidgetLayout->addWidget(_ColorLabel); _ColorWidgetLayout->addWidget(m_ColorButton); QWidget* _ColorWidget = new QWidget; _ColorWidget->setLayout(_ColorWidgetLayout); QWidgetAction* colorAction = new QWidgetAction(this); colorAction->setDefaultWidget(_ColorWidget); QObject::connect( colorAction, SIGNAL( changed() ) , this, SLOT( ColorActionChanged() ) ); unknownDataNodeDescriptor->AddAction(colorAction, false); m_DescriptorActionList.push_back(std::pair(unknownDataNodeDescriptor,colorAction)); m_ComponentSlider = new QmitkNumberPropertySlider; m_ComponentSlider->setOrientation(Qt::Horizontal); //QObject::connect( m_OpacitySlider, SIGNAL( valueChanged(int) ) // , this, SLOT( OpacityChanged(int) ) ); QLabel* _ComponentLabel = new QLabel("Component: "); QHBoxLayout* _ComponentWidgetLayout = new QHBoxLayout; _ComponentWidgetLayout->setContentsMargins(4,4,4,4); _ComponentWidgetLayout->addWidget(_ComponentLabel); _ComponentWidgetLayout->addWidget(m_ComponentSlider); QLabel* _ComponentValueLabel = new QLabel(); _ComponentWidgetLayout->addWidget(_ComponentValueLabel); connect(m_ComponentSlider, SIGNAL(valueChanged(int)), _ComponentValueLabel, SLOT(setNum(int))); QWidget* _ComponentWidget = new QWidget; _ComponentWidget->setLayout(_ComponentWidgetLayout); QWidgetAction* componentAction = new QWidgetAction(this); componentAction->setDefaultWidget(_ComponentWidget); QObject::connect( componentAction , SIGNAL( changed() ) , this, SLOT( ComponentActionChanged() ) ); imageDataNodeDescriptor->AddAction(componentAction, false); m_DescriptorActionList.push_back(std::pair(imageDataNodeDescriptor,componentAction)); if (diffusionImageDataNodeDescriptor!=NULL) { diffusionImageDataNodeDescriptor->AddAction(componentAction, false); m_DescriptorActionList.push_back(std::pair(diffusionImageDataNodeDescriptor,componentAction)); } m_TextureInterpolation = new QAction("Texture Interpolation", this); m_TextureInterpolation->setCheckable ( true ); QObject::connect( m_TextureInterpolation, SIGNAL( changed() ) , this, SLOT( TextureInterpolationChanged() ) ); QObject::connect( m_TextureInterpolation, SIGNAL( toggled(bool) ) , this, SLOT( TextureInterpolationToggled(bool) ) ); imageDataNodeDescriptor->AddAction(m_TextureInterpolation, false); m_DescriptorActionList.push_back(std::pair(imageDataNodeDescriptor,m_TextureInterpolation)); if (diffusionImageDataNodeDescriptor!=NULL) { diffusionImageDataNodeDescriptor->AddAction(m_TextureInterpolation, false); m_DescriptorActionList.push_back(std::pair(diffusionImageDataNodeDescriptor,m_TextureInterpolation)); } m_ColormapAction = new QAction("Colormap", this); m_ColormapAction->setMenu(new QMenu); QObject::connect( m_ColormapAction->menu(), SIGNAL( aboutToShow() ) , this, SLOT( ColormapMenuAboutToShow() ) ); imageDataNodeDescriptor->AddAction(m_ColormapAction, false); m_DescriptorActionList.push_back(std::pair(imageDataNodeDescriptor, m_ColormapAction)); if (diffusionImageDataNodeDescriptor!=NULL) { diffusionImageDataNodeDescriptor->AddAction(m_ColormapAction, false); m_DescriptorActionList.push_back(std::pair(diffusionImageDataNodeDescriptor, m_ColormapAction)); } m_SurfaceRepresentation = new QAction("Surface Representation", this); m_SurfaceRepresentation->setMenu(new QMenu); QObject::connect( m_SurfaceRepresentation->menu(), SIGNAL( aboutToShow() ) , this, SLOT( SurfaceRepresentationMenuAboutToShow() ) ); surfaceDataNodeDescriptor->AddAction(m_SurfaceRepresentation, false); m_DescriptorActionList.push_back(std::pair(surfaceDataNodeDescriptor, m_SurfaceRepresentation)); QAction* showOnlySelectedNodes = new QAction(QIcon(":/org.mitk.gui.qt.datamanager/ShowSelectedNode_48.png") , "Show only selected nodes", this); QObject::connect( showOnlySelectedNodes, SIGNAL( triggered(bool) ) , this, SLOT( ShowOnlySelectedNodes(bool) ) ); unknownDataNodeDescriptor->AddAction(showOnlySelectedNodes); m_DescriptorActionList.push_back(std::pair(unknownDataNodeDescriptor, showOnlySelectedNodes)); QAction* toggleSelectedVisibility = new QAction(QIcon(":/org.mitk.gui.qt.datamanager/InvertShowSelectedNode_48.png") , "Toggle visibility", this); QObject::connect( toggleSelectedVisibility, SIGNAL( triggered(bool) ) , this, SLOT( ToggleVisibilityOfSelectedNodes(bool) ) ); unknownDataNodeDescriptor->AddAction(toggleSelectedVisibility); m_DescriptorActionList.push_back(std::pair(unknownDataNodeDescriptor,toggleSelectedVisibility)); QAction* actionShowInfoDialog = new QAction(QIcon(":/org.mitk.gui.qt.datamanager/ShowDataInfo_48.png") , "Details...", this); QObject::connect( actionShowInfoDialog, SIGNAL( triggered(bool) ) , this, SLOT( ShowInfoDialogForSelectedNodes(bool) ) ); unknownDataNodeDescriptor->AddAction(actionShowInfoDialog); m_DescriptorActionList.push_back(std::pair(unknownDataNodeDescriptor,actionShowInfoDialog)); //obsolete... //QAction* otsuFilterAction = new QAction("Apply Otsu Filter", this); //QObject::connect( otsuFilterAction, SIGNAL( triggered(bool) ) // , this, SLOT( OtsuFilter(bool) ) ); // //Otsu filter does not work properly, remove it temporarily // imageDataNodeDescriptor->AddAction(otsuFilterAction); // m_DescriptorActionList.push_back(std::pair(imageDataNodeDescriptor,otsuFilterAction)); QGridLayout* _DndFrameWidgetLayout = new QGridLayout; _DndFrameWidgetLayout->addWidget(m_NodeTreeView, 0, 0); _DndFrameWidgetLayout->setContentsMargins(0,0,0,0); m_DndFrameWidget = new QmitkDnDFrameWidget(m_Parent); m_DndFrameWidget->setLayout(_DndFrameWidgetLayout); QVBoxLayout* layout = new QVBoxLayout(parent); layout->addWidget(m_DndFrameWidget); layout->setContentsMargins(0,0,0,0); m_Parent->setLayout(layout); } void QmitkDataManagerView::SetFocus() { } void QmitkDataManagerView::ContextMenuActionTriggered( bool ) { QAction* action = qobject_cast ( sender() ); std::map::iterator it = m_ConfElements.find( action ); if( it == m_ConfElements.end() ) { MITK_WARN << "associated conf element for action " << action->text().toStdString() << " not found"; return; } berry::IConfigurationElement::Pointer confElem = it->second; mitk::IContextMenuAction* contextMenuAction = confElem->CreateExecutableExtension("class"); std::string className; std::string smoothed; confElem->GetAttribute("class", className); confElem->GetAttribute("smoothed", smoothed); if(className == "QmitkCreatePolygonModelAction") { contextMenuAction->SetDataStorage(this->GetDataStorage()); if(smoothed == "false") { contextMenuAction->SetSmoothed(false); } else { contextMenuAction->SetSmoothed(true); } contextMenuAction->SetDecimated(m_SurfaceDecimation); } else if(className == "QmitkStatisticsAction") { contextMenuAction->SetFunctionality(this); } else if(className == "QmitkCreateSimulationAction") { contextMenuAction->SetDataStorage(this->GetDataStorage()); } contextMenuAction->Run( this->GetCurrentSelection() ); // run the action } void QmitkDataManagerView::OnPreferencesChanged(const berry::IBerryPreferences* prefs) { if( m_NodeTreeModel->GetPlaceNewNodesOnTopFlag() != prefs->GetBool("Place new nodes on top", true) ) m_NodeTreeModel->SetPlaceNewNodesOnTop( !m_NodeTreeModel->GetPlaceNewNodesOnTopFlag() ); bool hideHelperObjects = !prefs->GetBool("Show helper objects", false); if (m_FilterModel->HasFilterPredicate(m_HelperObjectFilterPredicate) != hideHelperObjects) { if (hideHelperObjects) { m_FilterModel->AddFilterPredicate(m_HelperObjectFilterPredicate); } else { m_FilterModel->RemoveFilterPredicate(m_HelperObjectFilterPredicate); } } bool hideNodesWithNoData = !prefs->GetBool("Show nodes containing no data", false); if (m_FilterModel->HasFilterPredicate(m_NodeWithNoDataFilterPredicate) != hideNodesWithNoData) { if (hideNodesWithNoData) { m_FilterModel->AddFilterPredicate(m_NodeWithNoDataFilterPredicate); } else { m_FilterModel->RemoveFilterPredicate(m_NodeWithNoDataFilterPredicate); } } m_GlobalReinitOnNodeDelete = prefs->GetBool("Call global reinit if node is deleted", true); m_NodeTreeView->expandAll(); m_SurfaceDecimation = prefs->GetBool("Use surface decimation", false); this->GlobalReinit(); } void QmitkDataManagerView::NodeTableViewContextMenuRequested( const QPoint & pos ) { QModelIndex selectedProxy = m_NodeTreeView->indexAt ( pos ); QModelIndex selected = m_FilterModel->mapToSource(selectedProxy); mitk::DataNode::Pointer node = m_NodeTreeModel->GetNode(selected); QList selectedNodes = this->GetCurrentSelection(); if(!selectedNodes.isEmpty()) { m_NodeMenu->clear(); QList actions; if(selectedNodes.size() == 1 ) { actions = QmitkNodeDescriptorManager::GetInstance()->GetActions(node); for(QList::iterator it = actions.begin(); it != actions.end(); ++it) { (*it)->setData(QVariant::fromValue(node.GetPointer())); } } else actions = QmitkNodeDescriptorManager::GetInstance()->GetActions(selectedNodes); if (!m_ShowInActions.isEmpty()) { QMenu* showInMenu = m_NodeMenu->addMenu("Show In"); showInMenu->addActions(m_ShowInActions); } m_NodeMenu->addActions(actions); m_NodeMenu->popup(QCursor::pos()); } } void QmitkDataManagerView::OpacityChanged(int value) { mitk::DataNode* node = m_NodeTreeModel->GetNode(m_FilterModel->mapToSource(m_NodeTreeView->selectionModel()->currentIndex())); if(node) { float opacity = static_cast(value)/100.0f; node->SetFloatProperty("opacity", opacity); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } } void QmitkDataManagerView::OpacityActionChanged() { mitk::DataNode* node = m_NodeTreeModel->GetNode(m_FilterModel->mapToSource(m_NodeTreeView->selectionModel()->currentIndex())); if(node) { float opacity = 0.0; if(node->GetFloatProperty("opacity", opacity)) { m_OpacitySlider->setValue(static_cast(opacity*100)); } } } void QmitkDataManagerView::ComponentActionChanged() { mitk::DataNode* node = m_NodeTreeModel->GetNode(m_FilterModel->mapToSource(m_NodeTreeView->selectionModel()->currentIndex())); mitk::IntProperty* componentProperty = NULL; int numComponents = 0; if(node) { componentProperty = dynamic_cast(node->GetProperty("Image.Displayed Component")); mitk::Image* img = dynamic_cast(node->GetData()); if (img != NULL) { numComponents = img->GetPixelType().GetNumberOfComponents(); } } if (componentProperty && numComponents > 1) { m_ComponentSlider->SetProperty(componentProperty); m_ComponentSlider->setMinValue(0); m_ComponentSlider->setMaxValue(numComponents-1); } else { m_ComponentSlider->SetProperty(static_cast(NULL)); } } void QmitkDataManagerView::ColorChanged() { mitk::DataNode* node = m_NodeTreeModel->GetNode(m_FilterModel->mapToSource(m_NodeTreeView->selectionModel()->currentIndex())); if(node) { mitk::Color color; mitk::ColorProperty::Pointer colorProp; node->GetProperty(colorProp,"color"); if(colorProp.IsNull()) return; color = colorProp->GetValue(); QColor initial(color.GetRed()*255,color.GetGreen()*255,color.GetBlue()*255); QColor qcolor = QColorDialog::getColor(initial,0,QString("Change color")); if (!qcolor.isValid()) return; m_ColorButton->setAutoFillBackground(true); node->SetProperty("color",mitk::ColorProperty::New(qcolor.red()/255.0,qcolor.green()/255.0,qcolor.blue()/255.0)); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } } void QmitkDataManagerView::ColorActionChanged() { mitk::DataNode* node = m_NodeTreeModel->GetNode(m_FilterModel->mapToSource(m_NodeTreeView->selectionModel()->currentIndex())); if(node) { mitk::Color color; mitk::ColorProperty::Pointer colorProp; node->GetProperty(colorProp,"color"); if(colorProp.IsNull()) return; color = colorProp->GetValue(); QString styleSheet = "background-color:rgb("; styleSheet.append(QString::number(color[0]*255)); styleSheet.append(","); styleSheet.append(QString::number(color[1]*255)); styleSheet.append(","); styleSheet.append(QString::number(color[2]*255)); styleSheet.append(")"); m_ColorButton->setStyleSheet(styleSheet); } } void QmitkDataManagerView::TextureInterpolationChanged() { mitk::DataNode* node = m_NodeTreeModel->GetNode(m_FilterModel->mapToSource(m_NodeTreeView->selectionModel()->currentIndex())); if(node) { bool textureInterpolation = false; node->GetBoolProperty("texture interpolation", textureInterpolation); m_TextureInterpolation->setChecked(textureInterpolation); } } void QmitkDataManagerView::TextureInterpolationToggled( bool checked ) { mitk::DataNode* node = m_NodeTreeModel->GetNode(m_FilterModel->mapToSource(m_NodeTreeView->selectionModel()->currentIndex())); if(node) { node->SetBoolProperty("texture interpolation", checked); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } } void QmitkDataManagerView::ColormapActionToggled( bool /*checked*/ ) { mitk::DataNode* node = m_NodeTreeModel->GetNode(m_FilterModel->mapToSource(m_NodeTreeView->selectionModel()->currentIndex())); if(!node) return; mitk::LookupTableProperty::Pointer lookupTableProperty = dynamic_cast(node->GetProperty("LookupTable")); if (!lookupTableProperty) return; QAction* senderAction = qobject_cast(QObject::sender()); if(!senderAction) return; std::string activatedItem = senderAction->text().toStdString(); mitk::LookupTable::Pointer lookupTable = lookupTableProperty->GetValue(); if (!lookupTable) return; lookupTable->SetType(activatedItem); lookupTableProperty->SetValue(lookupTable); mitk::RenderingModeProperty::Pointer renderingMode = dynamic_cast(node->GetProperty("Image Rendering.Mode")); renderingMode->SetValue(mitk::RenderingModeProperty::LOOKUPTABLE_LEVELWINDOW_COLOR); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } void QmitkDataManagerView::ColormapMenuAboutToShow() { mitk::DataNode* node = m_NodeTreeModel->GetNode(m_FilterModel->mapToSource(m_NodeTreeView->selectionModel()->currentIndex())); if(!node) return; mitk::LookupTableProperty::Pointer lookupTableProperty = dynamic_cast(node->GetProperty("LookupTable")); if (!lookupTableProperty) { mitk::LookupTable::Pointer mitkLut = mitk::LookupTable::New(); lookupTableProperty = mitk::LookupTableProperty::New(); lookupTableProperty->SetLookupTable(mitkLut); node->SetProperty("LookupTable", lookupTableProperty); } mitk::LookupTable::Pointer lookupTable = lookupTableProperty->GetValue(); if (!lookupTable) return; m_ColormapAction->menu()->clear(); QAction* tmp; int i = 0; std::string lutType = lookupTable->typenameList[i]; while (lutType != "END_OF_ARRAY") { tmp = m_ColormapAction->menu()->addAction(QString::fromStdString(lutType)); tmp->setCheckable(true); if (lutType == lookupTable->GetActiveTypeAsString()) { tmp->setChecked(true); } QObject::connect(tmp, SIGNAL(triggered(bool)), this, SLOT(ColormapActionToggled(bool))); lutType = lookupTable->typenameList[++i]; } } void QmitkDataManagerView::SurfaceRepresentationMenuAboutToShow() { mitk::DataNode* node = m_NodeTreeModel->GetNode(m_FilterModel->mapToSource(m_NodeTreeView->selectionModel()->currentIndex())); if(!node) return; mitk::EnumerationProperty* representationProp = dynamic_cast (node->GetProperty("material.representation")); if(!representationProp) return; // clear menu m_SurfaceRepresentation->menu()->clear(); QAction* tmp; // create menu entries for(mitk::EnumerationProperty::EnumConstIterator it=representationProp->Begin(); it!=representationProp->End() ; it++) { tmp = m_SurfaceRepresentation->menu()->addAction(QString::fromStdString(it->second)); tmp->setCheckable(true); if(it->second == representationProp->GetValueAsString()) { tmp->setChecked(true); } QObject::connect( tmp, SIGNAL( triggered(bool) ) , this, SLOT( SurfaceRepresentationActionToggled(bool) ) ); } } void QmitkDataManagerView::SurfaceRepresentationActionToggled( bool /*checked*/ ) { mitk::DataNode* node = m_NodeTreeModel->GetNode(m_FilterModel->mapToSource(m_NodeTreeView->selectionModel()->currentIndex())); if(!node) return; mitk::EnumerationProperty* representationProp = dynamic_cast (node->GetProperty("material.representation")); if(!representationProp) return; QAction* senderAction = qobject_cast ( QObject::sender() ); if(!senderAction) return; std::string activatedItem = senderAction->text().toStdString(); if ( activatedItem != representationProp->GetValueAsString() ) { if ( representationProp->IsValidEnumerationValue( activatedItem ) ) { representationProp->SetValue( activatedItem ); representationProp->InvokeEvent( itk::ModifiedEvent() ); representationProp->Modified(); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } } } void QmitkDataManagerView::ReinitSelectedNodes( bool ) { mitk::IRenderWindowPart* renderWindow = this->GetRenderWindowPart(); if (renderWindow == NULL) renderWindow = this->OpenRenderWindowPart(false); QList selectedNodes = this->GetCurrentSelection(); foreach(mitk::DataNode::Pointer node, selectedNodes) { mitk::BaseData::Pointer basedata = node->GetData(); if ( basedata.IsNotNull() && basedata->GetTimeGeometry()->IsValid() ) { renderWindow->GetRenderingManager()->InitializeViews( basedata->GetTimeGeometry(), mitk::RenderingManager::REQUEST_UPDATE_ALL, true ); renderWindow->GetRenderingManager()->RequestUpdateAll(); } } } void QmitkDataManagerView::RemoveSelectedNodes( bool ) { QModelIndexList indexesOfSelectedRowsFiltered = m_NodeTreeView->selectionModel()->selectedRows(); QModelIndexList indexesOfSelectedRows; for (int i = 0; i < indexesOfSelectedRowsFiltered.size(); ++i) { indexesOfSelectedRows.push_back(m_FilterModel->mapToSource(indexesOfSelectedRowsFiltered[i])); } if(indexesOfSelectedRows.size() < 1) { return; } std::vector selectedNodes; mitk::DataNode* node = 0; QString question = tr("Do you really want to remove "); for (QModelIndexList::iterator it = indexesOfSelectedRows.begin() ; it != indexesOfSelectedRows.end(); it++) { node = m_NodeTreeModel->GetNode(*it); // if node is not defined or if the node contains geometry data do not remove it if ( node != 0 /*& strcmp(node->GetData()->GetNameOfClass(), "PlaneGeometryData") != 0*/ ) { selectedNodes.push_back(node); question.append(QString::fromStdString(node->GetName())); question.append(", "); } } // remove the last two characters = ", " question = question.remove(question.size()-2, 2); question.append(" from data storage?"); QMessageBox::StandardButton answerButton = QMessageBox::question( m_Parent , tr("DataManager") , question , QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes); if(answerButton == QMessageBox::Yes) { for (std::vector::iterator it = selectedNodes.begin() ; it != selectedNodes.end(); it++) { node = *it; this->GetDataStorage()->Remove(node); if (m_GlobalReinitOnNodeDelete) this->GlobalReinit(false); } } } void QmitkDataManagerView::MakeAllNodesInvisible( bool ) { QList nodes = m_NodeTreeModel->GetNodeSet(); foreach(mitk::DataNode::Pointer node, nodes) { node->SetVisibility(false); } mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } void QmitkDataManagerView::ShowOnlySelectedNodes( bool ) { QList selectedNodes = this->GetCurrentSelection(); QList allNodes = m_NodeTreeModel->GetNodeSet(); foreach(mitk::DataNode::Pointer node, allNodes) { node->SetVisibility(selectedNodes.contains(node)); } mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } void QmitkDataManagerView::ToggleVisibilityOfSelectedNodes( bool ) { QList selectedNodes = this->GetCurrentSelection(); bool isVisible = false; foreach(mitk::DataNode::Pointer node, selectedNodes) { isVisible = false; node->GetBoolProperty("visible", isVisible); node->SetVisibility(!isVisible); } mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } void QmitkDataManagerView::ShowInfoDialogForSelectedNodes( bool ) { QList selectedNodes = this->GetCurrentSelection(); QmitkInfoDialog _QmitkInfoDialog(selectedNodes, this->m_Parent); _QmitkInfoDialog.exec(); } void QmitkDataManagerView::NodeChanged(const mitk::DataNode* /*node*/) { // m_FilterModel->invalidate(); // fix as proposed by R. Khlebnikov in the mitk-users mail from 02.09.2014 QMetaObject::invokeMethod( m_FilterModel, "invalidate", Qt::QueuedConnection ); } QItemSelectionModel *QmitkDataManagerView::GetDataNodeSelectionModel() const { return m_NodeTreeView->selectionModel(); } void QmitkDataManagerView::GlobalReinit( bool ) { mitk::IRenderWindowPart* renderWindow = this->GetRenderWindowPart(); if (renderWindow == NULL) renderWindow = this->OpenRenderWindowPart(false); // no render window available if (renderWindow == NULL) return; mitk::RenderingManager::GetInstance()->InitializeViewsByBoundingObjects(this->GetDataStorage()); } void QmitkDataManagerView::OtsuFilter( bool ) { QList selectedNodes = this->GetCurrentSelection(); mitk::Image::Pointer mitkImage = 0; foreach(mitk::DataNode::Pointer node, selectedNodes) { mitkImage = dynamic_cast( node->GetData() ); if(mitkImage.IsNull()) continue; try { // get selected mitk image const unsigned short dim = 3; typedef short InputPixelType; typedef unsigned char OutputPixelType; typedef itk::Image< InputPixelType, dim > InputImageType; typedef itk::Image< OutputPixelType, dim > OutputImageType; typedef itk::OtsuThresholdImageFilter< InputImageType, OutputImageType > FilterType; FilterType::Pointer filter = FilterType::New(); filter->SetOutsideValue( 1 ); filter->SetInsideValue( 0 ); InputImageType::Pointer itkImage; mitk::CastToItkImage(mitkImage, itkImage); filter->SetInput( itkImage ); filter->Update(); mitk::DataNode::Pointer resultNode = mitk::DataNode::New(); std::string nameOfResultImage = node->GetName(); nameOfResultImage.append("Otsu"); resultNode->SetProperty("name", mitk::StringProperty::New(nameOfResultImage) ); resultNode->SetProperty("binary", mitk::BoolProperty::New(true) ); resultNode->SetData( mitk::ImportItkImage(filter->GetOutput())->Clone()); this->GetDataStorage()->Add(resultNode, node); } catch( std::exception& err ) { MITK_ERROR(this->GetClassName()) << err.what(); } } } void QmitkDataManagerView::NodeTreeViewRowsRemoved ( const QModelIndex & /*parent*/, int /*start*/, int /*end*/ ) { m_CurrentRowCount = m_NodeTreeModel->rowCount(); } void QmitkDataManagerView::NodeTreeViewRowsInserted( const QModelIndex & parent, int, int ) { m_NodeTreeView->setExpanded(parent, true); // a new row was inserted if( m_CurrentRowCount == 0 && m_NodeTreeModel->rowCount() == 1 ) { this->OpenRenderWindowPart(); m_CurrentRowCount = m_NodeTreeModel->rowCount(); } } void QmitkDataManagerView::NodeSelectionChanged( const QItemSelection & /*selected*/, const QItemSelection & /*deselected*/ ) { QList nodes = m_NodeTreeModel->GetNodeSet(); foreach(mitk::DataNode::Pointer node, nodes) { if ( node.IsNotNull() ) node->SetBoolProperty("selected", false); } nodes.clear(); nodes = this->GetCurrentSelection(); foreach(mitk::DataNode::Pointer node, nodes) { if ( node.IsNotNull() ) node->SetBoolProperty("selected", true); } //changing the selection does NOT require any rendering processes! //mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } void QmitkDataManagerView::ShowIn(const QString &editorId) { berry::IWorkbenchPage::Pointer page = this->GetSite()->GetPage(); berry::IEditorInput::Pointer input(new mitk::DataStorageEditorInput(this->GetDataStorageReference())); page->OpenEditor(input, editorId.toStdString(), false, berry::IWorkbenchPage::MATCH_ID); } mitk::IRenderWindowPart* QmitkDataManagerView::OpenRenderWindowPart(bool activatedEditor) { if (activatedEditor) { return this->GetRenderWindowPart(QmitkAbstractView::ACTIVATE | QmitkAbstractView::OPEN); } else { return this->GetRenderWindowPart(QmitkAbstractView::BRING_TO_FRONT | QmitkAbstractView::OPEN); } } diff --git a/Plugins/org.mitk.gui.qt.datamanager/src/internal/mitkPluginActivator.cpp b/Plugins/org.mitk.gui.qt.datamanager/src/internal/mitkPluginActivator.cpp index 28251ba02b..93e95d4c09 100644 --- a/Plugins/org.mitk.gui.qt.datamanager/src/internal/mitkPluginActivator.cpp +++ b/Plugins/org.mitk.gui.qt.datamanager/src/internal/mitkPluginActivator.cpp @@ -1,40 +1,42 @@ /*=================================================================== 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 "mitkPluginActivator.h" #include #include "../QmitkDataManagerView.h" #include "../QmitkDataManagerPreferencePage.h" #include "../QmitkDataManagerHotkeysPrefPage.h" namespace mitk { void PluginActivator::start(ctkPluginContext* context) { BERRY_REGISTER_EXTENSION_CLASS(QmitkDataManagerView, context) BERRY_REGISTER_EXTENSION_CLASS(QmitkDataManagerPreferencePage, context) BERRY_REGISTER_EXTENSION_CLASS(QmitkDataManagerHotkeysPrefPage, context) } void PluginActivator::stop(ctkPluginContext* context) { Q_UNUSED(context) } } -Q_EXPORT_PLUGIN2(org_mitk_gui_qt_datamanager, mitk::PluginActivator) +#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) + Q_EXPORT_PLUGIN2(org_mitk_gui_qt_datamanager, mitk::PluginActivator) +#endif diff --git a/Plugins/org.mitk.gui.qt.datamanager/src/internal/mitkPluginActivator.h b/Plugins/org.mitk.gui.qt.datamanager/src/internal/mitkPluginActivator.h index 489bd853ca..d55dc02e3e 100644 --- a/Plugins/org.mitk.gui.qt.datamanager/src/internal/mitkPluginActivator.h +++ b/Plugins/org.mitk.gui.qt.datamanager/src/internal/mitkPluginActivator.h @@ -1,40 +1,43 @@ /*=================================================================== 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 MITKPLUGINACTIVATOR_H #define MITKPLUGINACTIVATOR_H #include #include namespace mitk { class MITK_LOCAL PluginActivator : public QObject, public ctkPluginActivator { Q_OBJECT +#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) + Q_PLUGIN_METADATA(IID "org_mitk_gui_qt_datamanager") +#endif Q_INTERFACES(ctkPluginActivator) public: void start(ctkPluginContext* context); void stop(ctkPluginContext* context); }; // PluginActivator } #endif // MITKPLUGINACTIVATOR_H diff --git a/Plugins/org.mitk.gui.qt.datamanagerlight/src/internal/QmitkDataManagerLightView.cpp b/Plugins/org.mitk.gui.qt.datamanagerlight/src/internal/QmitkDataManagerLightView.cpp index f8f7065f46..78817ff6fd 100644 --- a/Plugins/org.mitk.gui.qt.datamanagerlight/src/internal/QmitkDataManagerLightView.cpp +++ b/Plugins/org.mitk.gui.qt.datamanagerlight/src/internal/QmitkDataManagerLightView.cpp @@ -1,251 +1,258 @@ /*=================================================================== 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 "QmitkDataManagerLightView.h" #include "mitkNodePredicateDataType.h" -#include +#include +#include +#include +#include +#include +#include +#include +#include #include #include #include #include #include const std::string QmitkDataManagerLightView::VIEW_ID = "org.mitk.views.datamanagerlight"; struct QmitkDataManagerLightViewData { // static mitk::NodePredicateBase::Pointer m_Predicate; QIcon m_ItemIcon; // data QList m_DataNodes; int m_CurrentIndex; // widget QListWidget* m_ListWidget; QLabel* m_ImageInfoLabel; QPushButton* m_RemoveButton; }; QmitkDataManagerLightView::QmitkDataManagerLightView() : d( new QmitkDataManagerLightViewData ) { d->m_Predicate = mitk::NodePredicateDataType::New("Image"); d->m_ItemIcon = QIcon(":/org.mitk.gui.qt.datamanagerlight/Image_24.png"); d->m_CurrentIndex = -1; d->m_ListWidget = 0; d->m_ImageInfoLabel = 0; d->m_RemoveButton = 0; } QmitkDataManagerLightView::~QmitkDataManagerLightView() { delete d; } void QmitkDataManagerLightView::NodeAdded(const mitk::DataNode *node) { if( d->m_Predicate->CheckNode(node) ) { mitk::DataNode* nonConstNode = const_cast(node); d->m_DataNodes.append(nonConstNode); d->m_ListWidget->addItem( new QListWidgetItem( d->m_ItemIcon, QString::fromStdString( node->GetName() ) ) ); } } void QmitkDataManagerLightView::NodeRemoved(const mitk::DataNode *node) { this->RemoveNode( const_cast(node) ); } void QmitkDataManagerLightView::NodeChanged(const mitk::DataNode *node) { MITK_DEBUG << "NodeChanged"; if( d->m_DataNodes.contains(const_cast(node)) ) this->ToggleVisibility(); } void QmitkDataManagerLightView::RemoveNode(mitk::DataNode *node) { mitk::DataNode* nonConstNode = const_cast(node); int index = d->m_DataNodes.indexOf(nonConstNode); if( index >= 0 ) { MITK_DEBUG << "removing node at: " << index; QListWidgetItem* item = d->m_ListWidget->takeItem(index); delete item; d->m_DataNodes.removeAt(index); MITK_DEBUG << "item deleted"; } } void QmitkDataManagerLightView::CreateQtPartControl(QWidget* parent) { QPushButton* loadButton = new QPushButton(QIcon(":/org.mitk.gui.qt.datamanagerlight/Load_48.png"), "Load"); d->m_RemoveButton = new QPushButton(QIcon(":/org.mitk.gui.qt.datamanagerlight/Remove_48.png"), "Remove"); d->m_RemoveButton->setEnabled(false); d->m_ListWidget = new QListWidget; d->m_ImageInfoLabel = new QLabel; QGridLayout* layout = new QGridLayout; layout->addWidget( loadButton, 0,0 ); layout->addWidget( d->m_RemoveButton, 0,1 ); layout->addWidget( d->m_ImageInfoLabel, 1,0, 1, 2 ); layout->addWidget( d->m_ListWidget, 2,0,1,2 ); parent->setLayout(layout); connect(d->m_ListWidget, SIGNAL(currentRowChanged(int)), this, SLOT(on_DataItemList_currentRowChanged(int)) ); connect(loadButton, SIGNAL(pressed()), this, SLOT(on_Load_pressed()) ); connect(d->m_RemoveButton, SIGNAL(pressed()), this, SLOT(on_Remove_pressed()) ); this->ListSelectionChanged(); } void QmitkDataManagerLightView::SetFocus() { d->m_ListWidget->setFocus(); } void QmitkDataManagerLightView::on_DataItemList_currentRowChanged(int currentRow) { MITK_DEBUG << "DataItemList currentRowChanged: " << currentRow; Q_UNUSED(currentRow) this->ListSelectionChanged(); } void QmitkDataManagerLightView::ListSelectionChanged() { d->m_CurrentIndex = d->m_ListWidget->currentRow(); MITK_DEBUG << "the currently selected index: " << d->m_CurrentIndex; QString newLabelText = "Current patient: "; if( d->m_CurrentIndex >= 0 ) { // TODO WHERE IS THE PATIENT NAME? std::string name = d->m_DataNodes.at(d->m_CurrentIndex)->GetName(); newLabelText.append( QString("%1" ).arg( QString::fromStdString(name) ) ); d->m_RemoveButton->setEnabled(true); } else { newLabelText.append("Unknown"); d->m_RemoveButton->setEnabled(false); } d->m_ImageInfoLabel->setText(newLabelText); this->ToggleVisibility(); } void QmitkDataManagerLightView::on_Load_pressed() { MITK_DEBUG << "on_Load_pressed"; QStringList fileNames = QFileDialog::getOpenFileNames(NULL, "Load data", "", mitk::CoreObjectFactory::GetInstance()->GetFileExtensions()); for ( QStringList::Iterator it = fileNames.begin(); it != fileNames.end(); ++it ) { - FileOpen((*it).toAscii(), 0); + FileOpen((*it).toLatin1(), 0); } } void QmitkDataManagerLightView::FileOpen( const char * fileName, mitk::DataNode* /*parentNode*/ ) { try { QApplication::setOverrideCursor( QCursor(Qt::WaitCursor) ); mitk::IOUtil::Load(fileName, *this->GetDataStorage()); mitk::RenderingManager::GetInstance()->InitializeViews(); } catch ( itk::ExceptionObject & ex ) { MITK_ERROR << "Exception during file open: " << ex; } QApplication::restoreOverrideCursor(); } void QmitkDataManagerLightView::on_Remove_pressed() { d->m_CurrentIndex = d->m_ListWidget->currentRow(); MITK_DEBUG << "the currently selected index: " << d->m_CurrentIndex; mitk::DataNode* node = d->m_DataNodes.at(d->m_CurrentIndex); QString question = tr("Do you really want to remove "); // TODO patient name? question.append( QString::fromStdString( node->GetName() ) ); question.append(" ?"); QMessageBox::StandardButton answerButton = QMessageBox::question( NULL , tr("DataManagerLight") , question , QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes); if(answerButton == QMessageBox::Yes) { this->GetDataStorage()->Remove(node); this->GlobalReinit(); } } void QmitkDataManagerLightView::GlobalReinit() { mitk::IRenderWindowPart* renderWindow = this->GetRenderWindowPart(); // no render window available if (renderWindow == NULL) return; // get all nodes that have not set "includeInBoundingBox" to false mitk::NodePredicateNot::Pointer pred = mitk::NodePredicateNot::New(mitk::NodePredicateProperty::New("includeInBoundingBox" , mitk::BoolProperty::New(false))); mitk::DataStorage::SetOfObjects::ConstPointer rs = this->GetDataStorage()->GetSubset(pred); // calculate bounding geometry of these nodes mitk::TimeGeometry::Pointer bounds = this->GetDataStorage()->ComputeBoundingGeometry3D(rs, "visible"); // initialize the views to the bounding geometry renderWindow->GetRenderingManager()->InitializeViews(bounds); } void QmitkDataManagerLightView::ToggleVisibility() { bool changedAnything = false; bool isVisible = false; for(size_t i=0; im_DataNodes.size(); ++i) { isVisible = false; d->m_DataNodes.at(i)->GetVisibility(isVisible, 0 ); if( d->m_CurrentIndex == i && isVisible == false ) { d->m_DataNodes.at(i)->SetVisibility(true); changedAnything = true; } else if( d->m_CurrentIndex != i && isVisible == true ) { d->m_DataNodes.at(i)->SetVisibility(false); changedAnything = true; } } if( changedAnything ) mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } diff --git a/Plugins/org.mitk.gui.qt.datamanagerlight/src/internal/mitkPluginActivator.cpp b/Plugins/org.mitk.gui.qt.datamanagerlight/src/internal/mitkPluginActivator.cpp index f90ad379a6..fcfdc2351a 100644 --- a/Plugins/org.mitk.gui.qt.datamanagerlight/src/internal/mitkPluginActivator.cpp +++ b/Plugins/org.mitk.gui.qt.datamanagerlight/src/internal/mitkPluginActivator.cpp @@ -1,34 +1,36 @@ /*=================================================================== 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 "mitkPluginActivator.h" #include #include "QmitkDataManagerLightView.h" namespace mitk { void PluginActivator::start(ctkPluginContext* context) { BERRY_REGISTER_EXTENSION_CLASS(QmitkDataManagerLightView, context) } void PluginActivator::stop(ctkPluginContext* context) { Q_UNUSED(context) } } -Q_EXPORT_PLUGIN2(org_mitk_gui_qt_datamanagerlight, mitk::PluginActivator) +#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) + Q_EXPORT_PLUGIN2(org_mitk_gui_qt_datamanagerlight, mitk::PluginActivator) +#endif diff --git a/Plugins/org.mitk.gui.qt.datamanagerlight/src/internal/mitkPluginActivator.h b/Plugins/org.mitk.gui.qt.datamanagerlight/src/internal/mitkPluginActivator.h index 489bd853ca..3543c69b38 100644 --- a/Plugins/org.mitk.gui.qt.datamanagerlight/src/internal/mitkPluginActivator.h +++ b/Plugins/org.mitk.gui.qt.datamanagerlight/src/internal/mitkPluginActivator.h @@ -1,40 +1,43 @@ /*=================================================================== 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 MITKPLUGINACTIVATOR_H #define MITKPLUGINACTIVATOR_H #include #include namespace mitk { class MITK_LOCAL PluginActivator : public QObject, public ctkPluginActivator { Q_OBJECT +#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) + Q_PLUGIN_METADATA(IID "org_mitk_gui_qt_datamanagerlight") +#endif Q_INTERFACES(ctkPluginActivator) public: void start(ctkPluginContext* context); void stop(ctkPluginContext* context); }; // PluginActivator } #endif // MITKPLUGINACTIVATOR_H diff --git a/Plugins/org.mitk.gui.qt.dicom/src/internal/mitkPluginActivator.cpp b/Plugins/org.mitk.gui.qt.dicom/src/internal/mitkPluginActivator.cpp index 29953d3894..7aec5f01b0 100644 --- a/Plugins/org.mitk.gui.qt.dicom/src/internal/mitkPluginActivator.cpp +++ b/Plugins/org.mitk.gui.qt.dicom/src/internal/mitkPluginActivator.cpp @@ -1,45 +1,48 @@ /*=================================================================== 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 "mitkPluginActivator.h" #include #include "QmitkDicomBrowser.h" #include "QmitkDicomPreferencePage.h" namespace mitk { ctkPluginContext* PluginActivator::pluginContext = 0; void PluginActivator::start(ctkPluginContext* context) { BERRY_REGISTER_EXTENSION_CLASS(QmitkDicomBrowser, context) BERRY_REGISTER_EXTENSION_CLASS(QmitkDicomPreferencePage, context) pluginContext = context; } void PluginActivator::stop(ctkPluginContext* context) { Q_UNUSED(context) pluginContext = NULL; } ctkPluginContext* PluginActivator::getContext() { return pluginContext; } } -Q_EXPORT_PLUGIN2(org_mitk_gui_qt_dicom, mitk::PluginActivator) \ No newline at end of file +#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) + Q_EXPORT_PLUGIN2(org_mitk_gui_qt_dicom, mitk::PluginActivator) +#endif + diff --git a/Plugins/org.mitk.gui.qt.dicom/src/internal/mitkPluginActivator.h b/Plugins/org.mitk.gui.qt.dicom/src/internal/mitkPluginActivator.h index 90aa1c78d5..4344913a9a 100644 --- a/Plugins/org.mitk.gui.qt.dicom/src/internal/mitkPluginActivator.h +++ b/Plugins/org.mitk.gui.qt.dicom/src/internal/mitkPluginActivator.h @@ -1,41 +1,44 @@ /*=================================================================== 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 MITKPLUGINACTIVATOR_H #define MITKPLUGINACTIVATOR_H #include namespace mitk { class PluginActivator : public QObject, public ctkPluginActivator { Q_OBJECT +#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) + Q_PLUGIN_METADATA(IID "org_mitk_gui_qt_dicom") +#endif Q_INTERFACES(ctkPluginActivator) public: void start(ctkPluginContext* context); void stop(ctkPluginContext* context); static ctkPluginContext* getContext(); private: static ctkPluginContext* pluginContext; }; // PluginActivator } #endif // MITKPLUGINACTIVATOR_H diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging/documentation/UserManual/DataImport/dicom1.png b/Plugins/org.mitk.gui.qt.diffusionimaging/documentation/UserManual/DataImport/dicom1.png index 0151f56bea..85ca20974f 100644 Binary files a/Plugins/org.mitk.gui.qt.diffusionimaging/documentation/UserManual/DataImport/dicom1.png and b/Plugins/org.mitk.gui.qt.diffusionimaging/documentation/UserManual/DataImport/dicom1.png differ diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging/documentation/UserManual/Preproc_Recons/qballs1.png b/Plugins/org.mitk.gui.qt.diffusionimaging/documentation/UserManual/Preproc_Recons/qballs1.png index 379f21dc7e..1493a30fdf 100644 Binary files a/Plugins/org.mitk.gui.qt.diffusionimaging/documentation/UserManual/Preproc_Recons/qballs1.png and b/Plugins/org.mitk.gui.qt.diffusionimaging/documentation/UserManual/Preproc_Recons/qballs1.png differ diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging/documentation/UserManual/Preproc_Recons/qballs2.png b/Plugins/org.mitk.gui.qt.diffusionimaging/documentation/UserManual/Preproc_Recons/qballs2.png index b208895fc7..981d387842 100644 Binary files a/Plugins/org.mitk.gui.qt.diffusionimaging/documentation/UserManual/Preproc_Recons/qballs2.png and b/Plugins/org.mitk.gui.qt.diffusionimaging/documentation/UserManual/Preproc_Recons/qballs2.png differ diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging/documentation/UserManual/Preproc_Recons/qballs3.png b/Plugins/org.mitk.gui.qt.diffusionimaging/documentation/UserManual/Preproc_Recons/qballs3.png index 8f5155ae2f..9eea5739a5 100644 Binary files a/Plugins/org.mitk.gui.qt.diffusionimaging/documentation/UserManual/Preproc_Recons/qballs3.png and b/Plugins/org.mitk.gui.qt.diffusionimaging/documentation/UserManual/Preproc_Recons/qballs3.png differ diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging/documentation/UserManual/Preproc_Recons/residuals.png b/Plugins/org.mitk.gui.qt.diffusionimaging/documentation/UserManual/Preproc_Recons/residuals.png index 626fbaf6e3..f9d4996e15 100644 Binary files a/Plugins/org.mitk.gui.qt.diffusionimaging/documentation/UserManual/Preproc_Recons/residuals.png and b/Plugins/org.mitk.gui.qt.diffusionimaging/documentation/UserManual/Preproc_Recons/residuals.png differ diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging/documentation/UserManual/Preproc_Recons/tensor1.png b/Plugins/org.mitk.gui.qt.diffusionimaging/documentation/UserManual/Preproc_Recons/tensor1.png index 6aae4ff4d9..23af1def89 100644 Binary files a/Plugins/org.mitk.gui.qt.diffusionimaging/documentation/UserManual/Preproc_Recons/tensor1.png and b/Plugins/org.mitk.gui.qt.diffusionimaging/documentation/UserManual/Preproc_Recons/tensor1.png differ diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging/documentation/UserManual/Preproc_Recons/tensor4.png b/Plugins/org.mitk.gui.qt.diffusionimaging/documentation/UserManual/Preproc_Recons/tensor4.png index c4708fff21..546ab70b2f 100644 Binary files a/Plugins/org.mitk.gui.qt.diffusionimaging/documentation/UserManual/Preproc_Recons/tensor4.png and b/Plugins/org.mitk.gui.qt.diffusionimaging/documentation/UserManual/Preproc_Recons/tensor4.png differ diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging/documentation/UserManual/Preproc_Recons/visualization3.png b/Plugins/org.mitk.gui.qt.diffusionimaging/documentation/UserManual/Preproc_Recons/visualization3.png index acc816f8d7..1f0a0fd15b 100644 Binary files a/Plugins/org.mitk.gui.qt.diffusionimaging/documentation/UserManual/Preproc_Recons/visualization3.png and b/Plugins/org.mitk.gui.qt.diffusionimaging/documentation/UserManual/Preproc_Recons/visualization3.png differ diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging/documentation/UserManual/QmitkDiffusionImagingPortalPage.dox b/Plugins/org.mitk.gui.qt.diffusionimaging/documentation/UserManual/QmitkDiffusionImagingPortalPage.dox index f61238e231..571689e8e1 100644 --- a/Plugins/org.mitk.gui.qt.diffusionimaging/documentation/UserManual/QmitkDiffusionImagingPortalPage.dox +++ b/Plugins/org.mitk.gui.qt.diffusionimaging/documentation/UserManual/QmitkDiffusionImagingPortalPage.dox @@ -1,84 +1,84 @@ /** \page org_mitk_gui_qt_diffusionimaging MITK Diffusion Imaging (MITK-DI) \tableofcontents This module provides means to diffusion weighted image reconstruction, visualization and quantification. Diffusion tensors as well as different q-ball reconstruction schemes are supported. Q-ball imaging aims at recovering more detailed information about the orientations of fibers from diffusion MRI measurements and, in particular, to resolve the orientations of crossing fibers. \section org_mitk_gui_qt_diffusionimagingComponents Components MITK Diffusion consists of further components, which have their own documentation, see: \subsection org_mitk_gui_qt_diffusionimagingComponentsDataImport Data Import \li \subpage QmitkDiffusionImagingDataImportPage \subsection org_mitk_gui_qt_diffusionimagingComponentsPreprocessingAndReconstruction Preprocessing and Reconstruction Register or denoise original data and convert it into tensor or q-ball images. \li \subpage org_mitk_views_diffusionregistrationview \li \subpage org_mitk_views_diffusionpreprocessing \li \subpage QmitkDiffusionImagingReconstructionPage \li \subpage org_mitk_views_controlvisualizationpropertiesview \li \subpage org_mitk_views_odfdetails \li \subpage org_mitk_views_odfmaximaextraction \li \subpage org_mitk_views_denoisingview \subsection org_mitk_gui_qt_diffusionimagingComponentsFiberTracking Fiber Tracking Create and work with fiber tractographies. \li \subpage org_mitk_views_fiberprocessing \li \subpage org_mitk_views_gibbstracking \li \subpage org_mitk_views_stochasticfibertracking \li \subpage org_mitk_views_fiberextraction \li \subpage org_mitk_views_fiberprocessing \li \subpage org_mitk_views_streamlinetracking \li \subpage org_mitk_views_fiberfoxview \li \subpage org_mitk_views_fieldmapgenerator \subsection org_mitk_gui_qt_diffusionimagingComponentsQuantification Quantification Create parameter maps and quantify different properties. - \li \subpage QmitkDiffusionImagingQuantificationPage + \li \subpage org_mitk_views_diffusionquantification \li \subpage org_mitk_views_ivim \li \subpage org_mitk_views_partialvolumeanalysisview \li \subpage org_mitk_views_tractbasedspatialstatistics \subsection org_mitk_gui_qt_diffusionimagingComponentsConnectomics Connectomics Create and analyse connectome networks. \li \subpage org_mitk_diffusionimagingapp_perspectives_connectomics \section org_mitk_gui_qt_diffusionimagingIssues Known Issues \li Dicom Import: The dicom import has so far only been implemented for Siemens dicom images. MITK-DI is capable of reading the nrrd format, which is documented elsewhere [1, 2]. These files can be created by combining the raw image data with a corresponding textual header file. The file extension should be changed from *.nrrd to *.dwi or from *.nhdr to *.hdwi respectively in order to let MITK-DI recognize the diffusion related header information provided in the files. \section org_mitk_gui_qt_diffusionimagingTechnicalDetails Technical Information for Developers The diffusion imaging module uses additional properties beside the ones in use in other modules, for further information see \ref DiffusionImagingPropertiesPage . \section org_mitk_gui_qt_diffusionimagingReferences References Further reading regarding diffusion: 1. http://teem.sourceforge.net/nrrd/format.html 2. http://www.cmake.org/Wiki/Getting_Started_with_the_NRRD_Format 3. C.F.Westin, S.E.Maier, H.Mamata, A.Nabavi, F.A.Jolesz, R.Kikinis, "Processing and visualization for Diffusion tensor MRI", Medical image Analysis, 2002, pp 93-108 5. Tuch, D.S., 2004. Q-ball imaging. Magn Reson Med 52, 1358-1372. 6. Descoteaux, M., Angelino, E., Fitzgibbons, S., Deriche, R., 2007. Regularized, fast, and robust analytical Q-ball imaging. Magn Reson Med 58, 497-510. 7. Aganj, I., Lenglet, C., Sapiro, G., 2009. ODF reconstruction in q-ball imaging with solid angle consideration. Proceedings of the Sixth IEEE International Symposium on Biomedical Imaging Boston, MA. 8. Goh, A., Lenglet, C., Thompson, P.M., Vidal, R., 2009. Estimating Orientation Distribution Functions with Probability Density Constraints and Spatial Regularity. Med Image Comput Comput Assist Interv Int Conf Med Image Comput Comput Assist Interv LNCS 5761, 877 ff. 9. J.-D. Tournier, S. Mori, A. Leemans., 2011. Diffusion Tensor Imaging and Beyond. Magn Reson Med 65, 1532-1556. */ diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging/documentation/UserManual/Quantification/QmitkDiffusionImagingQuantificationPage.dox b/Plugins/org.mitk.gui.qt.diffusionimaging/documentation/UserManual/Quantification/QmitkDiffusionImagingQuantificationPage.dox index c3ca35f105..cec142beed 100644 --- a/Plugins/org.mitk.gui.qt.diffusionimaging/documentation/UserManual/Quantification/QmitkDiffusionImagingQuantificationPage.dox +++ b/Plugins/org.mitk.gui.qt.diffusionimaging/documentation/UserManual/Quantification/QmitkDiffusionImagingQuantificationPage.dox @@ -1,8 +1,8 @@ /** -\page QmitkDiffusionImagingQuantificationPage Quantification +\page org_mitk_views_diffusionquantification Scalar Indices -The quantification view allows the derivation of different scalar anisotropy measures for the reconstructed tensors (Fractional Anisotropy, Relative Anisotropy, Axial Diffusivity, Radial Diffusivity) or q-balls (Generalized Fractional Anisotropy). +The scalar indices view allows the derivation of different scalar anisotropy measures for the reconstructed tensors (Fractional Anisotropy, Relative Anisotropy, Axial Diffusivity, Radial Diffusivity) or q-balls (Generalized Fractional Anisotropy). -\imageMacro{quantification.png,"Anisotropy quantification",2} -*/ \ No newline at end of file +\imageMacro{ScalarIndicesGUI.png,"Anisotropy quantification",2} +*/ diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging/documentation/UserManual/Quantification/ScalarIndicesGUI.png b/Plugins/org.mitk.gui.qt.diffusionimaging/documentation/UserManual/Quantification/ScalarIndicesGUI.png new file mode 100644 index 0000000000..e3688f56cc Binary files /dev/null and b/Plugins/org.mitk.gui.qt.diffusionimaging/documentation/UserManual/Quantification/ScalarIndicesGUI.png differ diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging/documentation/UserManual/Quantification/quantification.png b/Plugins/org.mitk.gui.qt.diffusionimaging/documentation/UserManual/Quantification/quantification.png deleted file mode 100644 index a768b66dca..0000000000 Binary files a/Plugins/org.mitk.gui.qt.diffusionimaging/documentation/UserManual/Quantification/quantification.png and /dev/null differ diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging/src/QmitkIVIMWidget.cpp b/Plugins/org.mitk.gui.qt.diffusionimaging/src/QmitkIVIMWidget.cpp index cd3f7aa0b5..13ca553e98 100644 --- a/Plugins/org.mitk.gui.qt.diffusionimaging/src/QmitkIVIMWidget.cpp +++ b/Plugins/org.mitk.gui.qt.diffusionimaging/src/QmitkIVIMWidget.cpp @@ -1,150 +1,150 @@ /*=================================================================== 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 "QmitkIVIMWidget.h" #include "mitkHistogramGenerator.h" #include #include QmitkIVIMWidget::QmitkIVIMWidget( QWidget * parent ) : QmitkPlotWidget(parent) { // this->SetAxisTitle( QwtPlot::xBottom, "Grayvalue" ); // this->SetAxisTitle( QwtPlot::yLeft, "Probability" ); // this->Replot(); QFrame* canvas = qobject_cast(m_Plot->canvas()); if (canvas) { canvas->setLineWidth(0); canvas->setContentsMargins(0,0,0,0); } QwtLogScaleEngine* logScale = new QwtLogScaleEngine(); m_Plot->setAxisScaleEngine(0, logScale); m_Plot->setAxisScale( 0, 0.15, 1.0 ); } QmitkIVIMWidget::~QmitkIVIMWidget() { } void QmitkIVIMWidget::DrawGauss() { } void QmitkIVIMWidget::ClearItemModel() { } std::vector QmitkIVIMWidget::vec(const vnl_vector& vector) { std::vector retval(vector.size()); for(unsigned int i=0; iClear(); if (snap.bvalues.empty()) return; QString s("f=%1, D=%2, D*=%3"); s = s.arg(snap.currentF,4); s = s.arg(snap.currentD,4); s = s.arg(snap.currentDStar,4); - int curveId = this->InsertCurve( s.toAscii() ); + int curveId = this->InsertCurve( s.toLatin1() ); this->SetCurvePen( curveId, QPen( Qt::NoPen ) ); curveId = this->InsertCurve( "ignored measurement points" ); this->SetCurveData( curveId, vec(snap.bvalues), vec(snap.allmeas) ); this->SetCurvePen( curveId, QPen(Qt::NoPen) ); QwtSymbol* whiteSymbol = new QwtSymbol(QwtSymbol::Diamond, QColor(Qt::white), QColor(Qt::black), QSize(10,10)); this->SetCurveSymbol(curveId, whiteSymbol); if(snap.currentDStar != 0) { curveId = this->InsertCurve( "additional points second fit" ); this->SetCurveData( curveId, vec(snap.bvals2), vec(snap.meas2) ); this->SetCurvePen( curveId, QPen( Qt::NoPen ) ); QwtSymbol* blackSymbol = new QwtSymbol(QwtSymbol::Diamond, QColor(Qt::black), QColor(Qt::black), QSize(10,10)); this->SetCurveSymbol(curveId, blackSymbol); } curveId = this->InsertCurve( "points first fit" ); this->SetCurveData( curveId, vec(snap.bvals1), vec(snap.meas1) ); this->SetCurvePen( curveId, QPen( Qt::NoPen ) ); QwtSymbol* redSymbol = new QwtSymbol(QwtSymbol::Diamond, QColor(Qt::red), QColor(Qt::red), QSize(10,10)); this->SetCurveSymbol(curveId, redSymbol); QPen pen; pen.setColor( QColor(Qt::red) ); pen.setWidth(2); double maxb = snap.bvalues.max_value(); vnl_vector xvals(2); vnl_vector yvals(2); xvals[0] = 0; xvals[1] = maxb; yvals[0] = 1-snap.currentFunceiled; yvals[1] = yvals[0]*exp(-maxb * snap.currentD); curveId = this->InsertCurve( "contribution of D to the signal" ); this->SetCurveData( curveId, vec(xvals), vec(yvals) ); this->SetCurvePen( curveId, pen ); if(snap.currentDStar != 0) { pen.setColor(Qt::black); int nsampling = 50; xvals.set_size(nsampling); yvals.set_size(nsampling); double f = 1-snap.currentFunceiled; for(int i=0; iInsertCurve( "resulting fit of the model" ); this->SetCurveData( curveId, vec(xvals), vec(yvals) ); this->SetCurvePen( curveId, pen ); } // QMargins margins; // margins.setBottom(0); // margins.setLeft(0); // margins.setRight(0); // margins.setTop(0); QwtLegend* legend = new QwtLegend(); // legend->setContentsMargins(margins); m_Plot->insertLegend(legend, QwtPlot::BottomLegend); this->Replot(); } diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkControlVisualizationPropertiesView.cpp b/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkControlVisualizationPropertiesView.cpp index 57cafeefa5..b1c932dcf1 100644 --- a/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkControlVisualizationPropertiesView.cpp +++ b/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkControlVisualizationPropertiesView.cpp @@ -1,1831 +1,1831 @@ /*=================================================================== 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 "QmitkControlVisualizationPropertiesView.h" #include "mitkNodePredicateDataType.h" #include "mitkDataNodeObject.h" #include "mitkOdfNormalizationMethodProperty.h" #include "mitkOdfScaleByProperty.h" #include "mitkResliceMethodProperty.h" #include "mitkRenderingManager.h" #include "mitkTbssImage.h" #include "mitkPlanarFigure.h" #include "mitkFiberBundleX.h" #include "QmitkDataStorageComboBox.h" #include "QmitkStdMultiWidget.h" #include "mitkFiberBundleInteractor.h" #include "mitkPlanarFigureInteractor.h" #include #include #include #include #include "mitkGlobalInteraction.h" #include "usModuleRegistry.h" #include "mitkPlaneGeometry.h" #include "berryIWorkbenchWindow.h" #include "berryIWorkbenchPage.h" #include "berryISelectionService.h" #include "berryConstants.h" #include "berryPlatformUI.h" #include "itkRGBAPixel.h" #include #include "qwidgetaction.h" #include "qcolordialog.h" #include #define ROUND(a) ((a)>0 ? (int)((a)+0.5) : -(int)(0.5-(a))) static bool DetermineAffectedImageSlice( const mitk::Image* image, const mitk::PlaneGeometry* plane, int& affectedDimension, int& affectedSlice ) { assert(image); assert(plane); // compare normal of plane to the three axis vectors of the image mitk::Vector3D normal = plane->GetNormal(); mitk::Vector3D imageNormal0 = image->GetSlicedGeometry()->GetAxisVector(0); mitk::Vector3D imageNormal1 = image->GetSlicedGeometry()->GetAxisVector(1); mitk::Vector3D imageNormal2 = image->GetSlicedGeometry()->GetAxisVector(2); normal.Normalize(); imageNormal0.Normalize(); imageNormal1.Normalize(); imageNormal2.Normalize(); imageNormal0.SetVnlVector( vnl_cross_3d(normal.GetVnlVector(),imageNormal0.GetVnlVector()) ); imageNormal1.SetVnlVector( vnl_cross_3d(normal.GetVnlVector(),imageNormal1.GetVnlVector()) ); imageNormal2.SetVnlVector( vnl_cross_3d(normal.GetVnlVector(),imageNormal2.GetVnlVector()) ); double eps( 0.00001 ); // axial if ( imageNormal2.GetNorm() <= eps ) { affectedDimension = 2; } // sagittal else if ( imageNormal1.GetNorm() <= eps ) { affectedDimension = 1; } // frontal else if ( imageNormal0.GetNorm() <= eps ) { affectedDimension = 0; } else { affectedDimension = -1; // no idea return false; } // determine slice number in image mitk::BaseGeometry* imageGeometry = image->GetGeometry(0); mitk::Point3D testPoint = imageGeometry->GetCenter(); mitk::Point3D projectedPoint; plane->Project( testPoint, projectedPoint ); mitk::Point3D indexPoint; imageGeometry->WorldToIndex( projectedPoint, indexPoint ); affectedSlice = ROUND( indexPoint[affectedDimension] ); MITK_DEBUG << "indexPoint " << indexPoint << " affectedDimension " << affectedDimension << " affectedSlice " << affectedSlice; // check if this index is still within the image if ( affectedSlice < 0 || affectedSlice >= static_cast(image->GetDimension(affectedDimension)) ) return false; return true; } const std::string QmitkControlVisualizationPropertiesView::VIEW_ID = "org.mitk.views.controlvisualizationpropertiesview"; using namespace berry; struct CvpSelListener : ISelectionListener { berryObjectMacro(CvpSelListener); CvpSelListener(QmitkControlVisualizationPropertiesView* view) { m_View = view; } void ApplySettings(mitk::DataNode::Pointer node) { bool tex_int; node->GetBoolProperty("texture interpolation", tex_int); if(tex_int) { m_View->m_Controls->m_TextureIntON->setIcon(*m_View->m_IconTexON); m_View->m_Controls->m_TextureIntON->setChecked(true); m_View->m_TexIsOn = true; } else { m_View->m_Controls->m_TextureIntON->setIcon(*m_View->m_IconTexOFF); m_View->m_Controls->m_TextureIntON->setChecked(false); m_View->m_TexIsOn = false; } int val; node->GetIntProperty("ShowMaxNumber", val); m_View->m_Controls->m_ShowMaxNumber->setValue(val); m_View->m_Controls->m_NormalizationDropdown->setCurrentIndex(dynamic_cast(node->GetProperty("Normalization"))->GetValueAsId()); float fval; node->GetFloatProperty("Scaling",fval); m_View->m_Controls->m_ScalingFactor->setValue(fval); m_View->m_Controls->m_AdditionalScaling->setCurrentIndex(dynamic_cast(node->GetProperty("ScaleBy"))->GetValueAsId()); node->GetFloatProperty("IndexParam1",fval); m_View->m_Controls->m_IndexParam1->setValue(fval); node->GetFloatProperty("IndexParam2",fval); m_View->m_Controls->m_IndexParam2->setValue(fval); } void DoSelectionChanged(ISelection::ConstPointer selection) { // save current selection in member variable m_View->m_CurrentSelection = selection.Cast(); m_View->m_Controls->m_VisibleOdfsON_T->setVisible(false); m_View->m_Controls->m_VisibleOdfsON_S->setVisible(false); m_View->m_Controls->m_VisibleOdfsON_C->setVisible(false); m_View->m_Controls->m_TextureIntON->setVisible(false); m_View->m_Controls->m_ImageControlsFrame->setVisible(false); m_View->m_Controls->m_PlanarFigureControlsFrame->setVisible(false); m_View->m_Controls->m_BundleControlsFrame->setVisible(false); m_View->m_SelectedNode = 0; if(m_View->m_CurrentSelection.IsNull()) return; if(m_View->m_CurrentSelection->Size() == 1) { mitk::DataNodeObject::Pointer nodeObj = m_View->m_CurrentSelection->Begin()->Cast(); if(nodeObj.IsNotNull()) { mitk::DataNode::Pointer node = nodeObj->GetDataNode(); // check if node has data, // if some helper nodes are shown in the DataManager, the GetData() returns 0x0 which would lead to SIGSEV mitk::BaseData* nodeData = node->GetData(); if(nodeData != NULL ) { if(dynamic_cast(nodeData) != 0) { m_View->m_Controls->m_PlanarFigureControlsFrame->setVisible(true); m_View->m_SelectedNode = node; float val; node->GetFloatProperty("planarfigure.line.width", val); m_View->m_Controls->m_PFWidth->setValue((int)(val*10.0)); QString label = "Width %1"; label = label.arg(val); m_View->m_Controls->label_pfwidth->setText(label); float color[3]; node->GetColor( color, NULL, "planarfigure.default.line.color"); QString styleSheet = "background-color:rgb("; styleSheet.append(QString::number(color[0]*255.0)); styleSheet.append(","); styleSheet.append(QString::number(color[1]*255.0)); styleSheet.append(","); styleSheet.append(QString::number(color[2]*255.0)); styleSheet.append(")"); m_View->m_Controls->m_PFColor->setAutoFillBackground(true); m_View->m_Controls->m_PFColor->setStyleSheet(styleSheet); node->GetColor( color, NULL, "color"); styleSheet = "background-color:rgb("; styleSheet.append(QString::number(color[0]*255.0)); styleSheet.append(","); styleSheet.append(QString::number(color[1]*255.0)); styleSheet.append(","); styleSheet.append(QString::number(color[2]*255.0)); styleSheet.append(")"); m_View->PlanarFigureFocus(); } if(dynamic_cast(nodeData) != 0) { m_View->m_Controls->m_BundleControlsFrame->setVisible(true); m_View->m_SelectedNode = node; if(m_View->m_CurrentPickingNode != 0 && node.GetPointer() != m_View->m_CurrentPickingNode) { m_View->m_Controls->m_Crosshair->setEnabled(false); } else { m_View->m_Controls->m_Crosshair->setEnabled(true); } int width; node->GetIntProperty("LineWidth", width); m_View->m_Controls->m_LineWidth->setValue(width); float range; node->GetFloatProperty("Fiber2DSliceThickness",range); mitk::FiberBundleX::Pointer fib = dynamic_cast(node->GetData()); mitk::BaseGeometry::Pointer geo = fib->GetGeometry(); mitk::ScalarType max = geo->GetExtentInMM(0); max = std::max(max, geo->GetExtentInMM(1)); max = std::max(max, geo->GetExtentInMM(2)); m_View->m_Controls->m_FiberThicknessSlider->setMaximum(max * 10); m_View->m_Controls->m_FiberThicknessSlider->setValue(range * 10); } } // check node data != NULL } } if(m_View->m_CurrentSelection->Size() > 0 && m_View->m_SelectedNode == 0) { m_View->m_Controls->m_ImageControlsFrame->setVisible(true); bool foundDiffusionImage = false; bool foundQBIVolume = false; bool foundTensorVolume = false; bool foundImage = false; bool foundMultipleOdfImages = false; bool foundRGBAImage = false; bool foundTbssImage = false; // do something with the selected items if(m_View->m_CurrentSelection) { // iterate selection for (IStructuredSelection::iterator i = m_View->m_CurrentSelection->Begin(); i != m_View->m_CurrentSelection->End(); ++i) { // extract datatree node if (mitk::DataNodeObject::Pointer nodeObj = i->Cast()) { mitk::DataNode::Pointer node = nodeObj->GetDataNode(); mitk::BaseData* nodeData = node->GetData(); if(nodeData != NULL ) { // only look at interesting types if(QString("DiffusionImage").compare(nodeData->GetNameOfClass())==0) { foundDiffusionImage = true; bool tex_int; node->GetBoolProperty("texture interpolation", tex_int); if(tex_int) { m_View->m_Controls->m_TextureIntON->setIcon(*m_View->m_IconTexON); m_View->m_Controls->m_TextureIntON->setChecked(true); m_View->m_TexIsOn = true; } else { m_View->m_Controls->m_TextureIntON->setIcon(*m_View->m_IconTexOFF); m_View->m_Controls->m_TextureIntON->setChecked(false); m_View->m_TexIsOn = false; } int val; node->GetIntProperty("DisplayChannel", val); m_View->m_Controls->m_DisplayIndex->setValue(val); m_View->m_Controls->m_DisplayIndexSpinBox->setValue(val); QString label = "Channel %1"; label = label.arg(val); m_View->m_Controls->label_channel->setText(label); int maxVal = (dynamic_cast* >(nodeData))->GetVectorImage()->GetVectorLength(); m_View->m_Controls->m_DisplayIndex->setMaximum(maxVal-1); m_View->m_Controls->m_DisplayIndexSpinBox->setMaximum(maxVal-1); } if(QString("TbssImage").compare(nodeData->GetNameOfClass())==0) { foundTbssImage = true; bool tex_int; node->GetBoolProperty("texture interpolation", tex_int); if(tex_int) { m_View->m_Controls->m_TextureIntON->setIcon(*m_View->m_IconTexON); m_View->m_Controls->m_TextureIntON->setChecked(true); m_View->m_TexIsOn = true; } else { m_View->m_Controls->m_TextureIntON->setIcon(*m_View->m_IconTexOFF); m_View->m_Controls->m_TextureIntON->setChecked(false); m_View->m_TexIsOn = false; } int val; node->GetIntProperty("DisplayChannel", val); m_View->m_Controls->m_DisplayIndex->setValue(val); m_View->m_Controls->m_DisplayIndexSpinBox->setValue(val); QString label = "Channel %1"; label = label.arg(val); m_View->m_Controls->label_channel->setText(label); int maxVal = (dynamic_cast(nodeData))->GetImage()->GetVectorLength(); m_View->m_Controls->m_DisplayIndex->setMaximum(maxVal-1); m_View->m_Controls->m_DisplayIndexSpinBox->setMaximum(maxVal-1); } else if(QString("QBallImage").compare(nodeData->GetNameOfClass())==0) { foundMultipleOdfImages = foundQBIVolume || foundTensorVolume; foundQBIVolume = true; ApplySettings(node); } else if(QString("TensorImage").compare(nodeData->GetNameOfClass())==0) { foundMultipleOdfImages = foundQBIVolume || foundTensorVolume; foundTensorVolume = true; ApplySettings(node); } else if(QString("Image").compare(nodeData->GetNameOfClass())==0) { foundImage = true; mitk::Image::Pointer img = dynamic_cast(nodeData); if(img.IsNotNull() && img->GetPixelType().GetPixelType() == itk::ImageIOBase::RGBA && img->GetPixelType().GetComponentType() == itk::ImageIOBase::UCHAR ) { foundRGBAImage = true; } bool tex_int; node->GetBoolProperty("texture interpolation", tex_int); if(tex_int) { m_View->m_Controls->m_TextureIntON->setIcon(*m_View->m_IconTexON); m_View->m_Controls->m_TextureIntON->setChecked(true); m_View->m_TexIsOn = true; } else { m_View->m_Controls->m_TextureIntON->setIcon(*m_View->m_IconTexOFF); m_View->m_Controls->m_TextureIntON->setChecked(false); m_View->m_TexIsOn = false; } } } // END CHECK node != NULL } } } m_View->m_FoundSingleOdfImage = (foundQBIVolume || foundTensorVolume) && !foundMultipleOdfImages; m_View->m_Controls->m_NumberGlyphsFrame->setVisible(m_View->m_FoundSingleOdfImage); m_View->m_Controls->m_NormalizationDropdown->setVisible(m_View->m_FoundSingleOdfImage); m_View->m_Controls->label->setVisible(m_View->m_FoundSingleOdfImage); m_View->m_Controls->m_ScalingFactor->setVisible(m_View->m_FoundSingleOdfImage); m_View->m_Controls->m_AdditionalScaling->setVisible(m_View->m_FoundSingleOdfImage); m_View->m_Controls->m_NormalizationScalingFrame->setVisible(m_View->m_FoundSingleOdfImage); m_View->m_Controls->OpacMinFrame->setVisible(foundRGBAImage || m_View->m_FoundSingleOdfImage); // changed for SPIE paper, Principle curvature scaling //m_View->m_Controls->params_frame->setVisible(m_View->m_FoundSingleOdfImage); m_View->m_Controls->params_frame->setVisible(false); m_View->m_Controls->m_VisibleOdfsON_T->setVisible(m_View->m_FoundSingleOdfImage); m_View->m_Controls->m_VisibleOdfsON_S->setVisible(m_View->m_FoundSingleOdfImage); m_View->m_Controls->m_VisibleOdfsON_C->setVisible(m_View->m_FoundSingleOdfImage); bool foundAnyImage = foundDiffusionImage || foundQBIVolume || foundTensorVolume || foundImage || foundTbssImage; m_View->m_Controls->m_Reinit->setVisible(foundAnyImage); m_View->m_Controls->m_TextureIntON->setVisible(foundAnyImage); m_View->m_Controls->m_TSMenu->setVisible(foundAnyImage); } } void SelectionChanged(IWorkbenchPart::Pointer part, ISelection::ConstPointer selection) { // check, if selection comes from datamanager if (part) { QString partname(part->GetPartName().c_str()); if(partname.compare("Data Manager")==0) { // apply selection DoSelectionChanged(selection); } } } QmitkControlVisualizationPropertiesView* m_View; }; QmitkControlVisualizationPropertiesView::QmitkControlVisualizationPropertiesView() : QmitkFunctionality(), m_Controls(NULL), m_MultiWidget(NULL), m_NodeUsedForOdfVisualization(NULL), m_IconTexOFF(new QIcon(":/QmitkDiffusionImaging/texIntOFFIcon.png")), m_IconTexON(new QIcon(":/QmitkDiffusionImaging/texIntONIcon.png")), m_IconGlyOFF_T(new QIcon(":/QmitkDiffusionImaging/glyphsoff_T.png")), m_IconGlyON_T(new QIcon(":/QmitkDiffusionImaging/glyphson_T.png")), m_IconGlyOFF_C(new QIcon(":/QmitkDiffusionImaging/glyphsoff_C.png")), m_IconGlyON_C(new QIcon(":/QmitkDiffusionImaging/glyphson_C.png")), m_IconGlyOFF_S(new QIcon(":/QmitkDiffusionImaging/glyphsoff_S.png")), m_IconGlyON_S(new QIcon(":/QmitkDiffusionImaging/glyphson_S.png")), m_CurrentSelection(0), m_CurrentPickingNode(0), m_GlyIsOn_S(false), m_GlyIsOn_C(false), m_GlyIsOn_T(false), m_FiberBundleObserverTag(0), m_Color(NULL) { currentThickSlicesMode = 1; m_MyMenu = NULL; int numThread = itk::MultiThreader::GetGlobalMaximumNumberOfThreads(); if (numThread > 12) numThread = 12; itk::MultiThreader::SetGlobalDefaultNumberOfThreads(numThread); } QmitkControlVisualizationPropertiesView::QmitkControlVisualizationPropertiesView(const QmitkControlVisualizationPropertiesView& other) { Q_UNUSED(other) throw std::runtime_error("Copy constructor not implemented"); } QmitkControlVisualizationPropertiesView::~QmitkControlVisualizationPropertiesView() { if(m_SlicesRotationObserverTag1 ) { mitk::SlicesCoordinator::Pointer coordinator = m_MultiWidget->GetSlicesRotator(); if( coordinator.IsNotNull() ) coordinator->RemoveObserver(m_SlicesRotationObserverTag1); } if( m_SlicesRotationObserverTag2) { mitk::SlicesCoordinator::Pointer coordinator = m_MultiWidget->GetSlicesRotator(); if( coordinator.IsNotNull() ) coordinator->RemoveObserver(m_SlicesRotationObserverTag1); } this->GetSite()->GetWorkbenchWindow()->GetSelectionService()->RemovePostSelectionListener(/*"org.mitk.views.datamanager",*/ m_SelListener); } void QmitkControlVisualizationPropertiesView::OnThickSlicesModeSelected( QAction* action ) { currentThickSlicesMode = action->data().toInt(); switch(currentThickSlicesMode) { default: case 1: this->m_Controls->m_TSMenu->setText("MIP"); break; case 2: this->m_Controls->m_TSMenu->setText("SUM"); break; case 3: this->m_Controls->m_TSMenu->setText("WEIGH"); break; } mitk::DataNode* n; n = this->m_MultiWidget->GetWidgetPlane1(); if(n) n->SetProperty( "reslice.thickslices", mitk::ResliceMethodProperty::New( currentThickSlicesMode ) ); n = this->m_MultiWidget->GetWidgetPlane2(); if(n) n->SetProperty( "reslice.thickslices", mitk::ResliceMethodProperty::New( currentThickSlicesMode ) ); n = this->m_MultiWidget->GetWidgetPlane3(); if(n) n->SetProperty( "reslice.thickslices", mitk::ResliceMethodProperty::New( currentThickSlicesMode ) ); mitk::BaseRenderer::Pointer renderer = this->GetActiveStdMultiWidget()->GetRenderWindow1()->GetRenderer(); if(renderer.IsNotNull()) { renderer->SendUpdateSlice(); } renderer = this->GetActiveStdMultiWidget()->GetRenderWindow2()->GetRenderer(); if(renderer.IsNotNull()) { renderer->SendUpdateSlice(); } renderer = this->GetActiveStdMultiWidget()->GetRenderWindow3()->GetRenderer(); if(renderer.IsNotNull()) { renderer->SendUpdateSlice(); } renderer->GetRenderingManager()->RequestUpdateAll(); } void QmitkControlVisualizationPropertiesView::OnTSNumChanged(int num) { if(num==0) { mitk::DataNode* n; n = this->m_MultiWidget->GetWidgetPlane1(); if(n) n->SetProperty( "reslice.thickslices", mitk::ResliceMethodProperty::New( 0 ) ); if(n) n->SetProperty( "reslice.thickslices.num", mitk::IntProperty::New( num ) ); if(n) n->SetProperty( "reslice.thickslices.showarea", mitk::BoolProperty::New( false ) ); n = this->m_MultiWidget->GetWidgetPlane2(); if(n) n->SetProperty( "reslice.thickslices", mitk::ResliceMethodProperty::New( 0 ) ); if(n) n->SetProperty( "reslice.thickslices.num", mitk::IntProperty::New( num ) ); if(n) n->SetProperty( "reslice.thickslices.showarea", mitk::BoolProperty::New( false ) ); n = this->m_MultiWidget->GetWidgetPlane3(); if(n) n->SetProperty( "reslice.thickslices", mitk::ResliceMethodProperty::New( 0 ) ); if(n) n->SetProperty( "reslice.thickslices.num", mitk::IntProperty::New( num ) ); if(n) n->SetProperty( "reslice.thickslices.showarea", mitk::BoolProperty::New( false ) ); } else { mitk::DataNode* n; n = this->m_MultiWidget->GetWidgetPlane1(); if(n) n->SetProperty( "reslice.thickslices", mitk::ResliceMethodProperty::New( currentThickSlicesMode ) ); if(n) n->SetProperty( "reslice.thickslices.num", mitk::IntProperty::New( num ) ); if(n) n->SetProperty( "reslice.thickslices.showarea", mitk::BoolProperty::New( (num>0) ) ); n = this->m_MultiWidget->GetWidgetPlane2(); if(n) n->SetProperty( "reslice.thickslices", mitk::ResliceMethodProperty::New( currentThickSlicesMode ) ); if(n) n->SetProperty( "reslice.thickslices.num", mitk::IntProperty::New( num ) ); if(n) n->SetProperty( "reslice.thickslices.showarea", mitk::BoolProperty::New( (num>0) ) ); n = this->m_MultiWidget->GetWidgetPlane3(); if(n) n->SetProperty( "reslice.thickslices", mitk::ResliceMethodProperty::New( currentThickSlicesMode ) ); if(n) n->SetProperty( "reslice.thickslices.num", mitk::IntProperty::New( num ) ); if(n) n->SetProperty( "reslice.thickslices.showarea", mitk::BoolProperty::New( (num>0) ) ); } m_TSLabel->setText(QString::number(num*2+1)); mitk::BaseRenderer::Pointer renderer = this->GetActiveStdMultiWidget()->GetRenderWindow1()->GetRenderer(); if(renderer.IsNotNull()) renderer->SendUpdateSlice(); renderer = this->GetActiveStdMultiWidget()->GetRenderWindow2()->GetRenderer(); if(renderer.IsNotNull()) renderer->SendUpdateSlice(); renderer = this->GetActiveStdMultiWidget()->GetRenderWindow3()->GetRenderer(); if(renderer.IsNotNull()) renderer->SendUpdateSlice(); renderer->GetRenderingManager()->RequestUpdateAll(mitk::RenderingManager::REQUEST_UPDATE_2DWINDOWS); } void QmitkControlVisualizationPropertiesView::CreateQtPartControl(QWidget *parent) { if (!m_Controls) { // create GUI widgets m_Controls = new Ui::QmitkControlVisualizationPropertiesViewControls; m_Controls->setupUi(parent); this->CreateConnections(); // hide warning (ODFs in rotated planes) m_Controls->m_lblRotatedPlanesWarning->hide(); m_MyMenu = new QMenu(parent); // button for changing rotation mode m_Controls->m_TSMenu->setMenu( m_MyMenu ); //m_CrosshairModeButton->setIcon( QIcon( iconCrosshairMode_xpm ) ); m_Controls->params_frame->setVisible(false); QIcon icon5(":/QmitkDiffusionImaging/Refresh_48.png"); m_Controls->m_Reinit->setIcon(icon5); m_Controls->m_Focus->setIcon(icon5); QIcon iconColor(":/QmitkDiffusionImaging/color24.gif"); m_Controls->m_PFColor->setIcon(iconColor); m_Controls->m_Color->setIcon(iconColor); QIcon iconReset(":/QmitkDiffusionImaging/reset.png"); m_Controls->m_ResetColoring->setIcon(iconReset); m_Controls->m_PFColor->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); QIcon iconCrosshair(":/QmitkDiffusionImaging/crosshair.png"); m_Controls->m_Crosshair->setIcon(iconCrosshair); // was is los QIcon iconPaint(":/QmitkDiffusionImaging/paint2.png"); m_Controls->m_TDI->setIcon(iconPaint); QIcon iconFiberFade(":/QmitkDiffusionImaging/MapperEfx2D.png"); m_Controls->m_FiberFading2D->setIcon(iconFiberFade); m_Controls->m_TextureIntON->setCheckable(true); #ifndef DIFFUSION_IMAGING_EXTENDED int size = m_Controls->m_AdditionalScaling->count(); for(int t=0; tm_AdditionalScaling->itemText(t).toStdString() == "Scale by ASR") { - m_Controls->m_AdditionalScaling->removeItem(t); + m_Controls->m_AdditionalScaling->removeItem(t); } } #endif m_Controls->m_OpacitySlider->setRange(0.0,1.0); - m_Controls->m_OpacitySlider->setLowerValue(0.0); - m_Controls->m_OpacitySlider->setUpperValue(0.0); + m_Controls->m_OpacitySlider->setMinimumValue(0.0); + m_Controls->m_OpacitySlider->setMaximumValue(0.0); m_Controls->m_ScalingFrame->setVisible(false); m_Controls->m_NormalizationFrame->setVisible(false); } m_IsInitialized = false; m_SelListener = berry::ISelectionListener::Pointer(new CvpSelListener(this)); this->GetSite()->GetWorkbenchWindow()->GetSelectionService()->AddPostSelectionListener(/*"org.mitk.views.datamanager",*/ m_SelListener); berry::ISelection::ConstPointer sel( this->GetSite()->GetWorkbenchWindow()->GetSelectionService()->GetSelection("org.mitk.views.datamanager")); m_CurrentSelection = sel.Cast(); m_SelListener.Cast()->DoSelectionChanged(sel); m_IsInitialized = true; } void QmitkControlVisualizationPropertiesView::StdMultiWidgetAvailable (QmitkStdMultiWidget &stdMultiWidget) { m_MultiWidget = &stdMultiWidget; if (m_MultiWidget) { mitk::SlicesCoordinator* coordinator = m_MultiWidget->GetSlicesRotator(); if (coordinator) { itk::ReceptorMemberCommand::Pointer command2 = itk::ReceptorMemberCommand::New(); command2->SetCallbackFunction( this, &QmitkControlVisualizationPropertiesView::SliceRotation ); m_SlicesRotationObserverTag1 = coordinator->AddObserver( mitk::SliceRotationEvent(), command2 ); } coordinator = m_MultiWidget->GetSlicesSwiveller(); if (coordinator) { itk::ReceptorMemberCommand::Pointer command2 = itk::ReceptorMemberCommand::New(); command2->SetCallbackFunction( this, &QmitkControlVisualizationPropertiesView::SliceRotation ); m_SlicesRotationObserverTag2 = coordinator->AddObserver( mitk::SliceRotationEvent(), command2 ); } } } void QmitkControlVisualizationPropertiesView::SliceRotation(const itk::EventObject&) { // test if plane rotated if( m_GlyIsOn_T || m_GlyIsOn_C || m_GlyIsOn_S ) { if( this->IsPlaneRotated() ) { // show label m_Controls->m_lblRotatedPlanesWarning->show(); } else { //hide label m_Controls->m_lblRotatedPlanesWarning->hide(); } } } void QmitkControlVisualizationPropertiesView::StdMultiWidgetNotAvailable() { m_MultiWidget = NULL; } void QmitkControlVisualizationPropertiesView::NodeRemoved(const mitk::DataNode* node) { } #include void QmitkControlVisualizationPropertiesView::CreateConnections() { if ( m_Controls ) { connect( (QObject*)(m_Controls->m_DisplayIndex), SIGNAL(valueChanged(int)), this, SLOT(DisplayIndexChanged(int)) ); connect( (QObject*)(m_Controls->m_DisplayIndexSpinBox), SIGNAL(valueChanged(int)), this, SLOT(DisplayIndexChanged(int)) ); connect( (QObject*)(m_Controls->m_TextureIntON), SIGNAL(clicked()), this, SLOT(TextIntON()) ); connect( (QObject*)(m_Controls->m_Reinit), SIGNAL(clicked()), this, SLOT(Reinit()) ); connect( (QObject*)(m_Controls->m_VisibleOdfsON_T), SIGNAL(clicked()), this, SLOT(VisibleOdfsON_T()) ); connect( (QObject*)(m_Controls->m_VisibleOdfsON_S), SIGNAL(clicked()), this, SLOT(VisibleOdfsON_S()) ); connect( (QObject*)(m_Controls->m_VisibleOdfsON_C), SIGNAL(clicked()), this, SLOT(VisibleOdfsON_C()) ); connect( (QObject*)(m_Controls->m_ShowMaxNumber), SIGNAL(editingFinished()), this, SLOT(ShowMaxNumberChanged()) ); connect( (QObject*)(m_Controls->m_NormalizationDropdown), SIGNAL(currentIndexChanged(int)), this, SLOT(NormalizationDropdownChanged(int)) ); connect( (QObject*)(m_Controls->m_ScalingFactor), SIGNAL(valueChanged(double)), this, SLOT(ScalingFactorChanged(double)) ); connect( (QObject*)(m_Controls->m_AdditionalScaling), SIGNAL(currentIndexChanged(int)), this, SLOT(AdditionalScaling(int)) ); connect( (QObject*)(m_Controls->m_IndexParam1), SIGNAL(valueChanged(double)), this, SLOT(IndexParam1Changed(double)) ); connect( (QObject*)(m_Controls->m_IndexParam2), SIGNAL(valueChanged(double)), this, SLOT(IndexParam2Changed(double)) ); connect( (QObject*)(m_Controls->m_ScalingCheckbox), SIGNAL(clicked()), this, SLOT(ScalingCheckbox()) ); connect( (QObject*)(m_Controls->m_OpacitySlider), SIGNAL(spanChanged(double,double)), this, SLOT(OpacityChanged(double,double)) ); connect((QObject*) m_Controls->m_Color, SIGNAL(clicked()), (QObject*) this, SLOT(BundleRepresentationColor())); connect((QObject*) m_Controls->m_ResetColoring, SIGNAL(clicked()), (QObject*) this, SLOT(BundleRepresentationResetColoring())); connect((QObject*) m_Controls->m_Focus, SIGNAL(clicked()), (QObject*) this, SLOT(PlanarFigureFocus())); connect((QObject*) m_Controls->m_FiberFading2D, SIGNAL(clicked()), (QObject*) this, SLOT( Fiber2DfadingEFX() ) ); connect((QObject*) m_Controls->m_FiberThicknessSlider, SIGNAL(sliderReleased()), (QObject*) this, SLOT( FiberSlicingThickness2D() ) ); connect((QObject*) m_Controls->m_FiberThicknessSlider, SIGNAL(valueChanged(int)), (QObject*) this, SLOT( FiberSlicingUpdateLabel(int) )); connect((QObject*) m_Controls->m_Crosshair, SIGNAL(clicked()), (QObject*) this, SLOT(SetInteractor())); connect((QObject*) m_Controls->m_PFWidth, SIGNAL(valueChanged(int)), (QObject*) this, SLOT(PFWidth(int))); connect((QObject*) m_Controls->m_PFColor, SIGNAL(clicked()), (QObject*) this, SLOT(PFColor())); connect((QObject*) m_Controls->m_TDI, SIGNAL(clicked()), (QObject*) this, SLOT(GenerateTdi())); connect((QObject*) m_Controls->m_LineWidth, SIGNAL(editingFinished()), (QObject*) this, SLOT(LineWidthChanged())); } } void QmitkControlVisualizationPropertiesView::Activated() { berry::ISelection::ConstPointer sel( this->GetSite()->GetWorkbenchWindow()->GetSelectionService()->GetSelection("org.mitk.views.datamanager")); m_CurrentSelection = sel.Cast(); m_SelListener.Cast()->DoSelectionChanged(sel); QmitkFunctionality::Activated(); } void QmitkControlVisualizationPropertiesView::Deactivated() { QmitkFunctionality::Deactivated(); } int QmitkControlVisualizationPropertiesView::GetSizeFlags(bool width) { if(!width) { return berry::Constants::MIN | berry::Constants::MAX | berry::Constants::FILL; } else { return 0; } } int QmitkControlVisualizationPropertiesView::ComputePreferredSize(bool width, int /*availableParallel*/, int /*availablePerpendicular*/, int preferredResult) { if(width==false) { return m_FoundSingleOdfImage ? 120 : 80; } else { return preferredResult; } } // set diffusion image channel to b0 volume void QmitkControlVisualizationPropertiesView::NodeAdded(const mitk::DataNode *node) { mitk::DataNode* notConst = const_cast(node); if (dynamic_cast*>(notConst->GetData())) { mitk::DiffusionImage::Pointer dimg = dynamic_cast*>(notConst->GetData()); // if there is no b0 image in the dataset, the GetB0Indices() returns a vector of size 0 // and hence we cannot set the Property directly to .front() int displayChannelPropertyValue = 0; mitk::DiffusionImage::BValueMap map = dimg->GetBValueMap(); if( map[0].size() > 0) displayChannelPropertyValue = map[0].front(); notConst->SetIntProperty("DisplayChannel", displayChannelPropertyValue ); } } /* OnSelectionChanged is registered to SelectionService, therefore no need to implement SelectionService Listener explicitly */ void QmitkControlVisualizationPropertiesView::OnSelectionChanged( std::vector nodes ) { // deactivate channel slider if no diffusion weighted image or tbss image is selected m_Controls->m_DisplayIndex->setVisible(false); m_Controls->m_DisplayIndexSpinBox->setVisible(false); m_Controls->label_channel->setVisible(false); for( std::vector::iterator it = nodes.begin(); it != nodes.end(); ++it ) { mitk::DataNode::Pointer node = *it; // check if node has data, // if some helper nodes are shown in the DataManager, the GetData() returns 0x0 which would lead to SIGSEV mitk::BaseData* nodeData = node->GetData(); if(nodeData == NULL) continue; if (node.IsNotNull() && (dynamic_cast(nodeData) || dynamic_cast*>(nodeData))) { m_Controls->m_DisplayIndex->setVisible(true); m_Controls->m_DisplayIndexSpinBox->setVisible(true); m_Controls->label_channel->setVisible(true); } else if (node.IsNotNull() && dynamic_cast(node->GetData())) { if (m_Color.IsNotNull()) m_Color->RemoveObserver(m_FiberBundleObserverTag); itk::ReceptorMemberCommand::Pointer command = itk::ReceptorMemberCommand::New(); command->SetCallbackFunction( this, &QmitkControlVisualizationPropertiesView::SetFiberBundleCustomColor ); m_Color = dynamic_cast(node->GetProperty("color", NULL)); if (m_Color.IsNotNull()) m_FiberBundleObserverTag = m_Color->AddObserver( itk::ModifiedEvent(), command ); } } for( std::vector::iterator it = nodes.begin(); it != nodes.end(); ++it ) { mitk::DataNode::Pointer node = *it; // check if node has data, // if some helper nodes are shown in the DataManager, the GetData() returns 0x0 which would lead to SIGSEV mitk::BaseData* nodeData = node->GetData(); if(nodeData == NULL) continue; if( node.IsNotNull() && (dynamic_cast(nodeData) || dynamic_cast(nodeData)) ) { if(m_NodeUsedForOdfVisualization.IsNotNull()) { m_NodeUsedForOdfVisualization->SetBoolProperty("VisibleOdfs_S", false); m_NodeUsedForOdfVisualization->SetBoolProperty("VisibleOdfs_C", false); m_NodeUsedForOdfVisualization->SetBoolProperty("VisibleOdfs_T", false); } m_NodeUsedForOdfVisualization = node; m_NodeUsedForOdfVisualization->SetBoolProperty("VisibleOdfs_S", m_GlyIsOn_S); m_NodeUsedForOdfVisualization->SetBoolProperty("VisibleOdfs_C", m_GlyIsOn_C); m_NodeUsedForOdfVisualization->SetBoolProperty("VisibleOdfs_T", m_GlyIsOn_T); if(m_MultiWidget) m_MultiWidget->RequestUpdate(); m_Controls->m_TSMenu->setVisible(false); // deactivate mip etc. for tensor and q-ball images break; } else if( node.IsNotNull() && dynamic_cast(nodeData) ) m_Controls->m_TSMenu->setVisible(false); else m_Controls->m_TSMenu->setVisible(true); } // if selection changes, set the current selction member and call SellListener::DoSelectionChanged berry::ISelection::ConstPointer sel( this->GetSite()->GetWorkbenchWindow()->GetSelectionService()->GetSelection("org.mitk.views.datamanager")); m_CurrentSelection = sel.Cast(); m_SelListener.Cast()->DoSelectionChanged(sel); // adapt thick slice controls // THICK SLICE SUPPORT if( nodes.size() < 1) return; mitk::DataNode::Pointer node = nodes.at(0); if( node.IsNull() ) return; QMenu *myMenu = m_MyMenu; myMenu->clear(); QActionGroup* thickSlicesActionGroup = new QActionGroup(myMenu); thickSlicesActionGroup->setExclusive(true); int currentTSMode = 0; { mitk::ResliceMethodProperty::Pointer m = dynamic_cast(node->GetProperty( "reslice.thickslices" )); if( m.IsNotNull() ) currentTSMode = m->GetValueAsId(); } int maxTS = 30; for( std::vector::iterator it = nodes.begin(); it != nodes.end(); ++it ) { mitk::Image* image = dynamic_cast((*it)->GetData()); if (image) { int size = std::max(image->GetDimension(0), std::max(image->GetDimension(1), image->GetDimension(2))); if (size>maxTS) maxTS=size; } } maxTS /= 2; int currentNum = 0; { mitk::IntProperty::Pointer m = dynamic_cast(node->GetProperty( "reslice.thickslices.num" )); if( m.IsNotNull() ) { currentNum = m->GetValue(); if(currentNum < 0) currentNum = 0; if(currentNum > maxTS) currentNum = maxTS; } } if(currentTSMode==0) currentNum=0; QSlider *m_TSSlider = new QSlider(myMenu); m_TSSlider->setMinimum(0); m_TSSlider->setMaximum(maxTS-1); m_TSSlider->setValue(currentNum); m_TSSlider->setOrientation(Qt::Horizontal); connect( m_TSSlider, SIGNAL( valueChanged(int) ), this, SLOT( OnTSNumChanged(int) ) ); QHBoxLayout* _TSLayout = new QHBoxLayout; _TSLayout->setContentsMargins(4,4,4,4); _TSLayout->addWidget(m_TSSlider); _TSLayout->addWidget(m_TSLabel=new QLabel(QString::number(currentNum*2+1),myMenu)); QWidget* _TSWidget = new QWidget; _TSWidget->setLayout(_TSLayout); QActionGroup* thickSliceModeActionGroup = new QActionGroup(myMenu); thickSliceModeActionGroup->setExclusive(true); QWidgetAction *m_TSSliderAction = new QWidgetAction(myMenu); m_TSSliderAction->setDefaultWidget(_TSWidget); myMenu->addAction(m_TSSliderAction); QAction* mipThickSlicesAction = new QAction(myMenu); mipThickSlicesAction->setActionGroup(thickSliceModeActionGroup); mipThickSlicesAction->setText("MIP (max. intensity proj.)"); mipThickSlicesAction->setCheckable(true); mipThickSlicesAction->setChecked(currentThickSlicesMode==1); mipThickSlicesAction->setData(1); myMenu->addAction( mipThickSlicesAction ); QAction* sumThickSlicesAction = new QAction(myMenu); sumThickSlicesAction->setActionGroup(thickSliceModeActionGroup); sumThickSlicesAction->setText("SUM (sum intensity proj.)"); sumThickSlicesAction->setCheckable(true); sumThickSlicesAction->setChecked(currentThickSlicesMode==2); sumThickSlicesAction->setData(2); myMenu->addAction( sumThickSlicesAction ); QAction* weightedThickSlicesAction = new QAction(myMenu); weightedThickSlicesAction->setActionGroup(thickSliceModeActionGroup); weightedThickSlicesAction->setText("WEIGHTED (gaussian proj.)"); weightedThickSlicesAction->setCheckable(true); weightedThickSlicesAction->setChecked(currentThickSlicesMode==3); weightedThickSlicesAction->setData(3); myMenu->addAction( weightedThickSlicesAction ); connect( thickSliceModeActionGroup, SIGNAL(triggered(QAction*)), this, SLOT(OnThickSlicesModeSelected(QAction*)) ); } mitk::DataStorage::SetOfObjects::Pointer QmitkControlVisualizationPropertiesView::ActiveSet(std::string classname) { if (m_CurrentSelection) { mitk::DataStorage::SetOfObjects::Pointer set = mitk::DataStorage::SetOfObjects::New(); int at = 0; for (IStructuredSelection::iterator i = m_CurrentSelection->Begin(); i != m_CurrentSelection->End(); ++i) { if (mitk::DataNodeObject::Pointer nodeObj = i->Cast()) { mitk::DataNode::Pointer node = nodeObj->GetDataNode(); // check if node has data, // if some helper nodes are shown in the DataManager, the GetData() returns 0x0 which would lead to SIGSEV const mitk::BaseData* nodeData = node->GetData(); if(nodeData == NULL) continue; if(QString(classname.c_str()).compare(nodeData->GetNameOfClass())==0) { set->InsertElement(at++, node); } } } return set; } return 0; } void QmitkControlVisualizationPropertiesView::SetBoolProp( mitk::DataStorage::SetOfObjects::Pointer set, std::string name, bool value) { if(set.IsNotNull()) { mitk::DataStorage::SetOfObjects::const_iterator itemiter( set->begin() ); mitk::DataStorage::SetOfObjects::const_iterator itemiterend( set->end() ); while ( itemiter != itemiterend ) { (*itemiter)->SetBoolProperty(name.c_str(), value); ++itemiter; } } } void QmitkControlVisualizationPropertiesView::SetIntProp( mitk::DataStorage::SetOfObjects::Pointer set, std::string name, int value) { if(set.IsNotNull()) { mitk::DataStorage::SetOfObjects::const_iterator itemiter( set->begin() ); mitk::DataStorage::SetOfObjects::const_iterator itemiterend( set->end() ); while ( itemiter != itemiterend ) { (*itemiter)->SetIntProperty(name.c_str(), value); ++itemiter; } } } void QmitkControlVisualizationPropertiesView::SetFloatProp( mitk::DataStorage::SetOfObjects::Pointer set, std::string name, float value) { if(set.IsNotNull()) { mitk::DataStorage::SetOfObjects::const_iterator itemiter( set->begin() ); mitk::DataStorage::SetOfObjects::const_iterator itemiterend( set->end() ); while ( itemiter != itemiterend ) { (*itemiter)->SetFloatProperty(name.c_str(), value); ++itemiter; } } } void QmitkControlVisualizationPropertiesView::SetLevelWindowProp( mitk::DataStorage::SetOfObjects::Pointer set, std::string name, mitk::LevelWindow value) { if(set.IsNotNull()) { mitk::LevelWindowProperty::Pointer prop = mitk::LevelWindowProperty::New(value); mitk::DataStorage::SetOfObjects::const_iterator itemiter( set->begin() ); mitk::DataStorage::SetOfObjects::const_iterator itemiterend( set->end() ); while ( itemiter != itemiterend ) { (*itemiter)->SetProperty(name.c_str(), prop); ++itemiter; } } } void QmitkControlVisualizationPropertiesView::SetEnumProp( mitk::DataStorage::SetOfObjects::Pointer set, std::string name, mitk::EnumerationProperty::Pointer value) { if(set.IsNotNull()) { mitk::DataStorage::SetOfObjects::const_iterator itemiter( set->begin() ); mitk::DataStorage::SetOfObjects::const_iterator itemiterend( set->end() ); while ( itemiter != itemiterend ) { (*itemiter)->SetProperty(name.c_str(), value); ++itemiter; } } } void QmitkControlVisualizationPropertiesView::DisplayIndexChanged(int dispIndex) { m_Controls->m_DisplayIndex->setValue(dispIndex); m_Controls->m_DisplayIndexSpinBox->setValue(dispIndex); QString label = "Channel %1"; label = label.arg(dispIndex); m_Controls->label_channel->setText(label); std::vector sets; sets.push_back("DiffusionImage"); sets.push_back("TbssImage"); std::vector::iterator it = sets.begin(); while(it != sets.end()) { std::string s = *it; mitk::DataStorage::SetOfObjects::Pointer set = ActiveSet(s); if(set.IsNotNull()) { mitk::DataStorage::SetOfObjects::const_iterator itemiter( set->begin() ); mitk::DataStorage::SetOfObjects::const_iterator itemiterend( set->end() ); while ( itemiter != itemiterend ) { (*itemiter)->SetIntProperty("DisplayChannel", dispIndex); ++itemiter; } //m_MultiWidget->RequestUpdate(); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } it++; } } void QmitkControlVisualizationPropertiesView::Reinit() { if (m_CurrentSelection) { mitk::DataNodeObject::Pointer nodeObj = m_CurrentSelection->Begin()->Cast(); mitk::DataNode::Pointer node = nodeObj->GetDataNode(); mitk::BaseData::Pointer basedata = node->GetData(); if (basedata.IsNotNull()) { mitk::RenderingManager::GetInstance()->InitializeViews( basedata->GetTimeGeometry(), mitk::RenderingManager::REQUEST_UPDATE_ALL, true ); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } } } void QmitkControlVisualizationPropertiesView::TextIntON() { if(m_TexIsOn) { m_Controls->m_TextureIntON->setIcon(*m_IconTexOFF); } else { m_Controls->m_TextureIntON->setIcon(*m_IconTexON); } mitk::DataStorage::SetOfObjects::Pointer set = ActiveSet("DiffusionImage"); SetBoolProp(set,"texture interpolation", !m_TexIsOn); set = ActiveSet("TensorImage"); SetBoolProp(set,"texture interpolation", !m_TexIsOn); set = ActiveSet("QBallImage"); SetBoolProp(set,"texture interpolation", !m_TexIsOn); set = ActiveSet("Image"); SetBoolProp(set,"texture interpolation", !m_TexIsOn); m_TexIsOn = !m_TexIsOn; if(m_MultiWidget) m_MultiWidget->RequestUpdate(); } void QmitkControlVisualizationPropertiesView::VisibleOdfsON_S() { m_GlyIsOn_S = m_Controls->m_VisibleOdfsON_S->isChecked(); if (m_NodeUsedForOdfVisualization.IsNull()) { MITK_WARN << "ODF visualization activated but m_NodeUsedForOdfVisualization is NULL"; return; } m_NodeUsedForOdfVisualization->SetBoolProperty("VisibleOdfs_S", m_GlyIsOn_S); VisibleOdfsON(0); } void QmitkControlVisualizationPropertiesView::VisibleOdfsON_T() { m_GlyIsOn_T = m_Controls->m_VisibleOdfsON_T->isChecked(); if (m_NodeUsedForOdfVisualization.IsNull()) { MITK_WARN << "ODF visualization activated but m_NodeUsedForOdfVisualization is NULL"; return; } m_NodeUsedForOdfVisualization->SetBoolProperty("VisibleOdfs_T", m_GlyIsOn_T); VisibleOdfsON(1); } void QmitkControlVisualizationPropertiesView::VisibleOdfsON_C() { m_GlyIsOn_C = m_Controls->m_VisibleOdfsON_C->isChecked(); if (m_NodeUsedForOdfVisualization.IsNull()) { MITK_WARN << "ODF visualization activated but m_NodeUsedForOdfVisualization is NULL"; return; } m_NodeUsedForOdfVisualization->SetBoolProperty("VisibleOdfs_C", m_GlyIsOn_C); VisibleOdfsON(2); } bool QmitkControlVisualizationPropertiesView::IsPlaneRotated() { // for all 2D renderwindows of m_MultiWidget check alignment mitk::PlaneGeometry::ConstPointer displayPlane = dynamic_cast( m_MultiWidget->GetRenderWindow1()->GetRenderer()->GetCurrentWorldGeometry2D() ); if (displayPlane.IsNull()) return false; mitk::Image* currentImage = dynamic_cast( m_NodeUsedForOdfVisualization->GetData() ); if( currentImage == NULL ) { MITK_ERROR << " Casting problems. Returning false"; return false; } int affectedDimension(-1); int affectedSlice(-1); return !(DetermineAffectedImageSlice( currentImage, displayPlane, affectedDimension, affectedSlice )); } void QmitkControlVisualizationPropertiesView::VisibleOdfsON(int view) { if(m_MultiWidget) m_MultiWidget->RequestUpdate(); } void QmitkControlVisualizationPropertiesView::ShowMaxNumberChanged() { int maxNr = m_Controls->m_ShowMaxNumber->value(); if ( maxNr < 1 ) { m_Controls->m_ShowMaxNumber->setValue( 1 ); maxNr = 1; } mitk::DataStorage::SetOfObjects::Pointer set = ActiveSet("QBallImage"); SetIntProp(set,"ShowMaxNumber", maxNr); set = ActiveSet("TensorImage"); SetIntProp(set,"ShowMaxNumber", maxNr); if(m_MultiWidget) m_MultiWidget->RequestUpdate(); } void QmitkControlVisualizationPropertiesView::NormalizationDropdownChanged(int normDropdown) { typedef mitk::OdfNormalizationMethodProperty PropType; PropType::Pointer normMeth = PropType::New(); switch(normDropdown) { case 0: normMeth->SetNormalizationToMinMax(); break; case 1: normMeth->SetNormalizationToMax(); break; case 2: normMeth->SetNormalizationToNone(); break; case 3: normMeth->SetNormalizationToGlobalMax(); break; default: normMeth->SetNormalizationToMinMax(); } mitk::DataStorage::SetOfObjects::Pointer set = ActiveSet("QBallImage"); SetEnumProp(set,"Normalization", normMeth.GetPointer()); set = ActiveSet("TensorImage"); SetEnumProp(set,"Normalization", normMeth.GetPointer()); // if(m_MultiWidget) // m_MultiWidget->RequestUpdate(); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } void QmitkControlVisualizationPropertiesView::ScalingFactorChanged(double scalingFactor) { mitk::DataStorage::SetOfObjects::Pointer set = ActiveSet("QBallImage"); SetFloatProp(set,"Scaling", scalingFactor); set = ActiveSet("TensorImage"); SetFloatProp(set,"Scaling", scalingFactor); if(m_MultiWidget) m_MultiWidget->RequestUpdate(); } void QmitkControlVisualizationPropertiesView::AdditionalScaling(int additionalScaling) { typedef mitk::OdfScaleByProperty PropType; PropType::Pointer scaleBy = PropType::New(); switch(additionalScaling) { case 0: scaleBy->SetScaleByNothing(); break; case 1: scaleBy->SetScaleByGFA(); //m_Controls->params_frame->setVisible(true); break; #ifdef DIFFUSION_IMAGING_EXTENDED case 2: scaleBy->SetScaleByPrincipalCurvature(); // commented in for SPIE paper, Principle curvature scaling //m_Controls->params_frame->setVisible(true); break; #endif default: scaleBy->SetScaleByNothing(); } mitk::DataStorage::SetOfObjects::Pointer set = ActiveSet("QBallImage"); SetEnumProp(set,"ScaleBy", scaleBy.GetPointer()); set = ActiveSet("TensorImage"); SetEnumProp(set,"ScaleBy", scaleBy.GetPointer()); if(m_MultiWidget) m_MultiWidget->RequestUpdate(); } void QmitkControlVisualizationPropertiesView::IndexParam1Changed(double param1) { mitk::DataStorage::SetOfObjects::Pointer set = ActiveSet("QBallImage"); SetFloatProp(set,"IndexParam1", param1); set = ActiveSet("TensorImage"); SetFloatProp(set,"IndexParam1", param1); if(m_MultiWidget) m_MultiWidget->RequestUpdate(); } void QmitkControlVisualizationPropertiesView::IndexParam2Changed(double param2) { mitk::DataStorage::SetOfObjects::Pointer set = ActiveSet("QBallImage"); SetFloatProp(set,"IndexParam2", param2); set = ActiveSet("TensorImage"); SetFloatProp(set,"IndexParam2", param2); if(m_MultiWidget) m_MultiWidget->RequestUpdate(); } void QmitkControlVisualizationPropertiesView::OpacityChanged(double l, double u) { mitk::LevelWindow olw; olw.SetRangeMinMax(l*255, u*255); mitk::DataStorage::SetOfObjects::Pointer set = ActiveSet("QBallImage"); SetLevelWindowProp(set,"opaclevelwindow", olw); set = ActiveSet("TensorImage"); SetLevelWindowProp(set,"opaclevelwindow", olw); set = ActiveSet("Image"); SetLevelWindowProp(set,"opaclevelwindow", olw); m_Controls->m_OpacityMinFaLabel->setText(QString::number(l,'f',2) + " : " + QString::number(u,'f',2)); if(m_MultiWidget) m_MultiWidget->RequestUpdate(); } void QmitkControlVisualizationPropertiesView::ScalingCheckbox() { m_Controls->m_ScalingFrame->setVisible( m_Controls->m_ScalingCheckbox->isChecked()); if(!m_Controls->m_ScalingCheckbox->isChecked()) { m_Controls->m_AdditionalScaling->setCurrentIndex(0); m_Controls->m_ScalingFactor->setValue(1.0); } } void QmitkControlVisualizationPropertiesView::Fiber2DfadingEFX() { if (m_SelectedNode && dynamic_cast(m_SelectedNode->GetData()) ) { bool currentMode; m_SelectedNode->GetBoolProperty("Fiber2DfadeEFX", currentMode); m_SelectedNode->SetProperty("Fiber2DfadeEFX", mitk::BoolProperty::New(!currentMode)); dynamic_cast(m_SelectedNode->GetData())->RequestUpdate2D(); mitk::RenderingManager::GetInstance()->ForceImmediateUpdateAll(); } } void QmitkControlVisualizationPropertiesView::FiberSlicingThickness2D() { if (m_SelectedNode && dynamic_cast(m_SelectedNode->GetData())) { float fibThickness = m_Controls->m_FiberThicknessSlider->value() * 0.1; float currentThickness = 0; m_SelectedNode->GetFloatProperty("Fiber2DSliceThickness", currentThickness); if (fabs(fibThickness-currentThickness)<0.001) return; m_SelectedNode->SetProperty("Fiber2DSliceThickness", mitk::FloatProperty::New(fibThickness)); dynamic_cast(m_SelectedNode->GetData())->RequestUpdate2D(); mitk::RenderingManager::GetInstance()->ForceImmediateUpdateAll(); } } void QmitkControlVisualizationPropertiesView::FiberSlicingUpdateLabel(int value) { QString label = "Range %1 mm"; label = label.arg(value * 0.1); m_Controls->label_range->setText(label); this->FiberSlicingThickness2D(); } void QmitkControlVisualizationPropertiesView::SetFiberBundleCustomColor(const itk::EventObject& /*e*/) { float color[3]; m_SelectedNode->GetColor(color); m_Controls->m_Color->setAutoFillBackground(true); QString styleSheet = "background-color:rgb("; styleSheet.append(QString::number(color[0]*255.0)); styleSheet.append(","); styleSheet.append(QString::number(color[1]*255.0)); styleSheet.append(","); styleSheet.append(QString::number(color[2]*255.0)); styleSheet.append(")"); m_Controls->m_Color->setStyleSheet(styleSheet); m_SelectedNode->SetProperty("color",mitk::ColorProperty::New(color[0], color[1], color[2])); mitk::FiberBundleX::Pointer fib = dynamic_cast(m_SelectedNode->GetData()); fib->SetColorCoding(mitk::FiberBundleX::COLORCODING_CUSTOM); mitk::RenderingManager::GetInstance()->ForceImmediateUpdateAll(); } void QmitkControlVisualizationPropertiesView::BundleRepresentationColor() { if(m_SelectedNode) { QColor color = QColorDialog::getColor(); if (!color.isValid()) return; m_Controls->m_Color->setAutoFillBackground(true); QString styleSheet = "background-color:rgb("; styleSheet.append(QString::number(color.red())); styleSheet.append(","); styleSheet.append(QString::number(color.green())); styleSheet.append(","); styleSheet.append(QString::number(color.blue())); styleSheet.append(")"); m_Controls->m_Color->setStyleSheet(styleSheet); m_SelectedNode->SetProperty("color",mitk::ColorProperty::New(color.red()/255.0, color.green()/255.0, color.blue()/255.0)); mitk::FiberBundleX::Pointer fib = dynamic_cast(m_SelectedNode->GetData()); fib->SetColorCoding(mitk::FiberBundleX::COLORCODING_CUSTOM); mitk::RenderingManager::GetInstance()->ForceImmediateUpdateAll(); } } void QmitkControlVisualizationPropertiesView::BundleRepresentationResetColoring() { if(m_SelectedNode) { MITK_INFO << "reset colorcoding to oBased"; m_Controls->m_Color->setAutoFillBackground(true); QString styleSheet = "background-color:rgb(255,255,255)"; m_Controls->m_Color->setStyleSheet(styleSheet); // m_SelectedNode->SetProperty("color",NULL); m_SelectedNode->SetProperty("color",mitk::ColorProperty::New(1.0, 1.0, 1.0)); mitk::FiberBundleX::Pointer fib = dynamic_cast(m_SelectedNode->GetData()); fib->SetColorCoding(mitk::FiberBundleX::COLORCODING_ORIENTATION_BASED); fib->DoColorCodingOrientationBased(); mitk::RenderingManager::GetInstance()->ForceImmediateUpdateAll(); } } void QmitkControlVisualizationPropertiesView::PlanarFigureFocus() { if(m_SelectedNode) { mitk::PlanarFigure* _PlanarFigure = 0; _PlanarFigure = dynamic_cast (m_SelectedNode->GetData()); if (_PlanarFigure && _PlanarFigure->GetGeometry2D()) { QmitkRenderWindow* selectedRenderWindow = 0; bool PlanarFigureInitializedWindow = false; QmitkRenderWindow* RenderWindow1 = this->GetActiveStdMultiWidget()->GetRenderWindow1(); if (m_SelectedNode->GetBoolProperty("PlanarFigureInitializedWindow", PlanarFigureInitializedWindow, RenderWindow1->GetRenderer())) { selectedRenderWindow = RenderWindow1; } QmitkRenderWindow* RenderWindow2 = this->GetActiveStdMultiWidget()->GetRenderWindow2(); if (!selectedRenderWindow && m_SelectedNode->GetBoolProperty( "PlanarFigureInitializedWindow", PlanarFigureInitializedWindow, RenderWindow2->GetRenderer())) { selectedRenderWindow = RenderWindow2; } QmitkRenderWindow* RenderWindow3 = this->GetActiveStdMultiWidget()->GetRenderWindow3(); if (!selectedRenderWindow && m_SelectedNode->GetBoolProperty( "PlanarFigureInitializedWindow", PlanarFigureInitializedWindow, RenderWindow3->GetRenderer())) { selectedRenderWindow = RenderWindow3; } QmitkRenderWindow* RenderWindow4 = this->GetActiveStdMultiWidget()->GetRenderWindow4(); if (!selectedRenderWindow && m_SelectedNode->GetBoolProperty( "PlanarFigureInitializedWindow", PlanarFigureInitializedWindow, RenderWindow4->GetRenderer())) { selectedRenderWindow = RenderWindow4; } const mitk::PlaneGeometry * _PlaneGeometry = dynamic_cast (_PlanarFigure->GetGeometry2D()); mitk::VnlVector normal = _PlaneGeometry->GetNormalVnl(); mitk::Geometry2D::ConstPointer worldGeometry1 = RenderWindow1->GetRenderer()->GetCurrentWorldGeometry2D(); mitk::PlaneGeometry::ConstPointer _Plane1 = dynamic_cast( worldGeometry1.GetPointer() ); mitk::VnlVector normal1 = _Plane1->GetNormalVnl(); mitk::Geometry2D::ConstPointer worldGeometry2 = RenderWindow2->GetRenderer()->GetCurrentWorldGeometry2D(); mitk::PlaneGeometry::ConstPointer _Plane2 = dynamic_cast( worldGeometry2.GetPointer() ); mitk::VnlVector normal2 = _Plane2->GetNormalVnl(); mitk::Geometry2D::ConstPointer worldGeometry3 = RenderWindow3->GetRenderer()->GetCurrentWorldGeometry2D(); mitk::PlaneGeometry::ConstPointer _Plane3 = dynamic_cast( worldGeometry3.GetPointer() ); mitk::VnlVector normal3 = _Plane3->GetNormalVnl(); normal[0] = fabs(normal[0]); normal[1] = fabs(normal[1]); normal[2] = fabs(normal[2]); normal1[0] = fabs(normal1[0]); normal1[1] = fabs(normal1[1]); normal1[2] = fabs(normal1[2]); normal2[0] = fabs(normal2[0]); normal2[1] = fabs(normal2[1]); normal2[2] = fabs(normal2[2]); normal3[0] = fabs(normal3[0]); normal3[1] = fabs(normal3[1]); normal3[2] = fabs(normal3[2]); double ang1 = angle(normal, normal1); double ang2 = angle(normal, normal2); double ang3 = angle(normal, normal3); if(ang1 < ang2 && ang1 < ang3) { selectedRenderWindow = RenderWindow1; } else { if(ang2 < ang3) { selectedRenderWindow = RenderWindow2; } else { selectedRenderWindow = RenderWindow3; } } // make node visible if (selectedRenderWindow) { const mitk::Point3D& centerP = _PlaneGeometry->GetOrigin(); selectedRenderWindow->GetSliceNavigationController()->ReorientSlices( centerP, _PlaneGeometry->GetNormal()); } } // set interactor for new node (if not already set) mitk::PlanarFigureInteractor::Pointer figureInteractor = dynamic_cast(m_SelectedNode->GetDataInteractor().GetPointer()); if(figureInteractor.IsNull()) { figureInteractor = mitk::PlanarFigureInteractor::New(); us::Module* planarFigureModule = us::ModuleRegistry::GetModule( "MitkPlanarFigure" ); figureInteractor->LoadStateMachine("PlanarFigureInteraction.xml", planarFigureModule ); figureInteractor->SetEventConfig( "PlanarFigureConfig.xml", planarFigureModule ); figureInteractor->SetDataNode( m_SelectedNode ); } m_SelectedNode->SetProperty("planarfigure.iseditable",mitk::BoolProperty::New(true)); } } void QmitkControlVisualizationPropertiesView::SetInteractor() { typedef std::vector Container; Container _NodeSet = this->GetDataManagerSelection(); mitk::DataNode* node = 0; mitk::FiberBundleX* bundle = 0; mitk::FiberBundleInteractor::Pointer bundleInteractor = 0; // finally add all nodes to the model for(Container::const_iterator it=_NodeSet.begin(); it!=_NodeSet.end() ; it++) { node = const_cast(*it); bundle = dynamic_cast(node->GetData()); if(bundle) { bundleInteractor = dynamic_cast(node->GetInteractor()); if(bundleInteractor.IsNotNull()) mitk::GlobalInteraction::GetInstance()->RemoveInteractor(bundleInteractor); if(!m_Controls->m_Crosshair->isChecked()) { m_Controls->m_Crosshair->setChecked(false); this->GetActiveStdMultiWidget()->GetRenderWindow4()->setCursor(Qt::ArrowCursor); m_CurrentPickingNode = 0; } else { m_Controls->m_Crosshair->setChecked(true); bundleInteractor = mitk::FiberBundleInteractor::New("FiberBundleInteractor", node); mitk::GlobalInteraction::GetInstance()->AddInteractor(bundleInteractor); this->GetActiveStdMultiWidget()->GetRenderWindow4()->setCursor(Qt::CrossCursor); m_CurrentPickingNode = node; } } } } void QmitkControlVisualizationPropertiesView::PFWidth(int w) { double width = w/10.0; m_SelectedNode->SetProperty("planarfigure.line.width", mitk::FloatProperty::New(width) ); m_SelectedNode->SetProperty("planarfigure.shadow.widthmodifier", mitk::FloatProperty::New(width) ); m_SelectedNode->SetProperty("planarfigure.outline.width", mitk::FloatProperty::New(width) ); m_SelectedNode->SetProperty("planarfigure.helperline.width", mitk::FloatProperty::New(width) ); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); QString label = "Width %1"; label = label.arg(width); m_Controls->label_pfwidth->setText(label); } void QmitkControlVisualizationPropertiesView::PFColor() { QColor color = QColorDialog::getColor(); if (!color.isValid()) return; m_Controls->m_PFColor->setAutoFillBackground(true); QString styleSheet = "background-color:rgb("; styleSheet.append(QString::number(color.red())); styleSheet.append(","); styleSheet.append(QString::number(color.green())); styleSheet.append(","); styleSheet.append(QString::number(color.blue())); styleSheet.append(")"); m_Controls->m_PFColor->setStyleSheet(styleSheet); m_SelectedNode->SetProperty( "planarfigure.default.line.color", mitk::ColorProperty::New(color.red()/255.0, color.green()/255.0, color.blue()/255.0)); m_SelectedNode->SetProperty( "planarfigure.default.outline.color", mitk::ColorProperty::New(color.red()/255.0, color.green()/255.0, color.blue()/255.0)); m_SelectedNode->SetProperty( "planarfigure.default.helperline.color", mitk::ColorProperty::New(color.red()/255.0, color.green()/255.0, color.blue()/255.0)); m_SelectedNode->SetProperty( "planarfigure.default.markerline.color", mitk::ColorProperty::New(color.red()/255.0, color.green()/255.0, color.blue()/255.0)); m_SelectedNode->SetProperty( "planarfigure.default.marker.color", mitk::ColorProperty::New(color.red()/255.0, color.green()/255.0, color.blue()/255.0)); m_SelectedNode->SetProperty( "planarfigure.hover.line.color", mitk::ColorProperty::New(color.red()/255.0, color.green()/255.0, color.blue()/255.0) ); m_SelectedNode->SetProperty( "planarfigure.hover.outline.color", mitk::ColorProperty::New(color.red()/255.0, color.green()/255.0, color.blue()/255.0) ); m_SelectedNode->SetProperty( "planarfigure.hover.helperline.color", mitk::ColorProperty::New(color.red()/255.0, color.green()/255.0, color.blue()/255.0) ); m_SelectedNode->SetProperty( "color", mitk::ColorProperty::New(color.red()/255.0, color.green()/255.0, color.blue()/255.0)); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } void QmitkControlVisualizationPropertiesView::GenerateTdi() { if(m_SelectedNode) { mitk::FiberBundleX* bundle = dynamic_cast(m_SelectedNode->GetData()); if(!bundle) return; typedef float OutPixType; typedef itk::Image OutImageType; // run generator itk::TractDensityImageFilter< OutImageType >::Pointer generator = itk::TractDensityImageFilter< OutImageType >::New(); generator->SetFiberBundle(bundle); generator->SetOutputAbsoluteValues(true); generator->SetUpsamplingFactor(1); generator->Update(); // get result OutImageType::Pointer outImg = generator->GetOutput(); mitk::Image::Pointer img = mitk::Image::New(); img->InitializeByItk(outImg.GetPointer()); img->SetVolume(outImg->GetBufferPointer()); // to datastorage mitk::DataNode::Pointer node = mitk::DataNode::New(); node->SetData(img); QString name(m_SelectedNode->GetName().c_str()); name += "_TDI"; node->SetName(name.toStdString()); node->SetVisibility(true); GetDataStorage()->Add(node); } } void QmitkControlVisualizationPropertiesView::LineWidthChanged() { if(m_SelectedNode && dynamic_cast(m_SelectedNode->GetData())) { int newWidth = m_Controls->m_LineWidth->value(); int currentWidth = 0; m_SelectedNode->GetIntProperty("LineWidth", currentWidth); if (currentWidth==newWidth) return; m_SelectedNode->SetIntProperty("LineWidth", newWidth); dynamic_cast(m_SelectedNode->GetData())->RequestUpdate2D(); dynamic_cast(m_SelectedNode->GetData())->RequestUpdate3D(); mitk::RenderingManager::GetInstance()->ForceImmediateUpdateAll(); } } void QmitkControlVisualizationPropertiesView::Welcome() { berry::PlatformUI::GetWorkbench()->GetIntroManager()->ShowIntro( GetSite()->GetWorkbenchWindow(), false); } diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkControlVisualizationPropertiesViewControls.ui b/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkControlVisualizationPropertiesViewControls.ui index 449b6158de..01ef2755f9 100644 --- a/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkControlVisualizationPropertiesViewControls.ui +++ b/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkControlVisualizationPropertiesViewControls.ui @@ -1,965 +1,965 @@ QmitkControlVisualizationPropertiesViewControls 0 0 567 619 0 100 0 0 QmitkTemplate 0 0 0 0 QFrame::NoFrame QFrame::Raised 0 0 0 0 0 0 QFrame::NoFrame QFrame::Raised 0 0 0 0 Reinit view false false Texture interpolation ON true false Toggle visibility of ODF glyphs (axial) :/QmitkDiffusionImaging/glyphsoff_T.png :/QmitkDiffusionImaging/glyphson_T.png:/QmitkDiffusionImaging/glyphsoff_T.png true false Toggle visibility of ODF glyphs (sagittal) :/QmitkDiffusionImaging/glyphsoff_S.png :/QmitkDiffusionImaging/glyphson_S.png:/QmitkDiffusionImaging/glyphsoff_S.png true false Toggle visibility of ODF glyphs (coronal) :/QmitkDiffusionImaging/glyphsoff_C.png :/QmitkDiffusionImaging/glyphson_C.png:/QmitkDiffusionImaging/glyphsoff_C.png true false Multislice Projection MIP QToolButton::MenuButtonPopup Qt::NoArrow Channel 300 Qt::Horizontal QFrame::NoFrame QFrame::Plain 0 0 0 0 Qt::Horizontal 20 20 #Glyphs 9999 QFrame::NoFrame QFrame::Plain 0 0 0 0 Opacity - + 100 Qt::Horizontal 80 0 0.0 : 0.0 QFrame::NoFrame QFrame::Raised 0 0 0 0 0 QFrame::NoFrame QFrame::Raised 0 0 0 0 6 0 QFrame::NoFrame QFrame::Plain 0 0 0 0 false None By GFA By ASR * Additional scaling factor Scaling QFrame::NoFrame QFrame::Plain 0 0 0 0 0 ODF normalization false Min-Max Max None QFrame::NoFrame QFrame::Raised 0 0 0 0 Param1 9999.989999999999782 Param2 9999.989999999999782 QFrame::NoFrame QFrame::Raised 0 0 0 0 QFrame::NoFrame QFrame::Raised 0 0 0 0 Uniform Color for Bundle Reset to Default Coloring Position Crosshair by 3D-Click true false Generate Tract Density Image 2D Fiberfading on/off Qt::Horizontal 40 20 QFrame::NoFrame QFrame::Raised 0 0 0 0 2D Clipping 100 10 10 10 Qt::Horizontal 90 0 10000 16777215 Range QFrame::NoFrame QFrame::Raised 0 0 0 0 Line Width 1 10 QFrame::NoFrame QFrame::Raised 0 0 0 0 Focus Planar Figure 0 0 Select ROI color. Adjust 2D line width. 1 100 20 Qt::Horizontal 80 0 Width Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter 50 false false <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Ubuntu'; font-size:11pt; font-weight:400; font-style:normal;"> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" color:#ff0000;"> ODF Visualisation not possible in rotated planes. </span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" color:#ff0000;"> Use 'Reinit' on the image node to reset. </span></p></body></html> Qt::AutoText Qt::Vertical 20 40 - QmitkFloatingPointSpanSlider - QSlider -
QmitkFloatingPointSpanSlider.h
+ ctkRangeSlider + QWidget +
ctkRangeSlider.h
QmitkDataStorageComboBox.h
diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkDenoisingView.cpp b/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkDenoisingView.cpp index 6107a87178..6ccec586f7 100644 --- a/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkDenoisingView.cpp +++ b/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkDenoisingView.cpp @@ -1,508 +1,508 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ // Blueberry #include #include // Qmitk #include "QmitkDenoisingView.h" #include #include QmitkDenoisingWorker::QmitkDenoisingWorker(QmitkDenoisingView *view) : m_View(view) { } void QmitkDenoisingWorker::run() { if (m_View->m_ImageNode.IsNotNull()) { switch (m_View->m_SelectedFilter) { case QmitkDenoisingView::NOFILTERSELECTED: case QmitkDenoisingView::GAUSS: { break; } case QmitkDenoisingView::NLM: { try { m_View->m_CompletedCalculation = true; m_View->m_NonLocalMeansFilter->Update(); } catch (itk::ExceptionObject& e) { m_View->m_CompletedCalculation = false; MITK_ERROR << e.what(); } break; } } m_View->m_DenoisingThread.quit(); } } const std::string QmitkDenoisingView::VIEW_ID = "org.mitk.views.denoisingview"; QmitkDenoisingView::QmitkDenoisingView() : QmitkFunctionality() , m_Controls( 0 ) , m_ImageNode(NULL) , m_BrainMaskNode(NULL) , m_DenoisingWorker(this) , m_ThreadIsRunning(false) , m_NonLocalMeansFilter(NULL) , m_InputImage(NULL) , m_LastProgressCount(0) , m_MaxProgressCount(0) , m_SelectedFilter(NOFILTERSELECTED) { m_DenoisingWorker.moveToThread(&m_DenoisingThread); connect(&m_DenoisingThread, SIGNAL(started()), this, SLOT(BeforeThread())); connect(&m_DenoisingThread, SIGNAL(started()), &m_DenoisingWorker, SLOT(run())); connect(&m_DenoisingThread, SIGNAL(finished()), this, SLOT(AfterThread())); connect(&m_DenoisingThread, SIGNAL(terminated()), this, SLOT(AfterThread())); m_DenoisingTimer = new QTimer(this); } QmitkDenoisingView::~QmitkDenoisingView() { delete m_DenoisingTimer; } void QmitkDenoisingView::CreateQtPartControl( QWidget *parent ) { // build up qt view, unless already done if ( !m_Controls ) { // create GUI widgets from the Qt Designer's .ui file m_Controls = new Ui::QmitkDenoisingViewControls; m_Controls->setupUi( parent ); CreateConnections(); ResetParameterPanel(); } } void QmitkDenoisingView::CreateConnections() { if ( m_Controls ) { connect( (QObject*)(m_Controls->m_ApplyButton), SIGNAL(clicked()), this, SLOT(StartDenoising())); connect( (QObject*)(m_Controls->m_SelectFilterComboBox), SIGNAL(activated(int)), this, SLOT(SelectFilter(int))); connect( m_DenoisingTimer, SIGNAL(timeout()), this, SLOT(UpdateProgress())); } } void QmitkDenoisingView::Activated() { QmitkFunctionality::Activated(); m_Controls->m_SelectFilterComboBox->clear(); - m_Controls->m_SelectFilterComboBox->insertItem(NOFILTERSELECTED, QString( QApplication::translate("QmitkDenoisingView", "Please select a filter", 0, QApplication::UnicodeUTF8) )); - m_Controls->m_SelectFilterComboBox->insertItem(NLM, QString( QApplication::translate("QmitkDenoisingView", "Non-local means filter", 0, QApplication::UnicodeUTF8) )); - m_Controls->m_SelectFilterComboBox->insertItem(GAUSS, QString( QApplication::translate("QmitkDenoisingView", "Discrete gaussian filter", 0, QApplication::UnicodeUTF8) )); + m_Controls->m_SelectFilterComboBox->insertItem(NOFILTERSELECTED, "Please select a filter"); + m_Controls->m_SelectFilterComboBox->insertItem(NLM, "Non-local means filter"); + m_Controls->m_SelectFilterComboBox->insertItem(GAUSS, "Discrete gaussian filter"); } void QmitkDenoisingView::OnSelectionChanged( std::vector nodes ) { if (m_ThreadIsRunning) return; if (m_SelectedFilter != NOFILTERSELECTED) { m_Controls->m_InputImageLabel->setText("mandatory"); } else { m_Controls->m_InputImageLabel->setText("mandatory"); } m_Controls->m_InputBrainMaskLabel->setText("optional"); m_Controls->m_ApplyButton->setEnabled(false); m_ImageNode = NULL; m_BrainMaskNode = NULL; // iterate selection for( std::vector::iterator it = nodes.begin(); it != nodes.end(); ++it ) { mitk::DataNode::Pointer node = *it; if( node.IsNotNull() && dynamic_cast(node->GetData())) { m_Controls->m_InputImageLabel->setText(node->GetName().c_str()); m_ImageNode = node; } bool isBinary = false; node->GetBoolProperty("binary", isBinary); // look for a brainmask in selection if( node.IsNotNull() && static_cast(node->GetData()) && isBinary) { m_Controls->m_InputBrainMaskLabel->setText(node->GetName().c_str()); m_BrainMaskNode = node; } } // Preparation of GUI to start denoising if a filter is selected if (m_ImageNode.IsNotNull() && m_SelectedFilter != NOFILTERSELECTED) { m_Controls->m_ApplyButton->setEnabled(true); } } void QmitkDenoisingView::StartDenoising() { if (!m_ThreadIsRunning) { if (m_ImageNode.IsNotNull()) { m_LastProgressCount = 0; switch (m_SelectedFilter) { case NOFILTERSELECTED: { break; } case NLM: { // initialize NLM m_InputImage = dynamic_cast (m_ImageNode->GetData()); m_NonLocalMeansFilter = NonLocalMeansDenoisingFilterType::New(); if (m_BrainMaskNode.IsNotNull()) { // use brainmask if set m_ImageMask = dynamic_cast(m_BrainMaskNode->GetData()); itk::Image::Pointer itkMask; mitk::CastToItkImage(m_ImageMask, itkMask); m_NonLocalMeansFilter->SetInputMask(itkMask); itk::ImageRegionIterator< itk::Image > mit(itkMask, itkMask->GetLargestPossibleRegion()); mit.GoToBegin(); itk::Image::IndexType minIndex; itk::Image::IndexType maxIndex; minIndex.Fill(10000); maxIndex.Fill(0); while (!mit.IsAtEnd()) { if (mit.Get()) { // calculation of the start & end index of the smallest masked region minIndex[0] = minIndex[0] < mit.GetIndex()[0] ? minIndex[0] : mit.GetIndex()[0]; minIndex[1] = minIndex[1] < mit.GetIndex()[1] ? minIndex[1] : mit.GetIndex()[1]; minIndex[2] = minIndex[2] < mit.GetIndex()[2] ? minIndex[2] : mit.GetIndex()[2]; maxIndex[0] = maxIndex[0] > mit.GetIndex()[0] ? maxIndex[0] : mit.GetIndex()[0]; maxIndex[1] = maxIndex[1] > mit.GetIndex()[1] ? maxIndex[1] : mit.GetIndex()[1]; maxIndex[2] = maxIndex[2] > mit.GetIndex()[2] ? maxIndex[2] : mit.GetIndex()[2]; } ++mit; } itk::Image::SizeType size; size[0] = maxIndex[0] - minIndex[0] + 1; size[1] = maxIndex[1] - minIndex[1] + 1; size[2] = maxIndex[2] - minIndex[2] + 1; m_MaxProgressCount = size[0] * size[1] * size[2]; } else { // initialize the progressbar m_MaxProgressCount = m_InputImage->GetDimension(0) * m_InputImage->GetDimension(1) * m_InputImage->GetDimension(2); } mitk::ProgressBar::GetInstance()->AddStepsToDo(m_MaxProgressCount); m_NonLocalMeansFilter->SetInputImage(m_InputImage->GetVectorImage()); m_NonLocalMeansFilter->SetUseRicianAdaption(m_Controls->m_RicianCheckbox->isChecked()); m_NonLocalMeansFilter->SetUseJointInformation(m_Controls->m_JointInformationCheckbox->isChecked()); m_NonLocalMeansFilter->SetSearchRadius(m_Controls->m_SpinBoxParameter1->value()); m_NonLocalMeansFilter->SetComparisonRadius(m_Controls->m_SpinBoxParameter2->value()); m_NonLocalMeansFilter->SetVariance(m_Controls->m_DoubleSpinBoxParameter3->value()); // start denoising in detached thread m_DenoisingThread.start(QThread::HighestPriority); break; } case GAUSS: { // initialize GAUSS and run m_InputImage = dynamic_cast (m_ImageNode->GetData()); ExtractFilterType::Pointer extractor = ExtractFilterType::New(); extractor->SetInput(m_InputImage->GetVectorImage()); ComposeFilterType::Pointer composer = ComposeFilterType::New(); for (unsigned int i = 0; i < m_InputImage->GetVectorImage()->GetVectorLength(); ++i) { extractor->SetIndex(i); extractor->Update(); m_GaussianFilter = GaussianFilterType::New(); m_GaussianFilter->SetVariance(m_Controls->m_SpinBoxParameter1->value()); if (m_BrainMaskNode.IsNotNull()) { m_ImageMask = dynamic_cast(m_BrainMaskNode->GetData()); itk::Image::Pointer itkMask = itk::Image::New(); mitk::CastToItkImage(m_ImageMask, itkMask); itk::MaskImageFilter , itk::Image >::Pointer maskImageFilter = itk::MaskImageFilter , itk::Image >::New(); maskImageFilter->SetInput(extractor->GetOutput()); maskImageFilter->SetMaskImage(itkMask); maskImageFilter->Update(); m_GaussianFilter->SetInput(maskImageFilter->GetOutput()); } else { m_GaussianFilter->SetInput(extractor->GetOutput()); } m_GaussianFilter->Update(); composer->SetInput(i, m_GaussianFilter->GetOutput()); } composer->Update(); DiffusionImageType::Pointer image = DiffusionImageType::New(); image->SetVectorImage(composer->GetOutput()); image->SetReferenceBValue(m_InputImage->GetReferenceBValue()); image->SetDirections(m_InputImage->GetDirections()); image->InitializeFromVectorImage(); mitk::DataNode::Pointer imageNode = mitk::DataNode::New(); imageNode->SetData( image ); QString name = m_ImageNode->GetName().c_str(); imageNode->SetName((name+"_gauss_"+QString::number(m_Controls->m_SpinBoxParameter1->value())).toStdString().c_str()); GetDefaultDataStorage()->Add(imageNode); break; } } } } else { m_NonLocalMeansFilter->AbortGenerateDataOn(); m_CompletedCalculation = false; } } void QmitkDenoisingView::ResetParameterPanel() { m_Controls->m_DwiLabel->setEnabled(false); m_Controls->m_InputImageLabel->setEnabled(false); m_Controls->m_BrainMaskLabel->setEnabled(false); m_Controls->m_InputBrainMaskLabel->setEnabled(false); m_Controls->m_ParameterBox->hide(); m_Controls->m_LabelParameter_1->hide(); m_Controls->m_LabelParameter_2->hide(); m_Controls->m_LabelParameter_3->hide(); m_Controls->m_SpinBoxParameter1->hide(); m_Controls->m_SpinBoxParameter2->hide(); m_Controls->m_DoubleSpinBoxParameter3->hide(); m_Controls->m_RicianLabel->hide(); m_Controls->m_RicianCheckbox->hide(); m_Controls->m_JointInformationLabel->hide(); m_Controls->m_JointInformationCheckbox->hide(); m_Controls->m_ApplyButton->setEnabled(false); } void QmitkDenoisingView::SelectFilter(int filter) { if (m_ThreadIsRunning) return; //Prepare GUI this->ResetParameterPanel(); switch (filter) { case 0: { m_SelectedFilter = NOFILTERSELECTED; break; } case 1: { m_SelectedFilter = NLM; m_Controls->m_DwiLabel->setEnabled(true); m_Controls->m_InputImageLabel->setEnabled(true); m_Controls->m_BrainMaskLabel->setEnabled(true); m_Controls->m_InputBrainMaskLabel->setEnabled(true); m_Controls->m_ParameterBox->show(); m_Controls->m_LabelParameter_1->show(); m_Controls->m_LabelParameter_1->setText("Search Radius:"); m_Controls->m_LabelParameter_2->show(); m_Controls->m_LabelParameter_2->setText("Comparision Radius:"); m_Controls->m_LabelParameter_3->show(); m_Controls->m_LabelParameter_3->setText("Noise variance:"); m_Controls->m_SpinBoxParameter1->show(); m_Controls->m_SpinBoxParameter1->setValue(4); m_Controls->m_SpinBoxParameter2->show(); m_Controls->m_SpinBoxParameter2->setValue(1); m_Controls->m_DoubleSpinBoxParameter3->show(); m_Controls->m_DoubleSpinBoxParameter3->setValue(1.0); m_Controls->m_RicianLabel->show(); m_Controls->m_RicianCheckbox->show(); m_Controls->m_RicianCheckbox->setChecked(true); m_Controls->m_JointInformationLabel->show(); m_Controls->m_JointInformationCheckbox->show(); m_Controls->m_JointInformationCheckbox->setChecked(false); break; } case 2: { m_SelectedFilter = GAUSS; m_Controls->m_DwiLabel->setEnabled(true); m_Controls->m_InputImageLabel->setEnabled(true); m_Controls->m_BrainMaskLabel->setEnabled(true); m_Controls->m_InputBrainMaskLabel->setEnabled(true); m_Controls->m_ParameterBox->show(); m_Controls->m_LabelParameter_1->show(); m_Controls->m_LabelParameter_1->setText("Variance:"); m_Controls->m_SpinBoxParameter1->show(); m_Controls->m_SpinBoxParameter1->setValue(2); break; } } if (m_ImageNode.IsNull()) { if (m_SelectedFilter != NOFILTERSELECTED) m_Controls->m_InputImageLabel->setText("mandatory"); else m_Controls->m_InputImageLabel->setText("mandatory"); } if (m_ImageNode.IsNotNull()) { m_Controls->m_ApplyButton->setEnabled(false); switch(filter) { case NOFILTERSELECTED: { break; } case NLM: case GAUSS: { m_Controls->m_ApplyButton->setEnabled(true); break; } } } } void QmitkDenoisingView::BeforeThread() { m_ThreadIsRunning = true; // initialize timer to update the progressbar at each timestep m_DenoisingTimer->start(500); m_Controls->m_ParameterBox->setEnabled(false); m_Controls->m_ApplyButton->setText("Abort"); } void QmitkDenoisingView::AfterThread() { m_ThreadIsRunning = false; // stop timer to stop updates of progressbar m_DenoisingTimer->stop(); // make sure progressbar is finished mitk::ProgressBar::GetInstance()->Progress(m_MaxProgressCount); if (m_CompletedCalculation) { switch (m_SelectedFilter) { case NOFILTERSELECTED: case GAUSS: { break; } case NLM: { DiffusionImageType::Pointer image = DiffusionImageType::New(); image->SetVectorImage(m_NonLocalMeansFilter->GetOutput()); image->SetReferenceBValue(m_InputImage->GetReferenceBValue()); image->SetDirections(m_InputImage->GetDirections()); image->InitializeFromVectorImage(); mitk::DataNode::Pointer imageNode = mitk::DataNode::New(); imageNode->SetData( image ); QString name = m_ImageNode->GetName().c_str(); //TODO: Rician adaption & joint information in name if (m_Controls->m_RicianCheckbox->isChecked() && !m_Controls->m_JointInformationCheckbox->isChecked()) { imageNode->SetName((name+"_NLMr_"+QString::number(m_Controls->m_SpinBoxParameter1->value())+"-"+QString::number(m_Controls->m_SpinBoxParameter2->value())).toStdString().c_str()); } else if(!m_Controls->m_RicianCheckbox->isChecked() && m_Controls->m_JointInformationCheckbox->isChecked()) { imageNode->SetName((name+"_NLMv_"+QString::number(m_Controls->m_SpinBoxParameter1->value())+"-"+QString::number(m_Controls->m_SpinBoxParameter2->value())).toStdString().c_str()); } else if(m_Controls->m_RicianCheckbox->isChecked() && m_Controls->m_JointInformationCheckbox->isChecked()) { imageNode->SetName((name+"_NLMvr_"+QString::number(m_Controls->m_SpinBoxParameter1->value())+"-"+QString::number(m_Controls->m_SpinBoxParameter2->value())).toStdString().c_str()); } else { imageNode->SetName((name+"_NLM_"+QString::number(m_Controls->m_SpinBoxParameter1->value())+"-"+QString::number(m_Controls->m_SpinBoxParameter2->value())).toStdString().c_str()); } GetDefaultDataStorage()->Add(imageNode); break; } } } m_Controls->m_ParameterBox->setEnabled(true); m_Controls->m_ApplyButton->setText("Apply"); } void QmitkDenoisingView::UpdateProgress() { switch (m_SelectedFilter) { case NOFILTERSELECTED: case GAUSS: { break; } case NLM: { unsigned int currentProgressCount = m_NonLocalMeansFilter->GetCurrentVoxelCount(); mitk::ProgressBar::GetInstance()->Progress(currentProgressCount-m_LastProgressCount); m_LastProgressCount = currentProgressCount; break; } } } \ No newline at end of file diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkDiffusionDicomImportView.cpp b/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkDiffusionDicomImportView.cpp index 56386594c1..4ae704a475 100644 --- a/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkDiffusionDicomImportView.cpp +++ b/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkDiffusionDicomImportView.cpp @@ -1,558 +1,558 @@ /*=================================================================== 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 "QmitkDiffusionDicomImportView.h" // qt includes #include // itk includes #include "itkTimeProbesCollectorBase.h" #include "itkGDCMSeriesFileNames.h" #include "itksys/SystemTools.hxx" // mitk includes #include "mitkProgressBar.h" #include "mitkStatusBar.h" #include "mitkProperties.h" #include "mitkRenderingManager.h" #include "mitkMemoryUtilities.h" #include "mitkIOUtil.h" // diffusion module includes #include "mitkDicomDiffusionImageHeaderReader.h" #include "mitkDicomDiffusionImageReader.h" #include "mitkDiffusionImage.h" #include "mitkDiffusionDICOMFileReader.h" #include "mitkDICOMTagBasedSorter.h" #include "mitkDICOMSortByTag.h" #include "mitkSortByImagePositionPatient.h" #include "gdcmDirectory.h" #include "gdcmScanner.h" #include "gdcmSorter.h" #include "gdcmIPPSorter.h" #include "gdcmAttribute.h" #include "gdcmVersion.h" #include #include #include const std::string QmitkDiffusionDicomImport::VIEW_ID = "org.mitk.views.diffusiondicomimport"; QmitkDiffusionDicomImport::QmitkDiffusionDicomImport(QObject* /*parent*/, const char* /*name*/) : QmitkFunctionality(), m_Controls(NULL), m_MultiWidget(NULL), m_OutputFolderName(""), m_OutputFolderNameSet(false) { } QmitkDiffusionDicomImport::QmitkDiffusionDicomImport(const QmitkDiffusionDicomImport& other) { Q_UNUSED(other) throw std::runtime_error("Copy constructor not implemented"); } QmitkDiffusionDicomImport::~QmitkDiffusionDicomImport() {} void QmitkDiffusionDicomImport::CreateQtPartControl(QWidget *parent) { m_Parent = parent; if (m_Controls == NULL) { m_Controls = new Ui::QmitkDiffusionDicomImportControls; m_Controls->setupUi(parent); this->CreateConnections(); m_Controls->m_DicomLoadRecursiveCheckbox->setChecked(false); m_Controls->m_DicomLoadAverageDuplicatesCheckbox->setChecked(false); m_Controls->m_DicomLoadRecursiveCheckbox->setVisible(true); m_Controls->m_OverrideOptionCheckbox->setVisible(false); m_Controls->m_SubdirPrefixLineEdit->setVisible(false); m_Controls->m_SetPrefixButton->setVisible(false); m_Controls->m_ResetPrefixButton->setVisible(false); AverageClicked(); } } void QmitkDiffusionDicomImport::CreateConnections() { if ( m_Controls ) { connect( m_Controls->m_AddFoldersButton, SIGNAL(clicked()), this, SLOT(DicomLoadAddFolderNames()) ); connect( m_Controls->m_DeleteFoldersButton, SIGNAL(clicked()), this, SLOT(DicomLoadDeleteFolderNames()) ); //connect( m_Controls->m_DicomLoadStartLoadButton, SIGNAL(clicked()), this, SLOT(DicomLoadStartLoad()) ); connect( m_Controls->m_DicomLoadStartLoadButton, SIGNAL(clicked()), this, SLOT(NewDicomLoadStartLoad()) ); connect( m_Controls->m_DicomLoadAverageDuplicatesCheckbox, SIGNAL(clicked()), this, SLOT(AverageClicked()) ); connect( m_Controls->m_OutputSetButton, SIGNAL(clicked()), this, SLOT(OutputSet()) ); connect( m_Controls->m_OutputClearButton, SIGNAL(clicked()), this, SLOT(OutputClear()) ); connect( m_Controls->m_Remove, SIGNAL(clicked()), this, SLOT(Remove()) ); connect( m_Controls->m_SetPrefixButton, SIGNAL(clicked()), this, SLOT(SetPrefixButtonPushed())); connect( m_Controls->m_ResetPrefixButton, SIGNAL(clicked()), this, SLOT(ResetPrefixButtonPushed())); connect( m_Controls->m_DicomLoadRecursiveCheckbox, SIGNAL(clicked()), this, SLOT(RecursiveSettingsChanged()) ); } } void QmitkDiffusionDicomImport::RecursiveSettingsChanged() { m_Controls->m_SubdirPrefixLineEdit->setVisible( m_Controls->m_DicomLoadRecursiveCheckbox->isChecked() ); m_Controls->m_SetPrefixButton->setVisible( m_Controls->m_DicomLoadRecursiveCheckbox->isChecked() ); m_Controls->m_SubdirPrefixLineEdit->clear(); this->m_Controls->m_SubdirPrefixLineEdit->setEnabled(true); } void QmitkDiffusionDicomImport::SetPrefixButtonPushed() { m_Prefix = this->m_Controls->m_SubdirPrefixLineEdit->text().toStdString(); if( !this->m_Controls->m_ResetPrefixButton->isVisible() ) this->m_Controls->m_ResetPrefixButton->setVisible(true); this->m_Controls->m_SubdirPrefixLineEdit->setEnabled(false); this->m_Controls->m_ResetPrefixButton->setEnabled(true); this->m_Controls->m_SetPrefixButton->setEnabled(false); } void QmitkDiffusionDicomImport::ResetPrefixButtonPushed() { m_Controls->m_SubdirPrefixLineEdit->clear(); this->m_Controls->m_SubdirPrefixLineEdit->setEnabled(true); this->m_Controls->m_ResetPrefixButton->setEnabled(false); this->m_Controls->m_SetPrefixButton->setEnabled(true); } void QmitkDiffusionDicomImport::Remove() { int i = m_Controls->listWidget->currentRow(); m_Controls->listWidget->takeItem(i); } void QmitkDiffusionDicomImport::OutputSet() { // SELECT FOLDER DIALOG QFileDialog* w = new QFileDialog( m_Parent, QString("Select folders containing DWI data") ); w->setFileMode( QFileDialog::Directory ); // RETRIEVE SELECTION if ( w->exec() != QDialog::Accepted ) return; m_OutputFolderName = w->selectedFiles()[0]; m_OutputFolderNameSet = true; m_Controls->m_OutputLabel->setText(m_OutputFolderName); // show file override option checkbox m_Controls->m_OverrideOptionCheckbox->setVisible(true); } void QmitkDiffusionDicomImport::OutputClear() { m_OutputFolderName = ""; m_OutputFolderNameSet = false; m_Controls->m_OutputLabel->setText("... optional out-folder ..."); // hide file override option checkbox - no output specified m_Controls->m_OverrideOptionCheckbox->setVisible(false); } void QmitkDiffusionDicomImport::AverageClicked() { m_Controls->m_Blur->setEnabled(m_Controls->m_DicomLoadAverageDuplicatesCheckbox->isChecked()); } void QmitkDiffusionDicomImport::Activated() { QmitkFunctionality::Activated(); } void QmitkDiffusionDicomImport::DicomLoadDeleteFolderNames() { m_Controls->listWidget->clear(); } void QmitkDiffusionDicomImport::DicomLoadAddFolderNames() { // SELECT FOLDER DIALOG QFileDialog* w = new QFileDialog( m_Parent, QString("Select folders containing DWI data") ); w->setFileMode( QFileDialog::Directory ); // RETRIEVE SELECTION if ( w->exec() != QDialog::Accepted ) return; m_Controls->listWidget->addItems(w->selectedFiles()); } bool SortBySeriesUID(gdcm::DataSet const & ds1, gdcm::DataSet const & ds2 ) { gdcm::Attribute<0x0020,0x000e> at1; at1.Set( ds1 ); gdcm::Attribute<0x0020,0x000e> at2; at2.Set( ds2 ); return at1 < at2; } bool SortByAcquisitionNumber(gdcm::DataSet const & ds1, gdcm::DataSet const & ds2 ) { gdcm::Attribute<0x0020,0x0012> at1; at1.Set( ds1 ); gdcm::Attribute<0x0020,0x0012> at2; at2.Set( ds2 ); return at1 < at2; } bool SortBySeqName(gdcm::DataSet const & ds1, gdcm::DataSet const & ds2 ) { gdcm::Attribute<0x0018, 0x0024> at1; at1.Set( ds1 ); gdcm::Attribute<0x0018, 0x0024> at2; at2.Set( ds2 ); std::string str1 = at1.GetValue().Trim(); std::string str2 = at2.GetValue().Trim(); return std::lexicographical_compare(str1.begin(), str1.end(), str2.begin(), str2.end() ); } void QmitkDiffusionDicomImport::Status(QString status) { - mitk::StatusBar::GetInstance()->DisplayText(status.toAscii()); + mitk::StatusBar::GetInstance()->DisplayText(status.toLatin1()); MITK_INFO << status.toStdString().c_str(); } void QmitkDiffusionDicomImport::Status(std::string status) { mitk::StatusBar::GetInstance()->DisplayText(status.c_str()); MITK_INFO << status.c_str(); } void QmitkDiffusionDicomImport::Status(const char* status) { mitk::StatusBar::GetInstance()->DisplayText(status); MITK_INFO << status; } void QmitkDiffusionDicomImport::Error(QString status) { - mitk::StatusBar::GetInstance()->DisplayErrorText(status.toAscii()); + mitk::StatusBar::GetInstance()->DisplayErrorText(status.toLatin1()); MITK_ERROR << status.toStdString().c_str(); } void QmitkDiffusionDicomImport::Error(std::string status) { mitk::StatusBar::GetInstance()->DisplayErrorText(status.c_str()); MITK_ERROR << status.c_str(); } void QmitkDiffusionDicomImport::Error(const char* status) { mitk::StatusBar::GetInstance()->DisplayErrorText(status); MITK_ERROR << status; } void QmitkDiffusionDicomImport::PrintMemoryUsage() { size_t processSize = mitk::MemoryUtilities::GetProcessMemoryUsage(); size_t totalSize = mitk::MemoryUtilities::GetTotalSizeOfPhysicalRam(); float percentage = ( (float) processSize / (float) totalSize ) * 100.0; MITK_INFO << "Current memory usage: " << GetMemoryDescription( processSize, percentage ); } std::string QmitkDiffusionDicomImport::FormatMemorySize( size_t size ) { double val = size; std::string descriptor("B"); if ( val >= 1000.0 ) { val /= 1024.0; descriptor = "KB"; } if ( val >= 1000.0 ) { val /= 1024.0; descriptor = "MB"; } if ( val >= 1000.0 ) { val /= 1024.0; descriptor = "GB"; } std::ostringstream str; str << std::fixed << std::setprecision(2) << val << " " << descriptor; return str.str(); } std::string QmitkDiffusionDicomImport::FormatPercentage( double val ) { std::ostringstream str; str << std::fixed << std::setprecision(2) << val << " " << "%"; return str.str(); } std::string QmitkDiffusionDicomImport::GetMemoryDescription( size_t processSize, float percentage ) { std::ostringstream str; str << FormatMemorySize(processSize) << " (" << FormatPercentage( percentage ) <<")" ; return str.str(); } void QmitkDiffusionDicomImport::NewDicomLoadStartLoad() { itk::TimeProbesCollectorBase clock; bool imageSuccessfullySaved = true; bool has_prefix = true; try { const std::string& locale = "C"; const std::string& currLocale = setlocale( LC_ALL, NULL ); if ( locale.compare(currLocale)!=0 ) { try { MITK_INFO << " ** Changing locale from " << setlocale(LC_ALL, NULL) << " to '" << locale << "'"; setlocale(LC_ALL, locale.c_str()); } catch(...) { MITK_INFO << "Could not set locale " << locale; } } int nrFolders = m_Controls->listWidget->count(); if(!nrFolders) { Error(QString("No input folders were selected. ABORTING.")); return; } Status(QString("GDCM %1 used for DICOM parsing and sorting!").arg(gdcm::Version::GetVersion())); PrintMemoryUsage(); QString status; mitk::DataNode::Pointer node; mitk::ProgressBar::GetInstance()->AddStepsToDo(2*nrFolders); gdcm::Directory::FilenamesType complete_list; while(m_Controls->listWidget->count()) { // RETREIVE FOLDERNAME QListWidgetItem * item = m_Controls->listWidget->takeItem(0); QString folderName = item->text(); if( this->m_Controls->m_DicomLoadRecursiveCheckbox->isChecked() ) { std::string subdir_prefix = ""; if( has_prefix ) { subdir_prefix = this->m_Prefix; } itksys::Directory rootdir; rootdir.Load( folderName.toStdString().c_str() ); for( unsigned int idx=0; idxm_Controls->m_DicomLoadRecursiveCheckbox->isChecked() ); // recursive ! const gdcm::Directory::FilenamesType &l1 = d.GetFilenames(); const unsigned int ntotalfiles = l1.size(); Status(QString(" ... found %1 different files").arg(ntotalfiles)); for( unsigned int i=0; i< ntotalfiles; i++) { complete_list.push_back( l1.at(i) ); } } } { mitk::DiffusionDICOMFileReader::Pointer gdcmReader = mitk::DiffusionDICOMFileReader::New(); mitk::DICOMTagBasedSorter::Pointer tagSorter = mitk::DICOMTagBasedSorter::New(); // Use tags as in Qmitk // all the things that split by tag in DicomSeriesReader tagSorter->AddDistinguishingTag( mitk::DICOMTag(0x0028, 0x0010) ); // Number of Rows tagSorter->AddDistinguishingTag( mitk::DICOMTag(0x0028, 0x0011) ); // Number of Columns tagSorter->AddDistinguishingTag( mitk::DICOMTag(0x0028, 0x0030) ); // Pixel Spacing tagSorter->AddDistinguishingTag( mitk::DICOMTag(0x0018, 0x1164) ); // Imager Pixel Spacing tagSorter->AddDistinguishingTag( mitk::DICOMTag(0x0020, 0x0037) ); // Image Orientation (Patient) // TODO add tolerance parameter (l. 1572 of original code) // TODO handle as real vectors! cluster with configurable errors! tagSorter->AddDistinguishingTag( mitk::DICOMTag(0x0020, 0x000e) ); // Series Instance UID tagSorter->AddDistinguishingTag( mitk::DICOMTag(0x0018, 0x0050) ); // Slice Thickness tagSorter->AddDistinguishingTag( mitk::DICOMTag(0x0028, 0x0008) ); // Number of Frames //tagSorter->AddDistinguishingTag( mitk::DICOMTag(0x0020, 0x0052) ); // Frame of Reference UID // gdcmReader->AddSortingElement( tagSorter ); //mitk::DICOMFileReaderTestHelper::TestOutputsContainInputs( gdcmReader ); mitk::DICOMSortCriterion::ConstPointer sorting = mitk::SortByImagePositionPatient::New( // Image Position (Patient) //mitk::DICOMSortByTag::New( mitk::DICOMTag(0x0020, 0x0013), // instance number mitk::DICOMSortByTag::New( mitk::DICOMTag(0x0020, 0x0012), // aqcuisition number mitk::DICOMSortByTag::New( mitk::DICOMTag(0x0008, 0x0032), // aqcuisition time mitk::DICOMSortByTag::New( mitk::DICOMTag(0x0018, 0x1060), // trigger time mitk::DICOMSortByTag::New( mitk::DICOMTag(0x0008, 0x0018) // SOP instance UID (last resort, not really meaningful but decides clearly) ).GetPointer() ).GetPointer() ).GetPointer() ).GetPointer() // ).GetPointer() ).GetPointer(); tagSorter->SetSortCriterion( sorting ); // mosaic gdcmReader->SetResolveMosaic( this->m_Controls->m_SplitMosaicCheckBox->isChecked() ); gdcmReader->AddSortingElement( tagSorter ); gdcmReader->SetInputFiles( complete_list ); try { gdcmReader->AnalyzeInputFiles(); } catch( const itk::ExceptionObject &e) { MITK_ERROR << "Failed to analyze data. " << e.what(); } catch( const std::exception &se) { MITK_ERROR << "Std Exception " << se.what(); } gdcmReader->LoadImages(); for( int o = 0; o < gdcmReader->GetNumberOfOutputs(); o++ ) { mitk::Image::Pointer loaded_image = gdcmReader->GetOutput(o).GetMitkImage(); mitk::DiffusionImage::Pointer d_img = static_cast*>( loaded_image.GetPointer() ); std::stringstream ss; ss << "ImportedData_" << o; node = mitk::DataNode::New(); node->SetData( d_img ); std::string outname; d_img->GetPropertyList()->GetStringProperty("diffusion.dicom.importname", outname ); node->SetName( outname.c_str() ); GetDefaultDataStorage()->Add(node); //SetDwiNodeProperties(node, ss.str() ); //Status(QString("Image %1 added to datastorage").arg(descr)); } } Status("Timing information"); clock.Report(); if(!m_OutputFolderNameSet && node.IsNotNull()) { mitk::BaseData::Pointer basedata = node->GetData(); if (basedata.IsNotNull()) { mitk::RenderingManager::GetInstance()->InitializeViews( basedata->GetTimeGeometry(), mitk::RenderingManager::REQUEST_UPDATE_ALL, true ); } } mitk::RenderingManager::GetInstance()->RequestUpdateAll(); try { MITK_INFO << " ** Changing locale back from " << setlocale(LC_ALL, NULL) << " to '" << currLocale << "'"; setlocale(LC_ALL, currLocale.c_str()); } catch(...) { MITK_INFO << "Could not reset locale " << currLocale; } } catch (itk::ExceptionObject &ex) { Error(QString("%1\n%2\n%3\n%4\n%5\n%6").arg(ex.GetNameOfClass()).arg(ex.GetFile()).arg(ex.GetLine()).arg(ex.GetLocation()).arg(ex.what()).arg(ex.GetDescription())); return ; } if (!imageSuccessfullySaved) QMessageBox::warning(NULL,"WARNING","One or more files could not be saved! The according files where moved to the datastorage."); Status(QString("Finished import with memory:")); PrintMemoryUsage(); } void QmitkDiffusionDicomImport::SetDwiNodeProperties(mitk::DataNode::Pointer node, std::string name) { node->SetProperty( "IsDWIRawVolume", mitk::BoolProperty::New( true ) ); // set foldername as string property mitk::StringProperty::Pointer nameProp = mitk::StringProperty::New( name ); node->SetProperty( "name", nameProp ); } diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkDiffusionQuantificationView.cpp b/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkDiffusionQuantificationView.cpp index af9c7bf41d..507ee54a37 100644 --- a/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkDiffusionQuantificationView.cpp +++ b/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkDiffusionQuantificationView.cpp @@ -1,569 +1,569 @@ /*=================================================================== 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 "QmitkDiffusionQuantificationView.h" #include "mitkDiffusionImagingConfigure.h" #include "itkTimeProbe.h" #include "itkImage.h" #include "mitkNodePredicateDataType.h" #include "mitkDataNodeObject.h" #include "mitkQBallImage.h" #include #include "mitkImageCast.h" #include "mitkStatusBar.h" #include "itkDiffusionQballGeneralizedFaImageFilter.h" #include "itkShiftScaleImageFilter.h" #include "itkTensorFractionalAnisotropyImageFilter.h" #include "itkTensorRelativeAnisotropyImageFilter.h" #include "itkTensorDerivedMeasurementsFilter.h" #include "QmitkDataStorageComboBox.h" #include "QmitkStdMultiWidget.h" #include #include "berryIWorkbenchWindow.h" #include "berryISelectionService.h" const std::string QmitkDiffusionQuantificationView::VIEW_ID = "org.mitk.views.diffusionquantification"; QmitkDiffusionQuantificationView::QmitkDiffusionQuantificationView() : QmitkFunctionality(), m_Controls(NULL), m_MultiWidget(NULL) { m_QBallImages = mitk::DataStorage::SetOfObjects::New(); m_TensorImages = mitk::DataStorage::SetOfObjects::New(); } QmitkDiffusionQuantificationView::QmitkDiffusionQuantificationView(const QmitkDiffusionQuantificationView& other) { Q_UNUSED(other) throw std::runtime_error("Copy constructor not implemented"); } QmitkDiffusionQuantificationView::~QmitkDiffusionQuantificationView() { } void QmitkDiffusionQuantificationView::CreateQtPartControl(QWidget *parent) { if (!m_Controls) { // create GUI widgets m_Controls = new Ui::QmitkDiffusionQuantificationViewControls; m_Controls->setupUi(parent); this->CreateConnections(); GFACheckboxClicked(); #ifndef DIFFUSION_IMAGING_EXTENDED m_Controls->m_StandardGFACheckbox->setVisible(false); m_Controls->frame_3->setVisible(false); m_Controls->m_CurvatureButton->setVisible(false); #endif } } void QmitkDiffusionQuantificationView::StdMultiWidgetAvailable (QmitkStdMultiWidget &stdMultiWidget) { m_MultiWidget = &stdMultiWidget; } void QmitkDiffusionQuantificationView::StdMultiWidgetNotAvailable() { m_MultiWidget = NULL; } void QmitkDiffusionQuantificationView::CreateConnections() { if ( m_Controls ) { connect( (QObject*)(m_Controls->m_StandardGFACheckbox), SIGNAL(clicked()), this, SLOT(GFACheckboxClicked()) ); connect( (QObject*)(m_Controls->m_GFAButton), SIGNAL(clicked()), this, SLOT(GFA()) ); connect( (QObject*)(m_Controls->m_CurvatureButton), SIGNAL(clicked()), this, SLOT(Curvature()) ); connect( (QObject*)(m_Controls->m_FAButton), SIGNAL(clicked()), this, SLOT(FA()) ); connect( (QObject*)(m_Controls->m_RAButton), SIGNAL(clicked()), this, SLOT(RA()) ); connect( (QObject*)(m_Controls->m_ADButton), SIGNAL(clicked()), this, SLOT(AD()) ); connect( (QObject*)(m_Controls->m_RDButton), SIGNAL(clicked()), this, SLOT(RD()) ); connect( (QObject*)(m_Controls->m_MDButton), SIGNAL(clicked()), this, SLOT(MD()) ); connect( (QObject*)(m_Controls->m_ClusteringAnisotropy), SIGNAL(clicked()), this, SLOT(ClusterAnisotropy()) ); } } void QmitkDiffusionQuantificationView::OnSelectionChanged( std::vector nodes ) { m_QBallImages = mitk::DataStorage::SetOfObjects::New(); m_TensorImages = mitk::DataStorage::SetOfObjects::New(); bool foundQBIVolume = false; bool foundTensorVolume = false; mitk::DataNode::Pointer selNode = NULL; int c=0; for( std::vector::iterator it = nodes.begin(); it != nodes.end(); ++it ) { mitk::DataNode::Pointer node = *it; if( node.IsNotNull() && dynamic_cast(node->GetData()) ) { foundQBIVolume = true; m_QBallImages->push_back(node); selNode = node; c++; } else if( node.IsNotNull() && dynamic_cast(node->GetData()) ) { foundTensorVolume = true; m_TensorImages->push_back(node); selNode = node; c++; } } m_Controls->m_GFAButton->setEnabled(foundQBIVolume); m_Controls->m_CurvatureButton->setEnabled(foundQBIVolume); if (c>0) { m_Controls->m_InputData->setTitle("Input Data"); m_Controls->m_InputImageLabel->setText(selNode->GetName().c_str()); } else { m_Controls->m_InputData->setTitle("Please Select Input Data"); m_Controls->m_InputImageLabel->setText("mandatory"); } m_Controls->m_FAButton->setEnabled(foundTensorVolume); m_Controls->m_RAButton->setEnabled(foundTensorVolume); m_Controls->m_ADButton->setEnabled(foundTensorVolume); m_Controls->m_RDButton->setEnabled(foundTensorVolume); m_Controls->m_MDButton->setEnabled(foundTensorVolume); m_Controls->m_ClusteringAnisotropy->setEnabled(foundTensorVolume); } void QmitkDiffusionQuantificationView::Activated() { QmitkFunctionality::Activated(); } void QmitkDiffusionQuantificationView::Deactivated() { QmitkFunctionality::Deactivated(); } void QmitkDiffusionQuantificationView::GFACheckboxClicked() { m_Controls->frame_2->setVisible(m_Controls->m_StandardGFACheckbox->isChecked()); } void QmitkDiffusionQuantificationView::GFA() { if(m_Controls->m_StandardGFACheckbox->isChecked()) { QBIQuantify(13); } else { QBIQuantify(0); } } void QmitkDiffusionQuantificationView::Curvature() { QBIQuantify(12); } void QmitkDiffusionQuantificationView::FA() { TensorQuantify(0); } void QmitkDiffusionQuantificationView::RA() { TensorQuantify(1); } void QmitkDiffusionQuantificationView::AD() { TensorQuantify(2); } void QmitkDiffusionQuantificationView::RD() { TensorQuantify(3); } void QmitkDiffusionQuantificationView::ClusterAnisotropy() { TensorQuantify(4); } void QmitkDiffusionQuantificationView::MD() { TensorQuantify(5); } void QmitkDiffusionQuantificationView::QBIQuantify(int method) { QBIQuantification(m_QBallImages, method); } void QmitkDiffusionQuantificationView::TensorQuantify(int method) { TensorQuantification(m_TensorImages, method); } void QmitkDiffusionQuantificationView::QBIQuantification( mitk::DataStorage::SetOfObjects::Pointer inImages, int method) { itk::TimeProbe clock; QString status; int nrFiles = inImages->size(); if (!nrFiles) return; mitk::DataStorage::SetOfObjects::const_iterator itemiter( inImages->begin() ); mitk::DataStorage::SetOfObjects::const_iterator itemiterend( inImages->end() ); std::vector nodes; while ( itemiter != itemiterend ) // for all items { typedef float TOdfPixelType; const int odfsize = QBALL_ODFSIZE; typedef itk::Vector OdfVectorType; typedef itk::Image OdfVectorImgType; mitk::Image* vol = static_cast((*itemiter)->GetData()); OdfVectorImgType::Pointer itkvol = OdfVectorImgType::New(); mitk::CastToItkImage(vol, itkvol); std::string nodename; (*itemiter)->GetStringProperty("name", nodename); ++itemiter; float p1 = m_Controls->m_ParamKEdit->text().toFloat(); float p2 = m_Controls->m_ParamPEdit->text().toFloat(); // COMPUTE RA clock.Start(); MBI_INFO << "Computing GFA "; mitk::StatusBar::GetInstance()->DisplayText(status.sprintf( - "Computing GFA for %s", nodename.c_str()).toAscii()); + "Computing GFA for %s", nodename.c_str()).toLatin1()); typedef OdfVectorType::ValueType RealValueType; typedef itk::Image< RealValueType, 3 > RAImageType; typedef itk::DiffusionQballGeneralizedFaImageFilter GfaFilterType; GfaFilterType::Pointer gfaFilter = GfaFilterType::New(); gfaFilter->SetInput(itkvol); std::string newname; newname.append(nodename); switch(method) { case 0: { gfaFilter->SetComputationMethod(GfaFilterType::GFA_STANDARD); newname.append("GFA"); break; } case 1: { gfaFilter->SetComputationMethod(GfaFilterType::GFA_QUANTILES_HIGH_LOW); newname.append("01"); break; } case 2: { gfaFilter->SetComputationMethod(GfaFilterType::GFA_QUANTILE_HIGH); newname.append("02"); break; } case 3: { gfaFilter->SetComputationMethod(GfaFilterType::GFA_MAX_ODF_VALUE); newname.append("03"); break; } case 4: { gfaFilter->SetComputationMethod(GfaFilterType::GFA_DECONVOLUTION_COEFFS); newname.append("04"); break; } case 5: { gfaFilter->SetComputationMethod(GfaFilterType::GFA_MIN_MAX_NORMALIZED_STANDARD); newname.append("05"); break; } case 6: { gfaFilter->SetComputationMethod(GfaFilterType::GFA_NORMALIZED_ENTROPY); newname.append("06"); break; } case 7: { gfaFilter->SetComputationMethod(GfaFilterType::GFA_NEMATIC_ORDER_PARAMETER); newname.append("07"); break; } case 8: { gfaFilter->SetComputationMethod(GfaFilterType::GFA_QUANTILES_LOW_HIGH); newname.append("08"); break; } case 9: { gfaFilter->SetComputationMethod(GfaFilterType::GFA_QUANTILE_LOW); newname.append("09"); break; } case 10: { gfaFilter->SetComputationMethod(GfaFilterType::GFA_MIN_ODF_VALUE); newname.append("10"); break; } case 11: { gfaFilter->SetComputationMethod(GfaFilterType::GFA_STD_BY_MAX); newname.append("11"); break; } case 12: { p1 = m_Controls->MinAngle->text().toFloat(); p2 = m_Controls->MaxAngle->text().toFloat(); gfaFilter->SetComputationMethod(GfaFilterType::GFA_PRINCIPLE_CURVATURE); QString paramString; paramString = paramString.append("PC%1-%2").arg(p1).arg(p2); - newname.append(paramString.toAscii()); + newname.append(paramString.toLatin1()); gfaFilter->SetParam1(p1); gfaFilter->SetParam2(p2); break; } case 13: { gfaFilter->SetComputationMethod(GfaFilterType::GFA_GENERALIZED_GFA); QString paramString; paramString = paramString.append("GFAK%1P%2").arg(p1).arg(p2); - newname.append(paramString.toAscii()); + newname.append(paramString.toLatin1()); gfaFilter->SetParam1(p1); gfaFilter->SetParam2(p2); break; } default: { newname.append("0"); gfaFilter->SetComputationMethod(GfaFilterType::GFA_STANDARD); } } gfaFilter->Update(); clock.Stop(); typedef itk::Image ImgType; ImgType::Pointer img = ImgType::New(); img->SetSpacing( gfaFilter->GetOutput()->GetSpacing() ); // Set the image spacing img->SetOrigin( gfaFilter->GetOutput()->GetOrigin() ); // Set the image origin img->SetDirection( gfaFilter->GetOutput()->GetDirection() ); // Set the image direction img->SetLargestPossibleRegion( gfaFilter->GetOutput()->GetLargestPossibleRegion()); img->SetBufferedRegion( gfaFilter->GetOutput()->GetLargestPossibleRegion() ); img->Allocate(); itk::ImageRegionIterator ot (img, img->GetLargestPossibleRegion() ); ot.GoToBegin(); itk::ImageRegionConstIterator it (gfaFilter->GetOutput(), gfaFilter->GetOutput()->GetLargestPossibleRegion() ); for (it.GoToBegin(); !it.IsAtEnd(); ++it) { GfaFilterType::OutputImageType::PixelType val = it.Get(); ot.Set(val * m_Controls->m_ScaleImageValuesBox->value()); ++ot; } // GFA TO DATATREE mitk::Image::Pointer image = mitk::Image::New(); image->InitializeByItk( img.GetPointer() ); image->SetVolume( img->GetBufferPointer() ); mitk::DataNode::Pointer node=mitk::DataNode::New(); node->SetData( image ); node->SetProperty( "name", mitk::StringProperty::New(newname) ); nodes.push_back(node); mitk::StatusBar::GetInstance()->DisplayText("Computation complete."); } std::vector::iterator nodeIt; for(nodeIt = nodes.begin(); nodeIt != nodes.end(); ++nodeIt) GetDefaultDataStorage()->Add(*nodeIt); m_MultiWidget->RequestUpdate(); } void QmitkDiffusionQuantificationView::TensorQuantification( mitk::DataStorage::SetOfObjects::Pointer inImages, int method) { itk::TimeProbe clock; QString status; int nrFiles = inImages->size(); if (!nrFiles) return; mitk::DataStorage::SetOfObjects::const_iterator itemiter( inImages->begin() ); mitk::DataStorage::SetOfObjects::const_iterator itemiterend( inImages->end() ); std::vector nodes; while ( itemiter != itemiterend ) // for all items { typedef float TTensorPixelType; typedef itk::DiffusionTensor3D< TTensorPixelType > TensorPixelType; typedef itk::Image< TensorPixelType, 3 > TensorImageType; mitk::Image* vol = static_cast((*itemiter)->GetData()); TensorImageType::Pointer itkvol = TensorImageType::New(); mitk::CastToItkImage(vol, itkvol); std::string nodename; (*itemiter)->GetStringProperty("name", nodename); ++itemiter; // COMPUTE FA clock.Start(); MBI_INFO << "Computing FA "; mitk::StatusBar::GetInstance()->DisplayText(status.sprintf( - "Computing FA for %s", nodename.c_str()).toAscii()); + "Computing FA for %s", nodename.c_str()).toLatin1()); typedef itk::Image< TTensorPixelType, 3 > FAImageType; typedef itk::ShiftScaleImageFilter ShiftScaleFilterType; ShiftScaleFilterType::Pointer multi = ShiftScaleFilterType::New(); multi->SetShift(0.0); multi->SetScale(m_Controls->m_ScaleImageValuesBox->value());//itk::NumericTraits::max() typedef itk::TensorDerivedMeasurementsFilter MeasurementsType; if(method == 0) //FA { /* typedef itk::TensorFractionalAnisotropyImageFilter< TensorImageType, FAImageType > FilterType; FilterType::Pointer anisotropyFilter = FilterType::New(); anisotropyFilter->SetInput( itkvol.GetPointer() ); anisotropyFilter->Update(); multi->SetInput(anisotropyFilter->GetOutput()); nodename = QString(nodename.c_str()).append("_FA").toStdString();*/ MeasurementsType::Pointer measurementsCalculator = MeasurementsType::New(); measurementsCalculator->SetInput(itkvol.GetPointer() ); measurementsCalculator->SetMeasure(MeasurementsType::FA); measurementsCalculator->Update(); multi->SetInput(measurementsCalculator->GetOutput()); nodename = QString(nodename.c_str()).append("_FA").toStdString(); } else if(method == 1) //RA { /*typedef itk::TensorRelativeAnisotropyImageFilter< TensorImageType, FAImageType > FilterType; FilterType::Pointer anisotropyFilter = FilterType::New(); anisotropyFilter->SetInput( itkvol.GetPointer() ); anisotropyFilter->Update(); multi->SetInput(anisotropyFilter->GetOutput()); nodename = QString(nodename.c_str()).append("_RA").toStdString();*/ MeasurementsType::Pointer measurementsCalculator = MeasurementsType::New(); measurementsCalculator->SetInput(itkvol.GetPointer() ); measurementsCalculator->SetMeasure(MeasurementsType::RA); measurementsCalculator->Update(); multi->SetInput(measurementsCalculator->GetOutput()); nodename = QString(nodename.c_str()).append("_RA").toStdString(); } else if(method == 2) // AD (Axial diffusivity) { MeasurementsType::Pointer measurementsCalculator = MeasurementsType::New(); measurementsCalculator->SetInput(itkvol.GetPointer() ); measurementsCalculator->SetMeasure(MeasurementsType::AD); measurementsCalculator->Update(); multi->SetInput(measurementsCalculator->GetOutput()); nodename = QString(nodename.c_str()).append("_AD").toStdString(); } else if(method == 3) // RD (Radial diffusivity, (Lambda2+Lambda3)/2 { MeasurementsType::Pointer measurementsCalculator = MeasurementsType::New(); measurementsCalculator->SetInput(itkvol.GetPointer() ); measurementsCalculator->SetMeasure(MeasurementsType::RD); measurementsCalculator->Update(); multi->SetInput(measurementsCalculator->GetOutput()); nodename = QString(nodename.c_str()).append("_RD").toStdString(); } else if(method == 4) // 1-(Lambda2+Lambda3)/(2*Lambda1) { MeasurementsType::Pointer measurementsCalculator = MeasurementsType::New(); measurementsCalculator->SetInput(itkvol.GetPointer() ); measurementsCalculator->SetMeasure(MeasurementsType::CA); measurementsCalculator->Update(); multi->SetInput(measurementsCalculator->GetOutput()); nodename = QString(nodename.c_str()).append("_CA").toStdString(); } else if(method == 5) // MD (Mean Diffusivity, (Lambda1+Lambda2+Lambda3)/3 ) { MeasurementsType::Pointer measurementsCalculator = MeasurementsType::New(); measurementsCalculator->SetInput(itkvol.GetPointer() ); measurementsCalculator->SetMeasure(MeasurementsType::MD); measurementsCalculator->Update(); multi->SetInput(measurementsCalculator->GetOutput()); nodename = QString(nodename.c_str()).append("_MD").toStdString(); } multi->Update(); clock.Stop(); // FA TO DATATREE mitk::Image::Pointer image = mitk::Image::New(); image->InitializeByItk( multi->GetOutput() ); image->SetVolume( multi->GetOutput()->GetBufferPointer() ); mitk::DataNode::Pointer node=mitk::DataNode::New(); node->SetData( image ); node->SetProperty( "name", mitk::StringProperty::New(nodename) ); nodes.push_back(node); mitk::StatusBar::GetInstance()->DisplayText("Computation complete."); } std::vector::iterator nodeIt; for(nodeIt = nodes.begin(); nodeIt != nodes.end(); ++nodeIt) GetDefaultDataStorage()->Add(*nodeIt); m_MultiWidget->RequestUpdate(); } diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkFiberfoxView.cpp b/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkFiberfoxView.cpp index e1e77dd053..cd0b53ef56 100644 --- a/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkFiberfoxView.cpp +++ b/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkFiberfoxView.cpp @@ -1,2631 +1,2633 @@ /*=================================================================== 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. ===================================================================*/ //misc #define _USE_MATH_DEFINES #include // Blueberry #include #include // Qmitk #include "QmitkFiberfoxView.h" // MITK #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "usModuleRegistry.h" #include #include #include #include #include #include #include #include #define _USE_MATH_DEFINES #include QmitkFiberfoxWorker::QmitkFiberfoxWorker(QmitkFiberfoxView* view) : m_View(view) { } void QmitkFiberfoxWorker::run() { try{ switch (m_FilterType) { case 0: m_View->m_TractsToDwiFilter->Update(); break; case 1: m_View->m_ArtifactsToDwiFilter->Update(); break; } } catch( ... ) { } m_View->m_Thread.quit(); } const std::string QmitkFiberfoxView::VIEW_ID = "org.mitk.views.fiberfoxview"; QmitkFiberfoxView::QmitkFiberfoxView() : QmitkAbstractView() , m_Controls( 0 ) , m_SelectedImage( NULL ) , m_Worker(this) , m_ThreadIsRunning(false) { m_Worker.moveToThread(&m_Thread); connect(&m_Thread, SIGNAL(started()), this, SLOT(BeforeThread())); connect(&m_Thread, SIGNAL(started()), &m_Worker, SLOT(run())); connect(&m_Thread, SIGNAL(finished()), this, SLOT(AfterThread())); connect(&m_Thread, SIGNAL(terminated()), this, SLOT(AfterThread())); m_SimulationTimer = new QTimer(this); } void QmitkFiberfoxView::KillThread() { MITK_INFO << "Aborting DWI simulation."; switch (m_Worker.m_FilterType) { case 0: m_TractsToDwiFilter->SetAbortGenerateData(true); break; case 1: m_ArtifactsToDwiFilter->SetAbortGenerateData(true); break; } m_Controls->m_AbortSimulationButton->setEnabled(false); m_Controls->m_AbortSimulationButton->setText("Aborting simulation ..."); } void QmitkFiberfoxView::BeforeThread() { m_SimulationTime = QTime::currentTime(); m_SimulationTimer->start(100); m_Controls->m_AbortSimulationButton->setVisible(true); m_Controls->m_GenerateImageButton->setVisible(false); m_Controls->m_SimulationStatusText->setVisible(true); m_ThreadIsRunning = true; } void QmitkFiberfoxView::AfterThread() { UpdateSimulationStatus(); m_SimulationTimer->stop(); m_Controls->m_AbortSimulationButton->setVisible(false); m_Controls->m_AbortSimulationButton->setEnabled(true); m_Controls->m_AbortSimulationButton->setText("Abort simulation"); m_Controls->m_GenerateImageButton->setVisible(true); m_ThreadIsRunning = false; QString statusText; FiberfoxParameters parameters; mitk::DiffusionImage::Pointer mitkImage = mitk::DiffusionImage::New(); switch (m_Worker.m_FilterType) { case 0: { statusText = QString(m_TractsToDwiFilter->GetStatusText().c_str()); if (m_TractsToDwiFilter->GetAbortGenerateData()) { MITK_INFO << "Simulation aborted."; return; } parameters = m_TractsToDwiFilter->GetParameters(); mitkImage->SetVectorImage( m_TractsToDwiFilter->GetOutput() ); mitkImage->SetReferenceBValue(parameters.m_SignalGen.m_Bvalue); mitkImage->SetDirections(parameters.m_SignalGen.GetGradientDirections()); mitkImage->InitializeFromVectorImage(); parameters.m_Misc.m_ResultNode->SetData( mitkImage ); parameters.m_Misc.m_ResultNode->SetName(parameters.m_Misc.m_ParentNode->GetName() +"_D"+QString::number(parameters.m_SignalGen.m_ImageRegion.GetSize(0)).toStdString() +"-"+QString::number(parameters.m_SignalGen.m_ImageRegion.GetSize(1)).toStdString() +"-"+QString::number(parameters.m_SignalGen.m_ImageRegion.GetSize(2)).toStdString() +"_S"+QString::number(parameters.m_SignalGen.m_ImageSpacing[0]).toStdString() +"-"+QString::number(parameters.m_SignalGen.m_ImageSpacing[1]).toStdString() +"-"+QString::number(parameters.m_SignalGen.m_ImageSpacing[2]).toStdString() +"_b"+QString::number(parameters.m_SignalGen.m_Bvalue).toStdString() +"_"+parameters.m_Misc.m_SignalModelString +parameters.m_Misc.m_ArtifactModelString); GetDataStorage()->Add(parameters.m_Misc.m_ResultNode, parameters.m_Misc.m_ParentNode); parameters.m_Misc.m_ResultNode->SetProperty( "levelwindow", mitk::LevelWindowProperty::New(m_TractsToDwiFilter->GetLevelWindow()) ); if (m_Controls->m_VolumeFractionsBox->isChecked()) { std::vector< itk::TractsToDWIImageFilter< short >::ItkDoubleImgType::Pointer > volumeFractions = m_TractsToDwiFilter->GetVolumeFractions(); for (unsigned int k=0; kInitializeByItk(volumeFractions.at(k).GetPointer()); image->SetVolume(volumeFractions.at(k)->GetBufferPointer()); mitk::DataNode::Pointer node = mitk::DataNode::New(); node->SetData( image ); node->SetName(parameters.m_Misc.m_ParentNode->GetName()+"_CompartmentVolume-"+QString::number(k).toStdString()); GetDataStorage()->Add(node, parameters.m_Misc.m_ParentNode); } } m_TractsToDwiFilter = NULL; break; } case 1: { statusText = QString(m_ArtifactsToDwiFilter->GetStatusText().c_str()); if (m_ArtifactsToDwiFilter->GetAbortGenerateData()) { MITK_INFO << "Simulation aborted."; return; } parameters = m_ArtifactsToDwiFilter->GetParameters().CopyParameters(); mitk::DiffusionImage::Pointer diffImg = dynamic_cast*>(parameters.m_Misc.m_ParentNode->GetData()); mitkImage = mitk::DiffusionImage::New(); mitkImage->SetVectorImage( m_ArtifactsToDwiFilter->GetOutput() ); mitkImage->SetReferenceBValue(diffImg->GetReferenceBValue()); mitkImage->SetDirections(diffImg->GetDirections()); mitkImage->InitializeFromVectorImage(); parameters.m_Misc.m_ResultNode->SetData( mitkImage ); parameters.m_Misc.m_ResultNode->SetName(parameters.m_Misc.m_ParentNode->GetName()+parameters.m_Misc.m_ArtifactModelString); GetDataStorage()->Add(parameters.m_Misc.m_ResultNode, parameters.m_Misc.m_ParentNode); m_ArtifactsToDwiFilter = NULL; break; } } mitk::BaseData::Pointer basedata = parameters.m_Misc.m_ResultNode->GetData(); if (basedata.IsNotNull()) { mitk::RenderingManager::GetInstance()->InitializeViews( basedata->GetTimeGeometry(), mitk::RenderingManager::REQUEST_UPDATE_ALL, true ); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } if (!parameters.m_Misc.m_OutputPath.empty()) { try{ QString outputFileName(parameters.m_Misc.m_OutputPath.c_str()); outputFileName += parameters.m_Misc.m_ResultNode->GetName().c_str(); outputFileName.replace(QString("."), QString("_")); outputFileName += ".dwi"; QString status("Saving output image to "); status += outputFileName; m_Controls->m_SimulationStatusText->append(status); mitk::IOUtil::SaveBaseData(mitkImage, outputFileName.toStdString()); m_Controls->m_SimulationStatusText->append("File saved successfully."); } catch (itk::ExceptionObject &e) { QString status("Exception during DWI writing: "); status += e.GetDescription(); m_Controls->m_SimulationStatusText->append(status); } catch (...) { m_Controls->m_SimulationStatusText->append("Unknown exception during DWI writing!"); } } parameters.m_SignalGen.m_FrequencyMap = NULL; } void QmitkFiberfoxView::UpdateSimulationStatus() { QString statusText; switch (m_Worker.m_FilterType) { case 0: statusText = QString(m_TractsToDwiFilter->GetStatusText().c_str()); break; case 1: statusText = QString(m_ArtifactsToDwiFilter->GetStatusText().c_str()); break; } if (QString::compare(m_SimulationStatusText,statusText)!=0) { m_Controls->m_SimulationStatusText->clear(); statusText = "
"+statusText+"
"; m_Controls->m_SimulationStatusText->setText(statusText); QScrollBar *vScrollBar = m_Controls->m_SimulationStatusText->verticalScrollBar(); vScrollBar->triggerAction(QScrollBar::SliderToMaximum); } } // Destructor QmitkFiberfoxView::~QmitkFiberfoxView() { delete m_SimulationTimer; } void QmitkFiberfoxView::CreateQtPartControl( QWidget *parent ) { // build up qt view, unless already done if ( !m_Controls ) { // create GUI widgets from the Qt Designer's .ui file m_Controls = new Ui::QmitkFiberfoxViewControls; m_Controls->setupUi( parent ); // commented out m_Controls->m_DiffusionDirectionBox->setVisible(false); m_Controls->label_3->setVisible(false); m_Controls->m_SeparationAngleBox->setVisible(false); m_Controls->label_4->setVisible(false); // m_Controls->m_StickWidget1->setVisible(true); m_Controls->m_StickWidget2->setVisible(false); m_Controls->m_ZeppelinWidget1->setVisible(false); m_Controls->m_ZeppelinWidget2->setVisible(false); m_Controls->m_TensorWidget1->setVisible(false); m_Controls->m_TensorWidget2->setVisible(false); m_Controls->m_BallWidget1->setVisible(true); m_Controls->m_BallWidget2->setVisible(false); m_Controls->m_AstrosticksWidget1->setVisible(false); m_Controls->m_AstrosticksWidget2->setVisible(false); m_Controls->m_DotWidget1->setVisible(false); m_Controls->m_DotWidget2->setVisible(false); m_Controls->m_PrototypeWidget1->setVisible(false); m_Controls->m_PrototypeWidget2->setVisible(false); m_Controls->m_PrototypeWidget3->setVisible(false); m_Controls->m_PrototypeWidget4->setVisible(false); m_Controls->m_PrototypeWidget3->SetMinFa(0.0); m_Controls->m_PrototypeWidget3->SetMaxFa(0.15); m_Controls->m_PrototypeWidget4->SetMinFa(0.0); m_Controls->m_PrototypeWidget4->SetMaxFa(0.15); m_Controls->m_PrototypeWidget3->SetMinAdc(0.0); m_Controls->m_PrototypeWidget3->SetMaxAdc(0.001); m_Controls->m_PrototypeWidget4->SetMinAdc(0.003); m_Controls->m_PrototypeWidget4->SetMaxAdc(0.004); m_Controls->m_Comp4FractionFrame->setVisible(false); m_Controls->m_DiffusionPropsMessage->setVisible(false); m_Controls->m_GeometryMessage->setVisible(false); m_Controls->m_AdvancedSignalOptionsFrame->setVisible(false); m_Controls->m_AdvancedFiberOptionsFrame->setVisible(false); m_Controls->m_VarianceBox->setVisible(false); m_Controls->m_NoiseFrame->setVisible(false); m_Controls->m_GhostFrame->setVisible(false); m_Controls->m_DistortionsFrame->setVisible(false); m_Controls->m_EddyFrame->setVisible(false); m_Controls->m_SpikeFrame->setVisible(false); m_Controls->m_AliasingFrame->setVisible(false); m_Controls->m_MotionArtifactFrame->setVisible(false); m_ParameterFile = QDir::currentPath()+"/param.ffp"; m_Controls->m_AbortSimulationButton->setVisible(false); m_Controls->m_SimulationStatusText->setVisible(false); m_Controls->m_FrequencyMapBox->SetDataStorage(this->GetDataStorage()); mitk::TNodePredicateDataType::Pointer isMitkImage = mitk::TNodePredicateDataType::New(); mitk::NodePredicateDataType::Pointer isDwi = mitk::NodePredicateDataType::New("DiffusionImage"); mitk::NodePredicateDataType::Pointer isDti = mitk::NodePredicateDataType::New("TensorImage"); mitk::NodePredicateDataType::Pointer isQbi = mitk::NodePredicateDataType::New("QBallImage"); mitk::NodePredicateOr::Pointer isDiffusionImage = mitk::NodePredicateOr::New(isDwi, isDti); isDiffusionImage = mitk::NodePredicateOr::New(isDiffusionImage, isQbi); mitk::NodePredicateNot::Pointer noDiffusionImage = mitk::NodePredicateNot::New(isDiffusionImage); mitk::NodePredicateAnd::Pointer finalPredicate = mitk::NodePredicateAnd::New(isMitkImage, noDiffusionImage); m_Controls->m_FrequencyMapBox->SetPredicate(finalPredicate); m_Controls->m_Comp4VolumeFraction->SetDataStorage(this->GetDataStorage()); m_Controls->m_Comp4VolumeFraction->SetPredicate(finalPredicate); connect( m_SimulationTimer, SIGNAL(timeout()), this, SLOT(UpdateSimulationStatus()) ); connect((QObject*) m_Controls->m_AbortSimulationButton, SIGNAL(clicked()), (QObject*) this, SLOT(KillThread())); connect((QObject*) m_Controls->m_GenerateImageButton, SIGNAL(clicked()), (QObject*) this, SLOT(GenerateImage())); connect((QObject*) m_Controls->m_GenerateFibersButton, SIGNAL(clicked()), (QObject*) this, SLOT(GenerateFibers())); connect((QObject*) m_Controls->m_CircleButton, SIGNAL(clicked()), (QObject*) this, SLOT(OnDrawROI())); connect((QObject*) m_Controls->m_FlipButton, SIGNAL(clicked()), (QObject*) this, SLOT(OnFlipButton())); connect((QObject*) m_Controls->m_JoinBundlesButton, SIGNAL(clicked()), (QObject*) this, SLOT(JoinBundles())); connect((QObject*) m_Controls->m_VarianceBox, SIGNAL(valueChanged(double)), (QObject*) this, SLOT(OnVarianceChanged(double))); connect((QObject*) m_Controls->m_DistributionBox, SIGNAL(currentIndexChanged(int)), (QObject*) this, SLOT(OnDistributionChanged(int))); connect((QObject*) m_Controls->m_FiberDensityBox, SIGNAL(valueChanged(int)), (QObject*) this, SLOT(OnFiberDensityChanged(int))); connect((QObject*) m_Controls->m_FiberSamplingBox, SIGNAL(valueChanged(double)), (QObject*) this, SLOT(OnFiberSamplingChanged(double))); connect((QObject*) m_Controls->m_TensionBox, SIGNAL(valueChanged(double)), (QObject*) this, SLOT(OnTensionChanged(double))); connect((QObject*) m_Controls->m_ContinuityBox, SIGNAL(valueChanged(double)), (QObject*) this, SLOT(OnContinuityChanged(double))); connect((QObject*) m_Controls->m_BiasBox, SIGNAL(valueChanged(double)), (QObject*) this, SLOT(OnBiasChanged(double))); connect((QObject*) m_Controls->m_AddNoise, SIGNAL(stateChanged(int)), (QObject*) this, SLOT(OnAddNoise(int))); connect((QObject*) m_Controls->m_AddGhosts, SIGNAL(stateChanged(int)), (QObject*) this, SLOT(OnAddGhosts(int))); connect((QObject*) m_Controls->m_AddDistortions, SIGNAL(stateChanged(int)), (QObject*) this, SLOT(OnAddDistortions(int))); connect((QObject*) m_Controls->m_AddEddy, SIGNAL(stateChanged(int)), (QObject*) this, SLOT(OnAddEddy(int))); connect((QObject*) m_Controls->m_AddSpikes, SIGNAL(stateChanged(int)), (QObject*) this, SLOT(OnAddSpikes(int))); connect((QObject*) m_Controls->m_AddAliasing, SIGNAL(stateChanged(int)), (QObject*) this, SLOT(OnAddAliasing(int))); connect((QObject*) m_Controls->m_AddMotion, SIGNAL(stateChanged(int)), (QObject*) this, SLOT(OnAddMotion(int))); connect((QObject*) m_Controls->m_ConstantRadiusBox, SIGNAL(stateChanged(int)), (QObject*) this, SLOT(OnConstantRadius(int))); connect((QObject*) m_Controls->m_CopyBundlesButton, SIGNAL(clicked()), (QObject*) this, SLOT(CopyBundles())); connect((QObject*) m_Controls->m_TransformBundlesButton, SIGNAL(clicked()), (QObject*) this, SLOT(ApplyTransform())); connect((QObject*) m_Controls->m_AlignOnGrid, SIGNAL(clicked()), (QObject*) this, SLOT(AlignOnGrid())); connect((QObject*) m_Controls->m_Compartment1Box, SIGNAL(currentIndexChanged(int)), (QObject*) this, SLOT(Comp1ModelFrameVisibility(int))); connect((QObject*) m_Controls->m_Compartment2Box, SIGNAL(currentIndexChanged(int)), (QObject*) this, SLOT(Comp2ModelFrameVisibility(int))); connect((QObject*) m_Controls->m_Compartment3Box, SIGNAL(currentIndexChanged(int)), (QObject*) this, SLOT(Comp3ModelFrameVisibility(int))); connect((QObject*) m_Controls->m_Compartment4Box, SIGNAL(currentIndexChanged(int)), (QObject*) this, SLOT(Comp4ModelFrameVisibility(int))); connect((QObject*) m_Controls->m_AdvancedOptionsBox, SIGNAL( stateChanged(int)), (QObject*) this, SLOT(ShowAdvancedOptions(int))); connect((QObject*) m_Controls->m_AdvancedOptionsBox_2, SIGNAL( stateChanged(int)), (QObject*) this, SLOT(ShowAdvancedOptions(int))); connect((QObject*) m_Controls->m_SaveParametersButton, SIGNAL(clicked()), (QObject*) this, SLOT(SaveParameters())); connect((QObject*) m_Controls->m_LoadParametersButton, SIGNAL(clicked()), (QObject*) this, SLOT(LoadParameters())); connect((QObject*) m_Controls->m_OutputPathButton, SIGNAL(clicked()), (QObject*) this, SLOT(SetOutputPath())); } } template< class ScalarType > FiberfoxParameters< ScalarType > QmitkFiberfoxView::UpdateImageParameters() { FiberfoxParameters< ScalarType > parameters; parameters.m_Misc.m_OutputPath = ""; parameters.m_Misc.m_CheckAdvancedFiberOptionsBox = m_Controls->m_AdvancedOptionsBox->isChecked(); parameters.m_Misc.m_CheckAdvancedSignalOptionsBox = m_Controls->m_AdvancedOptionsBox_2->isChecked(); parameters.m_Misc.m_CheckOutputVolumeFractionsBox = m_Controls->m_VolumeFractionsBox->isChecked(); string outputPath = m_Controls->m_SavePathEdit->text().toStdString(); if (outputPath.compare("-")!=0) { parameters.m_Misc.m_OutputPath = outputPath; parameters.m_Misc.m_OutputPath += "/"; } if (m_MaskImageNode.IsNotNull()) { mitk::Image::Pointer mitkMaskImage = dynamic_cast(m_MaskImageNode->GetData()); mitk::CastToItkImage(mitkMaskImage, parameters.m_SignalGen.m_MaskImage); itk::ImageDuplicator::Pointer duplicator = itk::ImageDuplicator::New(); duplicator->SetInputImage(parameters.m_SignalGen.m_MaskImage); duplicator->Update(); parameters.m_SignalGen.m_MaskImage = duplicator->GetOutput(); } if (m_SelectedDWI.IsNotNull()) // use parameters of selected DWI { mitk::DiffusionImage::Pointer dwi = dynamic_cast*>(m_SelectedDWI->GetData()); parameters.m_SignalGen.m_ImageRegion = dwi->GetVectorImage()->GetLargestPossibleRegion(); parameters.m_SignalGen.m_ImageSpacing = dwi->GetVectorImage()->GetSpacing(); parameters.m_SignalGen.m_ImageOrigin = dwi->GetVectorImage()->GetOrigin(); parameters.m_SignalGen.m_ImageDirection = dwi->GetVectorImage()->GetDirection(); parameters.m_SignalGen.m_Bvalue = dwi->GetReferenceBValue(); parameters.m_SignalGen.SetGradienDirections(dwi->GetDirections()); } else if (m_SelectedImage.IsNotNull()) // use geometry of selected image { mitk::Image::Pointer img = dynamic_cast(m_SelectedImage->GetData()); itk::Image< float, 3 >::Pointer itkImg = itk::Image< float, 3 >::New(); CastToItkImage< itk::Image< float, 3 > >(img, itkImg); parameters.m_SignalGen.m_ImageRegion = itkImg->GetLargestPossibleRegion(); parameters.m_SignalGen.m_ImageSpacing = itkImg->GetSpacing(); parameters.m_SignalGen.m_ImageOrigin = itkImg->GetOrigin(); parameters.m_SignalGen.m_ImageDirection = itkImg->GetDirection(); parameters.m_SignalGen.SetNumWeightedVolumes(m_Controls->m_NumGradientsBox->value()); parameters.m_SignalGen.m_Bvalue = m_Controls->m_BvalueBox->value(); } else // use GUI parameters { parameters.m_SignalGen.m_ImageRegion.SetSize(0, m_Controls->m_SizeX->value()); parameters.m_SignalGen.m_ImageRegion.SetSize(1, m_Controls->m_SizeY->value()); parameters.m_SignalGen.m_ImageRegion.SetSize(2, m_Controls->m_SizeZ->value()); parameters.m_SignalGen.m_ImageSpacing[0] = m_Controls->m_SpacingX->value(); parameters.m_SignalGen.m_ImageSpacing[1] = m_Controls->m_SpacingY->value(); parameters.m_SignalGen.m_ImageSpacing[2] = m_Controls->m_SpacingZ->value(); parameters.m_SignalGen.m_ImageOrigin[0] = parameters.m_SignalGen.m_ImageSpacing[0]/2; parameters.m_SignalGen.m_ImageOrigin[1] = parameters.m_SignalGen.m_ImageSpacing[1]/2; parameters.m_SignalGen.m_ImageOrigin[2] = parameters.m_SignalGen.m_ImageSpacing[2]/2; parameters.m_SignalGen.m_ImageDirection.SetIdentity(); parameters.m_SignalGen.SetNumWeightedVolumes(m_Controls->m_NumGradientsBox->value()); parameters.m_SignalGen.m_Bvalue = m_Controls->m_BvalueBox->value(); parameters.m_SignalGen.GenerateGradientHalfShell(); } // signal relaxation parameters.m_SignalGen.m_DoSimulateRelaxation = m_Controls->m_RelaxationBox->isChecked(); parameters.m_SignalGen.m_SimulateKspaceAcquisition = parameters.m_SignalGen.m_DoSimulateRelaxation; if (parameters.m_SignalGen.m_DoSimulateRelaxation && m_SelectedBundles.size()>0 ) parameters.m_Misc.m_ArtifactModelString += "_RELAX"; // N/2 ghosts parameters.m_Misc.m_CheckAddGhostsBox = m_Controls->m_AddGhosts->isChecked(); if (m_Controls->m_AddGhosts->isChecked()) { parameters.m_SignalGen.m_SimulateKspaceAcquisition = true; parameters.m_Misc.m_ArtifactModelString += "_GHOST"; parameters.m_SignalGen.m_KspaceLineOffset = m_Controls->m_kOffsetBox->value(); parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Ghost", DoubleProperty::New(parameters.m_SignalGen.m_KspaceLineOffset)); } else parameters.m_SignalGen.m_KspaceLineOffset = 0; // Aliasing parameters.m_Misc.m_CheckAddAliasingBox = m_Controls->m_AddAliasing->isChecked(); if (m_Controls->m_AddAliasing->isChecked()) { parameters.m_SignalGen.m_SimulateKspaceAcquisition = true; parameters.m_Misc.m_ArtifactModelString += "_ALIASING"; parameters.m_SignalGen.m_CroppingFactor = (100-m_Controls->m_WrapBox->value())/100; parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Aliasing", DoubleProperty::New(m_Controls->m_WrapBox->value())); } // Spikes parameters.m_Misc.m_CheckAddSpikesBox = m_Controls->m_AddSpikes->isChecked(); if (m_Controls->m_AddSpikes->isChecked()) { parameters.m_SignalGen.m_SimulateKspaceAcquisition = true; parameters.m_SignalGen.m_Spikes = m_Controls->m_SpikeNumBox->value(); parameters.m_SignalGen.m_SpikeAmplitude = m_Controls->m_SpikeScaleBox->value(); parameters.m_Misc.m_ArtifactModelString += "_SPIKES"; parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Spikes.Number", IntProperty::New(parameters.m_SignalGen.m_Spikes)); parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Spikes.Amplitude", DoubleProperty::New(parameters.m_SignalGen.m_SpikeAmplitude)); } // gibbs ringing parameters.m_SignalGen.m_DoAddGibbsRinging = m_Controls->m_AddGibbsRinging->isChecked(); if (m_Controls->m_AddGibbsRinging->isChecked()) { parameters.m_SignalGen.m_SimulateKspaceAcquisition = true; parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Ringing", BoolProperty::New(true)); parameters.m_Misc.m_ArtifactModelString += "_RINGING"; } // add distortions parameters.m_Misc.m_CheckAddDistortionsBox = m_Controls->m_AddDistortions->isChecked(); if (m_Controls->m_AddDistortions->isChecked() && m_Controls->m_FrequencyMapBox->GetSelectedNode().IsNotNull()) { mitk::DataNode::Pointer fMapNode = m_Controls->m_FrequencyMapBox->GetSelectedNode(); mitk::Image* img = dynamic_cast(fMapNode->GetData()); ItkDoubleImgType::Pointer itkImg = ItkDoubleImgType::New(); CastToItkImage< ItkDoubleImgType >(img, itkImg); if (m_SelectedImage.IsNull()) // use geometry of frequency map { parameters.m_SignalGen.m_ImageRegion = itkImg->GetLargestPossibleRegion(); parameters.m_SignalGen.m_ImageSpacing = itkImg->GetSpacing(); parameters.m_SignalGen.m_ImageOrigin = itkImg->GetOrigin(); parameters.m_SignalGen.m_ImageDirection = itkImg->GetDirection(); } if (parameters.m_SignalGen.m_ImageRegion.GetSize(0)==itkImg->GetLargestPossibleRegion().GetSize(0) && parameters.m_SignalGen.m_ImageRegion.GetSize(1)==itkImg->GetLargestPossibleRegion().GetSize(1) && parameters.m_SignalGen.m_ImageRegion.GetSize(2)==itkImg->GetLargestPossibleRegion().GetSize(2)) { parameters.m_SignalGen.m_SimulateKspaceAcquisition = true; itk::ImageDuplicator::Pointer duplicator = itk::ImageDuplicator::New(); duplicator->SetInputImage(itkImg); duplicator->Update(); parameters.m_SignalGen.m_FrequencyMap = duplicator->GetOutput(); parameters.m_Misc.m_ArtifactModelString += "_DISTORTED"; parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Distortions", BoolProperty::New(true)); } } parameters.m_SignalGen.m_EddyStrength = 0; parameters.m_Misc.m_CheckAddEddyCurrentsBox = m_Controls->m_AddEddy->isChecked(); if (m_Controls->m_AddEddy->isChecked()) { parameters.m_SignalGen.m_EddyStrength = m_Controls->m_EddyGradientStrength->value(); parameters.m_Misc.m_ArtifactModelString += "_EDDY"; parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Eddy-strength", DoubleProperty::New(parameters.m_SignalGen.m_EddyStrength)); } // Motion parameters.m_SignalGen.m_DoAddMotion = m_Controls->m_AddMotion->isChecked(); parameters.m_SignalGen.m_DoRandomizeMotion = m_Controls->m_RandomMotion->isChecked(); parameters.m_SignalGen.m_Translation[0] = m_Controls->m_MaxTranslationBoxX->value(); parameters.m_SignalGen.m_Translation[1] = m_Controls->m_MaxTranslationBoxY->value(); parameters.m_SignalGen.m_Translation[2] = m_Controls->m_MaxTranslationBoxZ->value(); parameters.m_SignalGen.m_Rotation[0] = m_Controls->m_MaxRotationBoxX->value(); parameters.m_SignalGen.m_Rotation[1] = m_Controls->m_MaxRotationBoxY->value(); parameters.m_SignalGen.m_Rotation[2] = m_Controls->m_MaxRotationBoxZ->value(); if ( m_Controls->m_AddMotion->isChecked() && m_SelectedBundles.size()>0 ) { parameters.m_Misc.m_ArtifactModelString += "_MOTION"; parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Motion.Random", BoolProperty::New(parameters.m_SignalGen.m_DoRandomizeMotion)); parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Motion.Translation-x", DoubleProperty::New(parameters.m_SignalGen.m_Translation[0])); parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Motion.Translation-y", DoubleProperty::New(parameters.m_SignalGen.m_Translation[1])); parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Motion.Translation-z", DoubleProperty::New(parameters.m_SignalGen.m_Translation[2])); parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Motion.Rotation-x", DoubleProperty::New(parameters.m_SignalGen.m_Rotation[0])); parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Motion.Rotation-y", DoubleProperty::New(parameters.m_SignalGen.m_Rotation[1])); parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Motion.Rotation-z", DoubleProperty::New(parameters.m_SignalGen.m_Rotation[2])); } // other imaging parameters parameters.m_SignalGen.m_tLine = m_Controls->m_LineReadoutTimeBox->value(); parameters.m_SignalGen.m_tInhom = m_Controls->m_T2starBox->value(); parameters.m_SignalGen.m_tEcho = m_Controls->m_TEbox->value(); parameters.m_SignalGen.m_DoDisablePartialVolume = m_Controls->m_EnforcePureFiberVoxelsBox->isChecked(); parameters.m_SignalGen.m_AxonRadius = m_Controls->m_FiberRadius->value(); parameters.m_SignalGen.m_SignalScale = m_Controls->m_SignalScaleBox->value(); // adjust echo time if needed if ( parameters.m_SignalGen.m_tEcho < parameters.m_SignalGen.m_ImageRegion.GetSize(1)*parameters.m_SignalGen.m_tLine ) { this->m_Controls->m_TEbox->setValue( parameters.m_SignalGen.m_ImageRegion.GetSize(1)*parameters.m_SignalGen.m_tLine ); parameters.m_SignalGen.m_tEcho = m_Controls->m_TEbox->value(); QMessageBox::information( NULL, "Warning", "Echo time is too short! Time not sufficient to read slice. Automaticall adjusted to "+QString::number(parameters.m_SignalGen.m_tEcho)+" ms"); } // Noise parameters.m_Misc.m_CheckAddNoiseBox = m_Controls->m_AddNoise->isChecked(); if (m_Controls->m_AddNoise->isChecked()) { double noiseVariance = m_Controls->m_NoiseLevel->value(); { switch (m_Controls->m_NoiseDistributionBox->currentIndex()) { case 0: { parameters.m_NoiseModel = new mitk::RicianNoiseModel(); parameters.m_Misc.m_ArtifactModelString += "_RICIAN-"; parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Noise-Distribution", StringProperty::New("Rician")); break; } case 1: { parameters.m_NoiseModel = new mitk::ChiSquareNoiseModel(); parameters.m_Misc.m_ArtifactModelString += "_CHISQUARED-"; parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Noise-Distribution", StringProperty::New("Chi-squared")); break; } default: { parameters.m_NoiseModel = new mitk::RicianNoiseModel(); parameters.m_Misc.m_ArtifactModelString += "_RICIAN-"; parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Noise-Distribution", StringProperty::New("Rician")); } } } parameters.m_NoiseModel->SetNoiseVariance(noiseVariance); parameters.m_Misc.m_ArtifactModelString += QString::number(noiseVariance).toStdString(); parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Noise-Variance", DoubleProperty::New(noiseVariance)); } // adjusting line readout time to the adapted image size needed for the DFT unsigned int y = parameters.m_SignalGen.m_ImageRegion.GetSize(1); y += y%2; if ( y>parameters.m_SignalGen.m_ImageRegion.GetSize(1) ) parameters.m_SignalGen.m_tLine *= (double)parameters.m_SignalGen.m_ImageRegion.GetSize(1)/y; // signal models { // compartment 1 switch (m_Controls->m_Compartment1Box->currentIndex()) { case 0: { mitk::StickModel* model = new mitk::StickModel(); model->SetGradientList(parameters.m_SignalGen.GetGradientDirections()); model->SetBvalue(parameters.m_SignalGen.m_Bvalue); model->SetDiffusivity(m_Controls->m_StickWidget1->GetD()); model->SetT2(m_Controls->m_StickWidget1->GetT2()); model->m_CompartmentId = 1; parameters.m_FiberModelList.push_back(model); parameters.m_Misc.m_SignalModelString += "Stick"; parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Compartment1.Description", StringProperty::New("Intra-axonal compartment") ); parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Compartment1.Model", StringProperty::New("Stick") ); parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Compartment1.D", DoubleProperty::New(m_Controls->m_StickWidget1->GetD()) ); parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Compartment1.T2", DoubleProperty::New(model->GetT2()) ); break; } case 1: { mitk::TensorModel* model = new mitk::TensorModel(); model->SetGradientList(parameters.m_SignalGen.GetGradientDirections()); model->SetBvalue(parameters.m_SignalGen.m_Bvalue); model->SetDiffusivity1(m_Controls->m_ZeppelinWidget1->GetD1()); model->SetDiffusivity2(m_Controls->m_ZeppelinWidget1->GetD2()); model->SetDiffusivity3(m_Controls->m_ZeppelinWidget1->GetD2()); model->SetT2(m_Controls->m_ZeppelinWidget1->GetT2()); model->m_CompartmentId = 1; parameters.m_FiberModelList.push_back(model); parameters.m_Misc.m_SignalModelString += "Zeppelin"; parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Compartment1.Description", StringProperty::New("Intra-axonal compartment") ); parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Compartment1.Model", StringProperty::New("Zeppelin") ); parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Compartment1.D1", DoubleProperty::New(m_Controls->m_ZeppelinWidget1->GetD1()) ); parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Compartment1.D2", DoubleProperty::New(m_Controls->m_ZeppelinWidget1->GetD2()) ); parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Compartment1.T2", DoubleProperty::New(model->GetT2()) ); break; } case 2: { mitk::TensorModel* model = new mitk::TensorModel(); model->SetGradientList(parameters.m_SignalGen.GetGradientDirections()); model->SetBvalue(parameters.m_SignalGen.m_Bvalue); model->SetDiffusivity1(m_Controls->m_TensorWidget1->GetD1()); model->SetDiffusivity2(m_Controls->m_TensorWidget1->GetD2()); model->SetDiffusivity3(m_Controls->m_TensorWidget1->GetD3()); model->SetT2(m_Controls->m_TensorWidget1->GetT2()); model->m_CompartmentId = 1; parameters.m_FiberModelList.push_back(model); parameters.m_Misc.m_SignalModelString += "Tensor"; parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Compartment1.Description", StringProperty::New("Intra-axonal compartment") ); parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Compartment1.Model", StringProperty::New("Tensor") ); parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Compartment1.D1", DoubleProperty::New(m_Controls->m_TensorWidget1->GetD1()) ); parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Compartment1.D2", DoubleProperty::New(m_Controls->m_TensorWidget1->GetD2()) ); parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Compartment1.D3", DoubleProperty::New(m_Controls->m_TensorWidget1->GetD3()) ); parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Compartment1.T2", DoubleProperty::New(model->GetT2()) ); break; } case 3: { mitk::RawShModel* model = new mitk::RawShModel(); parameters.m_SignalGen.m_DoSimulateRelaxation = false; model->SetGradientList(parameters.m_SignalGen.GetGradientDirections()); model->SetMaxNumKernels(m_Controls->m_PrototypeWidget1->GetNumberOfSamples()); model->SetFaRange(m_Controls->m_PrototypeWidget1->GetMinFa(), m_Controls->m_PrototypeWidget1->GetMaxFa()); model->SetAdcRange(m_Controls->m_PrototypeWidget1->GetMinAdc(), m_Controls->m_PrototypeWidget1->GetMaxAdc()); model->m_CompartmentId = 1; parameters.m_FiberModelList.push_back(model); parameters.m_Misc.m_SignalModelString += "Prototype"; parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Compartment1.Description", StringProperty::New("Intra-axonal compartment") ); parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Compartment1.Model", StringProperty::New("Prototype") ); break; } } // compartment 2 switch (m_Controls->m_Compartment2Box->currentIndex()) { case 0: break; case 1: { mitk::StickModel* model = new mitk::StickModel(); model->SetGradientList(parameters.m_SignalGen.GetGradientDirections()); model->SetBvalue(parameters.m_SignalGen.m_Bvalue); model->SetDiffusivity(m_Controls->m_StickWidget2->GetD()); model->SetT2(m_Controls->m_StickWidget2->GetT2()); model->m_CompartmentId = 2; parameters.m_FiberModelList.push_back(model); parameters.m_Misc.m_SignalModelString += "Stick"; parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Compartment2.Description", StringProperty::New("Inter-axonal compartment") ); parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Compartment2.Model", StringProperty::New("Stick") ); parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Compartment2.D", DoubleProperty::New(m_Controls->m_StickWidget2->GetD()) ); parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Compartment2.T2", DoubleProperty::New(model->GetT2()) ); break; } case 2: { mitk::TensorModel* model = new mitk::TensorModel(); model->SetGradientList(parameters.m_SignalGen.GetGradientDirections()); model->SetBvalue(parameters.m_SignalGen.m_Bvalue); model->SetDiffusivity1(m_Controls->m_ZeppelinWidget2->GetD1()); model->SetDiffusivity2(m_Controls->m_ZeppelinWidget2->GetD2()); model->SetDiffusivity3(m_Controls->m_ZeppelinWidget2->GetD2()); model->SetT2(m_Controls->m_ZeppelinWidget2->GetT2()); model->m_CompartmentId = 2; parameters.m_FiberModelList.push_back(model); parameters.m_Misc.m_SignalModelString += "Zeppelin"; parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Compartment2.Description", StringProperty::New("Inter-axonal compartment") ); parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Compartment2.Model", StringProperty::New("Zeppelin") ); parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Compartment2.D1", DoubleProperty::New(m_Controls->m_ZeppelinWidget2->GetD1()) ); parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Compartment2.D2", DoubleProperty::New(m_Controls->m_ZeppelinWidget2->GetD2()) ); parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Compartment2.T2", DoubleProperty::New(model->GetT2()) ); break; } case 3: { mitk::TensorModel* model = new mitk::TensorModel(); model->SetGradientList(parameters.m_SignalGen.GetGradientDirections()); model->SetBvalue(parameters.m_SignalGen.m_Bvalue); model->SetDiffusivity1(m_Controls->m_TensorWidget2->GetD1()); model->SetDiffusivity2(m_Controls->m_TensorWidget2->GetD2()); model->SetDiffusivity3(m_Controls->m_TensorWidget2->GetD3()); model->SetT2(m_Controls->m_TensorWidget2->GetT2()); model->m_CompartmentId = 2; parameters.m_FiberModelList.push_back(model); parameters.m_Misc.m_SignalModelString += "Tensor"; parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Compartment2.Description", StringProperty::New("Inter-axonal compartment") ); parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Compartment2.Model", StringProperty::New("Tensor") ); parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Compartment2.D1", DoubleProperty::New(m_Controls->m_TensorWidget2->GetD1()) ); parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Compartment2.D2", DoubleProperty::New(m_Controls->m_TensorWidget2->GetD2()) ); parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Compartment2.D3", DoubleProperty::New(m_Controls->m_TensorWidget2->GetD3()) ); parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Compartment2.T2", DoubleProperty::New(model->GetT2()) ); break; } } // compartment 3 switch (m_Controls->m_Compartment3Box->currentIndex()) { case 0: { mitk::BallModel* model = new mitk::BallModel(); model->SetGradientList(parameters.m_SignalGen.GetGradientDirections()); model->SetBvalue(parameters.m_SignalGen.m_Bvalue); model->SetDiffusivity(m_Controls->m_BallWidget1->GetD()); model->SetT2(m_Controls->m_BallWidget1->GetT2()); model->m_CompartmentId = 3; parameters.m_NonFiberModelList.push_back(model); parameters.m_Misc.m_SignalModelString += "Ball"; parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Compartment3.Description", StringProperty::New("Extra-axonal compartment 1") ); parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Compartment3.Model", StringProperty::New("Ball") ); parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Compartment3.D", DoubleProperty::New(m_Controls->m_BallWidget1->GetD()) ); parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Compartment3.T2", DoubleProperty::New(model->GetT2()) ); break; } case 1: { mitk::AstroStickModel* model = new mitk::AstroStickModel(); model->SetGradientList(parameters.m_SignalGen.GetGradientDirections()); model->SetBvalue(parameters.m_SignalGen.m_Bvalue); model->SetDiffusivity(m_Controls->m_AstrosticksWidget1->GetD()); model->SetT2(m_Controls->m_AstrosticksWidget1->GetT2()); model->SetRandomizeSticks(m_Controls->m_AstrosticksWidget1->GetRandomizeSticks()); model->m_CompartmentId = 3; parameters.m_NonFiberModelList.push_back(model); parameters.m_Misc.m_SignalModelString += "Astrosticks"; parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Compartment3.Description", StringProperty::New("Extra-axonal compartment 1") ); parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Compartment3.Model", StringProperty::New("Astrosticks") ); parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Compartment3.D", DoubleProperty::New(m_Controls->m_AstrosticksWidget1->GetD()) ); parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Compartment3.T2", DoubleProperty::New(model->GetT2()) ); parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Compartment3.RandomSticks", BoolProperty::New(m_Controls->m_AstrosticksWidget1->GetRandomizeSticks()) ); break; } case 2: { mitk::DotModel* model = new mitk::DotModel(); model->SetGradientList(parameters.m_SignalGen.GetGradientDirections()); model->SetT2(m_Controls->m_DotWidget1->GetT2()); model->m_CompartmentId = 3; parameters.m_NonFiberModelList.push_back(model); parameters.m_Misc.m_SignalModelString += "Dot"; parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Compartment3.Description", StringProperty::New("Extra-axonal compartment 1") ); parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Compartment3.Model", StringProperty::New("Dot") ); parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Compartment3.T2", DoubleProperty::New(model->GetT2()) ); break; } case 3: { mitk::RawShModel* model = new mitk::RawShModel(); parameters.m_SignalGen.m_DoSimulateRelaxation = false; model->SetGradientList(parameters.m_SignalGen.GetGradientDirections()); model->SetMaxNumKernels(m_Controls->m_PrototypeWidget3->GetNumberOfSamples()); model->SetFaRange(m_Controls->m_PrototypeWidget3->GetMinFa(), m_Controls->m_PrototypeWidget3->GetMaxFa()); model->SetAdcRange(m_Controls->m_PrototypeWidget3->GetMinAdc(), m_Controls->m_PrototypeWidget3->GetMaxAdc()); model->m_CompartmentId = 3; parameters.m_NonFiberModelList.push_back(model); parameters.m_Misc.m_SignalModelString += "Prototype"; parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Compartment3.Description", StringProperty::New("Extra-axonal compartment 1") ); parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Compartment3.Model", StringProperty::New("Prototype") ); break; } } // compartment 4 ItkDoubleImgType::Pointer comp4VolumeImage = NULL; ItkDoubleImgType::Pointer comp3VolumeImage = NULL; if (m_Controls->m_Compartment4Box->currentIndex()>0) { mitk::DataNode::Pointer volumeNode = m_Controls->m_Comp4VolumeFraction->GetSelectedNode(); if (volumeNode.IsNull()) { QMessageBox::information( NULL, "Information", "No volume fraction image selected! Second extra-axonal compartment has been disabled for this simultation."); MITK_WARN << "No volume fraction image selected! Second extra-axonal compartment has been disabled."; } else { MITK_INFO << "Rescaling volume fraction image..."; comp4VolumeImage = ItkDoubleImgType::New(); mitk::Image* img = dynamic_cast(volumeNode->GetData()); CastToItkImage< ItkDoubleImgType >(img, comp4VolumeImage); double max = itk::NumericTraits::min(); double min = itk::NumericTraits::max(); itk::ImageRegionIterator< ItkDoubleImgType > it(comp4VolumeImage, comp4VolumeImage->GetLargestPossibleRegion()); while(!it.IsAtEnd()) { if (parameters.m_SignalGen.m_MaskImage.IsNotNull() && parameters.m_SignalGen.m_MaskImage->GetPixel(it.GetIndex())<=0) { it.Set(0.0); ++it; continue; } if (it.Get()>max) max = it.Get(); if (it.Get()::Pointer scaler = itk::ShiftScaleImageFilter< ItkDoubleImgType, ItkDoubleImgType >::New(); scaler->SetInput(comp4VolumeImage); scaler->SetShift(-min); scaler->SetScale(1.0/(max-min)); scaler->Update(); comp4VolumeImage = scaler->GetOutput(); // itk::ImageFileWriter< ItkDoubleImgType >::Pointer wr = itk::ImageFileWriter< ItkDoubleImgType >::New(); // wr->SetInput(comp4VolumeImage); // wr->SetFileName("/local/comp4.nrrd"); // wr->Update(); // if (max>1 || min<0) // are volume fractions between 0 and 1? // { // itk::RescaleIntensityImageFilter::Pointer rescaler = itk::RescaleIntensityImageFilter::New(); // rescaler->SetInput(0, comp4VolumeImage); // rescaler->SetOutputMaximum(1); // rescaler->SetOutputMinimum(0); // rescaler->Update(); // comp4VolumeImage = rescaler->GetOutput(); // } itk::InvertIntensityImageFilter< ItkDoubleImgType, ItkDoubleImgType >::Pointer inverter = itk::InvertIntensityImageFilter< ItkDoubleImgType, ItkDoubleImgType >::New(); inverter->SetMaximum(1.0); inverter->SetInput(comp4VolumeImage); inverter->Update(); comp3VolumeImage = inverter->GetOutput(); } } if (comp4VolumeImage.IsNotNull()) { switch (m_Controls->m_Compartment4Box->currentIndex()) { case 0: break; case 1: { mitk::BallModel* model = new mitk::BallModel(); model->SetGradientList(parameters.m_SignalGen.GetGradientDirections()); model->SetBvalue(parameters.m_SignalGen.m_Bvalue); model->SetDiffusivity(m_Controls->m_BallWidget2->GetD()); model->SetT2(m_Controls->m_BallWidget2->GetT2()); model->SetVolumeFractionImage(comp4VolumeImage); model->m_CompartmentId = 4; parameters.m_NonFiberModelList.back()->SetVolumeFractionImage(comp3VolumeImage); parameters.m_NonFiberModelList.push_back(model); parameters.m_Misc.m_SignalModelString += "Ball"; parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Compartment4.Description", StringProperty::New("Extra-axonal compartment 2") ); parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Compartment4.Model", StringProperty::New("Ball") ); parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Compartment4.D", DoubleProperty::New(m_Controls->m_BallWidget2->GetD()) ); parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Compartment4.T2", DoubleProperty::New(model->GetT2()) ); break; } case 2: { mitk::AstroStickModel* model = new mitk::AstroStickModel(); model->SetGradientList(parameters.m_SignalGen.GetGradientDirections()); model->SetBvalue(parameters.m_SignalGen.m_Bvalue); model->SetDiffusivity(m_Controls->m_AstrosticksWidget2->GetD()); model->SetT2(m_Controls->m_AstrosticksWidget2->GetT2()); model->SetRandomizeSticks(m_Controls->m_AstrosticksWidget2->GetRandomizeSticks()); parameters.m_NonFiberModelList.back()->SetVolumeFractionImage(comp3VolumeImage); model->SetVolumeFractionImage(comp4VolumeImage); model->m_CompartmentId = 4; parameters.m_NonFiberModelList.push_back(model); parameters.m_Misc.m_SignalModelString += "Astrosticks"; parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Compartment4.Description", StringProperty::New("Extra-axonal compartment 2") ); parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Compartment4.Model", StringProperty::New("Astrosticks") ); parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Compartment4.D", DoubleProperty::New(m_Controls->m_AstrosticksWidget2->GetD()) ); parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Compartment4.T2", DoubleProperty::New(model->GetT2()) ); parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Compartment4.RandomSticks", BoolProperty::New(m_Controls->m_AstrosticksWidget2->GetRandomizeSticks()) ); break; } case 3: { mitk::DotModel* model = new mitk::DotModel(); model->SetGradientList(parameters.m_SignalGen.GetGradientDirections()); model->SetT2(m_Controls->m_DotWidget2->GetT2()); model->SetVolumeFractionImage(comp4VolumeImage); model->m_CompartmentId = 4; parameters.m_NonFiberModelList.back()->SetVolumeFractionImage(comp3VolumeImage); parameters.m_NonFiberModelList.push_back(model); parameters.m_Misc.m_SignalModelString += "Dot"; parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Compartment4.Description", StringProperty::New("Extra-axonal compartment 2") ); parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Compartment4.Model", StringProperty::New("Dot") ); parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Compartment4.T2", DoubleProperty::New(model->GetT2()) ); break; } case 4: { mitk::RawShModel* model = new mitk::RawShModel(); parameters.m_SignalGen.m_DoSimulateRelaxation = false; model->SetGradientList(parameters.m_SignalGen.GetGradientDirections()); model->SetMaxNumKernels(m_Controls->m_PrototypeWidget4->GetNumberOfSamples()); model->SetFaRange(m_Controls->m_PrototypeWidget4->GetMinFa(), m_Controls->m_PrototypeWidget4->GetMaxFa()); model->SetAdcRange(m_Controls->m_PrototypeWidget4->GetMinAdc(), m_Controls->m_PrototypeWidget4->GetMaxAdc()); model->SetVolumeFractionImage(comp4VolumeImage); model->m_CompartmentId = 4; parameters.m_NonFiberModelList.back()->SetVolumeFractionImage(comp3VolumeImage); parameters.m_NonFiberModelList.push_back(model); parameters.m_Misc.m_SignalModelString += "Prototype"; parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Compartment4.Description", StringProperty::New("Extra-axonal compartment 2") ); parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Compartment4.Model", StringProperty::New("Prototype") ); break; } } } } parameters.m_SignalGen.m_FiberSeparationThreshold = m_Controls->m_SeparationAngleBox->value(); switch (m_Controls->m_DiffusionDirectionBox->currentIndex()) { case 0: parameters.m_SignalGen.m_DiffusionDirectionMode = SignalGenerationParameters::FIBER_TANGENT_DIRECTIONS; break; case 1: parameters.m_SignalGen.m_DiffusionDirectionMode = SignalGenerationParameters::MAIN_FIBER_DIRECTIONS; break; case 2: parameters.m_SignalGen.m_DiffusionDirectionMode = SignalGenerationParameters::RANDOM_DIRECTIONS; parameters.m_SignalGen.m_DoAddMotion = false; parameters.m_SignalGen.m_DoAddGibbsRinging = false; parameters.m_SignalGen.m_KspaceLineOffset = 0.0; parameters.m_SignalGen.m_FrequencyMap = NULL; parameters.m_SignalGen.m_CroppingFactor = 1.0; parameters.m_SignalGen.m_EddyStrength = 0; break; default: parameters.m_SignalGen.m_DiffusionDirectionMode = SignalGenerationParameters::FIBER_TANGENT_DIRECTIONS; } parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.SignalScale", IntProperty::New(parameters.m_SignalGen.m_SignalScale)); parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.FiberRadius", IntProperty::New(parameters.m_SignalGen.m_AxonRadius)); parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Tinhom", DoubleProperty::New(parameters.m_SignalGen.m_tInhom)); parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Tline", DoubleProperty::New(parameters.m_SignalGen.m_tLine)); parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.TE", DoubleProperty::New(parameters.m_SignalGen.m_tEcho)); parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.b-value", DoubleProperty::New(parameters.m_SignalGen.m_Bvalue)); parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.NoPartialVolume", BoolProperty::New(parameters.m_SignalGen.m_DoDisablePartialVolume)); parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Relaxation", BoolProperty::New(parameters.m_SignalGen.m_DoSimulateRelaxation)); parameters.m_Misc.m_ResultNode->AddProperty("binary", BoolProperty::New(false)); parameters.m_Misc.m_CheckRealTimeFibersBox = m_Controls->m_RealTimeFibers->isChecked(); parameters.m_Misc.m_CheckAdvancedFiberOptionsBox = m_Controls->m_AdvancedOptionsBox->isChecked(); parameters.m_Misc.m_CheckIncludeFiducialsBox = m_Controls->m_IncludeFiducials->isChecked(); parameters.m_Misc.m_CheckConstantRadiusBox = m_Controls->m_ConstantRadiusBox->isChecked(); switch(m_Controls->m_DistributionBox->currentIndex()) { case 0: parameters.m_FiberGen.m_Distribution = FiberGenerationParameters::DISTRIBUTE_UNIFORM; break; case 1: parameters.m_FiberGen.m_Distribution = FiberGenerationParameters::DISTRIBUTE_GAUSSIAN; break; default: parameters.m_FiberGen.m_Distribution = FiberGenerationParameters::DISTRIBUTE_UNIFORM; } parameters.m_FiberGen.m_Variance = m_Controls->m_VarianceBox->value(); parameters.m_FiberGen.m_Density = m_Controls->m_FiberDensityBox->value(); parameters.m_FiberGen.m_Sampling = m_Controls->m_FiberSamplingBox->value(); parameters.m_FiberGen.m_Tension = m_Controls->m_TensionBox->value(); parameters.m_FiberGen.m_Continuity = m_Controls->m_ContinuityBox->value(); parameters.m_FiberGen.m_Bias = m_Controls->m_BiasBox->value(); parameters.m_FiberGen.m_Rotation[0] = m_Controls->m_XrotBox->value(); parameters.m_FiberGen.m_Rotation[1] = m_Controls->m_YrotBox->value(); parameters.m_FiberGen.m_Rotation[2] = m_Controls->m_ZrotBox->value(); parameters.m_FiberGen.m_Translation[0] = m_Controls->m_XtransBox->value(); parameters.m_FiberGen.m_Translation[1] = m_Controls->m_YtransBox->value(); parameters.m_FiberGen.m_Translation[2] = m_Controls->m_ZtransBox->value(); parameters.m_FiberGen.m_Scale[0] = m_Controls->m_XscaleBox->value(); parameters.m_FiberGen.m_Scale[1] = m_Controls->m_YscaleBox->value(); parameters.m_FiberGen.m_Scale[2] = m_Controls->m_ZscaleBox->value(); return parameters; } void QmitkFiberfoxView::SaveParameters() { FiberfoxParameters<> ffParamaters = UpdateImageParameters(); QString filename = QFileDialog::getSaveFileName( 0, tr("Save Parameters"), m_ParameterFile, tr("Fiberfox Parameters (*.ffp)") ); bool ok = true; bool first = true; bool dosampling = false; mitk::DiffusionImage::Pointer diffImg; itk::Image< itk::DiffusionTensor3D< double >, 3 >::Pointer tensorImage = NULL; const int shOrder = 2; typedef itk::AnalyticalDiffusionQballReconstructionImageFilter QballFilterType; QballFilterType::CoefficientImageType::Pointer itkFeatureImage = NULL; ItkDoubleImgType::Pointer adcImage = NULL; for (unsigned int i=0; i* model = NULL; if (i* >(ffParamaters.m_FiberModelList.at(i)); else model = dynamic_cast< mitk::RawShModel<>* >(ffParamaters.m_NonFiberModelList.at(i-ffParamaters.m_FiberModelList.size())); if (model!=0 && model->GetNumberOfKernels()<=0) { if (first==true) { if (QMessageBox::question(NULL, "Prototype signal sampling", "Do you want to sample prototype signals from the selected diffusion-weighted imag and save them?",QMessageBox::Yes,QMessageBox::No)==QMessageBox::Yes) dosampling = true; first = false; if (dosampling && m_SelectedDWI.IsNull()) { QMessageBox::information(NULL, "Parameter file not saved", "No diffusion-weighted image selected to sample signal from."); return; } else if (dosampling) { diffImg = dynamic_cast*>(m_SelectedDWI->GetData()); typedef itk::DiffusionTensor3DReconstructionImageFilter< short, short, double > TensorReconstructionImageFilterType; TensorReconstructionImageFilterType::Pointer filter = TensorReconstructionImageFilterType::New(); filter->SetGradientImage( diffImg->GetDirections(), diffImg->GetVectorImage() ); filter->SetBValue(diffImg->GetReferenceBValue()); filter->Update(); tensorImage = filter->GetOutput(); const int NumCoeffs = (shOrder*shOrder + shOrder + 2)/2 + shOrder; QballFilterType::Pointer qballfilter = QballFilterType::New(); qballfilter->SetGradientImage( diffImg->GetDirections(), diffImg->GetVectorImage() ); qballfilter->SetBValue(diffImg->GetReferenceBValue()); qballfilter->SetLambda(0.006); qballfilter->SetNormalizationMethod(QballFilterType::QBAR_RAW_SIGNAL); qballfilter->Update(); itkFeatureImage = qballfilter->GetCoefficientImage(); itk::AdcImageFilter< short, double >::Pointer adcFilter = itk::AdcImageFilter< short, double >::New(); adcFilter->SetInput(diffImg->GetVectorImage()); adcFilter->SetGradientDirections(diffImg->GetDirections()); adcFilter->SetB_value(diffImg->GetReferenceBValue()); adcFilter->Update(); adcImage = adcFilter->GetOutput(); } } if (dosampling && m_SelectedDWI.IsNotNull()) { ok = model->SampleKernels(diffImg, ffParamaters.m_SignalGen.m_MaskImage, tensorImage, itkFeatureImage, adcImage); if (!ok) { QMessageBox::information( NULL, "Parameter file not saved", "No valid prototype signals could be sampled."); return; } } } } ffParamaters.SaveParameters(filename.toStdString()); m_ParameterFile = filename; } void QmitkFiberfoxView::LoadParameters() { QString filename = QFileDialog::getOpenFileName(0, tr("Load Parameters"), QString(itksys::SystemTools::GetFilenamePath(m_ParameterFile.toStdString()).c_str()), tr("Fiberfox Parameters (*.ffp)") ); if(filename.isEmpty() || filename.isNull()) return; m_ParameterFile = filename; FiberfoxParameters<> parameters; parameters.LoadParameters(filename.toStdString()); m_Controls->m_RealTimeFibers->setChecked(parameters.m_Misc.m_CheckRealTimeFibersBox); m_Controls->m_AdvancedOptionsBox->setChecked(parameters.m_Misc.m_CheckAdvancedFiberOptionsBox); m_Controls->m_IncludeFiducials->setChecked(parameters.m_Misc.m_CheckIncludeFiducialsBox); m_Controls->m_ConstantRadiusBox->setChecked(parameters.m_Misc.m_CheckConstantRadiusBox); m_Controls->m_DistributionBox->setCurrentIndex(parameters.m_FiberGen.m_Distribution); m_Controls->m_VarianceBox->setValue(parameters.m_FiberGen.m_Variance); m_Controls->m_FiberDensityBox->setValue(parameters.m_FiberGen.m_Density); m_Controls->m_FiberSamplingBox->setValue(parameters.m_FiberGen.m_Sampling); m_Controls->m_TensionBox->setValue(parameters.m_FiberGen.m_Tension); m_Controls->m_ContinuityBox->setValue(parameters.m_FiberGen.m_Continuity); m_Controls->m_BiasBox->setValue(parameters.m_FiberGen.m_Bias); m_Controls->m_XrotBox->setValue(parameters.m_FiberGen.m_Rotation[0]); m_Controls->m_YrotBox->setValue(parameters.m_FiberGen.m_Rotation[1]); m_Controls->m_ZrotBox->setValue(parameters.m_FiberGen.m_Rotation[2]); m_Controls->m_XtransBox->setValue(parameters.m_FiberGen.m_Translation[0]); m_Controls->m_YtransBox->setValue(parameters.m_FiberGen.m_Translation[1]); m_Controls->m_ZtransBox->setValue(parameters.m_FiberGen.m_Translation[2]); m_Controls->m_XscaleBox->setValue(parameters.m_FiberGen.m_Scale[0]); m_Controls->m_YscaleBox->setValue(parameters.m_FiberGen.m_Scale[1]); m_Controls->m_ZscaleBox->setValue(parameters.m_FiberGen.m_Scale[2]); // image generation parameters m_Controls->m_SizeX->setValue(parameters.m_SignalGen.m_ImageRegion.GetSize(0)); m_Controls->m_SizeY->setValue(parameters.m_SignalGen.m_ImageRegion.GetSize(1)); m_Controls->m_SizeZ->setValue(parameters.m_SignalGen.m_ImageRegion.GetSize(2)); m_Controls->m_SpacingX->setValue(parameters.m_SignalGen.m_ImageSpacing[0]); m_Controls->m_SpacingY->setValue(parameters.m_SignalGen.m_ImageSpacing[1]); m_Controls->m_SpacingZ->setValue(parameters.m_SignalGen.m_ImageSpacing[2]); m_Controls->m_NumGradientsBox->setValue(parameters.m_SignalGen.GetNumWeightedVolumes()); m_Controls->m_BvalueBox->setValue(parameters.m_SignalGen.m_Bvalue); m_Controls->m_SignalScaleBox->setValue(parameters.m_SignalGen.m_SignalScale); m_Controls->m_TEbox->setValue(parameters.m_SignalGen.m_tEcho); m_Controls->m_LineReadoutTimeBox->setValue(parameters.m_SignalGen.m_tLine); m_Controls->m_T2starBox->setValue(parameters.m_SignalGen.m_tInhom); m_Controls->m_FiberRadius->setValue(parameters.m_SignalGen.m_AxonRadius); m_Controls->m_RelaxationBox->setChecked(parameters.m_SignalGen.m_DoSimulateRelaxation); m_Controls->m_EnforcePureFiberVoxelsBox->setChecked(parameters.m_SignalGen.m_DoDisablePartialVolume); if (parameters.m_NoiseModel!=NULL) { m_Controls->m_AddNoise->setChecked(parameters.m_Misc.m_CheckAddNoiseBox); if (dynamic_cast*>(parameters.m_NoiseModel)) m_Controls->m_NoiseDistributionBox->setCurrentIndex(0); else if (dynamic_cast*>(parameters.m_NoiseModel)) m_Controls->m_NoiseDistributionBox->setCurrentIndex(1); m_Controls->m_NoiseLevel->setValue(parameters.m_NoiseModel->GetNoiseVariance()); } else m_Controls->m_AddNoise->setChecked(false); m_Controls->m_VolumeFractionsBox->setChecked(parameters.m_Misc.m_CheckOutputVolumeFractionsBox); m_Controls->m_AdvancedOptionsBox_2->setChecked(parameters.m_Misc.m_CheckAdvancedSignalOptionsBox); m_Controls->m_AddGhosts->setChecked(parameters.m_Misc.m_CheckAddGhostsBox); m_Controls->m_AddAliasing->setChecked(parameters.m_Misc.m_CheckAddAliasingBox); m_Controls->m_AddDistortions->setChecked(parameters.m_Misc.m_CheckAddDistortionsBox); m_Controls->m_AddSpikes->setChecked(parameters.m_Misc.m_CheckAddSpikesBox); m_Controls->m_AddEddy->setChecked(parameters.m_Misc.m_CheckAddEddyCurrentsBox); m_Controls->m_kOffsetBox->setValue(parameters.m_SignalGen.m_KspaceLineOffset); m_Controls->m_WrapBox->setValue(100*(1-parameters.m_SignalGen.m_CroppingFactor)); m_Controls->m_SpikeNumBox->setValue(parameters.m_SignalGen.m_Spikes); m_Controls->m_SpikeScaleBox->setValue(parameters.m_SignalGen.m_SpikeAmplitude); m_Controls->m_EddyGradientStrength->setValue(parameters.m_SignalGen.m_EddyStrength); m_Controls->m_AddGibbsRinging->setChecked(parameters.m_SignalGen.m_DoAddGibbsRinging); m_Controls->m_AddMotion->setChecked(parameters.m_SignalGen.m_DoAddMotion); m_Controls->m_RandomMotion->setChecked(parameters.m_SignalGen.m_DoRandomizeMotion); m_Controls->m_MaxTranslationBoxX->setValue(parameters.m_SignalGen.m_Translation[0]); m_Controls->m_MaxTranslationBoxY->setValue(parameters.m_SignalGen.m_Translation[1]); m_Controls->m_MaxTranslationBoxZ->setValue(parameters.m_SignalGen.m_Translation[2]); m_Controls->m_MaxRotationBoxX->setValue(parameters.m_SignalGen.m_Rotation[0]); m_Controls->m_MaxRotationBoxY->setValue(parameters.m_SignalGen.m_Rotation[1]); m_Controls->m_MaxRotationBoxZ->setValue(parameters.m_SignalGen.m_Rotation[2]); m_Controls->m_DiffusionDirectionBox->setCurrentIndex(parameters.m_SignalGen.m_DiffusionDirectionMode); m_Controls->m_SeparationAngleBox->setValue(parameters.m_SignalGen.m_FiberSeparationThreshold); m_Controls->m_Compartment1Box->setCurrentIndex(0); m_Controls->m_Compartment2Box->setCurrentIndex(0); m_Controls->m_Compartment3Box->setCurrentIndex(0); m_Controls->m_Compartment4Box->setCurrentIndex(0); for (unsigned int i=0; i* signalModel = NULL; if (im_CompartmentId) { case 1: { if (dynamic_cast*>(signalModel)) { mitk::StickModel<>* model = dynamic_cast*>(signalModel); m_Controls->m_StickWidget1->SetT2(model->GetT2()); m_Controls->m_StickWidget1->SetD(model->GetDiffusivity()); m_Controls->m_Compartment1Box->setCurrentIndex(0); break; } else if (dynamic_cast*>(signalModel)) { mitk::TensorModel<>* model = dynamic_cast*>(signalModel); m_Controls->m_TensorWidget1->SetT2(model->GetT2()); m_Controls->m_TensorWidget1->SetD1(model->GetDiffusivity1()); m_Controls->m_TensorWidget1->SetD2(model->GetDiffusivity2()); m_Controls->m_TensorWidget1->SetD3(model->GetDiffusivity3()); m_Controls->m_Compartment1Box->setCurrentIndex(2); break; } else if (dynamic_cast*>(signalModel)) { mitk::RawShModel<>* model = dynamic_cast*>(signalModel); m_Controls->m_PrototypeWidget1->SetNumberOfSamples(model->GetMaxNumKernels()); m_Controls->m_PrototypeWidget1->SetMinFa(model->GetFaRange().first); m_Controls->m_PrototypeWidget1->SetMaxFa(model->GetFaRange().second); m_Controls->m_PrototypeWidget1->SetMinAdc(model->GetAdcRange().first); m_Controls->m_PrototypeWidget1->SetMaxAdc(model->GetAdcRange().second); m_Controls->m_Compartment1Box->setCurrentIndex(3); break; } break; } case 2: { if (dynamic_cast*>(signalModel)) { mitk::StickModel<>* model = dynamic_cast*>(signalModel); m_Controls->m_StickWidget2->SetT2(model->GetT2()); m_Controls->m_StickWidget2->SetD(model->GetDiffusivity()); m_Controls->m_Compartment2Box->setCurrentIndex(1); break; } else if (dynamic_cast*>(signalModel)) { mitk::TensorModel<>* model = dynamic_cast*>(signalModel); m_Controls->m_TensorWidget2->SetT2(model->GetT2()); m_Controls->m_TensorWidget2->SetD1(model->GetDiffusivity1()); m_Controls->m_TensorWidget2->SetD2(model->GetDiffusivity2()); m_Controls->m_TensorWidget2->SetD3(model->GetDiffusivity3()); m_Controls->m_Compartment2Box->setCurrentIndex(3); break; } break; } case 3: { if (dynamic_cast*>(signalModel)) { mitk::BallModel<>* model = dynamic_cast*>(signalModel); m_Controls->m_BallWidget1->SetT2(model->GetT2()); m_Controls->m_BallWidget1->SetD(model->GetDiffusivity()); m_Controls->m_Compartment3Box->setCurrentIndex(0); break; } else if (dynamic_cast*>(signalModel)) { mitk::AstroStickModel<>* model = dynamic_cast*>(signalModel); m_Controls->m_AstrosticksWidget1->SetT2(model->GetT2()); m_Controls->m_AstrosticksWidget1->SetD(model->GetDiffusivity()); m_Controls->m_AstrosticksWidget1->SetRandomizeSticks(model->GetRandomizeSticks()); m_Controls->m_Compartment3Box->setCurrentIndex(1); break; } else if (dynamic_cast*>(signalModel)) { mitk::DotModel<>* model = dynamic_cast*>(signalModel); m_Controls->m_DotWidget1->SetT2(model->GetT2()); m_Controls->m_Compartment3Box->setCurrentIndex(2); break; } else if (dynamic_cast*>(signalModel)) { mitk::RawShModel<>* model = dynamic_cast*>(signalModel); m_Controls->m_PrototypeWidget3->SetNumberOfSamples(model->GetMaxNumKernels()); m_Controls->m_PrototypeWidget3->SetMinFa(model->GetFaRange().first); m_Controls->m_PrototypeWidget3->SetMaxFa(model->GetFaRange().second); m_Controls->m_PrototypeWidget3->SetMinAdc(model->GetAdcRange().first); m_Controls->m_PrototypeWidget3->SetMaxAdc(model->GetAdcRange().second); m_Controls->m_Compartment3Box->setCurrentIndex(3); break; } break; } case 4: { if (dynamic_cast*>(signalModel)) { mitk::BallModel<>* model = dynamic_cast*>(signalModel); m_Controls->m_BallWidget2->SetT2(model->GetT2()); m_Controls->m_BallWidget2->SetD(model->GetDiffusivity()); m_Controls->m_Compartment4Box->setCurrentIndex(1); break; } else if (dynamic_cast*>(signalModel)) { mitk::AstroStickModel<>* model = dynamic_cast*>(signalModel); m_Controls->m_AstrosticksWidget2->SetT2(model->GetT2()); m_Controls->m_AstrosticksWidget2->SetD(model->GetDiffusivity()); m_Controls->m_AstrosticksWidget2->SetRandomizeSticks(model->GetRandomizeSticks()); m_Controls->m_Compartment4Box->setCurrentIndex(2); break; } else if (dynamic_cast*>(signalModel)) { mitk::DotModel<>* model = dynamic_cast*>(signalModel); m_Controls->m_DotWidget2->SetT2(model->GetT2()); m_Controls->m_Compartment4Box->setCurrentIndex(3); break; } else if (dynamic_cast*>(signalModel)) { mitk::RawShModel<>* model = dynamic_cast*>(signalModel); m_Controls->m_PrototypeWidget4->SetNumberOfSamples(model->GetMaxNumKernels()); m_Controls->m_PrototypeWidget4->SetMinFa(model->GetFaRange().first); m_Controls->m_PrototypeWidget4->SetMaxFa(model->GetFaRange().second); m_Controls->m_PrototypeWidget4->SetMinAdc(model->GetAdcRange().first); m_Controls->m_PrototypeWidget4->SetMaxAdc(model->GetAdcRange().second); m_Controls->m_Compartment4Box->setCurrentIndex(4); break; } break; } } } } void QmitkFiberfoxView::ShowAdvancedOptions(int state) { if (state) { m_Controls->m_AdvancedFiberOptionsFrame->setVisible(true); m_Controls->m_AdvancedSignalOptionsFrame->setVisible(true); m_Controls->m_AdvancedOptionsBox->setChecked(true); m_Controls->m_AdvancedOptionsBox_2->setChecked(true); } else { m_Controls->m_AdvancedFiberOptionsFrame->setVisible(false); m_Controls->m_AdvancedSignalOptionsFrame->setVisible(false); m_Controls->m_AdvancedOptionsBox->setChecked(false); m_Controls->m_AdvancedOptionsBox_2->setChecked(false); } } void QmitkFiberfoxView::Comp1ModelFrameVisibility(int index) { m_Controls->m_StickWidget1->setVisible(false); m_Controls->m_ZeppelinWidget1->setVisible(false); m_Controls->m_TensorWidget1->setVisible(false); m_Controls->m_PrototypeWidget1->setVisible(false); switch (index) { case 0: m_Controls->m_StickWidget1->setVisible(true); break; case 1: m_Controls->m_ZeppelinWidget1->setVisible(true); break; case 2: m_Controls->m_TensorWidget1->setVisible(true); break; case 3: m_Controls->m_PrototypeWidget1->setVisible(true); break; } } void QmitkFiberfoxView::Comp2ModelFrameVisibility(int index) { m_Controls->m_StickWidget2->setVisible(false); m_Controls->m_ZeppelinWidget2->setVisible(false); m_Controls->m_TensorWidget2->setVisible(false); switch (index) { case 0: break; case 1: m_Controls->m_StickWidget2->setVisible(true); break; case 2: m_Controls->m_ZeppelinWidget2->setVisible(true); break; case 3: m_Controls->m_TensorWidget2->setVisible(true); break; } } void QmitkFiberfoxView::Comp3ModelFrameVisibility(int index) { m_Controls->m_BallWidget1->setVisible(false); m_Controls->m_AstrosticksWidget1->setVisible(false); m_Controls->m_DotWidget1->setVisible(false); m_Controls->m_PrototypeWidget3->setVisible(false); switch (index) { case 0: m_Controls->m_BallWidget1->setVisible(true); break; case 1: m_Controls->m_AstrosticksWidget1->setVisible(true); break; case 2: m_Controls->m_DotWidget1->setVisible(true); break; case 3: m_Controls->m_PrototypeWidget3->setVisible(true); break; } } void QmitkFiberfoxView::Comp4ModelFrameVisibility(int index) { m_Controls->m_BallWidget2->setVisible(false); m_Controls->m_AstrosticksWidget2->setVisible(false); m_Controls->m_DotWidget2->setVisible(false); m_Controls->m_PrototypeWidget4->setVisible(false); m_Controls->m_Comp4FractionFrame->setVisible(false); switch (index) { case 0: break; case 1: m_Controls->m_BallWidget2->setVisible(true); m_Controls->m_Comp4FractionFrame->setVisible(true); break; case 2: m_Controls->m_AstrosticksWidget2->setVisible(true); m_Controls->m_Comp4FractionFrame->setVisible(true); break; case 3: m_Controls->m_DotWidget2->setVisible(true); m_Controls->m_Comp4FractionFrame->setVisible(true); break; case 4: m_Controls->m_PrototypeWidget4->setVisible(true); m_Controls->m_Comp4FractionFrame->setVisible(true); break; } } void QmitkFiberfoxView::OnConstantRadius(int value) { if (value>0 && m_Controls->m_RealTimeFibers->isChecked()) GenerateFibers(); } void QmitkFiberfoxView::OnAddMotion(int value) { if (value>0) m_Controls->m_MotionArtifactFrame->setVisible(true); else m_Controls->m_MotionArtifactFrame->setVisible(false); } void QmitkFiberfoxView::OnAddAliasing(int value) { if (value>0) m_Controls->m_AliasingFrame->setVisible(true); else m_Controls->m_AliasingFrame->setVisible(false); } void QmitkFiberfoxView::OnAddSpikes(int value) { if (value>0) m_Controls->m_SpikeFrame->setVisible(true); else m_Controls->m_SpikeFrame->setVisible(false); } void QmitkFiberfoxView::OnAddEddy(int value) { if (value>0) m_Controls->m_EddyFrame->setVisible(true); else m_Controls->m_EddyFrame->setVisible(false); } void QmitkFiberfoxView::OnAddDistortions(int value) { if (value>0) m_Controls->m_DistortionsFrame->setVisible(true); else m_Controls->m_DistortionsFrame->setVisible(false); } void QmitkFiberfoxView::OnAddGhosts(int value) { if (value>0) m_Controls->m_GhostFrame->setVisible(true); else m_Controls->m_GhostFrame->setVisible(false); } void QmitkFiberfoxView::OnAddNoise(int value) { if (value>0) m_Controls->m_NoiseFrame->setVisible(true); else m_Controls->m_NoiseFrame->setVisible(false); } void QmitkFiberfoxView::OnDistributionChanged(int value) { if (value==1) m_Controls->m_VarianceBox->setVisible(true); else m_Controls->m_VarianceBox->setVisible(false); if (m_Controls->m_RealTimeFibers->isChecked()) GenerateFibers(); } void QmitkFiberfoxView::OnVarianceChanged(double) { if (m_Controls->m_RealTimeFibers->isChecked()) GenerateFibers(); } void QmitkFiberfoxView::OnFiberDensityChanged(int) { if (m_Controls->m_RealTimeFibers->isChecked()) GenerateFibers(); } void QmitkFiberfoxView::OnFiberSamplingChanged(double) { if (m_Controls->m_RealTimeFibers->isChecked()) GenerateFibers(); } void QmitkFiberfoxView::OnTensionChanged(double) { if (m_Controls->m_RealTimeFibers->isChecked()) GenerateFibers(); } void QmitkFiberfoxView::OnContinuityChanged(double) { if (m_Controls->m_RealTimeFibers->isChecked()) GenerateFibers(); } void QmitkFiberfoxView::OnBiasChanged(double) { if (m_Controls->m_RealTimeFibers->isChecked()) GenerateFibers(); } void QmitkFiberfoxView::AlignOnGrid() { for (unsigned int i=0; i(m_SelectedFiducials.at(i)->GetData()); mitk::Point3D wc0 = pe->GetWorldControlPoint(0); mitk::DataStorage::SetOfObjects::ConstPointer parentFibs = GetDataStorage()->GetSources(m_SelectedFiducials.at(i)); for( mitk::DataStorage::SetOfObjects::const_iterator it = parentFibs->begin(); it != parentFibs->end(); ++it ) { mitk::DataNode::Pointer pFibNode = *it; if ( pFibNode.IsNotNull() && dynamic_cast(pFibNode->GetData()) ) { mitk::DataStorage::SetOfObjects::ConstPointer parentImgs = GetDataStorage()->GetSources(pFibNode); for( mitk::DataStorage::SetOfObjects::const_iterator it2 = parentImgs->begin(); it2 != parentImgs->end(); ++it2 ) { mitk::DataNode::Pointer pImgNode = *it2; if ( pImgNode.IsNotNull() && dynamic_cast(pImgNode->GetData()) ) { mitk::Image::Pointer img = dynamic_cast(pImgNode->GetData()); mitk::BaseGeometry::Pointer geom = img->GetGeometry(); itk::Index<3> idx; geom->WorldToIndex(wc0, idx); mitk::Point3D cIdx; cIdx[0]=idx[0]; cIdx[1]=idx[1]; cIdx[2]=idx[2]; mitk::Point3D world; geom->IndexToWorld(cIdx,world); mitk::Vector3D trans = world - wc0; pe->GetGeometry()->Translate(trans); break; } } break; } } } for(unsigned int i=0; iGetSources(fibNode); for( mitk::DataStorage::SetOfObjects::const_iterator it = sources->begin(); it != sources->end(); ++it ) { mitk::DataNode::Pointer imgNode = *it; if ( imgNode.IsNotNull() && dynamic_cast(imgNode->GetData()) ) { mitk::DataStorage::SetOfObjects::ConstPointer derivations = GetDataStorage()->GetDerivations(fibNode); for( mitk::DataStorage::SetOfObjects::const_iterator it2 = derivations->begin(); it2 != derivations->end(); ++it2 ) { mitk::DataNode::Pointer fiducialNode = *it2; if ( fiducialNode.IsNotNull() && dynamic_cast(fiducialNode->GetData()) ) { mitk::PlanarEllipse::Pointer pe = dynamic_cast(fiducialNode->GetData()); mitk::Point3D wc0 = pe->GetWorldControlPoint(0); mitk::Image::Pointer img = dynamic_cast(imgNode->GetData()); mitk::BaseGeometry::Pointer geom = img->GetGeometry(); itk::Index<3> idx; geom->WorldToIndex(wc0, idx); mitk::Point3D cIdx; cIdx[0]=idx[0]; cIdx[1]=idx[1]; cIdx[2]=idx[2]; mitk::Point3D world; geom->IndexToWorld(cIdx,world); mitk::Vector3D trans = world - wc0; pe->GetGeometry()->Translate(trans); } } break; } } } for(unsigned int i=0; i(m_SelectedImages.at(i)->GetData()); mitk::DataStorage::SetOfObjects::ConstPointer derivations = GetDataStorage()->GetDerivations(m_SelectedImages.at(i)); for( mitk::DataStorage::SetOfObjects::const_iterator it = derivations->begin(); it != derivations->end(); ++it ) { mitk::DataNode::Pointer fibNode = *it; if ( fibNode.IsNotNull() && dynamic_cast(fibNode->GetData()) ) { mitk::DataStorage::SetOfObjects::ConstPointer derivations2 = GetDataStorage()->GetDerivations(fibNode); for( mitk::DataStorage::SetOfObjects::const_iterator it2 = derivations2->begin(); it2 != derivations2->end(); ++it2 ) { mitk::DataNode::Pointer fiducialNode = *it2; if ( fiducialNode.IsNotNull() && dynamic_cast(fiducialNode->GetData()) ) { mitk::PlanarEllipse::Pointer pe = dynamic_cast(fiducialNode->GetData()); mitk::Point3D wc0 = pe->GetWorldControlPoint(0); mitk::BaseGeometry::Pointer geom = img->GetGeometry(); itk::Index<3> idx; geom->WorldToIndex(wc0, idx); mitk::Point3D cIdx; cIdx[0]=idx[0]; cIdx[1]=idx[1]; cIdx[2]=idx[2]; mitk::Point3D world; geom->IndexToWorld(cIdx,world); mitk::Vector3D trans = world - wc0; pe->GetGeometry()->Translate(trans); } } } } } mitk::RenderingManager::GetInstance()->RequestUpdateAll(); if (m_Controls->m_RealTimeFibers->isChecked()) GenerateFibers(); } void QmitkFiberfoxView::OnFlipButton() { if (m_SelectedFiducial.IsNull()) return; std::map::iterator it = m_DataNodeToPlanarFigureData.find(m_SelectedFiducial.GetPointer()); if( it != m_DataNodeToPlanarFigureData.end() ) { QmitkPlanarFigureData& data = it->second; data.m_Flipped += 1; data.m_Flipped %= 2; } if (m_Controls->m_RealTimeFibers->isChecked()) GenerateFibers(); } QmitkFiberfoxView::GradientListType QmitkFiberfoxView::GenerateHalfShell(int NPoints) { NPoints *= 2; GradientListType pointshell; int numB0 = NPoints/20; if (numB0==0) numB0=1; GradientType g; g.Fill(0.0); for (int i=0; i theta; theta.set_size(NPoints); vnl_vector phi; phi.set_size(NPoints); double C = sqrt(4*M_PI); phi(0) = 0.0; phi(NPoints-1) = 0.0; for(int i=0; i0 && i std::vector > QmitkFiberfoxView::MakeGradientList() { std::vector > retval; vnl_matrix_fixed* U = itk::PointShell >::DistributePointShell(); // Add 0 vector for B0 int numB0 = ndirs/10; if (numB0==0) numB0=1; itk::Vector v; v.Fill(0.0); for (int i=0; i v; v[0] = U->get(0,i); v[1] = U->get(1,i); v[2] = U->get(2,i); retval.push_back(v); } return retval; } void QmitkFiberfoxView::OnAddBundle() { if (m_SelectedImage.IsNull()) return; mitk::DataStorage::SetOfObjects::ConstPointer children = GetDataStorage()->GetDerivations(m_SelectedImage); mitk::FiberBundleX::Pointer bundle = mitk::FiberBundleX::New(); mitk::DataNode::Pointer node = mitk::DataNode::New(); node->SetData( bundle ); QString name = QString("Bundle_%1").arg(children->size()); node->SetName(name.toStdString()); m_SelectedBundles.push_back(node); UpdateGui(); GetDataStorage()->Add(node, m_SelectedImage); } void QmitkFiberfoxView::OnDrawROI() { if (m_SelectedBundles.empty()) OnAddBundle(); if (m_SelectedBundles.empty()) return; mitk::DataStorage::SetOfObjects::ConstPointer children = GetDataStorage()->GetDerivations(m_SelectedBundles.at(0)); mitk::PlanarEllipse::Pointer figure = mitk::PlanarEllipse::New(); mitk::DataNode::Pointer node = mitk::DataNode::New(); node->SetData( figure ); node->SetBoolProperty("planarfigure.3drendering", true); QList nodes = this->GetDataManagerSelection(); for( int i=0; iSetSelected(false); m_SelectedFiducial = node; QString name = QString("Fiducial_%1").arg(children->size()); node->SetName(name.toStdString()); node->SetSelected(true); this->DisableCrosshairNavigation(); mitk::PlanarFigureInteractor::Pointer figureInteractor = dynamic_cast(node->GetDataInteractor().GetPointer()); if(figureInteractor.IsNull()) { figureInteractor = mitk::PlanarFigureInteractor::New(); us::Module* planarFigureModule = us::ModuleRegistry::GetModule( "MitkPlanarFigure" ); figureInteractor->LoadStateMachine("PlanarFigureInteraction.xml", planarFigureModule ); figureInteractor->SetEventConfig( "PlanarFigureConfig.xml", planarFigureModule ); figureInteractor->SetDataNode( node ); } UpdateGui(); GetDataStorage()->Add(node, m_SelectedBundles.at(0)); } bool CompareLayer(mitk::DataNode::Pointer i,mitk::DataNode::Pointer j) { int li = -1; i->GetPropertyValue("layer", li); int lj = -1; j->GetPropertyValue("layer", lj); return liGetSources(m_SelectedFiducial); for( mitk::DataStorage::SetOfObjects::const_iterator it = parents->begin(); it != parents->end(); ++it ) if(dynamic_cast((*it)->GetData())) m_SelectedBundles.push_back(*it); if (m_SelectedBundles.empty()) return; } FiberfoxParameters parameters = UpdateImageParameters(); for (unsigned int i=0; iGetDerivations(m_SelectedBundles.at(i)); std::vector< mitk::DataNode::Pointer > childVector; for( mitk::DataStorage::SetOfObjects::const_iterator it = children->begin(); it != children->end(); ++it ) childVector.push_back(*it); sort(childVector.begin(), childVector.end(), CompareLayer); vector< mitk::PlanarEllipse::Pointer > fib; vector< unsigned int > flip; float radius = 1; int count = 0; for( std::vector< mitk::DataNode::Pointer >::const_iterator it = childVector.begin(); it != childVector.end(); ++it ) { mitk::DataNode::Pointer node = *it; if ( node.IsNotNull() && dynamic_cast(node->GetData()) ) { mitk::PlanarEllipse* ellipse = dynamic_cast(node->GetData()); if (m_Controls->m_ConstantRadiusBox->isChecked()) { ellipse->SetTreatAsCircle(true); mitk::Point2D c = ellipse->GetControlPoint(0); mitk::Point2D p = ellipse->GetControlPoint(1); mitk::Vector2D v = p-c; if (count==0) { radius = v.GetVnlVector().magnitude(); ellipse->SetControlPoint(1, p); + ellipse->Modified(); } else { v.Normalize(); v *= radius; ellipse->SetControlPoint(1, c+v); + ellipse->Modified(); } } fib.push_back(ellipse); std::map::iterator it = m_DataNodeToPlanarFigureData.find(node.GetPointer()); if( it != m_DataNodeToPlanarFigureData.end() ) { QmitkPlanarFigureData& data = it->second; flip.push_back(data.m_Flipped); } else flip.push_back(0); } count++; } if (fib.size()>1) { parameters.m_FiberGen.m_Fiducials.push_back(fib); parameters.m_FiberGen.m_FlipList.push_back(flip); } else if (fib.size()>0) m_SelectedBundles.at(i)->SetData( mitk::FiberBundleX::New() ); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } itk::FibersFromPlanarFiguresFilter::Pointer filter = itk::FibersFromPlanarFiguresFilter::New(); filter->SetParameters(parameters.m_FiberGen); filter->Update(); vector< mitk::FiberBundleX::Pointer > fiberBundles = filter->GetFiberBundles(); for (unsigned int i=0; iSetData( fiberBundles.at(i) ); if (fiberBundles.at(i)->GetNumFibers()>50000) m_SelectedBundles.at(i)->SetVisibility(false); } mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } void QmitkFiberfoxView::GenerateImage() { if (m_SelectedBundles.empty() && m_SelectedDWI.IsNull()) { mitk::Image::Pointer image = mitk::ImageGenerator::GenerateGradientImage( m_Controls->m_SizeX->value(), m_Controls->m_SizeY->value(), m_Controls->m_SizeZ->value(), m_Controls->m_SpacingX->value(), m_Controls->m_SpacingY->value(), m_Controls->m_SpacingZ->value()); mitk::DataNode::Pointer node = mitk::DataNode::New(); node->SetData( image ); node->SetName("Dummy"); unsigned int window = m_Controls->m_SizeX->value()*m_Controls->m_SizeY->value()*m_Controls->m_SizeZ->value(); unsigned int level = window/2; mitk::LevelWindow lw; lw.SetLevelWindow(level, window); node->SetProperty( "levelwindow", mitk::LevelWindowProperty::New( lw ) ); GetDataStorage()->Add(node); m_SelectedImage = node; mitk::BaseData::Pointer basedata = node->GetData(); if (basedata.IsNotNull()) { mitk::RenderingManager::GetInstance()->InitializeViews( basedata->GetTimeGeometry(), mitk::RenderingManager::REQUEST_UPDATE_ALL, true ); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } UpdateGui(); } else if (!m_SelectedBundles.empty()) SimulateImageFromFibers(m_SelectedBundles.at(0)); else if (m_SelectedDWI.IsNotNull()) SimulateForExistingDwi(m_SelectedDWI); } void QmitkFiberfoxView::SimulateForExistingDwi(mitk::DataNode* imageNode) { if (!dynamic_cast*>(imageNode->GetData())) return; FiberfoxParameters parameters = UpdateImageParameters(); if (parameters.m_NoiseModel==NULL && parameters.m_SignalGen.m_Spikes==0 && parameters.m_SignalGen.m_FrequencyMap.IsNull() && parameters.m_SignalGen.m_KspaceLineOffset<=0.000001 && !parameters.m_SignalGen.m_DoAddGibbsRinging && !(parameters.m_SignalGen.m_EddyStrength>0) && parameters.m_SignalGen.m_CroppingFactor>0.999) { QMessageBox::information( NULL, "Simulation cancelled", "No valid artifact enabled! Motion artifacts and relaxation effects can NOT be added to an existing diffusion weighted image."); return; } mitk::DiffusionImage::Pointer diffImg = dynamic_cast*>(imageNode->GetData()); m_ArtifactsToDwiFilter = itk::AddArtifactsToDwiImageFilter< short >::New(); m_ArtifactsToDwiFilter->SetInput(diffImg->GetVectorImage()); parameters.m_Misc.m_ParentNode = imageNode; m_ArtifactsToDwiFilter->SetParameters(parameters); m_Worker.m_FilterType = 1; m_Thread.start(QThread::LowestPriority); } void QmitkFiberfoxView::SimulateImageFromFibers(mitk::DataNode* fiberNode) { mitk::FiberBundleX::Pointer fiberBundle = dynamic_cast(fiberNode->GetData()); if (fiberBundle->GetNumFibers()<=0) return; FiberfoxParameters parameters = UpdateImageParameters(); m_TractsToDwiFilter = itk::TractsToDWIImageFilter< short >::New(); parameters.m_Misc.m_ParentNode = fiberNode; if (m_SelectedDWI.IsNotNull()) { bool first = true; bool ok = true; mitk::DiffusionImage::Pointer diffImg = dynamic_cast*>(m_SelectedDWI->GetData()); itk::Image< itk::DiffusionTensor3D< double >, 3 >::Pointer tensorImage = NULL; const int shOrder = 2; typedef itk::AnalyticalDiffusionQballReconstructionImageFilter QballFilterType; QballFilterType::CoefficientImageType::Pointer itkFeatureImage = NULL; ItkDoubleImgType::Pointer adcImage = NULL; for (unsigned int i=0; i* model = NULL; if (i* >(parameters.m_FiberModelList.at(i)); else model = dynamic_cast< mitk::RawShModel<>* >(parameters.m_NonFiberModelList.at(i-parameters.m_FiberModelList.size())); if (model!=0 && model->GetNumberOfKernels()<=0) { if (first==true) { typedef itk::DiffusionTensor3DReconstructionImageFilter< short, short, double > TensorReconstructionImageFilterType; TensorReconstructionImageFilterType::Pointer filter = TensorReconstructionImageFilterType::New(); filter->SetGradientImage( diffImg->GetDirections(), diffImg->GetVectorImage() ); filter->SetBValue(diffImg->GetReferenceBValue()); filter->Update(); tensorImage = filter->GetOutput(); const int NumCoeffs = (shOrder*shOrder + shOrder + 2)/2 + shOrder; QballFilterType::Pointer qballfilter = QballFilterType::New(); qballfilter->SetGradientImage( diffImg->GetDirections(), diffImg->GetVectorImage() ); qballfilter->SetBValue(diffImg->GetReferenceBValue()); qballfilter->SetLambda(0.006); qballfilter->SetNormalizationMethod(QballFilterType::QBAR_RAW_SIGNAL); qballfilter->Update(); itkFeatureImage = qballfilter->GetCoefficientImage(); itk::AdcImageFilter< short, double >::Pointer adcFilter = itk::AdcImageFilter< short, double >::New(); adcFilter->SetInput(diffImg->GetVectorImage()); adcFilter->SetGradientDirections(diffImg->GetDirections()); adcFilter->SetB_value(diffImg->GetReferenceBValue()); adcFilter->Update(); adcImage = adcFilter->GetOutput(); } ok = model->SampleKernels(diffImg, parameters.m_SignalGen.m_MaskImage, tensorImage, itkFeatureImage, adcImage); if (!ok) break; } } if (!ok) { QMessageBox::information( NULL, "Simulation cancelled", "No valid prototype signals could be sampled."); return; } } else if ( m_Controls->m_Compartment1Box->currentIndex()==3 || m_Controls->m_Compartment3Box->currentIndex()==3 || m_Controls->m_Compartment4Box->currentIndex()==4 ) { QMessageBox::information( NULL, "Simulation cancelled", "Prototype signal but no diffusion-weighted image selected to sample signal from."); return; } m_TractsToDwiFilter->SetParameters(parameters); m_TractsToDwiFilter->SetFiberBundle(fiberBundle); m_Worker.m_FilterType = 0; m_Thread.start(QThread::LowestPriority); } void QmitkFiberfoxView::ApplyTransform() { vector< mitk::DataNode::Pointer > selectedBundles; for(unsigned int i=0; iGetDerivations(m_SelectedImages.at(i)); for( mitk::DataStorage::SetOfObjects::const_iterator it = derivations->begin(); it != derivations->end(); ++it ) { mitk::DataNode::Pointer fibNode = *it; if ( fibNode.IsNotNull() && dynamic_cast(fibNode->GetData()) ) selectedBundles.push_back(fibNode); } } if (selectedBundles.empty()) selectedBundles = m_SelectedBundles2; if (!selectedBundles.empty()) { for (std::vector::const_iterator it = selectedBundles.begin(); it!=selectedBundles.end(); ++it) { mitk::FiberBundleX::Pointer fib = dynamic_cast((*it)->GetData()); fib->RotateAroundAxis(m_Controls->m_XrotBox->value(), m_Controls->m_YrotBox->value(), m_Controls->m_ZrotBox->value()); fib->TranslateFibers(m_Controls->m_XtransBox->value(), m_Controls->m_YtransBox->value(), m_Controls->m_ZtransBox->value()); fib->ScaleFibers(m_Controls->m_XscaleBox->value(), m_Controls->m_YscaleBox->value(), m_Controls->m_ZscaleBox->value()); // handle child fiducials if (m_Controls->m_IncludeFiducials->isChecked()) { mitk::DataStorage::SetOfObjects::ConstPointer derivations = GetDataStorage()->GetDerivations(*it); for( mitk::DataStorage::SetOfObjects::const_iterator it2 = derivations->begin(); it2 != derivations->end(); ++it2 ) { mitk::DataNode::Pointer fiducialNode = *it2; if ( fiducialNode.IsNotNull() && dynamic_cast(fiducialNode->GetData()) ) { mitk::PlanarEllipse* pe = dynamic_cast(fiducialNode->GetData()); mitk::BaseGeometry* geom = pe->GetGeometry(); // translate mitk::Vector3D world; world[0] = m_Controls->m_XtransBox->value(); world[1] = m_Controls->m_YtransBox->value(); world[2] = m_Controls->m_ZtransBox->value(); geom->Translate(world); // calculate rotation matrix double x = m_Controls->m_XrotBox->value()*M_PI/180; double y = m_Controls->m_YrotBox->value()*M_PI/180; double z = m_Controls->m_ZrotBox->value()*M_PI/180; itk::Matrix< double, 3, 3 > rotX; rotX.SetIdentity(); rotX[1][1] = cos(x); rotX[2][2] = rotX[1][1]; rotX[1][2] = -sin(x); rotX[2][1] = -rotX[1][2]; itk::Matrix< double, 3, 3 > rotY; rotY.SetIdentity(); rotY[0][0] = cos(y); rotY[2][2] = rotY[0][0]; rotY[0][2] = sin(y); rotY[2][0] = -rotY[0][2]; itk::Matrix< double, 3, 3 > rotZ; rotZ.SetIdentity(); rotZ[0][0] = cos(z); rotZ[1][1] = rotZ[0][0]; rotZ[0][1] = -sin(z); rotZ[1][0] = -rotZ[0][1]; itk::Matrix< double, 3, 3 > rot = rotZ*rotY*rotX; // transform control point coordinate into geometry translation geom->SetOrigin(pe->GetWorldControlPoint(0)); mitk::Point2D cp; cp.Fill(0.0); pe->SetControlPoint(0, cp); // rotate fiducial geom->GetIndexToWorldTransform()->SetMatrix(rot*geom->GetIndexToWorldTransform()->GetMatrix()); // implicit translation mitk::Vector3D trans; trans[0] = geom->GetOrigin()[0]-fib->GetGeometry()->GetCenter()[0]; trans[1] = geom->GetOrigin()[1]-fib->GetGeometry()->GetCenter()[1]; trans[2] = geom->GetOrigin()[2]-fib->GetGeometry()->GetCenter()[2]; mitk::Vector3D newWc = rot*trans; newWc = newWc-trans; geom->Translate(newWc); pe->Modified(); } } } } } else { for (unsigned int i=0; i(m_SelectedFiducials.at(i)->GetData()); mitk::BaseGeometry* geom = pe->GetGeometry(); // translate mitk::Vector3D world; world[0] = m_Controls->m_XtransBox->value(); world[1] = m_Controls->m_YtransBox->value(); world[2] = m_Controls->m_ZtransBox->value(); geom->Translate(world); // calculate rotation matrix double x = m_Controls->m_XrotBox->value()*M_PI/180; double y = m_Controls->m_YrotBox->value()*M_PI/180; double z = m_Controls->m_ZrotBox->value()*M_PI/180; itk::Matrix< double, 3, 3 > rotX; rotX.SetIdentity(); rotX[1][1] = cos(x); rotX[2][2] = rotX[1][1]; rotX[1][2] = -sin(x); rotX[2][1] = -rotX[1][2]; itk::Matrix< double, 3, 3 > rotY; rotY.SetIdentity(); rotY[0][0] = cos(y); rotY[2][2] = rotY[0][0]; rotY[0][2] = sin(y); rotY[2][0] = -rotY[0][2]; itk::Matrix< double, 3, 3 > rotZ; rotZ.SetIdentity(); rotZ[0][0] = cos(z); rotZ[1][1] = rotZ[0][0]; rotZ[0][1] = -sin(z); rotZ[1][0] = -rotZ[0][1]; itk::Matrix< double, 3, 3 > rot = rotZ*rotY*rotX; // transform control point coordinate into geometry translation geom->SetOrigin(pe->GetWorldControlPoint(0)); mitk::Point2D cp; cp.Fill(0.0); pe->SetControlPoint(0, cp); // rotate fiducial geom->GetIndexToWorldTransform()->SetMatrix(rot*geom->GetIndexToWorldTransform()->GetMatrix()); pe->Modified(); } if (m_Controls->m_RealTimeFibers->isChecked()) GenerateFibers(); } mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } void QmitkFiberfoxView::CopyBundles() { if ( m_SelectedBundles.size()<1 ){ QMessageBox::information( NULL, "Warning", "Select at least one fiber bundle!"); MITK_WARN("QmitkFiberProcessingView") << "Select at least one fiber bundle!"; return; } for (std::vector::const_iterator it = m_SelectedBundles.begin(); it!=m_SelectedBundles.end(); ++it) { // find parent image mitk::DataNode::Pointer parentNode; mitk::DataStorage::SetOfObjects::ConstPointer parentImgs = GetDataStorage()->GetSources(*it); for( mitk::DataStorage::SetOfObjects::const_iterator it2 = parentImgs->begin(); it2 != parentImgs->end(); ++it2 ) { mitk::DataNode::Pointer pImgNode = *it2; if ( pImgNode.IsNotNull() && dynamic_cast(pImgNode->GetData()) ) { parentNode = pImgNode; break; } } mitk::FiberBundleX::Pointer fib = dynamic_cast((*it)->GetData()); mitk::FiberBundleX::Pointer newBundle = fib->GetDeepCopy(); QString name((*it)->GetName().c_str()); name += "_copy"; mitk::DataNode::Pointer fbNode = mitk::DataNode::New(); fbNode->SetData(newBundle); fbNode->SetName(name.toStdString()); fbNode->SetVisibility(true); if (parentNode.IsNotNull()) GetDataStorage()->Add(fbNode, parentNode); else GetDataStorage()->Add(fbNode); // copy child fiducials if (m_Controls->m_IncludeFiducials->isChecked()) { mitk::DataStorage::SetOfObjects::ConstPointer derivations = GetDataStorage()->GetDerivations(*it); for( mitk::DataStorage::SetOfObjects::const_iterator it2 = derivations->begin(); it2 != derivations->end(); ++it2 ) { mitk::DataNode::Pointer fiducialNode = *it2; if ( fiducialNode.IsNotNull() && dynamic_cast(fiducialNode->GetData()) ) { mitk::PlanarEllipse::Pointer pe = mitk::PlanarEllipse::New(); pe->DeepCopy(dynamic_cast(fiducialNode->GetData())); mitk::DataNode::Pointer newNode = mitk::DataNode::New(); newNode->SetData(pe); newNode->SetName(fiducialNode->GetName()); newNode->SetBoolProperty("planarfigure.3drendering", true); GetDataStorage()->Add(newNode, fbNode); } } } } mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } void QmitkFiberfoxView::JoinBundles() { if ( m_SelectedBundles.size()<2 ){ QMessageBox::information( NULL, "Warning", "Select at least two fiber bundles!"); MITK_WARN("QmitkFiberProcessingView") << "Select at least two fiber bundles!"; return; } std::vector::const_iterator it = m_SelectedBundles.begin(); mitk::FiberBundleX::Pointer newBundle = dynamic_cast((*it)->GetData()); QString name(""); name += QString((*it)->GetName().c_str()); ++it; for (; it!=m_SelectedBundles.end(); ++it) { newBundle = newBundle->AddBundle(dynamic_cast((*it)->GetData())); name += "+"+QString((*it)->GetName().c_str()); } mitk::DataNode::Pointer fbNode = mitk::DataNode::New(); fbNode->SetData(newBundle); fbNode->SetName(name.toStdString()); fbNode->SetVisibility(true); GetDataStorage()->Add(fbNode); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } void QmitkFiberfoxView::UpdateGui() { m_Controls->m_FiberBundleLabel->setText("mandatory"); m_Controls->m_GeometryFrame->setEnabled(true); m_Controls->m_GeometryMessage->setVisible(false); m_Controls->m_DiffusionPropsMessage->setVisible(false); m_Controls->m_FiberGenMessage->setVisible(true); m_Controls->m_TransformBundlesButton->setEnabled(false); m_Controls->m_CopyBundlesButton->setEnabled(false); m_Controls->m_GenerateFibersButton->setEnabled(false); m_Controls->m_FlipButton->setEnabled(false); m_Controls->m_CircleButton->setEnabled(false); m_Controls->m_BvalueBox->setEnabled(true); m_Controls->m_NumGradientsBox->setEnabled(true); m_Controls->m_JoinBundlesButton->setEnabled(false); m_Controls->m_AlignOnGrid->setEnabled(false); if (m_SelectedFiducial.IsNotNull()) { m_Controls->m_TransformBundlesButton->setEnabled(true); m_Controls->m_FlipButton->setEnabled(true); m_Controls->m_AlignOnGrid->setEnabled(true); } if (m_SelectedImage.IsNotNull() || !m_SelectedBundles.empty()) { m_Controls->m_TransformBundlesButton->setEnabled(true); m_Controls->m_CircleButton->setEnabled(true); m_Controls->m_FiberGenMessage->setVisible(false); m_Controls->m_AlignOnGrid->setEnabled(true); } if (m_MaskImageNode.IsNotNull() || m_SelectedImage.IsNotNull()) { m_Controls->m_GeometryMessage->setVisible(true); m_Controls->m_GeometryFrame->setEnabled(false); } if (m_SelectedDWI.IsNotNull()) { m_Controls->m_DiffusionPropsMessage->setVisible(true); m_Controls->m_BvalueBox->setEnabled(false); m_Controls->m_NumGradientsBox->setEnabled(false); m_Controls->m_GeometryMessage->setVisible(true); m_Controls->m_GeometryFrame->setEnabled(false); } if (!m_SelectedBundles.empty()) { m_Controls->m_CopyBundlesButton->setEnabled(true); m_Controls->m_GenerateFibersButton->setEnabled(true); m_Controls->m_FiberBundleLabel->setText(m_SelectedBundles.at(0)->GetName().c_str()); if (m_SelectedBundles.size()>1) m_Controls->m_JoinBundlesButton->setEnabled(true); } } void QmitkFiberfoxView::OnSelectionChanged( berry::IWorkbenchPart::Pointer, const QList& nodes ) { m_SelectedBundles2.clear(); m_SelectedImages.clear(); m_SelectedFiducials.clear(); m_SelectedFiducial = NULL; m_SelectedBundles.clear(); m_SelectedImage = NULL; m_SelectedDWI = NULL; m_MaskImageNode = NULL; m_Controls->m_TissueMaskLabel->setText("optional"); // iterate all selected objects, adjust warning visibility for( int i=0; i*>(node->GetData()) ) { m_SelectedDWI = node; m_SelectedImage = node; m_SelectedImages.push_back(node); } else if( node.IsNotNull() && dynamic_cast(node->GetData()) ) { m_SelectedImages.push_back(node); m_SelectedImage = node; bool isbinary = false; node->GetPropertyValue("binary", isbinary); if (isbinary) { m_MaskImageNode = node; m_Controls->m_TissueMaskLabel->setText(m_MaskImageNode->GetName().c_str()); } } else if ( node.IsNotNull() && dynamic_cast(node->GetData()) ) { m_SelectedBundles2.push_back(node); if (m_Controls->m_RealTimeFibers->isChecked()) { m_SelectedBundles.push_back(node); mitk::FiberBundleX::Pointer newFib = dynamic_cast(node->GetData()); if (newFib->GetNumFibers()!=m_Controls->m_FiberDensityBox->value()) GenerateFibers(); } else m_SelectedBundles.push_back(node); } else if ( node.IsNotNull() && dynamic_cast(node->GetData()) ) { m_SelectedFiducials.push_back(node); m_SelectedFiducial = node; m_SelectedBundles.clear(); mitk::DataStorage::SetOfObjects::ConstPointer parents = GetDataStorage()->GetSources(node); for( mitk::DataStorage::SetOfObjects::const_iterator it = parents->begin(); it != parents->end(); ++it ) { mitk::DataNode::Pointer pNode = *it; if ( pNode.IsNotNull() && dynamic_cast(pNode->GetData()) ) m_SelectedBundles.push_back(pNode); } } } UpdateGui(); } void QmitkFiberfoxView::EnableCrosshairNavigation() { MITK_DEBUG << "EnableCrosshairNavigation"; // enable the crosshair navigation if (mitk::ILinkedRenderWindowPart* linkedRenderWindow = dynamic_cast(this->GetRenderWindowPart())) { MITK_DEBUG << "enabling linked navigation"; linkedRenderWindow->EnableLinkedNavigation(true); // linkedRenderWindow->EnableSlicingPlanes(true); } if (m_Controls->m_RealTimeFibers->isChecked()) GenerateFibers(); } void QmitkFiberfoxView::DisableCrosshairNavigation() { MITK_DEBUG << "DisableCrosshairNavigation"; // disable the crosshair navigation during the drawing if (mitk::ILinkedRenderWindowPart* linkedRenderWindow = dynamic_cast(this->GetRenderWindowPart())) { MITK_DEBUG << "disabling linked navigation"; linkedRenderWindow->EnableLinkedNavigation(false); // linkedRenderWindow->EnableSlicingPlanes(false); } } void QmitkFiberfoxView::NodeRemoved(const mitk::DataNode* node) { mitk::DataNode* nonConstNode = const_cast(node); std::map::iterator it = m_DataNodeToPlanarFigureData.find(nonConstNode); if (dynamic_cast(node->GetData())) { m_SelectedBundles.clear(); m_SelectedBundles2.clear(); } else if (dynamic_cast(node->GetData())) m_SelectedImages.clear(); if( it != m_DataNodeToPlanarFigureData.end() ) { QmitkPlanarFigureData& data = it->second; // remove observers data.m_Figure->RemoveObserver( data.m_EndPlacementObserverTag ); data.m_Figure->RemoveObserver( data.m_SelectObserverTag ); data.m_Figure->RemoveObserver( data.m_StartInteractionObserverTag ); data.m_Figure->RemoveObserver( data.m_EndInteractionObserverTag ); m_DataNodeToPlanarFigureData.erase( it ); } } void QmitkFiberfoxView::NodeAdded( const mitk::DataNode* node ) { // add observer for selection in renderwindow mitk::PlanarFigure* figure = dynamic_cast(node->GetData()); bool isPositionMarker (false); node->GetBoolProperty("isContourMarker", isPositionMarker); if( figure && !isPositionMarker ) { MITK_DEBUG << "figure added. will add interactor if needed."; mitk::PlanarFigureInteractor::Pointer figureInteractor = dynamic_cast(node->GetDataInteractor().GetPointer()); mitk::DataNode* nonConstNode = const_cast( node ); if(figureInteractor.IsNull()) { figureInteractor = mitk::PlanarFigureInteractor::New(); us::Module* planarFigureModule = us::ModuleRegistry::GetModule( "MitkPlanarFigure" ); figureInteractor->LoadStateMachine("PlanarFigureInteraction.xml", planarFigureModule ); figureInteractor->SetEventConfig( "PlanarFigureConfig.xml", planarFigureModule ); figureInteractor->SetDataNode( nonConstNode ); } MITK_DEBUG << "will now add observers for planarfigure"; QmitkPlanarFigureData data; data.m_Figure = figure; // // add observer for event when figure has been placed typedef itk::SimpleMemberCommand< QmitkFiberfoxView > SimpleCommandType; // SimpleCommandType::Pointer initializationCommand = SimpleCommandType::New(); // initializationCommand->SetCallbackFunction( this, &QmitkFiberfoxView::PlanarFigureInitialized ); // data.m_EndPlacementObserverTag = figure->AddObserver( mitk::EndPlacementPlanarFigureEvent(), initializationCommand ); // add observer for event when figure is picked (selected) typedef itk::MemberCommand< QmitkFiberfoxView > MemberCommandType; MemberCommandType::Pointer selectCommand = MemberCommandType::New(); selectCommand->SetCallbackFunction( this, &QmitkFiberfoxView::PlanarFigureSelected ); data.m_SelectObserverTag = figure->AddObserver( mitk::SelectPlanarFigureEvent(), selectCommand ); // add observer for event when interaction with figure starts SimpleCommandType::Pointer startInteractionCommand = SimpleCommandType::New(); startInteractionCommand->SetCallbackFunction( this, &QmitkFiberfoxView::DisableCrosshairNavigation); data.m_StartInteractionObserverTag = figure->AddObserver( mitk::StartInteractionPlanarFigureEvent(), startInteractionCommand ); // add observer for event when interaction with figure starts SimpleCommandType::Pointer endInteractionCommand = SimpleCommandType::New(); endInteractionCommand->SetCallbackFunction( this, &QmitkFiberfoxView::EnableCrosshairNavigation); data.m_EndInteractionObserverTag = figure->AddObserver( mitk::EndInteractionPlanarFigureEvent(), endInteractionCommand ); m_DataNodeToPlanarFigureData[nonConstNode] = data; } } void QmitkFiberfoxView::PlanarFigureSelected( itk::Object* object, const itk::EventObject& ) { mitk::TNodePredicateDataType::Pointer isPf = mitk::TNodePredicateDataType::New(); mitk::DataStorage::SetOfObjects::ConstPointer allPfs = this->GetDataStorage()->GetSubset( isPf ); for ( mitk::DataStorage::SetOfObjects::const_iterator it = allPfs->begin(); it!=allPfs->end(); ++it) { mitk::DataNode* node = *it; if( node->GetData() == object ) { node->SetSelected(true); m_SelectedFiducial = node; } else node->SetSelected(false); } UpdateGui(); this->RequestRenderWindowUpdate(); } void QmitkFiberfoxView::SetFocus() { m_Controls->m_CircleButton->setFocus(); } void QmitkFiberfoxView::SetOutputPath() { // SELECT FOLDER DIALOG string outputPath = QFileDialog::getExistingDirectory(NULL, "Save images to...", QString(outputPath.c_str())).toStdString(); if (outputPath.empty()) m_Controls->m_SavePathEdit->setText("-"); else { outputPath += "/"; m_Controls->m_SavePathEdit->setText(QString(outputPath.c_str())); } } diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkIVIMView.cpp b/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkIVIMView.cpp index e5ca91a8f4..d7a48764db 100644 --- a/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkIVIMView.cpp +++ b/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkIVIMView.cpp @@ -1,826 +1,826 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ // Blueberry #include #include // Qmitk #include "QmitkIVIMView.h" #include "QmitkStdMultiWidget.h" // qt #include "qmessagebox.h" #include "qclipboard.h" // mitk #include "mitkDiffusionImage.h" #include "mitkImageCast.h" // itk #include "itkScalarImageToHistogramGenerator.h" #include "itkRegionOfInterestImageFilter.h" #include "itkImageRegionConstIteratorWithIndex.h" // itk/mitk #include "itkDiffusionIntravoxelIncoherentMotionReconstructionImageFilter.h" #include "itkRegularizedIVIMReconstructionFilter.h" #include "mitkImageCast.h" const std::string QmitkIVIMView::VIEW_ID = "org.mitk.views.ivim"; QmitkIVIMView::QmitkIVIMView() : QmitkFunctionality() , m_Controls( 0 ) , m_MultiWidget( NULL ) , m_SliceObserverTag1(0), m_SliceObserverTag2(0), m_SliceObserverTag3(0) , m_DiffusionImageNode(NULL) , m_MaskImageNode(NULL) , m_Active(false) { } QmitkIVIMView::~QmitkIVIMView() { // QmitkStdMultiWidget* MultiWidget = this->GetActiveStdMultiWidget(false); // if(MultiWidget) // { // //unregister observers when view is destroyed // if( MultiWidget->mitkWidget1 != NULL && m_SliceObserverTag1 != 0) // { // mitk::SliceNavigationController* slicer = MultiWidget->mitkWidget1->GetSliceNavigationController(); // slicer->RemoveObserver( m_SliceObserverTag1 ); // } // if( MultiWidget->mitkWidget2 != NULL && m_SliceObserverTag2 != 0) // { // mitk::SliceNavigationController* slicer = MultiWidget->mitkWidget2->GetSliceNavigationController(); // slicer->RemoveObserver( m_SliceObserverTag2 ); // } // if( MultiWidget->mitkWidget3!= NULL && m_SliceObserverTag3 != 0) // { // mitk::SliceNavigationController* slicer = MultiWidget->mitkWidget3->GetSliceNavigationController(); // slicer->RemoveObserver( m_SliceObserverTag3 ); // } // } } void QmitkIVIMView::CreateQtPartControl( QWidget *parent ) { // build up qt view, unless already done if ( !m_Controls ) { // create GUI widgets from the Qt Designer's .ui file m_Controls = new Ui::QmitkIVIMViewControls; m_Controls->setupUi( parent ); connect( m_Controls->m_ButtonStart, SIGNAL(clicked()), this, SLOT(FittIVIMStart()) ); connect( m_Controls->m_ButtonAutoThres, SIGNAL(clicked()), this, SLOT(AutoThreshold()) ); connect( m_Controls->m_MethodCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(MethodCombo(int)) ); connect( m_Controls->m_DStarSlider, SIGNAL(valueChanged(int)), this, SLOT(DStarSlider(int)) ); connect( m_Controls->m_BThreshSlider, SIGNAL(valueChanged(int)), this, SLOT(BThreshSlider(int)) ); connect( m_Controls->m_S0ThreshSlider, SIGNAL(valueChanged(int)), this, SLOT(S0ThreshSlider(int)) ); connect( m_Controls->m_NumItSlider, SIGNAL(valueChanged(int)), this, SLOT(NumItsSlider(int)) ); connect( m_Controls->m_LambdaSlider, SIGNAL(valueChanged(int)), this, SLOT(LambdaSlider(int)) ); connect( m_Controls->m_CheckDStar, SIGNAL(clicked()), this, SLOT(Checkbox()) ); connect( m_Controls->m_CheckD, SIGNAL(clicked()), this, SLOT(Checkbox()) ); connect( m_Controls->m_Checkf, SIGNAL(clicked()), this, SLOT(Checkbox()) ); connect( m_Controls->m_ChooseMethod, SIGNAL(clicked()), this, SLOT(ChooseMethod()) ); connect( m_Controls->m_CurveClipboard, SIGNAL(clicked()), this, SLOT(ClipboardCurveButtonClicked()) ); connect( m_Controls->m_ValuesClipboard, SIGNAL(clicked()), this, SLOT(ClipboardStatisticsButtonClicked()) ); } QString dstar = QString::number(m_Controls->m_DStarSlider->value()/1000.0); m_Controls->m_DStarLabel->setText(dstar); QString bthresh = QString::number(m_Controls->m_BThreshSlider->value()*5.0); m_Controls->m_BThreshLabel->setText(bthresh); QString s0thresh = QString::number(m_Controls->m_S0ThreshSlider->value()*0.5); m_Controls->m_S0ThreshLabel->setText(s0thresh); QString numits = QString::number(m_Controls->m_NumItSlider->value()); m_Controls->m_NumItsLabel->setText(numits); QString lambda = QString::number(m_Controls->m_LambdaSlider->value()*.00001); m_Controls->m_LambdaLabel->setText(lambda); m_Controls->m_MethodCombo->setVisible(m_Controls->m_ChooseMethod->isChecked()); m_Controls->m_Warning->setVisible(false); MethodCombo(m_Controls->m_MethodCombo->currentIndex()); } void QmitkIVIMView::Checkbox() { itk::StartEvent dummy; OnSliceChanged(dummy); } void QmitkIVIMView::MethodCombo(int val) { switch(val) { case 0: m_Controls->m_DstarFrame->setVisible(false); m_Controls->m_NeglSiFrame->setVisible(true); m_Controls->m_NeglBframe->setVisible(false); m_Controls->m_IterationsFrame->setVisible(false); m_Controls->m_LambdaFrame->setVisible(false); break; case 1: m_Controls->m_DstarFrame->setVisible(true); m_Controls->m_NeglSiFrame->setVisible(true); m_Controls->m_NeglBframe->setVisible(false); m_Controls->m_IterationsFrame->setVisible(false); m_Controls->m_LambdaFrame->setVisible(false); break; case 2: m_Controls->m_DstarFrame->setVisible(false); m_Controls->m_NeglSiFrame->setVisible(true); m_Controls->m_NeglBframe->setVisible(true); m_Controls->m_IterationsFrame->setVisible(false); m_Controls->m_LambdaFrame->setVisible(false); break; case 3: m_Controls->m_DstarFrame->setVisible(false); m_Controls->m_NeglSiFrame->setVisible(true); m_Controls->m_NeglBframe->setVisible(true); m_Controls->m_IterationsFrame->setVisible(false); m_Controls->m_LambdaFrame->setVisible(false); break; case 4: m_Controls->m_DstarFrame->setVisible(false); m_Controls->m_NeglSiFrame->setVisible(false); m_Controls->m_NeglBframe->setVisible(false); m_Controls->m_IterationsFrame->setVisible(false); m_Controls->m_LambdaFrame->setVisible(false); break; } itk::StartEvent dummy; OnSliceChanged(dummy); } void QmitkIVIMView::DStarSlider (int val) { QString sval = QString::number(val/1000.0); m_Controls->m_DStarLabel->setText(sval); itk::StartEvent dummy; OnSliceChanged(dummy); } void QmitkIVIMView::BThreshSlider (int val) { QString sval = QString::number(val*5.0); m_Controls->m_BThreshLabel->setText(sval); itk::StartEvent dummy; OnSliceChanged(dummy); } void QmitkIVIMView::S0ThreshSlider (int val) { QString sval = QString::number(val*0.5); m_Controls->m_S0ThreshLabel->setText(sval); itk::StartEvent dummy; OnSliceChanged(dummy); } void QmitkIVIMView::NumItsSlider (int val) { QString sval = QString::number(val); m_Controls->m_NumItsLabel->setText(sval); itk::StartEvent dummy; OnSliceChanged(dummy); } void QmitkIVIMView::LambdaSlider (int val) { QString sval = QString::number(val*.00001); m_Controls->m_LambdaLabel->setText(sval); itk::StartEvent dummy; OnSliceChanged(dummy); } void QmitkIVIMView::StdMultiWidgetAvailable (QmitkStdMultiWidget &stdMultiWidget) { m_MultiWidget = &stdMultiWidget; { mitk::SliceNavigationController* slicer = m_MultiWidget->mitkWidget1->GetSliceNavigationController(); itk::ReceptorMemberCommand::Pointer command = itk::ReceptorMemberCommand::New(); command->SetCallbackFunction( this, &QmitkIVIMView::OnSliceChanged ); m_SliceObserverTag1 = slicer->AddObserver( mitk::SliceNavigationController::GeometrySliceEvent(NULL, 0), command ); } { mitk::SliceNavigationController* slicer = m_MultiWidget->mitkWidget2->GetSliceNavigationController(); itk::ReceptorMemberCommand::Pointer command = itk::ReceptorMemberCommand::New(); command->SetCallbackFunction( this, &QmitkIVIMView::OnSliceChanged ); m_SliceObserverTag2 = slicer->AddObserver( mitk::SliceNavigationController::GeometrySliceEvent(NULL, 0), command ); } { mitk::SliceNavigationController* slicer = m_MultiWidget->mitkWidget3->GetSliceNavigationController(); itk::ReceptorMemberCommand::Pointer command = itk::ReceptorMemberCommand::New(); command->SetCallbackFunction( this, &QmitkIVIMView::OnSliceChanged ); m_SliceObserverTag3 = slicer->AddObserver( mitk::SliceNavigationController::GeometrySliceEvent(NULL, 0), command ); } } void QmitkIVIMView::StdMultiWidgetNotAvailable() { { mitk::SliceNavigationController* slicer = m_MultiWidget->mitkWidget1->GetSliceNavigationController(); slicer->RemoveObserver( m_SliceObserverTag1 ); } { mitk::SliceNavigationController* slicer = m_MultiWidget->mitkWidget2->GetSliceNavigationController(); slicer->RemoveObserver( m_SliceObserverTag2 ); } { mitk::SliceNavigationController* slicer = m_MultiWidget->mitkWidget3->GetSliceNavigationController(); slicer->RemoveObserver( m_SliceObserverTag3 ); } m_MultiWidget = NULL; } void QmitkIVIMView::OnSelectionChanged( std::vector nodes ) { bool foundOneDiffusionImage = false; m_Controls->m_InputData->setTitle("Please Select Input Data"); m_Controls->m_DiffusionImageLabel->setText("mandatory"); m_Controls->m_MaskImageLabel->setText("optional"); m_MaskImageNode = NULL; m_DiffusionImageNode = NULL; // iterate all selected objects, adjust warning visibility for( std::vector::iterator it = nodes.begin(); it != nodes.end(); ++it ) { mitk::DataNode::Pointer node = *it; if( node.IsNotNull() && dynamic_cast(node->GetData()) ) { if( dynamic_cast*>(node->GetData()) ) { m_DiffusionImageNode = node; foundOneDiffusionImage = true; m_Controls->m_DiffusionImageLabel->setText(node->GetName().c_str()); } else { bool isBinary = false; node->GetPropertyValue("binary", isBinary); if (isBinary) { m_MaskImageNode = node; m_Controls->m_MaskImageLabel->setText(node->GetName().c_str()); } } } } if (m_DiffusionImageNode.IsNotNull()) { m_Controls->m_VisualizeResultsWidget->setVisible(true); m_Controls->m_InputData->setTitle("Input Data"); } else { m_Controls->m_VisualizeResultsWidget->setVisible(false); m_Controls->m_DiffusionImageLabel->setText("mandatory"); } m_Controls->m_ButtonStart->setEnabled( foundOneDiffusionImage ); m_Controls->m_ButtonAutoThres->setEnabled( foundOneDiffusionImage ); m_Controls->m_ControlsFrame->setEnabled( foundOneDiffusionImage ); m_Controls->m_BottomControlsFrame->setEnabled( foundOneDiffusionImage ); itk::StartEvent dummy; OnSliceChanged(dummy); } void QmitkIVIMView::AutoThreshold() { std::vector nodes = this->GetDataManagerSelection(); if (nodes.empty()) return; if (!nodes.front()) { // Nothing selected. Inform the user and return QMessageBox::information( NULL, "Template", "Please load and select a diffusion image before starting image processing."); return; } typedef mitk::DiffusionImage DiffImgType; DiffImgType* dimg = dynamic_cast(nodes.front()->GetData()); if (!dimg) { // Nothing selected. Inform the user and return QMessageBox::information( NULL, "Template", "No valid diffusion image was found."); return; } // find bzero index int index = -1; DiffImgType::GradientDirectionContainerType::Pointer directions = dimg->GetDirections(); for(DiffImgType::GradientDirectionContainerType::ConstIterator it = directions->Begin(); it != directions->End(); ++it) { index++; DiffImgType::GradientDirectionType g = it.Value(); if(g[0] == 0 && g[1] == 0 && g[2] == 0 ) break; } typedef itk::VectorImage VecImgType; VecImgType::Pointer vecimg = dimg->GetVectorImage(); int vecLength = vecimg->GetVectorLength(); index = index > vecLength-1 ? vecLength-1 : index; MITK_INFO << "Performing Histogram Analysis on Channel" << index; typedef itk::Image ImgType; ImgType::Pointer img = ImgType::New(); mitk::CastToItkImage(dimg, img); itk::ImageRegionIterator itw (img, img->GetLargestPossibleRegion() ); itw.GoToBegin(); itk::ImageRegionConstIterator itr (vecimg, vecimg->GetLargestPossibleRegion() ); itr.GoToBegin(); while(!itr.IsAtEnd()) { itw.Set(itr.Get().GetElement(index)); ++itr; ++itw; } typedef itk::Statistics::ScalarImageToHistogramGenerator< ImgType > HistogramGeneratorType; typedef HistogramGeneratorType::HistogramType HistogramType; HistogramGeneratorType::Pointer histogramGenerator = HistogramGeneratorType::New(); histogramGenerator->SetInput( img ); histogramGenerator->SetMarginalScale( 10 ); // Defines y-margin width of histogram histogramGenerator->SetNumberOfBins( 100 ); // CT range [-1024, +2048] --> bin size 4 values histogramGenerator->SetHistogramMin( dimg->GetScalarValueMin() ); histogramGenerator->SetHistogramMax( dimg->GetScalarValueMax() * .5 ); histogramGenerator->Compute(); HistogramType::ConstIterator iter = histogramGenerator->GetOutput()->Begin(); float maxFreq = 0; float maxValue = 0; while ( iter != histogramGenerator->GetOutput()->End() ) { if(iter.GetFrequency() > maxFreq) { maxFreq = iter.GetFrequency(); maxValue = iter.GetMeasurementVector()[0]; } ++iter; } maxValue *= 2; int sliderPos = maxValue * 2; m_Controls->m_S0ThreshSlider->setValue(sliderPos); S0ThreshSlider(sliderPos); } void QmitkIVIMView::FittIVIMStart() { std::vector nodes = this->GetDataManagerSelection(); mitk::DiffusionImage* img = 0; for ( unsigned int i=0; i*>(nodes.at(i)->GetData()); if (img) break; } if (!img) { QMessageBox::information( NULL, "Template", "No valid diffusion image was found."); return; } typedef itk::VectorImage VecImgType; VecImgType::Pointer vecimg = img->GetVectorImage(); OutImgType::IndexType dummy; FittIVIM(vecimg, img->GetDirections(), img->GetReferenceBValue(), true, dummy); OutputToDatastorage(nodes); } void QmitkIVIMView::OnSliceChanged(const itk::EventObject& /*e*/) { if(!m_Visible) return; m_Controls->m_Warning->setVisible(false); if(!m_Controls || m_DiffusionImageNode.IsNull()) return; m_Controls->m_VisualizeResultsWidget->setVisible(false); mitk::DiffusionImage::Pointer diffusionImg = dynamic_cast*>(m_DiffusionImageNode->GetData()); mitk::Image::Pointer maskImg = NULL; if (m_MaskImageNode.IsNotNull()) maskImg = dynamic_cast(m_MaskImageNode->GetData()); if (!m_MultiWidget) return; typedef itk::VectorImage VecImgType; VecImgType::Pointer vecimg = (VecImgType*)diffusionImg->GetVectorImage().GetPointer(); VecImgType::Pointer roiImage = VecImgType::New(); bool success = false; if(maskImg.IsNull()) { int roisize = 0; if(m_Controls->m_MethodCombo->currentIndex() == 4) roisize = 5; mitk::Point3D pos = m_MultiWidget->GetCrossPosition(); VecImgType::IndexType crosspos; diffusionImg->GetGeometry()->WorldToIndex(pos, crosspos); if (!vecimg->GetLargestPossibleRegion().IsInside(crosspos)) { m_Controls->m_Warning->setText(QString("Crosshair position not inside of selected diffusion weighted image. Reinit needed!")); m_Controls->m_Warning->setVisible(true); return; } else m_Controls->m_Warning->setVisible(false); VecImgType::IndexType index; index[0] = crosspos[0] - roisize; index[0] = index[0] < 0 ? 0 : index[0]; index[1] = crosspos[1] - roisize; index[1] = index[1] < 0 ? 0 : index[1]; index[2] = crosspos[2] - roisize; index[2] = index[2] < 0 ? 0 : index[2]; VecImgType::SizeType size; size[0] = roisize*2+1; size[1] = roisize*2+1; size[2] = roisize*2+1; VecImgType::SizeType maxSize = vecimg->GetLargestPossibleRegion().GetSize(); size[0] = index[0]+size[0] > maxSize[0] ? maxSize[0]-index[0] : size[0]; size[1] = index[1]+size[1] > maxSize[1] ? maxSize[1]-index[1] : size[1]; size[2] = index[2]+size[2] > maxSize[2] ? maxSize[2]-index[2] : size[2]; VecImgType::RegionType region; region.SetSize( size ); region.SetIndex( index ); vecimg->SetRequestedRegion( region ); VecImgType::IndexType newstart; newstart.Fill(0); VecImgType::RegionType newregion; newregion.SetSize( size ); newregion.SetIndex( newstart ); roiImage->CopyInformation( vecimg ); roiImage->SetRegions( newregion ); roiImage->SetOrigin( pos ); roiImage->Allocate(); roiImage->SetPixel(newstart, vecimg->GetPixel(index)); success = FittIVIM(roiImage, diffusionImg->GetDirections(), diffusionImg->GetReferenceBValue(), false, crosspos); } else { typedef itk::Image MaskImgType; MaskImgType::Pointer maskItk; CastToItkImage( maskImg, maskItk ); mitk::Point3D pos; pos[0] = 0; pos[1] = 0; pos[2] = 0; VecImgType::IndexType index; index[0] = 0; index[1] = 0; index[2] = 0; VecImgType::SizeType size; size[0] = 1; size[1] = 1; size[2] = 1; VecImgType::RegionType region; region.SetSize( size ); region.SetIndex( index ); vecimg->SetRequestedRegion( region ); // iterators over output and input itk::ImageRegionConstIteratorWithIndex vecit(vecimg, vecimg->GetLargestPossibleRegion()); itk::VariableLengthVector avg(vecimg->GetVectorLength()); avg.Fill(0); float numPixels = 0; while ( ! vecit.IsAtEnd() ) { VecImgType::PointType point; vecimg->TransformIndexToPhysicalPoint(vecit.GetIndex(), point); MaskImgType::IndexType index; maskItk->TransformPhysicalPointToIndex(point, index); if(maskItk->GetPixel(index) != 0) { avg += vecit.Get(); numPixels += 1.0; } // update iterators ++vecit; } avg /= numPixels; m_Controls->m_Warning->setText(QString("Averaging ")+QString::number((int)numPixels)+QString(" voxels!")); m_Controls->m_Warning->setVisible(true); roiImage->CopyInformation( vecimg ); roiImage->SetRegions( region ); roiImage->SetOrigin( pos ); roiImage->Allocate(); roiImage->SetPixel(index, avg); success = FittIVIM(roiImage, diffusionImg->GetDirections(), diffusionImg->GetReferenceBValue(), false, index); } vecimg->SetRegions( vecimg->GetLargestPossibleRegion() ); if (success) { m_Controls->m_VisualizeResultsWidget->setVisible(true); m_Controls->m_VisualizeResultsWidget->SetParameters(m_Snap); } } bool QmitkIVIMView::FittIVIM(itk::VectorImage* vecimg, DirContainerType* dirs, float bval, bool multivoxel, OutImgType::IndexType &crosspos) { IVIMFilterType::Pointer filter = IVIMFilterType::New(); filter->SetInput(vecimg); filter->SetGradientDirections(dirs); filter->SetBValue(bval); switch(m_Controls->m_MethodCombo->currentIndex()) { case 0: filter->SetMethod(IVIMFilterType::IVIM_FIT_ALL); filter->SetS0Thres(m_Controls->m_S0ThreshLabel->text().toDouble()); break; case 1: filter->SetMethod(IVIMFilterType::IVIM_DSTAR_FIX); filter->SetDStar(m_Controls->m_DStarLabel->text().toDouble()); filter->SetS0Thres(m_Controls->m_S0ThreshLabel->text().toDouble()); break; case 2: filter->SetMethod(IVIMFilterType::IVIM_D_THEN_DSTAR); filter->SetBThres(m_Controls->m_BThreshLabel->text().toDouble()); filter->SetS0Thres(m_Controls->m_S0ThreshLabel->text().toDouble()); filter->SetFitDStar(m_Controls->m_CheckDStar->isChecked()); break; case 3: filter->SetMethod(IVIMFilterType::IVIM_LINEAR_D_THEN_F); filter->SetBThres(m_Controls->m_BThreshLabel->text().toDouble()); filter->SetS0Thres(m_Controls->m_S0ThreshLabel->text().toDouble()); filter->SetFitDStar(m_Controls->m_CheckDStar->isChecked()); break; case 4: filter->SetMethod(IVIMFilterType::IVIM_REGULARIZED); filter->SetBThres(m_Controls->m_BThreshLabel->text().toDouble()); filter->SetS0Thres(m_Controls->m_S0ThreshLabel->text().toDouble()); filter->SetNumberIterations(m_Controls->m_NumItsLabel->text().toInt()); filter->SetLambda(m_Controls->m_LambdaLabel->text().toDouble()); filter->SetFitDStar(m_Controls->m_CheckDStar->isChecked()); break; } if(!multivoxel) { filter->SetFitDStar(true); } filter->SetNumberOfThreads(1); filter->SetVerbose(false); filter->SetCrossPosition(crosspos); try{ filter->Update(); m_Snap = filter->GetSnapshot(); m_DStarMap = filter->GetOutput(2); m_DMap = filter->GetOutput(1); m_fMap = filter->GetOutput(); } catch (itk::ExceptionObject &ex) { MITK_INFO << ex ; m_Controls->m_Warning->setText(QString("IVIM fit not possible: ")+ex.GetDescription()); m_Controls->m_Warning->setVisible(true); return false; } return true; } void QmitkIVIMView::OutputToDatastorage(std::vector nodes) { // Outputs to Datastorage QString basename(nodes.front()->GetName().c_str()); if(m_Controls->m_CheckDStar->isChecked()) { mitk::Image::Pointer dstarimage = mitk::Image::New(); dstarimage->InitializeByItk(m_DStarMap.GetPointer()); dstarimage->SetVolume(m_DStarMap->GetBufferPointer()); QString newname2 = basename; newname2 = newname2.append("_DStarMap_%1").arg(m_Controls->m_MethodCombo->currentText()); mitk::DataNode::Pointer node2=mitk::DataNode::New(); node2->SetData( dstarimage ); - node2->SetName(newname2.toAscii()); + node2->SetName(newname2.toLatin1()); GetDefaultDataStorage()->Add(node2); } if(m_Controls->m_CheckD->isChecked()) { mitk::Image::Pointer dimage = mitk::Image::New(); dimage->InitializeByItk(m_DMap.GetPointer()); dimage->SetVolume(m_DMap->GetBufferPointer()); QString newname1 = basename; newname1 = newname1.append("_DMap_%1").arg(m_Controls->m_MethodCombo->currentText()); mitk::DataNode::Pointer node1=mitk::DataNode::New(); node1->SetData( dimage ); - node1->SetName(newname1.toAscii()); + node1->SetName(newname1.toLatin1()); GetDefaultDataStorage()->Add(node1); } if(m_Controls->m_Checkf->isChecked()) { mitk::Image::Pointer image = mitk::Image::New(); image->InitializeByItk(m_fMap.GetPointer()); image->SetVolume(m_fMap->GetBufferPointer()); QString newname0 = basename; newname0 = newname0.append("_fMap_%1").arg(m_Controls->m_MethodCombo->currentText()); mitk::DataNode::Pointer node=mitk::DataNode::New(); node->SetData( image ); - node->SetName(newname0.toAscii()); + node->SetName(newname0.toLatin1()); GetDefaultDataStorage()->Add(node); } m_MultiWidget->RequestUpdate(); // reset the data node labels, the selection in DataManager is lost after adding // a new node -> we cannot directly proceed twice, the DWI ( and MASK) image have to be selected again m_Controls->m_InputData->setTitle("Please Select Input Data"); m_Controls->m_DiffusionImageLabel->setText("mandatory"); m_Controls->m_MaskImageLabel->setText("optional"); m_MaskImageNode = NULL; m_DiffusionImageNode = NULL; } void QmitkIVIMView::ChooseMethod() { m_Controls->m_MethodCombo->setVisible(m_Controls->m_ChooseMethod->isChecked()); } void QmitkIVIMView::ClipboardCurveButtonClicked() { if(true) { QString clipboard("Measurement Points\n"); for ( unsigned int i=0; isetText( clipboard, QClipboard::Clipboard ); } else { QApplication::clipboard()->clear(); } } void QmitkIVIMView::ClipboardStatisticsButtonClicked() { if ( true ) { QString clipboard( "f \t D \t D* \n" ); clipboard = clipboard.append( "%L1 \t %L2 \t %L3" ) .arg( m_Snap.currentF, 0, 'f', 10 ) .arg( m_Snap.currentD, 0, 'f', 10 ) .arg( m_Snap.currentDStar, 0, 'f', 10 ) ; QApplication::clipboard()->setText( clipboard, QClipboard::Clipboard ); } else { QApplication::clipboard()->clear(); } } void QmitkIVIMView::Activated() { m_Active = true; } void QmitkIVIMView::Deactivated() { m_Active = false; } diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkPreprocessingView.cpp b/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkPreprocessingView.cpp index 96d82570d6..f088491113 100644 --- a/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkPreprocessingView.cpp +++ b/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkPreprocessingView.cpp @@ -1,1775 +1,1781 @@ /*=================================================================== 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. ===================================================================*/ //#define MBILOG_ENABLE_DEBUG #include "QmitkPreprocessingView.h" #include "mitkDiffusionImagingConfigure.h" // qt includes #include // itk includes #include "itkTimeProbe.h" #include "itkB0ImageExtractionImageFilter.h" #include "itkB0ImageExtractionToSeparateImageFilter.h" #include "itkBrainMaskExtractionImageFilter.h" #include "itkCastImageFilter.h" #include "itkVectorContainer.h" #include #include #include #include // Multishell includes #include // Multishell Functors #include #include #include #include // mitk includes #include "QmitkDataStorageComboBox.h" #include "QmitkStdMultiWidget.h" #include "mitkProgressBar.h" #include "mitkStatusBar.h" #include "mitkNodePredicateDataType.h" #include "mitkProperties.h" #include "mitkVtkResliceInterpolationProperty.h" #include "mitkLookupTable.h" #include "mitkLookupTableProperty.h" #include "mitkTransferFunction.h" #include "mitkTransferFunctionProperty.h" #include "mitkDataNodeObject.h" #include "mitkOdfNormalizationMethodProperty.h" #include "mitkOdfScaleByProperty.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include const std::string QmitkPreprocessingView::VIEW_ID = "org.mitk.views.preprocessing"; #define DI_INFO MITK_INFO("DiffusionImaging") typedef float TTensorPixelType; QmitkPreprocessingView::QmitkPreprocessingView() : QmitkFunctionality(), m_Controls(NULL), m_MultiWidget(NULL), m_DiffusionImage(NULL) { } QmitkPreprocessingView::~QmitkPreprocessingView() { } void QmitkPreprocessingView::CreateQtPartControl(QWidget *parent) { if (!m_Controls) { // create GUI widgets m_Controls = new Ui::QmitkPreprocessingViewControls; m_Controls->setupUi(parent); this->CreateConnections(); +#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) m_Controls->m_MeasurementFrameTable->horizontalHeader()->setResizeMode(QHeaderView::Stretch); m_Controls->m_MeasurementFrameTable->verticalHeader()->setResizeMode(QHeaderView::Stretch); - m_Controls->m_DirectionMatrixTable->horizontalHeader()->setResizeMode(QHeaderView::Stretch); m_Controls->m_DirectionMatrixTable->verticalHeader()->setResizeMode(QHeaderView::Stretch); +#else + m_Controls->m_MeasurementFrameTable->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch); + m_Controls->m_MeasurementFrameTable->verticalHeader()->setSectionResizeMode(QHeaderView::Stretch); + m_Controls->m_DirectionMatrixTable->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch); + m_Controls->m_DirectionMatrixTable->verticalHeader()->setSectionResizeMode(QHeaderView::Stretch); +#endif } } void QmitkPreprocessingView::StdMultiWidgetAvailable (QmitkStdMultiWidget &stdMultiWidget) { m_MultiWidget = &stdMultiWidget; } void QmitkPreprocessingView::StdMultiWidgetNotAvailable() { m_MultiWidget = NULL; } void QmitkPreprocessingView::CreateConnections() { if ( m_Controls ) { m_Controls->m_NormalizationMaskBox->SetDataStorage(this->GetDataStorage()); mitk::TNodePredicateDataType::Pointer isMitkImage = mitk::TNodePredicateDataType::New(); mitk::NodePredicateDataType::Pointer isDwi = mitk::NodePredicateDataType::New("DiffusionImage"); mitk::NodePredicateDataType::Pointer isDti = mitk::NodePredicateDataType::New("TensorImage"); mitk::NodePredicateDataType::Pointer isQbi = mitk::NodePredicateDataType::New("QBallImage"); mitk::NodePredicateOr::Pointer isDiffusionImage = mitk::NodePredicateOr::New(isDwi, isDti); isDiffusionImage = mitk::NodePredicateOr::New(isDiffusionImage, isQbi); mitk::NodePredicateNot::Pointer noDiffusionImage = mitk::NodePredicateNot::New(isDiffusionImage); mitk::NodePredicateAnd::Pointer finalPredicate = mitk::NodePredicateAnd::New(isMitkImage, noDiffusionImage); mitk::NodePredicateProperty::Pointer isBinaryPredicate = mitk::NodePredicateProperty::New("binary", mitk::BoolProperty::New(true)); finalPredicate = mitk::NodePredicateAnd::New(finalPredicate, isBinaryPredicate); m_Controls->m_NormalizationMaskBox->SetPredicate(finalPredicate); m_Controls->m_ExtractBrainMask->setVisible(false); m_Controls->m_BrainMaskIterationsBox->setVisible(false); m_Controls->m_ResampleIntFrame->setVisible(false); connect( (QObject*)(m_Controls->m_ButtonAverageGradients), SIGNAL(clicked()), this, SLOT(AverageGradients()) ); connect( (QObject*)(m_Controls->m_ButtonExtractB0), SIGNAL(clicked()), this, SLOT(ExtractB0()) ); connect( (QObject*)(m_Controls->m_ModifyMeasurementFrame), SIGNAL(clicked()), this, SLOT(DoApplyMesurementFrame()) ); connect( (QObject*)(m_Controls->m_ReduceGradientsButton), SIGNAL(clicked()), this, SLOT(DoReduceGradientDirections()) ); connect( (QObject*)(m_Controls->m_ShowGradientsButton), SIGNAL(clicked()), this, SLOT(DoShowGradientDirections()) ); connect( (QObject*)(m_Controls->m_MirrorGradientToHalfSphereButton), SIGNAL(clicked()), this, SLOT(DoHalfSphereGradientDirections()) ); connect( (QObject*)(m_Controls->m_MergeDwisButton), SIGNAL(clicked()), this, SLOT(MergeDwis()) ); connect( (QObject*)(m_Controls->m_ProjectSignalButton), SIGNAL(clicked()), this, SLOT(DoProjectSignal()) ); connect( (QObject*)(m_Controls->m_B_ValueMap_Rounder_SpinBox), SIGNAL(valueChanged(int)), this, SLOT(UpdateDwiBValueMapRounder(int))); connect( (QObject*)(m_Controls->m_CreateLengthCorrectedDwi), SIGNAL(clicked()), this, SLOT(DoLengthCorrection()) ); connect( (QObject*)(m_Controls->m_CalcAdcButton), SIGNAL(clicked()), this, SLOT(DoAdcCalculation()) ); connect( (QObject*)(m_Controls->m_NormalizeImageValuesButton), SIGNAL(clicked()), this, SLOT(DoDwiNormalization()) ); connect( (QObject*)(m_Controls->m_ModifyDirection), SIGNAL(clicked()), this, SLOT(DoApplyDirectionMatrix()) ); connect( (QObject*)(m_Controls->m_ModifySpacingButton), SIGNAL(clicked()), this, SLOT(DoApplySpacing()) ); connect( (QObject*)(m_Controls->m_ModifyOriginButton), SIGNAL(clicked()), this, SLOT(DoApplyOrigin()) ); connect( (QObject*)(m_Controls->m_ResampleImageButton), SIGNAL(clicked()), this, SLOT(DoResampleImage()) ); connect( (QObject*)(m_Controls->m_ResampleTypeBox), SIGNAL(currentIndexChanged(int)), this, SLOT(DoUpdateInterpolationGui(int)) ); connect( (QObject*)(m_Controls->m_CropImageButton), SIGNAL(clicked()), this, SLOT(DoCropImage()) ); connect( (QObject*)(m_Controls->m_RemoveGradientButton), SIGNAL(clicked()), this, SLOT(DoRemoveGradient()) ); connect( (QObject*)(m_Controls->m_ExtractGradientButton), SIGNAL(clicked()), this, SLOT(DoExtractGradient()) ); // connect( (QObject*)(m_Controls->m_ExtractBrainMask), SIGNAL(clicked()), this, SLOT(DoExtractBrainMask()) ); } } void QmitkPreprocessingView::DoRemoveGradient() { if (m_DiffusionImage.IsNull()) return; std::vector< unsigned int > channelsToRemove; channelsToRemove.push_back(m_Controls->m_RemoveGradientBox->value()); itk::RemoveDwiChannelFilter< short >::Pointer filter = itk::RemoveDwiChannelFilter< short >::New(); filter->SetInput(m_DiffusionImage->GetVectorImage()); filter->SetChannelIndices(channelsToRemove); filter->SetDirections(m_DiffusionImage->GetDirections()); filter->Update(); MitkDwiType::Pointer image = MitkDwiType::New(); image->SetVectorImage( filter->GetOutput() ); image->SetReferenceBValue( m_DiffusionImage->GetReferenceBValue() ); image->SetDirections( filter->GetNewDirections() ); image->InitializeFromVectorImage(); mitk::DataNode::Pointer imageNode = mitk::DataNode::New(); imageNode->SetData( image ); QString name = m_SelectedDiffusionNodes.back()->GetName().c_str(); imageNode->SetName((name+"_removedgradients").toStdString().c_str()); GetDefaultDataStorage()->Add(imageNode, m_SelectedDiffusionNodes.back()); mitk::RenderingManager::GetInstance()->InitializeViews( imageNode->GetData()->GetTimeGeometry(), mitk::RenderingManager::REQUEST_UPDATE_ALL, true ); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } void QmitkPreprocessingView::DoExtractGradient() { if (m_DiffusionImage.IsNull()) return; unsigned int channel = m_Controls->m_ExtractGradientBox->value(); itk::ExtractDwiChannelFilter< short >::Pointer filter = itk::ExtractDwiChannelFilter< short >::New(); filter->SetInput(m_DiffusionImage->GetVectorImage()); filter->SetChannelIndex(channel); filter->Update(); mitk::Image::Pointer mitkImage = mitk::Image::New(); mitkImage->InitializeByItk( filter->GetOutput() ); mitkImage->SetImportChannel( filter->GetOutput()->GetBufferPointer() ); mitk::DataNode::Pointer imageNode = mitk::DataNode::New(); imageNode->SetData( mitkImage ); QString name = m_SelectedDiffusionNodes.back()->GetName().c_str(); imageNode->SetName((name+"_direction-"+QString::number(channel)).toStdString().c_str()); GetDefaultDataStorage()->Add(imageNode, m_SelectedDiffusionNodes.back()); mitk::RenderingManager::GetInstance()->InitializeViews(imageNode->GetData()->GetTimeGeometry(),mitk::RenderingManager::REQUEST_UPDATE_ALL, true); } void QmitkPreprocessingView::DoCropImage() { if (m_DiffusionImage.IsNotNull()) { ItkDwiType::SizeType lower; ItkDwiType::SizeType upper; lower[0] = m_Controls->m_XstartBox->value(); lower[1] = m_Controls->m_YstartBox->value(); lower[2] = m_Controls->m_ZstartBox->value(); upper[0] = m_Controls->m_XendBox->value(); upper[1] = m_Controls->m_YendBox->value(); upper[2] = m_Controls->m_ZendBox->value(); itk::CropImageFilter< ItkDwiType, ItkDwiType >::Pointer cropper = itk::CropImageFilter< ItkDwiType, ItkDwiType >::New(); cropper->SetLowerBoundaryCropSize(lower); cropper->SetUpperBoundaryCropSize(upper); cropper->SetInput(m_DiffusionImage->GetVectorImage()); cropper->Update(); MitkDwiType::Pointer image = MitkDwiType::New(); image->SetVectorImage( cropper->GetOutput() ); image->SetReferenceBValue( m_DiffusionImage->GetReferenceBValue() ); image->SetDirections( m_DiffusionImage->GetDirections() ); image->InitializeFromVectorImage(); mitk::DataNode::Pointer imageNode = mitk::DataNode::New(); imageNode->SetData( image ); QString name = m_SelectedDiffusionNodes.back()->GetName().c_str(); imageNode->SetName((name+"_cropped").toStdString().c_str()); GetDefaultDataStorage()->Add(imageNode, m_SelectedDiffusionNodes.back()); mitk::RenderingManager::GetInstance()->InitializeViews( imageNode->GetData()->GetTimeGeometry(), mitk::RenderingManager::REQUEST_UPDATE_ALL, true ); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); mitk::RenderingManager::GetInstance()->InitializeViews( imageNode->GetData()->GetTimeGeometry(), mitk::RenderingManager::REQUEST_UPDATE_ALL, true ); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } else if(m_SelectedImage.IsNotNull()) { AccessFixedDimensionByItk(m_SelectedImage, TemplatedCropImage,3); } } template < typename TPixel, unsigned int VImageDimension > void QmitkPreprocessingView::TemplatedCropImage( itk::Image* itkImage) { ItkDwiType::SizeType lower; ItkDwiType::SizeType upper; lower[0] = m_Controls->m_XstartBox->value(); lower[1] = m_Controls->m_YstartBox->value(); lower[2] = m_Controls->m_ZstartBox->value(); upper[0] = m_Controls->m_XendBox->value(); upper[1] = m_Controls->m_YendBox->value(); upper[2] = m_Controls->m_ZendBox->value(); typedef itk::Image ImageType; typename itk::CropImageFilter< ImageType, ImageType >::Pointer cropper = itk::CropImageFilter< ImageType, ImageType >::New(); cropper->SetLowerBoundaryCropSize(lower); cropper->SetUpperBoundaryCropSize(upper); cropper->SetInput(itkImage); cropper->Update(); mitk::Image::Pointer image = mitk::Image::New(); image->InitializeByItk( cropper->GetOutput() ); image->SetVolume( cropper->GetOutput()->GetBufferPointer() ); mitk::DataNode::Pointer imageNode = mitk::DataNode::New(); imageNode->SetData( image ); QString name = m_SelectedImageNode->GetName().c_str(); imageNode->SetName((name+"_cropped").toStdString().c_str()); GetDefaultDataStorage()->Add(imageNode, m_SelectedImageNode); mitk::RenderingManager::GetInstance()->InitializeViews( imageNode->GetData()->GetTimeGeometry(), mitk::RenderingManager::REQUEST_UPDATE_ALL, true ); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } void QmitkPreprocessingView::DoApplySpacing() { if (m_DiffusionImage.IsNotNull()) { mitk::Vector3D spacing; spacing[0] = m_Controls->m_HeaderSpacingX->value(); spacing[1] = m_Controls->m_HeaderSpacingY->value(); spacing[2] = m_Controls->m_HeaderSpacingZ->value(); MitkDwiType::Pointer image = m_DiffusionImage->Clone(); image->GetVectorImage()->SetSpacing(spacing); image->InitializeFromVectorImage(); mitk::DataNode::Pointer imageNode = mitk::DataNode::New(); imageNode->SetData( image ); QString name = m_SelectedDiffusionNodes.back()->GetName().c_str(); imageNode->SetName((name+"_newspacing").toStdString().c_str()); GetDefaultDataStorage()->Add(imageNode, m_SelectedDiffusionNodes.back()); mitk::RenderingManager::GetInstance()->InitializeViews( imageNode->GetData()->GetTimeGeometry(), mitk::RenderingManager::REQUEST_UPDATE_ALL, true ); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } else if(m_SelectedImage.IsNotNull()) { AccessFixedDimensionByItk(m_SelectedImage, TemplatedSetImageSpacing,3); } } template < typename TPixel, unsigned int VImageDimension > void QmitkPreprocessingView::TemplatedSetImageSpacing( itk::Image* itkImage) { mitk::Vector3D spacing; spacing[0] = m_Controls->m_HeaderSpacingX->value(); spacing[1] = m_Controls->m_HeaderSpacingY->value(); spacing[2] = m_Controls->m_HeaderSpacingZ->value(); typedef itk::ImageDuplicator< itk::Image > DuplicateFilterType; typename DuplicateFilterType::Pointer duplicator = DuplicateFilterType::New(); duplicator->SetInputImage( itkImage ); duplicator->Update(); typename itk::Image::Pointer newImage = duplicator->GetOutput(); newImage->SetSpacing(spacing); mitk::Image::Pointer image = mitk::Image::New(); image->InitializeByItk( newImage.GetPointer() ); image->SetVolume( newImage->GetBufferPointer() ); mitk::DataNode::Pointer imageNode = mitk::DataNode::New(); imageNode->SetData( image ); QString name = m_SelectedImageNode->GetName().c_str(); imageNode->SetName((name+"_newspacing").toStdString().c_str()); GetDefaultDataStorage()->Add(imageNode, m_SelectedImageNode); mitk::RenderingManager::GetInstance()->InitializeViews( imageNode->GetData()->GetTimeGeometry(), mitk::RenderingManager::REQUEST_UPDATE_ALL, true ); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } void QmitkPreprocessingView::DoApplyOrigin() { if (m_DiffusionImage.IsNotNull()) { mitk::Vector3D origin; origin[0] = m_Controls->m_HeaderOriginX->value(); origin[1] = m_Controls->m_HeaderOriginY->value(); origin[2] = m_Controls->m_HeaderOriginZ->value(); MitkDwiType::Pointer image = m_DiffusionImage->Clone(); image->GetVectorImage()->SetOrigin(origin); image->InitializeFromVectorImage(); mitk::DataNode::Pointer imageNode = mitk::DataNode::New(); imageNode->SetData( image ); QString name = m_SelectedDiffusionNodes.back()->GetName().c_str(); imageNode->SetName((name+"_neworigin").toStdString().c_str()); GetDefaultDataStorage()->Add(imageNode, m_SelectedDiffusionNodes.back()); mitk::RenderingManager::GetInstance()->InitializeViews( imageNode->GetData()->GetTimeGeometry(), mitk::RenderingManager::REQUEST_UPDATE_ALL, true ); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } else if(m_SelectedImage.IsNotNull()) { AccessFixedDimensionByItk(m_SelectedImage, TemplatedSetImageOrigin,3); } } template < typename TPixel, unsigned int VImageDimension > void QmitkPreprocessingView::TemplatedSetImageOrigin( itk::Image* itkImage) { mitk::Vector3D origin; origin[0] = m_Controls->m_HeaderOriginX->value(); origin[1] = m_Controls->m_HeaderOriginY->value(); origin[2] = m_Controls->m_HeaderOriginZ->value(); typedef itk::ImageDuplicator< itk::Image > DuplicateFilterType; typename DuplicateFilterType::Pointer duplicator = DuplicateFilterType::New(); duplicator->SetInputImage( itkImage ); duplicator->Update(); typename itk::Image::Pointer newImage = duplicator->GetOutput(); newImage->SetOrigin(origin); mitk::Image::Pointer image = mitk::Image::New(); image->InitializeByItk( newImage.GetPointer() ); image->SetVolume( newImage->GetBufferPointer() ); mitk::DataNode::Pointer imageNode = mitk::DataNode::New(); imageNode->SetData( image ); QString name = m_SelectedImageNode->GetName().c_str(); imageNode->SetName((name+"_neworigin").toStdString().c_str()); GetDefaultDataStorage()->Add(imageNode, m_SelectedImageNode); mitk::RenderingManager::GetInstance()->InitializeViews( imageNode->GetData()->GetTimeGeometry(), mitk::RenderingManager::REQUEST_UPDATE_ALL, true ); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } void QmitkPreprocessingView::DoUpdateInterpolationGui(int i) { switch (i) { case 0: { m_Controls->m_ResampleIntFrame->setVisible(false); m_Controls->m_ResampleDoubleFrame->setVisible(true); break; } case 1: { m_Controls->m_ResampleIntFrame->setVisible(false); m_Controls->m_ResampleDoubleFrame->setVisible(true); if (m_DiffusionImage.IsNotNull()) { ItkDwiType::Pointer itkDwi = m_DiffusionImage->GetVectorImage(); m_Controls->m_ResampleDoubleX->setValue(itkDwi->GetSpacing()[0]); m_Controls->m_ResampleDoubleY->setValue(itkDwi->GetSpacing()[1]); m_Controls->m_ResampleDoubleZ->setValue(itkDwi->GetSpacing()[2]); } else if (m_SelectedImage.IsNotNull()) { mitk::BaseGeometry* geom = m_SelectedImage->GetGeometry(); m_Controls->m_ResampleDoubleX->setValue(geom->GetSpacing()[0]); m_Controls->m_ResampleDoubleY->setValue(geom->GetSpacing()[1]); m_Controls->m_ResampleDoubleZ->setValue(geom->GetSpacing()[2]); } break; } case 2: { m_Controls->m_ResampleIntFrame->setVisible(true); m_Controls->m_ResampleDoubleFrame->setVisible(false); if (m_DiffusionImage.IsNotNull()) { ItkDwiType::Pointer itkDwi = m_DiffusionImage->GetVectorImage(); m_Controls->m_ResampleIntX->setValue(itkDwi->GetLargestPossibleRegion().GetSize(0)); m_Controls->m_ResampleIntY->setValue(itkDwi->GetLargestPossibleRegion().GetSize(1)); m_Controls->m_ResampleIntZ->setValue(itkDwi->GetLargestPossibleRegion().GetSize(2)); } else if (m_SelectedImage.IsNotNull()) { mitk::BaseGeometry* geom = m_SelectedImage->GetGeometry(); m_Controls->m_ResampleIntX->setValue(geom->GetExtent(0)); m_Controls->m_ResampleIntY->setValue(geom->GetExtent(1)); m_Controls->m_ResampleIntZ->setValue(geom->GetExtent(2)); } break; } default: { m_Controls->m_ResampleIntFrame->setVisible(false); m_Controls->m_ResampleDoubleFrame->setVisible(true); } } } void QmitkPreprocessingView::DoExtractBrainMask() { // if (m_SelectedImage.IsNull()) // return; // typedef itk::Image ShortImageType; // ShortImageType::Pointer itkImage = ShortImageType::New(); // mitk::CastToItkImage(m_SelectedImage, itkImage); // typedef itk::BrainMaskExtractionImageFilter< unsigned char > FilterType; // FilterType::Pointer filter = FilterType::New(); // filter->SetInput(itkImage); // filter->SetMaxNumIterations(m_Controls->m_BrainMaskIterationsBox->value()); // filter->Update(); // mitk::Image::Pointer image = mitk::Image::New(); // image->InitializeByItk( filter->GetOutput() ); // image->SetVolume( filter->GetOutput()->GetBufferPointer() ); // mitk::DataNode::Pointer imageNode = mitk::DataNode::New(); // imageNode->SetData( image ); // imageNode->SetName("BRAINMASK"); // GetDefaultDataStorage()->Add(imageNode); } void QmitkPreprocessingView::DoResampleImage() { if (m_DiffusionImage.IsNotNull()) { typedef itk::ResampleDwiImageFilter< short > ResampleFilter; ResampleFilter::Pointer resampler = ResampleFilter::New(); resampler->SetInput(m_DiffusionImage->GetVectorImage()); switch (m_Controls->m_ResampleTypeBox->currentIndex()) { case 0: { itk::Vector< double, 3 > samplingFactor; samplingFactor[0] = m_Controls->m_ResampleDoubleX->value(); samplingFactor[1] = m_Controls->m_ResampleDoubleY->value(); samplingFactor[2] = m_Controls->m_ResampleDoubleZ->value(); resampler->SetSamplingFactor(samplingFactor); break; } case 1: { itk::Vector< double, 3 > newSpacing; newSpacing[0] = m_Controls->m_ResampleDoubleX->value(); newSpacing[1] = m_Controls->m_ResampleDoubleY->value(); newSpacing[2] = m_Controls->m_ResampleDoubleZ->value(); resampler->SetNewSpacing(newSpacing); break; } case 2: { itk::ImageRegion<3> newRegion; newRegion.SetSize(0, m_Controls->m_ResampleIntX->value()); newRegion.SetSize(1, m_Controls->m_ResampleIntY->value()); newRegion.SetSize(2, m_Controls->m_ResampleIntZ->value()); resampler->SetNewImageSize(newRegion); break; } default: { MITK_WARN << "Unknown resampling parameters!"; return; } } QString outAdd; switch (m_Controls->m_InterpolatorBox->currentIndex()) { case 0: { resampler->SetInterpolation(ResampleFilter::Interpolate_NearestNeighbour); outAdd = "NearestNeighbour"; break; } case 1: { resampler->SetInterpolation(ResampleFilter::Interpolate_Linear); outAdd = "Linear"; break; } case 2: { resampler->SetInterpolation(ResampleFilter::Interpolate_BSpline); outAdd = "BSpline"; break; } case 3: { resampler->SetInterpolation(ResampleFilter::Interpolate_WindowedSinc); outAdd = "WindowedSinc"; break; } default: { resampler->SetInterpolation(ResampleFilter::Interpolate_NearestNeighbour); outAdd = "NearestNeighbour"; } } resampler->Update(); typedef mitk::DiffusionImage DiffusionImageType; DiffusionImageType::Pointer image = DiffusionImageType::New(); image->SetVectorImage( resampler->GetOutput() ); image->SetReferenceBValue( m_DiffusionImage->GetReferenceBValue() ); image->SetDirections( m_DiffusionImage->GetDirections() ); image->InitializeFromVectorImage(); mitk::DataNode::Pointer imageNode = mitk::DataNode::New(); imageNode->SetData( image ); QString name = m_SelectedDiffusionNodes.back()->GetName().c_str(); imageNode->SetName((name+"_resampled_"+outAdd).toStdString().c_str()); GetDefaultDataStorage()->Add(imageNode, m_SelectedDiffusionNodes.back()); } else if (m_SelectedImage.IsNotNull()) { AccessFixedDimensionByItk(m_SelectedImage, TemplatedResampleImage,3); } } template < typename TPixel, unsigned int VImageDimension > void QmitkPreprocessingView::TemplatedResampleImage( itk::Image* itkImage) { itk::Vector< double, 3 > newSpacing; itk::ImageRegion<3> newRegion; switch (m_Controls->m_ResampleTypeBox->currentIndex()) { case 0: { itk::Vector< double, 3 > sampling; sampling[0] = m_Controls->m_ResampleDoubleX->value(); sampling[1] = m_Controls->m_ResampleDoubleY->value(); sampling[2] = m_Controls->m_ResampleDoubleZ->value(); newSpacing = itkImage->GetSpacing(); newSpacing[0] /= sampling[0]; newSpacing[1] /= sampling[1]; newSpacing[2] /= sampling[2]; newRegion = itkImage->GetLargestPossibleRegion(); newRegion.SetSize(0, newRegion.GetSize(0)*sampling[0]); newRegion.SetSize(1, newRegion.GetSize(1)*sampling[1]); newRegion.SetSize(2, newRegion.GetSize(2)*sampling[2]); break; } case 1: { newSpacing[0] = m_Controls->m_ResampleDoubleX->value(); newSpacing[1] = m_Controls->m_ResampleDoubleY->value(); newSpacing[2] = m_Controls->m_ResampleDoubleZ->value(); itk::Vector< double, 3 > oldSpacing = itkImage->GetSpacing(); itk::Vector< double, 3 > sampling; sampling[0] = oldSpacing[0]/newSpacing[0]; sampling[1] = oldSpacing[1]/newSpacing[1]; sampling[2] = oldSpacing[2]/newSpacing[2]; newRegion = itkImage->GetLargestPossibleRegion(); newRegion.SetSize(0, newRegion.GetSize(0)*sampling[0]); newRegion.SetSize(1, newRegion.GetSize(1)*sampling[1]); newRegion.SetSize(2, newRegion.GetSize(2)*sampling[2]); break; } case 2: { newRegion.SetSize(0, m_Controls->m_ResampleIntX->value()); newRegion.SetSize(1, m_Controls->m_ResampleIntY->value()); newRegion.SetSize(2, m_Controls->m_ResampleIntZ->value()); itk::ImageRegion<3> oldRegion = itkImage->GetLargestPossibleRegion(); itk::Vector< double, 3 > sampling; sampling[0] = (double)newRegion.GetSize(0)/oldRegion.GetSize(0); sampling[1] = (double)newRegion.GetSize(1)/oldRegion.GetSize(1); sampling[2] = (double)newRegion.GetSize(2)/oldRegion.GetSize(2); newSpacing = itkImage->GetSpacing(); newSpacing[0] /= sampling[0]; newSpacing[1] /= sampling[1]; newSpacing[2] /= sampling[2]; break; } default: { MITK_WARN << "Unknown resampling parameters!"; return; } } itk::Point origin = itkImage->GetOrigin(); origin[0] -= itkImage->GetSpacing()[0]/2; origin[1] -= itkImage->GetSpacing()[1]/2; origin[2] -= itkImage->GetSpacing()[2]/2; origin[0] += newSpacing[0]/2; origin[1] += newSpacing[1]/2; origin[2] += newSpacing[2]/2; typedef itk::Image ImageType; typename ImageType::Pointer outImage = ImageType::New(); outImage->SetSpacing( newSpacing ); outImage->SetOrigin( origin ); outImage->SetDirection( itkImage->GetDirection() ); outImage->SetLargestPossibleRegion( newRegion ); outImage->SetBufferedRegion( newRegion ); outImage->SetRequestedRegion( newRegion ); outImage->Allocate(); typedef itk::ResampleImageFilter ResampleFilter; typename ResampleFilter::Pointer resampler = ResampleFilter::New(); resampler->SetInput(itkImage); resampler->SetOutputParametersFromImage(outImage); QString outAdd; switch (m_Controls->m_InterpolatorBox->currentIndex()) { case 0: { typename itk::NearestNeighborInterpolateImageFunction::Pointer interp = itk::NearestNeighborInterpolateImageFunction::New(); resampler->SetInterpolator(interp); outAdd = "NearestNeighbour"; break; } case 1: { typename itk::LinearInterpolateImageFunction::Pointer interp = itk::LinearInterpolateImageFunction::New(); resampler->SetInterpolator(interp); outAdd = "Linear"; break; } case 2: { typename itk::BSplineInterpolateImageFunction::Pointer interp = itk::BSplineInterpolateImageFunction::New(); resampler->SetInterpolator(interp); outAdd = "BSpline"; break; } case 3: { typename itk::WindowedSincInterpolateImageFunction::Pointer interp = itk::WindowedSincInterpolateImageFunction::New(); resampler->SetInterpolator(interp); outAdd = "WindowedSinc"; break; } default: { typename itk::NearestNeighborInterpolateImageFunction::Pointer interp = itk::NearestNeighborInterpolateImageFunction::New(); resampler->SetInterpolator(interp); outAdd = "NearestNeighbour"; } } resampler->Update(); mitk::Image::Pointer image = mitk::Image::New(); image->InitializeByItk( resampler->GetOutput() ); image->SetVolume( resampler->GetOutput()->GetBufferPointer() ); mitk::DataNode::Pointer imageNode = mitk::DataNode::New(); imageNode->SetData( image ); QString name = m_SelectedImageNode->GetName().c_str(); imageNode->SetName((name+"_resampled_"+outAdd).toStdString().c_str()); GetDefaultDataStorage()->Add(imageNode, m_SelectedImageNode); } void QmitkPreprocessingView::DoApplyDirectionMatrix() { if (m_DiffusionImage.IsNotNull()) { MitkDwiType::Pointer newDwi = m_DiffusionImage->Clone(); ItkDwiType::DirectionType newDirection; for (int r=0; r<3; r++) for (int c=0; c<3; c++) { QTableWidgetItem* item = m_Controls->m_DirectionMatrixTable->item(r,c); if (!item) return; newDirection[r][c] = item->text().toDouble(); } ItkDwiType::Pointer itkDwi = newDwi->GetVectorImage(); typedef mitk::DiffusionImage MitkDwiType; vnl_matrix_fixed< double,3,3 > oldInverseDirection = itkDwi->GetDirection().GetInverse(); MitkDwiType::GradientDirectionContainerType::Pointer oldGradients = m_DiffusionImage->GetDirectionsWithoutMeasurementFrame(); MitkDwiType::GradientDirectionContainerType::Pointer newGradients = MitkDwiType::GradientDirectionContainerType::New(); for (unsigned int i=0; iSize(); i++) { MitkDwiType::GradientDirectionType g = oldGradients->GetElement(i); double mag = g.magnitude(); MitkDwiType::GradientDirectionType newG = oldInverseDirection*g; newG = newDirection.GetVnlMatrix()*newG; newG.normalize(); newGradients->InsertElement(i, newG*mag); } newDwi->SetDirections(newGradients); itkDwi->SetDirection(newDirection); newDwi->InitializeFromVectorImage(); mitk::DataNode::Pointer imageNode = mitk::DataNode::New(); imageNode->SetData( newDwi ); QString name = m_SelectedDiffusionNodes.back()->GetName().c_str(); imageNode->SetName((name+"_newdirection").toStdString().c_str()); GetDefaultDataStorage()->Add(imageNode, m_SelectedDiffusionNodes.back()); mitk::RenderingManager::GetInstance()->InitializeViews( imageNode->GetData()->GetTimeGeometry(), mitk::RenderingManager::REQUEST_UPDATE_ALL, true ); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } else if (m_SelectedImage.IsNotNull()) { AccessFixedDimensionByItk(m_SelectedImage, TemplatedApplyRotation,3); } } template < typename TPixel, unsigned int VImageDimension > void QmitkPreprocessingView::TemplatedApplyRotation( itk::Image* itkImage) { ItkDwiType::DirectionType newDirection; for (int r=0; r<3; r++) for (int c=0; c<3; c++) { QTableWidgetItem* item = m_Controls->m_DirectionMatrixTable->item(r,c); if (!item) return; newDirection[r][c] = item->text().toDouble(); } typedef itk::Image ImageType; typename ImageType::Pointer newImage = ImageType::New(); newImage->SetSpacing( itkImage->GetSpacing() ); newImage->SetOrigin( itkImage->GetOrigin() ); newImage->SetDirection( newDirection ); newImage->SetLargestPossibleRegion( itkImage->GetLargestPossibleRegion() ); newImage->SetBufferedRegion( itkImage->GetLargestPossibleRegion() ); newImage->SetRequestedRegion( itkImage->GetLargestPossibleRegion() ); newImage->Allocate(); newImage->FillBuffer(0); itk::ImageRegionIterator< itk::Image > it(itkImage, itkImage->GetLargestPossibleRegion()); while(!it.IsAtEnd()) { newImage->SetPixel(it.GetIndex(), it.Get()); ++it; } mitk::Image::Pointer newMitkImage = mitk::Image::New(); newMitkImage->InitializeByItk(newImage.GetPointer()); newMitkImage->SetVolume(newImage->GetBufferPointer()); mitk::DataNode::Pointer imageNode = mitk::DataNode::New(); imageNode->SetData( newMitkImage ); QString name = m_SelectedImageNode->GetName().c_str(); imageNode->SetName((name+"_newdirection").toStdString().c_str()); GetDefaultDataStorage()->Add(imageNode, m_SelectedImageNode); mitk::RenderingManager::GetInstance()->InitializeViews( imageNode->GetData()->GetTimeGeometry(), mitk::RenderingManager::REQUEST_UPDATE_ALL, true ); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } void QmitkPreprocessingView::DoProjectSignal() { switch(m_Controls->m_ProjectionMethodBox->currentIndex()) { case 0: DoADCAverage(); break; case 1: DoAKCFit(); break; case 2: DoBiExpFit(); break; default: DoADCAverage(); } } void QmitkPreprocessingView::DoDwiNormalization() { if (m_DiffusionImage.IsNull()) return; int b0Index = -1; for (unsigned int i=0; iGetNumberOfChannels(); i++) { GradientDirectionType g = m_DiffusionImage->GetDirections()->GetElement(i); if (g.magnitude()<0.001) { b0Index = i; break; } } if (b0Index==-1) return; typedef mitk::DiffusionImage DiffusionImageType; typedef itk::DwiNormilzationFilter FilterType; FilterType::Pointer filter = FilterType::New(); filter->SetInput(m_DiffusionImage->GetVectorImage()); filter->SetGradientDirections(m_DiffusionImage->GetDirections()); UcharImageType::Pointer itkImage = NULL; if (m_Controls->m_NormalizationMaskBox->GetSelectedNode().IsNotNull()) { itkImage = UcharImageType::New(); mitk::CastToItkImage(dynamic_cast(m_Controls->m_NormalizationMaskBox->GetSelectedNode()->GetData()), itkImage); filter->SetMaskImage(itkImage); } // determin normalization reference switch(m_Controls->m_NormalizationReferenceBox->currentIndex()) { case 0: // normalize relative to mean white matter signal intensity { typedef itk::DiffusionTensor3DReconstructionImageFilter< short, short, double > TensorReconstructionImageFilterType; TensorReconstructionImageFilterType::Pointer dtFilter = TensorReconstructionImageFilterType::New(); dtFilter->SetGradientImage( m_DiffusionImage->GetDirections(), m_DiffusionImage->GetVectorImage() ); dtFilter->SetBValue(m_DiffusionImage->GetReferenceBValue()); dtFilter->Update(); itk::Image< itk::DiffusionTensor3D< double >, 3 >::Pointer tensorImage = dtFilter->GetOutput(); itk::ImageRegionIterator< itk::Image< itk::DiffusionTensor3D< double >, 3 > > inIt(tensorImage, tensorImage->GetLargestPossibleRegion()); double ref = 0; unsigned int count = 0; while ( !inIt.IsAtEnd() ) { if (itkImage.IsNotNull() && itkImage->GetPixel(inIt.GetIndex())<=0) { ++inIt; continue; } double FA = inIt.Get().GetFractionalAnisotropy(); if (FA>0.4 && FA<0.99) { ref += m_DiffusionImage->GetVectorImage()->GetPixel(inIt.GetIndex())[b0Index]; count++; } ++inIt; } if (count>0) { ref /= count; filter->SetUseGlobalReference(true); filter->SetReference(ref); } break; } case 1: // normalize relative to mean CSF signal intensity { itk::AdcImageFilter< short, double >::Pointer adcFilter = itk::AdcImageFilter< short, double >::New(); adcFilter->SetInput(m_DiffusionImage->GetVectorImage()); adcFilter->SetGradientDirections(m_DiffusionImage->GetDirections()); adcFilter->SetB_value(m_DiffusionImage->GetReferenceBValue()); adcFilter->Update(); ItkDoubleImageType::Pointer adcImage = adcFilter->GetOutput(); itk::ImageRegionIterator inIt(adcImage, adcImage->GetLargestPossibleRegion()); double max = 0.0030; double ref = 0; unsigned int count = 0; while ( !inIt.IsAtEnd() ) { if (itkImage.IsNotNull() && itkImage->GetPixel(inIt.GetIndex())<=0) { ++inIt; continue; } if (inIt.Get()>max && inIt.Get()<0.004) { ref += m_DiffusionImage->GetVectorImage()->GetPixel(inIt.GetIndex())[b0Index]; count++; } ++inIt; } if (count>0) { ref /= count; filter->SetUseGlobalReference(true); filter->SetReference(ref); } break; } case 2: { filter->SetUseGlobalReference(false); } } filter->Update(); DiffusionImageType::Pointer image = DiffusionImageType::New(); image->SetVectorImage( filter->GetOutput() ); image->SetReferenceBValue( m_DiffusionImage->GetReferenceBValue() ); image->SetDirections( m_DiffusionImage->GetDirections() ); image->InitializeFromVectorImage(); mitk::DataNode::Pointer imageNode = mitk::DataNode::New(); imageNode->SetData( image ); QString name = m_SelectedDiffusionNodes.back()->GetName().c_str(); imageNode->SetName((name+"_normalized").toStdString().c_str()); GetDefaultDataStorage()->Add(imageNode, m_SelectedDiffusionNodes.back()); } void QmitkPreprocessingView::DoLengthCorrection() { if (m_DiffusionImage.IsNull()) return; typedef mitk::DiffusionImage DiffusionImageType; typedef itk::DwiGradientLengthCorrectionFilter FilterType; FilterType::Pointer filter = FilterType::New(); filter->SetRoundingValue( m_Controls->m_B_ValueMap_Rounder_SpinBox->value()); filter->SetReferenceBValue(m_DiffusionImage->GetReferenceBValue()); filter->SetReferenceGradientDirectionContainer(m_DiffusionImage->GetDirections()); filter->Update(); DiffusionImageType::Pointer image = DiffusionImageType::New(); image->SetVectorImage( m_DiffusionImage->GetVectorImage()); image->SetReferenceBValue( filter->GetNewBValue() ); image->SetDirections( filter->GetOutputGradientDirectionContainer()); image->InitializeFromVectorImage(); mitk::DataNode::Pointer imageNode = mitk::DataNode::New(); imageNode->SetData( image ); QString name = m_SelectedDiffusionNodes.back()->GetName().c_str(); imageNode->SetName((name+"_rounded").toStdString().c_str()); GetDefaultDataStorage()->Add(imageNode, m_SelectedDiffusionNodes.back()); } void QmitkPreprocessingView::UpdateDwiBValueMapRounder(int i) { if (m_DiffusionImage.IsNull()) return; //m_DiffusionImage->UpdateBValueMap(); UpdateBValueTableWidget(i); } void QmitkPreprocessingView::CallMultishellToSingleShellFilter(itk::DWIVoxelFunctor * functor, mitk::DiffusionImage::Pointer ImPtr, QString imageName, mitk::DataNode* parent) { typedef itk::RadialMultishellToSingleshellImageFilter FilterType; // filter input parameter const mitk::DiffusionImage::BValueMap &originalShellMap = ImPtr->GetBValueMap(); const mitk::DiffusionImage::ImageType *vectorImage = ImPtr->GetVectorImage(); const mitk::DiffusionImage::GradientDirectionContainerType::Pointer gradientContainer = ImPtr->GetDirections(); const unsigned int &bValue = ImPtr->GetReferenceBValue(); mitk::DataNode::Pointer imageNode = 0; // filter call FilterType::Pointer filter = FilterType::New(); filter->SetInput(vectorImage); filter->SetOriginalGradientDirections(gradientContainer); filter->SetOriginalBValueMap(originalShellMap); filter->SetOriginalBValue(bValue); filter->SetFunctor(functor); filter->Update(); // create new DWI image mitk::DiffusionImage::Pointer outImage = mitk::DiffusionImage::New(); outImage->SetVectorImage( filter->GetOutput() ); outImage->SetReferenceBValue( m_Controls->m_targetBValueSpinBox->value() ); outImage->SetDirections( filter->GetTargetGradientDirections() ); outImage->InitializeFromVectorImage(); imageNode = mitk::DataNode::New(); imageNode->SetData( outImage ); imageNode->SetName(imageName.toStdString().c_str()); GetDefaultDataStorage()->Add(imageNode, parent); // if(m_Controls->m_OutputRMSErrorImage->isChecked()){ // // create new Error image // FilterType::ErrorImageType::Pointer errImage = filter->GetErrorImage(); // mitk::Image::Pointer mitkErrImage = mitk::Image::New(); // mitkErrImage->InitializeByItk(errImage); // mitkErrImage->SetVolume(errImage->GetBufferPointer()); // imageNode = mitk::DataNode::New(); // imageNode->SetData( mitkErrImage ); // imageNode->SetName((imageName+"_Error").toStdString().c_str()); // GetDefaultDataStorage()->Add(imageNode); // } } void QmitkPreprocessingView::DoBiExpFit() { itk::BiExpFitFunctor::Pointer functor = itk::BiExpFitFunctor::New(); for (unsigned int i=0; i::Pointer inImage = dynamic_cast< mitk::DiffusionImage* >(m_SelectedDiffusionNodes.at(i)->GetData()); QString name(m_SelectedDiffusionNodes.at(i)->GetName().c_str()); const mitk::DiffusionImage::BValueMap & originalShellMap = inImage->GetBValueMap(); mitk::DiffusionImage::BValueMap::const_iterator it = originalShellMap.begin(); ++it;/* skip b=0*/ unsigned int s = 0; /*shell index */ vnl_vector bValueList(originalShellMap.size()-1); while(it != originalShellMap.end()) bValueList.put(s++,(it++)->first); const double targetBValue = m_Controls->m_targetBValueSpinBox->value(); functor->setListOfBValues(bValueList); functor->setTargetBValue(targetBValue); CallMultishellToSingleShellFilter(functor,inImage,name + "_BiExp", m_SelectedDiffusionNodes.at(i)); } } void QmitkPreprocessingView::DoAKCFit() { itk::KurtosisFitFunctor::Pointer functor = itk::KurtosisFitFunctor::New(); for (unsigned int i=0; i::Pointer inImage = dynamic_cast< mitk::DiffusionImage* >(m_SelectedDiffusionNodes.at(i)->GetData()); QString name(m_SelectedDiffusionNodes.at(i)->GetName().c_str()); const mitk::DiffusionImage::BValueMap & originalShellMap = inImage->GetBValueMap(); mitk::DiffusionImage::BValueMap::const_iterator it = originalShellMap.begin(); ++it;/* skip b=0*/ unsigned int s = 0; /*shell index */ vnl_vector bValueList(originalShellMap.size()-1); while(it != originalShellMap.end()) bValueList.put(s++,(it++)->first); const double targetBValue = m_Controls->m_targetBValueSpinBox->value(); functor->setListOfBValues(bValueList); functor->setTargetBValue(targetBValue); CallMultishellToSingleShellFilter(functor,inImage,name + "_AKC", m_SelectedDiffusionNodes.at(i)); } } void QmitkPreprocessingView::DoADCFit() { // later } void QmitkPreprocessingView::DoADCAverage() { itk::ADCAverageFunctor::Pointer functor = itk::ADCAverageFunctor::New(); for (unsigned int i=0; i::Pointer inImage = dynamic_cast< mitk::DiffusionImage* >(m_SelectedDiffusionNodes.at(i)->GetData()); QString name(m_SelectedDiffusionNodes.at(i)->GetName().c_str()); const mitk::DiffusionImage::BValueMap & originalShellMap = inImage->GetBValueMap(); mitk::DiffusionImage::BValueMap::const_iterator it = originalShellMap.begin(); ++it;/* skip b=0*/ unsigned int s = 0; /*shell index */ vnl_vector bValueList(originalShellMap.size()-1); while(it != originalShellMap.end()) bValueList.put(s++,(it++)->first); const double targetBValue = m_Controls->m_targetBValueSpinBox->value(); functor->setListOfBValues(bValueList); functor->setTargetBValue(targetBValue); CallMultishellToSingleShellFilter(functor,inImage,name + "_ADC", m_SelectedDiffusionNodes.at(i)); } } void QmitkPreprocessingView::DoAdcCalculation() { if (m_DiffusionImage.IsNull()) return; typedef mitk::DiffusionImage< DiffusionPixelType > DiffusionImageType; typedef itk::AdcImageFilter< DiffusionPixelType, double > FilterType; for (unsigned int i=0; i(m_SelectedDiffusionNodes.at(i)->GetData()); FilterType::Pointer filter = FilterType::New(); filter->SetInput(inImage->GetVectorImage()); filter->SetGradientDirections(inImage->GetDirections()); filter->SetB_value(inImage->GetReferenceBValue()); filter->Update(); mitk::Image::Pointer image = mitk::Image::New(); image->InitializeByItk( filter->GetOutput() ); image->SetVolume( filter->GetOutput()->GetBufferPointer() ); mitk::DataNode::Pointer imageNode = mitk::DataNode::New(); imageNode->SetData( image ); QString name = m_SelectedDiffusionNodes.at(i)->GetName().c_str(); imageNode->SetName((name+"_ADC").toStdString().c_str()); GetDefaultDataStorage()->Add(imageNode, m_SelectedDiffusionNodes.at(i)); } } void QmitkPreprocessingView::UpdateBValueTableWidget(int i) { if (m_DiffusionImage.IsNull()) { m_Controls->m_B_ValueMap_TableWidget->clear(); m_Controls->m_B_ValueMap_TableWidget->setRowCount(1); QStringList headerList; headerList << "b-Value" << "Number of gradients"; m_Controls->m_B_ValueMap_TableWidget->setHorizontalHeaderLabels(headerList); m_Controls->m_B_ValueMap_TableWidget->setItem(0,0,new QTableWidgetItem("-")); m_Controls->m_B_ValueMap_TableWidget->setItem(0,1,new QTableWidgetItem("-")); }else{ typedef mitk::DiffusionImage::BValueMap BValueMap; typedef mitk::DiffusionImage::BValueMap::iterator BValueMapIterator; BValueMapIterator it; BValueMap roundedBValueMap = m_DiffusionImage->GetBValueMap(); m_Controls->m_B_ValueMap_TableWidget->clear(); m_Controls->m_B_ValueMap_TableWidget->setRowCount(roundedBValueMap.size() ); QStringList headerList; headerList << "b-Value" << "Number of gradients"; m_Controls->m_B_ValueMap_TableWidget->setHorizontalHeaderLabels(headerList); int i = 0 ; for(it = roundedBValueMap.begin() ;it != roundedBValueMap.end(); it++) { m_Controls->m_B_ValueMap_TableWidget->setItem(i,0,new QTableWidgetItem(QString::number(it->first))); QTableWidgetItem* item = m_Controls->m_B_ValueMap_TableWidget->item(i,0); item->setFlags(item->flags() & ~Qt::ItemIsEditable); m_Controls->m_B_ValueMap_TableWidget->setItem(i,1,new QTableWidgetItem(QString::number(it->second.size()))); i++; } } } template < typename TPixel, unsigned int VImageDimension > void QmitkPreprocessingView::TemplatedUpdateGui( itk::Image* itkImage) { for (int r=0; r<3; r++) for (int c=0; c<3; c++) { QTableWidgetItem* item = m_Controls->m_DirectionMatrixTable->item(r,c); delete item; item = new QTableWidgetItem(); item->setTextAlignment(Qt::AlignCenter | Qt::AlignVCenter); item->setText(QString::number(itkImage->GetDirection()[r][c])); m_Controls->m_DirectionMatrixTable->setItem(r,c,item); } } void QmitkPreprocessingView::OnSelectionChanged( std::vector nodes ) { bool foundDwiVolume = false; bool foundImageVolume = false; m_DiffusionImage = NULL; m_SelectedImage = NULL; m_SelectedImageNode = NULL; m_SelectedDiffusionNodes.clear(); // iterate selection for( std::vector::iterator it = nodes.begin(); it != nodes.end(); ++it ) { mitk::DataNode::Pointer node = *it; if( node.IsNotNull() && dynamic_cast*>(node->GetData()) ) { foundDwiVolume = true; foundImageVolume = true; m_DiffusionImage = dynamic_cast*>(node->GetData()); m_Controls->m_DiffusionImageLabel->setText(node->GetName().c_str()); m_SelectedDiffusionNodes.push_back(node); } else if( node.IsNotNull() && dynamic_cast(node->GetData()) ) { foundImageVolume = true; m_SelectedImage = dynamic_cast(node->GetData()); m_Controls->m_DiffusionImageLabel->setText(node->GetName().c_str()); m_SelectedImageNode = node; } } m_Controls->m_ButtonAverageGradients->setEnabled(foundDwiVolume); m_Controls->m_ButtonExtractB0->setEnabled(foundDwiVolume); m_Controls->m_CheckExtractAll->setEnabled(foundDwiVolume); m_Controls->m_ModifyMeasurementFrame->setEnabled(foundDwiVolume); m_Controls->m_MeasurementFrameTable->setEnabled(foundDwiVolume); m_Controls->m_ReduceGradientsButton->setEnabled(foundDwiVolume); m_Controls->m_ShowGradientsButton->setEnabled(foundDwiVolume); m_Controls->m_MirrorGradientToHalfSphereButton->setEnabled(foundDwiVolume); m_Controls->m_MergeDwisButton->setEnabled(foundDwiVolume); m_Controls->m_B_ValueMap_Rounder_SpinBox->setEnabled(foundDwiVolume); m_Controls->m_ProjectSignalButton->setEnabled(foundDwiVolume); m_Controls->m_CreateLengthCorrectedDwi->setEnabled(foundDwiVolume); m_Controls->m_CalcAdcButton->setEnabled(foundDwiVolume); m_Controls->m_targetBValueSpinBox->setEnabled(foundDwiVolume); m_Controls->m_NormalizeImageValuesButton->setEnabled(foundDwiVolume); m_Controls->m_DirectionMatrixTable->setEnabled(foundImageVolume); m_Controls->m_ModifyDirection->setEnabled(foundImageVolume); m_Controls->m_ExtractBrainMask->setEnabled(foundImageVolume); m_Controls->m_ResampleImageButton->setEnabled(foundImageVolume); m_Controls->m_ModifySpacingButton->setEnabled(foundImageVolume); m_Controls->m_ModifyOriginButton->setEnabled(foundImageVolume); m_Controls->m_CropImageButton->setEnabled(foundImageVolume); m_Controls->m_RemoveGradientButton->setEnabled(foundDwiVolume); m_Controls->m_ExtractGradientButton->setEnabled(foundDwiVolume); // reset sampling frame to 1 and update all ealted components m_Controls->m_B_ValueMap_Rounder_SpinBox->setValue(1); UpdateBValueTableWidget(m_Controls->m_B_ValueMap_Rounder_SpinBox->value()); DoUpdateInterpolationGui(m_Controls->m_ResampleTypeBox->currentIndex()); if (foundDwiVolume) { m_Controls->m_InputData->setTitle("Input Data"); vnl_matrix_fixed< double, 3, 3 > mf = m_DiffusionImage->GetMeasurementFrame(); for (int r=0; r<3; r++) for (int c=0; c<3; c++) { // Measurement frame { QTableWidgetItem* item = m_Controls->m_MeasurementFrameTable->item(r,c); delete item; item = new QTableWidgetItem(); item->setTextAlignment(Qt::AlignCenter | Qt::AlignVCenter); item->setText(QString::number(mf.get(r,c))); m_Controls->m_MeasurementFrameTable->setItem(r,c,item); } // Direction matrix { QTableWidgetItem* item = m_Controls->m_DirectionMatrixTable->item(r,c); delete item; item = new QTableWidgetItem(); item->setTextAlignment(Qt::AlignCenter | Qt::AlignVCenter); item->setText(QString::number(m_DiffusionImage->GetVectorImage()->GetDirection()[r][c])); m_Controls->m_DirectionMatrixTable->setItem(r,c,item); } } //calculate target bValue for MultishellToSingleShellfilter const mitk::DiffusionImage::BValueMap & bValMap = m_DiffusionImage->GetBValueMap(); mitk::DiffusionImage::BValueMap::const_iterator it = bValMap.begin(); unsigned int targetBVal = 0; while(it != bValMap.end()) targetBVal += (it++)->first; targetBVal /= (float)bValMap.size()-1; m_Controls->m_targetBValueSpinBox->setValue(targetBVal); m_Controls->m_HeaderSpacingX->setValue(m_DiffusionImage->GetGeometry()->GetSpacing()[0]); m_Controls->m_HeaderSpacingY->setValue(m_DiffusionImage->GetGeometry()->GetSpacing()[1]); m_Controls->m_HeaderSpacingZ->setValue(m_DiffusionImage->GetGeometry()->GetSpacing()[2]); m_Controls->m_HeaderOriginX->setValue(m_DiffusionImage->GetGeometry()->GetOrigin()[0]); m_Controls->m_HeaderOriginY->setValue(m_DiffusionImage->GetGeometry()->GetOrigin()[1]); m_Controls->m_HeaderOriginZ->setValue(m_DiffusionImage->GetGeometry()->GetOrigin()[2]); m_Controls->m_XstartBox->setMaximum(m_DiffusionImage->GetGeometry()->GetExtent(0)-1); m_Controls->m_YstartBox->setMaximum(m_DiffusionImage->GetGeometry()->GetExtent(1)-1); m_Controls->m_ZstartBox->setMaximum(m_DiffusionImage->GetGeometry()->GetExtent(2)-1); m_Controls->m_XendBox->setMaximum(m_DiffusionImage->GetGeometry()->GetExtent(0)-1); m_Controls->m_YendBox->setMaximum(m_DiffusionImage->GetGeometry()->GetExtent(1)-1); m_Controls->m_ZendBox->setMaximum(m_DiffusionImage->GetGeometry()->GetExtent(2)-1); m_Controls->m_RemoveGradientBox->setMaximum(m_DiffusionImage->GetDirections()->Size()-1); m_Controls->m_ExtractGradientBox->setMaximum(m_DiffusionImage->GetDirections()->Size()-1); } else if (foundImageVolume) { for (int r=0; r<3; r++) for (int c=0; c<3; c++) { QTableWidgetItem* item = m_Controls->m_MeasurementFrameTable->item(r,c); delete item; item = new QTableWidgetItem(); m_Controls->m_MeasurementFrameTable->setItem(r,c,item); } m_Controls->m_HeaderSpacingX->setValue(m_SelectedImage->GetGeometry()->GetSpacing()[0]); m_Controls->m_HeaderSpacingY->setValue(m_SelectedImage->GetGeometry()->GetSpacing()[1]); m_Controls->m_HeaderSpacingZ->setValue(m_SelectedImage->GetGeometry()->GetSpacing()[2]); m_Controls->m_HeaderOriginX->setValue(m_SelectedImage->GetGeometry()->GetOrigin()[0]); m_Controls->m_HeaderOriginY->setValue(m_SelectedImage->GetGeometry()->GetOrigin()[1]); m_Controls->m_HeaderOriginZ->setValue(m_SelectedImage->GetGeometry()->GetOrigin()[2]); m_Controls->m_XstartBox->setMaximum(m_SelectedImage->GetGeometry()->GetExtent(0)-1); m_Controls->m_YstartBox->setMaximum(m_SelectedImage->GetGeometry()->GetExtent(1)-1); m_Controls->m_ZstartBox->setMaximum(m_SelectedImage->GetGeometry()->GetExtent(2)-1); m_Controls->m_XendBox->setMaximum(m_SelectedImage->GetGeometry()->GetExtent(0)-1); m_Controls->m_YendBox->setMaximum(m_SelectedImage->GetGeometry()->GetExtent(1)-1); m_Controls->m_ZendBox->setMaximum(m_SelectedImage->GetGeometry()->GetExtent(2)-1); AccessFixedDimensionByItk(m_SelectedImage, TemplatedUpdateGui,3); } else { for (int r=0; r<3; r++) for (int c=0; c<3; c++) { { QTableWidgetItem* item = m_Controls->m_MeasurementFrameTable->item(r,c); delete item; item = new QTableWidgetItem(); m_Controls->m_MeasurementFrameTable->setItem(r,c,item); } { QTableWidgetItem* item = m_Controls->m_DirectionMatrixTable->item(r,c); delete item; item = new QTableWidgetItem(); m_Controls->m_DirectionMatrixTable->setItem(r,c,item); } } m_Controls->m_DiffusionImageLabel->setText("mandatory"); m_Controls->m_InputData->setTitle("Please Select Input Data"); } } void QmitkPreprocessingView::Activated() { QmitkFunctionality::Activated(); } void QmitkPreprocessingView::Deactivated() { QmitkFunctionality::Deactivated(); } void QmitkPreprocessingView::DoHalfSphereGradientDirections() { MitkDwiType::Pointer newDwi = m_DiffusionImage->Clone(); GradientDirectionContainerType::Pointer gradientContainer = newDwi->GetDirections(); for (unsigned int j=0; jSize(); j++) if (gradientContainer->at(j)[0]<0) gradientContainer->at(j) = -gradientContainer->at(j); newDwi->SetDirections(gradientContainer); mitk::DataNode::Pointer imageNode = mitk::DataNode::New(); imageNode->SetData( newDwi ); QString name = m_SelectedDiffusionNodes.back()->GetName().c_str(); imageNode->SetName((name+"_halfsphere").toStdString().c_str()); GetDefaultDataStorage()->Add(imageNode, m_SelectedDiffusionNodes.back()); } void QmitkPreprocessingView::DoApplyMesurementFrame() { if (m_DiffusionImage.IsNull()) return; vnl_matrix_fixed< double, 3, 3 > mf; for (int r=0; r<3; r++) for (int c=0; c<3; c++) { QTableWidgetItem* item = m_Controls->m_MeasurementFrameTable->item(r,c); if (!item) return; mf[r][c] = item->text().toDouble(); } MitkDwiType::Pointer newDwi = m_DiffusionImage->Clone(); newDwi->SetMeasurementFrame(mf); mitk::DataNode::Pointer imageNode = mitk::DataNode::New(); imageNode->SetData( newDwi ); QString name = m_SelectedDiffusionNodes.back()->GetName().c_str(); imageNode->SetName((name+"_new-MF").toStdString().c_str()); GetDefaultDataStorage()->Add(imageNode, m_SelectedDiffusionNodes.back()); } void QmitkPreprocessingView::DoShowGradientDirections() { if (m_DiffusionImage.IsNull()) return; int maxIndex = 0; unsigned int maxSize = m_DiffusionImage->GetDimension(0); if (maxSizeGetDimension(1)) { maxSize = m_DiffusionImage->GetDimension(1); maxIndex = 1; } if (maxSizeGetDimension(2)) { maxSize = m_DiffusionImage->GetDimension(2); maxIndex = 2; } mitk::Point3D origin = m_DiffusionImage->GetGeometry()->GetOrigin(); mitk::PointSet::Pointer originSet = mitk::PointSet::New(); typedef mitk::DiffusionImage::BValueMap BValueMap; typedef mitk::DiffusionImage::BValueMap::iterator BValueMapIterator; BValueMap bValMap = m_DiffusionImage->GetBValueMap(); GradientDirectionContainerType::Pointer gradientContainer = m_DiffusionImage->GetDirections(); mitk::BaseGeometry::Pointer geometry = m_DiffusionImage->GetGeometry(); int shellCount = 1; for(BValueMapIterator it = bValMap.begin(); it!=bValMap.end(); ++it) { mitk::PointSet::Pointer pointset = mitk::PointSet::New(); for (unsigned int j=0; jsecond.size(); j++) { mitk::Point3D ip; vnl_vector_fixed< double, 3 > v = gradientContainer->at(it->second[j]); if (v.magnitude()>mitk::eps) { ip[0] = v[0]*maxSize*geometry->GetSpacing()[maxIndex]/2 + origin[0]-0.5*geometry->GetSpacing()[0] + geometry->GetSpacing()[0]*m_DiffusionImage->GetDimension(0)/2; ip[1] = v[1]*maxSize*geometry->GetSpacing()[maxIndex]/2 + origin[1]-0.5*geometry->GetSpacing()[1] + geometry->GetSpacing()[1]*m_DiffusionImage->GetDimension(1)/2; ip[2] = v[2]*maxSize*geometry->GetSpacing()[maxIndex]/2 + origin[2]-0.5*geometry->GetSpacing()[2] + geometry->GetSpacing()[2]*m_DiffusionImage->GetDimension(2)/2; pointset->InsertPoint(j, ip); } else if (originSet->IsEmpty()) { ip[0] = v[0]*maxSize*geometry->GetSpacing()[maxIndex]/2 + origin[0]-0.5*geometry->GetSpacing()[0] + geometry->GetSpacing()[0]*m_DiffusionImage->GetDimension(0)/2; ip[1] = v[1]*maxSize*geometry->GetSpacing()[maxIndex]/2 + origin[1]-0.5*geometry->GetSpacing()[1] + geometry->GetSpacing()[1]*m_DiffusionImage->GetDimension(1)/2; ip[2] = v[2]*maxSize*geometry->GetSpacing()[maxIndex]/2 + origin[2]-0.5*geometry->GetSpacing()[2] + geometry->GetSpacing()[2]*m_DiffusionImage->GetDimension(2)/2; originSet->InsertPoint(j, ip); } } if (it->firstSetData(pointset); QString name = m_SelectedDiffusionNodes.front()->GetName().c_str(); name += "_Shell_"; name += QString::number(it->first); node->SetName(name.toStdString().c_str()); node->SetProperty("pointsize", mitk::FloatProperty::New((float)maxSize/50)); int b0 = shellCount%2; int b1 = 0; int b2 = 0; if (shellCount>4) b2 = 1; if (shellCount%4 >= 2) b1 = 1; node->SetProperty("color", mitk::ColorProperty::New(b2, b1, b0)); GetDefaultDataStorage()->Add(node, m_SelectedDiffusionNodes.front()); shellCount++; } // add origin to datastorage mitk::DataNode::Pointer node = mitk::DataNode::New(); node->SetData(originSet); QString name = m_SelectedDiffusionNodes.front()->GetName().c_str(); name += "_Origin"; node->SetName(name.toStdString().c_str()); node->SetProperty("pointsize", mitk::FloatProperty::New((float)maxSize/50)); node->SetProperty("color", mitk::ColorProperty::New(1,1,1)); GetDefaultDataStorage()->Add(node, m_SelectedDiffusionNodes.front()); } void QmitkPreprocessingView::DoReduceGradientDirections() { if (m_DiffusionImage.IsNull()) return; typedef mitk::DiffusionImage DiffusionImageType; typedef itk::ElectrostaticRepulsionDiffusionGradientReductionFilter FilterType; typedef DiffusionImageType::BValueMap BValueMap; // GetShellSelection from GUI BValueMap shellSlectionMap; BValueMap originalShellMap = m_DiffusionImage->GetBValueMap(); std::vector newNumGradientDirections; int shellCounter = 0; QString name = m_SelectedDiffusionNodes.front()->GetName().c_str(); for (int i=0; im_B_ValueMap_TableWidget->rowCount(); i++) { double BValue = m_Controls->m_B_ValueMap_TableWidget->item(i,0)->text().toDouble(); shellSlectionMap[BValue] = originalShellMap[BValue]; unsigned int num = m_Controls->m_B_ValueMap_TableWidget->item(i,1)->text().toUInt(); newNumGradientDirections.push_back(num); name += "_"; name += QString::number(num); shellCounter++; } if (newNumGradientDirections.empty()) return; GradientDirectionContainerType::Pointer gradientContainer = m_DiffusionImage->GetDirections(); FilterType::Pointer filter = FilterType::New(); filter->SetInput(m_DiffusionImage->GetVectorImage()); filter->SetOriginalGradientDirections(gradientContainer); filter->SetNumGradientDirections(newNumGradientDirections); filter->SetOriginalBValueMap(originalShellMap); filter->SetShellSelectionBValueMap(shellSlectionMap); filter->Update(); DiffusionImageType::Pointer image = DiffusionImageType::New(); image->SetVectorImage( filter->GetOutput() ); image->SetReferenceBValue(m_DiffusionImage->GetReferenceBValue()); image->SetDirections(filter->GetGradientDirections()); image->SetMeasurementFrame(m_DiffusionImage->GetMeasurementFrame()); image->InitializeFromVectorImage(); mitk::DataNode::Pointer imageNode = mitk::DataNode::New(); imageNode->SetData( image ); imageNode->SetName(name.toStdString().c_str()); GetDefaultDataStorage()->Add(imageNode, m_SelectedDiffusionNodes.back()); } void QmitkPreprocessingView::MergeDwis() { typedef mitk::DiffusionImage DiffusionImageType; typedef DiffusionImageType::GradientDirectionContainerType GradientContainerType; if (m_SelectedDiffusionNodes.size()<2) return; typedef itk::VectorImage DwiImageType; typedef DwiImageType::PixelType DwiPixelType; typedef DwiImageType::RegionType DwiRegionType; typedef std::vector< DwiImageType::Pointer > DwiImageContainerType; typedef std::vector< GradientContainerType::Pointer > GradientListContainerType; DwiImageContainerType imageContainer; GradientListContainerType gradientListContainer; std::vector< double > bValueContainer; QString name = m_SelectedDiffusionNodes.front()->GetName().c_str(); for (unsigned int i=0; i* >( m_SelectedDiffusionNodes.at(i)->GetData() ); if ( dwi.IsNotNull() ) { imageContainer.push_back(dwi->GetVectorImage()); gradientListContainer.push_back(dwi->GetDirections()); bValueContainer.push_back(dwi->GetReferenceBValue()); if (i>0) { name += "+"; name += m_SelectedDiffusionNodes.at(i)->GetName().c_str(); } } } typedef itk::MergeDiffusionImagesFilter FilterType; FilterType::Pointer filter = FilterType::New(); filter->SetImageVolumes(imageContainer); filter->SetGradientLists(gradientListContainer); filter->SetBValues(bValueContainer); filter->Update(); vnl_matrix_fixed< double, 3, 3 > mf; mf.set_identity(); DiffusionImageType::Pointer image = DiffusionImageType::New(); image->SetVectorImage( filter->GetOutput() ); image->SetReferenceBValue(filter->GetB_Value()); image->SetDirections(filter->GetOutputGradients()); image->SetMeasurementFrame(mf); image->InitializeFromVectorImage(); mitk::DataNode::Pointer imageNode = mitk::DataNode::New(); imageNode->SetData( image ); imageNode->SetName(name.toStdString().c_str()); GetDefaultDataStorage()->Add(imageNode); } void QmitkPreprocessingView::ExtractB0() { typedef mitk::DiffusionImage DiffusionImageType; typedef DiffusionImageType::GradientDirectionContainerType GradientContainerType; int nrFiles = m_SelectedDiffusionNodes.size(); if (!nrFiles) return; // call the extraction withou averaging if the check-box is checked if( this->m_Controls->m_CheckExtractAll->isChecked() ) { DoExtractBOWithoutAveraging(); return; } mitk::DataStorage::SetOfObjects::const_iterator itemiter( m_SelectedDiffusionNodes.begin() ); mitk::DataStorage::SetOfObjects::const_iterator itemiterend( m_SelectedDiffusionNodes.end() ); std::vector nodes; while ( itemiter != itemiterend ) // for all items { DiffusionImageType* vols = static_cast( (*itemiter)->GetData()); std::string nodename; (*itemiter)->GetStringProperty("name", nodename); // Extract image using found index typedef itk::B0ImageExtractionImageFilter FilterType; FilterType::Pointer filter = FilterType::New(); filter->SetInput(vols->GetVectorImage()); filter->SetDirections(vols->GetDirections()); filter->Update(); mitk::Image::Pointer mitkImage = mitk::Image::New(); mitkImage->InitializeByItk( filter->GetOutput() ); mitkImage->SetVolume( filter->GetOutput()->GetBufferPointer() ); mitk::DataNode::Pointer node=mitk::DataNode::New(); node->SetData( mitkImage ); node->SetProperty( "name", mitk::StringProperty::New(nodename + "_B0")); GetDefaultDataStorage()->Add(node, (*itemiter)); ++itemiter; } } void QmitkPreprocessingView::DoExtractBOWithoutAveraging() { // typedefs typedef mitk::DiffusionImage DiffusionImageType; typedef DiffusionImageType::GradientDirectionContainerType GradientContainerType; typedef itk::B0ImageExtractionToSeparateImageFilter< short, short> FilterType; // check number of selected objects, return if empty int nrFiles = m_SelectedDiffusionNodes.size(); if (!nrFiles) return; mitk::DataStorage::SetOfObjects::const_iterator itemiter( m_SelectedDiffusionNodes.begin() ); mitk::DataStorage::SetOfObjects::const_iterator itemiterend( m_SelectedDiffusionNodes.end() ); while ( itemiter != itemiterend ) // for all items { DiffusionImageType* vols = static_cast( (*itemiter)->GetData()); std::string nodename; (*itemiter)->GetStringProperty("name", nodename); // Extract image using found index FilterType::Pointer filter = FilterType::New(); filter->SetInput(vols->GetVectorImage()); filter->SetDirections(vols->GetDirections()); filter->Update(); mitk::Image::Pointer mitkImage = mitk::Image::New(); mitkImage->InitializeByItk( filter->GetOutput() ); mitkImage->SetImportChannel( filter->GetOutput()->GetBufferPointer() ); mitk::DataNode::Pointer node=mitk::DataNode::New(); node->SetData( mitkImage ); node->SetProperty( "name", mitk::StringProperty::New(nodename + "_B0_ALL")); GetDefaultDataStorage()->Add(node, (*itemiter)); /*A reinitialization is needed to access the time channels via the ImageNavigationController The Global-Geometry can not recognize the time channel without a re-init. (for a new selection in datamanger a automatically updated of the Global-Geometry should be done - if it contains the time channel)*/ mitk::RenderingManager::GetInstance()->InitializeViews(node->GetData()->GetTimeGeometry(),mitk::RenderingManager::REQUEST_UPDATE_ALL, true); ++itemiter; } } void QmitkPreprocessingView::AverageGradients() { int nrFiles = m_SelectedDiffusionNodes.size(); if (!nrFiles) return; mitk::DataStorage::SetOfObjects::const_iterator itemiter( m_SelectedDiffusionNodes.begin() ); mitk::DataStorage::SetOfObjects::const_iterator itemiterend( m_SelectedDiffusionNodes.end() ); while ( itemiter != itemiterend ) // for all items { mitk::DiffusionImage* mitkDwi = static_cast*>( (*itemiter)->GetData()); MitkDwiType::Pointer newDwi = mitkDwi->Clone(); newDwi->AverageRedundantGradients(m_Controls->m_Blur->value()); mitk::DataNode::Pointer imageNode = mitk::DataNode::New(); imageNode->SetData( newDwi ); QString name = (*itemiter)->GetName().c_str(); imageNode->SetName((name+"_averaged").toStdString().c_str()); GetDefaultDataStorage()->Add(imageNode, (*itemiter)); ++itemiter; } } diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkQBallReconstructionView.cpp b/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkQBallReconstructionView.cpp index c1f42bf379..32e86ab070 100644 --- a/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkQBallReconstructionView.cpp +++ b/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkQBallReconstructionView.cpp @@ -1,1086 +1,1086 @@ /*=================================================================== 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. ===================================================================*/ //#define MBILOG_ENABLE_DEBUG #include "QmitkQBallReconstructionView.h" #include "mitkDiffusionImagingConfigure.h" // qt includes #include // itk includes #include "itkTimeProbe.h" // mitk includes #include "mitkProgressBar.h" #include "mitkStatusBar.h" #include "mitkNodePredicateDataType.h" #include "QmitkDataStorageComboBox.h" #include "QmitkStdMultiWidget.h" #include "itkDiffusionQballReconstructionImageFilter.h" #include "itkAnalyticalDiffusionQballReconstructionImageFilter.h" #include "itkDiffusionMultiShellQballReconstructionImageFilter.h" #include "itkVectorContainer.h" #include "itkB0ImageExtractionImageFilter.h" #include #include "mitkQBallImage.h" #include "mitkProperties.h" #include "mitkVtkResliceInterpolationProperty.h" #include "mitkLookupTable.h" #include "mitkLookupTableProperty.h" #include "mitkTransferFunction.h" #include "mitkTransferFunctionProperty.h" #include "mitkDataNodeObject.h" #include "mitkOdfNormalizationMethodProperty.h" #include "mitkOdfScaleByProperty.h" #include "berryIStructuredSelection.h" #include "berryIWorkbenchWindow.h" #include "berryISelectionService.h" #include const std::string QmitkQBallReconstructionView::VIEW_ID = "org.mitk.views.qballreconstruction"; typedef float TTensorPixelType; const int QmitkQBallReconstructionView::nrconvkernels = 252; struct QbrShellSelection { QmitkQBallReconstructionView* m_View; mitk::DataNode * m_Node; std::string m_NodeName; std::vector m_CheckBoxes; QLabel * m_Label; mitk::DiffusionImage * m_Image; typedef mitk::DiffusionImage::BValueMap BValueMap; QbrShellSelection(QmitkQBallReconstructionView* view, mitk::DataNode * node) : m_View(view), m_Node(node), m_NodeName(node->GetName()) { m_Image = dynamic_cast * > (node->GetData()); if(!m_Image){MITK_INFO << "QmitkQBallReconstructionView::QbrShellSelection : fail to initialize DiffusionImage "; return;} GenerateCheckboxes(); } void GenerateCheckboxes() { BValueMap origMap = m_Image->GetBValueMap(); BValueMap::iterator itStart = origMap.begin(); itStart++; BValueMap::iterator itEnd = origMap.end(); m_Label = new QLabel(m_NodeName.c_str()); m_Label->setVisible(true); m_View->m_Controls->m_QBallSelectionBox->layout()->addWidget(m_Label); for(BValueMap::iterator it = itStart ; it!= itEnd; it++) { QCheckBox * box = new QCheckBox(QString::number(it->first)); m_View->m_Controls->m_QBallSelectionBox->layout()->addWidget(box); box->setChecked(true); box->setCheckable(true); // box->setVisible(true); m_CheckBoxes.push_back(box); } } void SetVisible(bool vis) { foreach(QCheckBox * box, m_CheckBoxes) { box->setVisible(vis); } } BValueMap GetBValueSelctionMap() { BValueMap inputMap = m_Image->GetBValueMap(); BValueMap outputMap; unsigned int val = 0; if(inputMap.find(0) == inputMap.end()){ MITK_INFO << "QbrShellSelection: return empty BValueMap from GUI Selection"; return outputMap; }else{ outputMap[val] = inputMap[val]; MITK_INFO << val; } foreach(QCheckBox * box, m_CheckBoxes) { if(box->isChecked()){ val = box->text().toDouble(); outputMap[val] = inputMap[val]; MITK_INFO << val; } } return outputMap; } ~QbrShellSelection() { m_View->m_Controls->m_QBallSelectionBox->layout()->removeWidget(m_Label); delete m_Label; for(std::vector::iterator it = m_CheckBoxes.begin() ; it!= m_CheckBoxes.end(); it++) { m_View->m_Controls->m_QBallSelectionBox->layout()->removeWidget((*it)); delete (*it); } m_CheckBoxes.clear(); } }; using namespace berry; struct QbrSelListener : ISelectionListener { berryObjectMacro(QbrSelListener); QbrSelListener(QmitkQBallReconstructionView* view) { m_View = view; } void DoSelectionChanged(ISelection::ConstPointer selection) { // save current selection in member variable m_View->m_CurrentSelection = selection.Cast(); // do something with the selected items if(m_View->m_CurrentSelection) { bool foundDwiVolume = false; m_View->m_Controls->m_DiffusionImageLabel->setText("mandatory"); m_View->m_Controls->m_InputData->setTitle("Please Select Input Data"); QString selected_images = ""; mitk::DataStorage::SetOfObjects::Pointer set = mitk::DataStorage::SetOfObjects::New(); int at = 0; // iterate selection for (IStructuredSelection::iterator i = m_View->m_CurrentSelection->Begin(); i != m_View->m_CurrentSelection->End(); ++i) { // extract datatree node if (mitk::DataNodeObject::Pointer nodeObj = i->Cast()) { mitk::DataNode::Pointer node = nodeObj->GetDataNode(); mitk::DiffusionImage* diffusionImage = dynamic_cast * >(node->GetData()); // only look at interesting types if(diffusionImage) { foundDwiVolume = true; selected_images += QString(node->GetName().c_str()); if(i + 1 != m_View->m_CurrentSelection->End()) selected_images += "\n"; set->InsertElement(at++, node); } } } m_View->GenerateShellSelectionUI(set); m_View->m_Controls->m_DiffusionImageLabel->setText(selected_images); m_View->m_Controls->m_ButtonStandard->setEnabled(foundDwiVolume); if (foundDwiVolume) m_View->m_Controls->m_InputData->setTitle("Input Data"); else m_View->m_Controls->m_DiffusionImageLabel->setText("mandatory"); } } void SelectionChanged(IWorkbenchPart::Pointer part, ISelection::ConstPointer selection) { // check, if selection comes from datamanager if (part) { QString partname(part->GetPartName().c_str()); if(partname.compare("Data Manager")==0) { // apply selection DoSelectionChanged(selection); } } } QmitkQBallReconstructionView* m_View; }; // --------------- QmitkQBallReconstructionView----------------- // QmitkQBallReconstructionView::QmitkQBallReconstructionView() : QmitkFunctionality(), m_Controls(NULL), m_MultiWidget(NULL) { } QmitkQBallReconstructionView::~QmitkQBallReconstructionView() { this->GetSite()->GetWorkbenchWindow()->GetSelectionService()->RemovePostSelectionListener(/*"org.mitk.views.datamanager",*/ m_SelListener); } void QmitkQBallReconstructionView::CreateQtPartControl(QWidget *parent) { if (!m_Controls) { // create GUI widgets m_Controls = new Ui::QmitkQBallReconstructionViewControls; m_Controls->setupUi(parent); this->CreateConnections(); m_Controls->m_DiffusionImageLabel->setText("mandatory"); QStringList items; items << "2" << "4" << "6" << "8" << "10" << "12"; m_Controls->m_QBallReconstructionMaxLLevelComboBox->addItems(items); m_Controls->m_QBallReconstructionMaxLLevelComboBox->setCurrentIndex(1); MethodChoosen(m_Controls->m_QBallReconstructionMethodComboBox->currentIndex()); #ifndef DIFFUSION_IMAGING_EXTENDED m_Controls->m_QBallReconstructionMethodComboBox->removeItem(3); #endif AdvancedCheckboxClicked(); } m_SelListener = berry::ISelectionListener::Pointer(new QbrSelListener(this)); this->GetSite()->GetWorkbenchWindow()->GetSelectionService()->AddPostSelectionListener(/*"org.mitk.views.datamanager",*/ m_SelListener); berry::ISelection::ConstPointer sel( this->GetSite()->GetWorkbenchWindow()->GetSelectionService()->GetSelection("org.mitk.views.datamanager")); m_CurrentSelection = sel.Cast(); m_SelListener.Cast()->DoSelectionChanged(sel); } void QmitkQBallReconstructionView::StdMultiWidgetAvailable (QmitkStdMultiWidget &stdMultiWidget) { m_MultiWidget = &stdMultiWidget; } void QmitkQBallReconstructionView::StdMultiWidgetNotAvailable() { m_MultiWidget = NULL; } void QmitkQBallReconstructionView::CreateConnections() { if ( m_Controls ) { connect( (QObject*)(m_Controls->m_ButtonStandard), SIGNAL(clicked()), this, SLOT(ReconstructStandard()) ); connect( (QObject*)(m_Controls->m_AdvancedCheckbox), SIGNAL(clicked()), this, SLOT(AdvancedCheckboxClicked()) ); connect( (QObject*)(m_Controls->m_QBallReconstructionMethodComboBox), SIGNAL(currentIndexChanged(int)), this, SLOT(MethodChoosen(int)) ); connect( (QObject*)(m_Controls->m_QBallReconstructionThreasholdEdit), SIGNAL(valueChanged(int)), this, SLOT(PreviewThreshold(int)) ); } } void QmitkQBallReconstructionView::OnSelectionChanged( std::vector ) { } void QmitkQBallReconstructionView::Activated() { QmitkFunctionality::Activated(); berry::ISelection::ConstPointer sel( this->GetSite()->GetWorkbenchWindow()->GetSelectionService()->GetSelection("org.mitk.views.datamanager")); m_CurrentSelection = sel.Cast(); m_SelListener.Cast()->DoSelectionChanged(sel); } void QmitkQBallReconstructionView::Deactivated() { mitk::DataStorage::SetOfObjects::ConstPointer objects = this->GetDefaultDataStorage()->GetAll(); mitk::DataStorage::SetOfObjects::const_iterator itemiter( objects->begin() ); mitk::DataStorage::SetOfObjects::const_iterator itemiterend( objects->end() ); while ( itemiter != itemiterend ) // for all items { mitk::DataNode::Pointer node = *itemiter; if (node.IsNull()) continue; // only look at interesting types if(dynamic_cast*>(node->GetData())) { if (this->GetDefaultDataStorage()->GetNamedDerivedNode("ThresholdOverlay", *itemiter)) { node = this->GetDefaultDataStorage()->GetNamedDerivedNode("ThresholdOverlay", *itemiter); this->GetDefaultDataStorage()->Remove(node); } } itemiter++; } mitk::RenderingManager::GetInstance()->RequestUpdateAll(); QmitkFunctionality::Deactivated(); } void QmitkQBallReconstructionView::ReconstructStandard() { int index = m_Controls->m_QBallReconstructionMethodComboBox->currentIndex(); #ifndef DIFFUSION_IMAGING_EXTENDED if(index>=3) { index = index + 1; } #endif switch(index) { case 0: { // Numerical Reconstruct(0,0); break; } case 1: { // Standard Reconstruct(1,0); break; } case 2: { // Solid Angle Reconstruct(1,6); break; } case 3: { // Constrained Solid Angle Reconstruct(1,7); break; } case 4: { // ADC Reconstruct(1,4); break; } case 5: { // Raw Signal Reconstruct(1,5); break; } case 6: { // Q-Ball reconstruction Reconstruct(2,0); break; } } } void QmitkQBallReconstructionView::MethodChoosen(int method) { #ifndef DIFFUSION_IMAGING_EXTENDED if(method>=3) { method = method + 1; } #endif m_Controls->m_QBallSelectionBox->setHidden(true); m_Controls->m_OutputCoeffsImage->setHidden(true); if (method==0) m_Controls->m_ShFrame->setVisible(false); else m_Controls->m_ShFrame->setVisible(true); switch(method) { case 0: m_Controls->m_Description->setText("Numerical recon. (Tuch 2004)"); break; case 1: m_Controls->m_Description->setText("Spherical harmonics recon. (Descoteaux 2007)"); m_Controls->m_OutputCoeffsImage->setHidden(false); break; case 2: m_Controls->m_Description->setText("SH recon. with solid angle consideration (Aganj 2009)"); m_Controls->m_OutputCoeffsImage->setHidden(false); break; case 3: m_Controls->m_Description->setText("SH solid angle with non-neg. constraint (Goh 2009)"); break; case 4: m_Controls->m_Description->setText("SH recon. of the plain ADC-profiles"); break; case 5: m_Controls->m_Description->setText("SH recon. of the raw diffusion signal"); break; case 6: m_Controls->m_Description->setText("SH recon. of the multi shell diffusion signal (Aganj 2010)"); m_Controls->m_QBallSelectionBox->setHidden(false); m_Controls->m_OutputCoeffsImage->setHidden(false); break; } } void QmitkQBallReconstructionView::AdvancedCheckboxClicked() { bool check = m_Controls->m_AdvancedCheckbox->isChecked(); m_Controls->m_QBallReconstructionMaxLLevelTextLabel_2->setVisible(check); m_Controls->m_QBallReconstructionMaxLLevelComboBox->setVisible(check); m_Controls->m_QBallReconstructionLambdaTextLabel_2->setVisible(check); m_Controls->m_QBallReconstructionLambdaLineEdit->setVisible(check); m_Controls->m_QBallReconstructionThresholdLabel_2->setVisible(check); m_Controls->m_QBallReconstructionThreasholdEdit->setVisible(check); m_Controls->label_2->setVisible(check); m_Controls->frame_2->setVisible(check); } void QmitkQBallReconstructionView::Reconstruct(int method, int normalization) { if (m_CurrentSelection) { mitk::DataStorage::SetOfObjects::Pointer set = mitk::DataStorage::SetOfObjects::New(); int at = 0; for (IStructuredSelection::iterator i = m_CurrentSelection->Begin(); i != m_CurrentSelection->End(); ++i) { if (mitk::DataNodeObject::Pointer nodeObj = i->Cast()) { mitk::DataNode::Pointer node = nodeObj->GetDataNode(); if(QString("DiffusionImage").compare(node->GetData()->GetNameOfClass())==0) { set->InsertElement(at++, node); } } } if(method == 0) { NumericalQBallReconstruction(set, normalization); } else { #if BOOST_VERSION / 100000 > 0 #if BOOST_VERSION / 100 % 1000 > 34 if(method == 1) { AnalyticalQBallReconstruction(set, normalization); } if(method == 2) { MultiQBallReconstruction(set); } #else std::cout << "ERROR: Boost 1.35 minimum required" << std::endl; QMessageBox::warning(NULL,"ERROR","Boost 1.35 minimum required"); #endif #else std::cout << "ERROR: Boost 1.35 minimum required" << std::endl; QMessageBox::warning(NULL,"ERROR","Boost 1.35 minimum required"); #endif } } } void QmitkQBallReconstructionView::NumericalQBallReconstruction (mitk::DataStorage::SetOfObjects::Pointer inImages, int normalization) { try { itk::TimeProbe clock; int nrFiles = inImages->size(); if (!nrFiles) return; QString status; mitk::ProgressBar::GetInstance()->AddStepsToDo(nrFiles); mitk::DataStorage::SetOfObjects::const_iterator itemiter( inImages->begin() ); mitk::DataStorage::SetOfObjects::const_iterator itemiterend( inImages->end() ); while ( itemiter != itemiterend ) // for all items { mitk::DiffusionImage* vols = static_cast*>( (*itemiter)->GetData()); std::string nodename; (*itemiter)->GetStringProperty("name", nodename); // QBALL RECONSTRUCTION clock.Start(); MITK_INFO << "QBall reconstruction "; mitk::StatusBar::GetInstance()->DisplayText(status.sprintf( - "QBall reconstruction for %s", nodename.c_str()).toAscii()); + "QBall reconstruction for %s", nodename.c_str()).toLatin1()); typedef itk::DiffusionQballReconstructionImageFilter QballReconstructionImageFilterType; QballReconstructionImageFilterType::Pointer filter = QballReconstructionImageFilterType::New(); filter->SetGradientImage( vols->GetDirections(), vols->GetVectorImage() ); filter->SetBValue(vols->GetReferenceBValue()); filter->SetThreshold( m_Controls->m_QBallReconstructionThreasholdEdit->value() ); std::string nodePostfix; switch(normalization) { case 0: { filter->SetNormalizationMethod(QballReconstructionImageFilterType::QBR_STANDARD); nodePostfix = "_Numerical_Qball"; break; } case 1: { filter->SetNormalizationMethod(QballReconstructionImageFilterType::QBR_B_ZERO_B_VALUE); nodePostfix = "_Numerical_ZeroBvalueNormalization_Qball"; break; } case 2: { filter->SetNormalizationMethod(QballReconstructionImageFilterType::QBR_B_ZERO); nodePostfix = "_NumericalQball_ZeroNormalization_Qball"; break; } case 3: { filter->SetNormalizationMethod(QballReconstructionImageFilterType::QBR_NONE); nodePostfix = "_NumericalQball_NoNormalization_Qball"; break; } default: { filter->SetNormalizationMethod(QballReconstructionImageFilterType::QBR_STANDARD); nodePostfix = "_NumericalQball_Qball"; } } filter->Update(); clock.Stop(); MITK_DEBUG << "took " << clock.GetMean() << "s." ; // ODFs TO DATATREE mitk::QBallImage::Pointer image = mitk::QBallImage::New(); image->InitializeByItk( filter->GetOutput() ); image->SetVolume( filter->GetOutput()->GetBufferPointer() ); mitk::DataNode::Pointer node=mitk::DataNode::New(); node->SetData( image ); SetDefaultNodeProperties(node, nodename+nodePostfix); mitk::ProgressBar::GetInstance()->Progress(); GetDefaultDataStorage()->Add(node, *itemiter); ++itemiter; } - mitk::StatusBar::GetInstance()->DisplayText(status.sprintf("Finished Processing %d Files", nrFiles).toAscii()); + mitk::StatusBar::GetInstance()->DisplayText(status.sprintf("Finished Processing %d Files", nrFiles).toLatin1()); m_MultiWidget->RequestUpdate(); } catch (itk::ExceptionObject &ex) { MITK_INFO << ex ; QMessageBox::information(0, "Reconstruction not possible:", ex.GetDescription()); return ; } } void QmitkQBallReconstructionView::AnalyticalQBallReconstruction( mitk::DataStorage::SetOfObjects::Pointer inImages, int normalization) { try { itk::TimeProbe clock; int nrFiles = inImages->size(); if (!nrFiles) return; std::vector lambdas; float minLambda = m_Controls->m_QBallReconstructionLambdaLineEdit->value(); lambdas.push_back(minLambda); int nLambdas = lambdas.size(); QString status; mitk::ProgressBar::GetInstance()->AddStepsToDo(nrFiles*nLambdas); mitk::DataStorage::SetOfObjects::const_iterator itemiter( inImages->begin() ); mitk::DataStorage::SetOfObjects::const_iterator itemiterend( inImages->end() ); std::vector* nodes = new std::vector(); while ( itemiter != itemiterend ) // for all items { // QBALL RECONSTRUCTION clock.Start(); MITK_INFO << "QBall reconstruction "; - mitk::StatusBar::GetInstance()->DisplayText(status.sprintf("QBall reconstruction for %s", (*itemiter)->GetName().c_str()).toAscii()); + mitk::StatusBar::GetInstance()->DisplayText(status.sprintf("QBall reconstruction for %s", (*itemiter)->GetName().c_str()).toLatin1()); for(int i=0; im_QBallReconstructionMaxLLevelComboBox->currentIndex()) { case 0: { TemplatedAnalyticalQBallReconstruction<2>(*itemiter, currentLambda, normalization); break; } case 1: { TemplatedAnalyticalQBallReconstruction<4>(*itemiter, currentLambda, normalization); break; } case 2: { TemplatedAnalyticalQBallReconstruction<6>(*itemiter, currentLambda, normalization); break; } case 3: { TemplatedAnalyticalQBallReconstruction<8>(*itemiter, currentLambda, normalization); break; } case 4: { TemplatedAnalyticalQBallReconstruction<10>(*itemiter, currentLambda, normalization); break; } case 5: { TemplatedAnalyticalQBallReconstruction<12>(*itemiter, currentLambda, normalization); break; } } clock.Stop(); MITK_DEBUG << "took " << clock.GetMean() << "s." ; mitk::ProgressBar::GetInstance()->Progress(); itemiter++; } } std::vector::iterator nodeIt; for(nodeIt = nodes->begin(); nodeIt != nodes->end(); ++nodeIt) GetDefaultDataStorage()->Add(*nodeIt); m_MultiWidget->RequestUpdate(); - mitk::StatusBar::GetInstance()->DisplayText(status.sprintf("Finished Processing %d Files", nrFiles).toAscii()); + mitk::StatusBar::GetInstance()->DisplayText(status.sprintf("Finished Processing %d Files", nrFiles).toLatin1()); } catch (itk::ExceptionObject &ex) { MITK_INFO << ex; QMessageBox::information(0, "Reconstruction not possible:", ex.GetDescription()); return; } } template void QmitkQBallReconstructionView::TemplatedAnalyticalQBallReconstruction(mitk::DataNode* dataNodePointer, float lambda, int normalization) { typedef itk::AnalyticalDiffusionQballReconstructionImageFilter FilterType; typename FilterType::Pointer filter = FilterType::New(); mitk::DiffusionImage* vols = dynamic_cast*>(dataNodePointer->GetData()); filter->SetGradientImage( vols->GetDirections(), vols->GetVectorImage() ); filter->SetBValue(vols->GetReferenceBValue()); filter->SetThreshold( m_Controls->m_QBallReconstructionThreasholdEdit->value() ); filter->SetLambda(lambda); std::string nodePostfix; switch(normalization) { case 0: { filter->SetNormalizationMethod(FilterType::QBAR_STANDARD); nodePostfix = "_SphericalHarmonics_Qball"; break; } case 1: { filter->SetNormalizationMethod(FilterType::QBAR_B_ZERO_B_VALUE); nodePostfix = "_SphericalHarmonics_1_Qball"; break; } case 2: { filter->SetNormalizationMethod(FilterType::QBAR_B_ZERO); nodePostfix = "_SphericalHarmonics_2_Qball"; break; } case 3: { filter->SetNormalizationMethod(FilterType::QBAR_NONE); nodePostfix = "_SphericalHarmonics_3_Qball"; break; } case 4: { filter->SetNormalizationMethod(FilterType::QBAR_ADC_ONLY); nodePostfix = "_AdcProfile"; break; } case 5: { filter->SetNormalizationMethod(FilterType::QBAR_RAW_SIGNAL); nodePostfix = "_RawSignal"; break; } case 6: { filter->SetNormalizationMethod(FilterType::QBAR_SOLID_ANGLE); nodePostfix = "_SphericalHarmonics_CSA_Qball"; break; } case 7: { filter->SetNormalizationMethod(FilterType::QBAR_NONNEG_SOLID_ANGLE); nodePostfix = "_SphericalHarmonics_NonNegCSA_Qball"; break; } default: { filter->SetNormalizationMethod(FilterType::QBAR_STANDARD); } } filter->Update(); // ODFs TO DATATREE mitk::QBallImage::Pointer image = mitk::QBallImage::New(); image->InitializeByItk( filter->GetOutput() ); image->SetVolume( filter->GetOutput()->GetBufferPointer() ); mitk::DataNode::Pointer node=mitk::DataNode::New(); node->SetData( image ); SetDefaultNodeProperties(node, dataNodePointer->GetName()+nodePostfix); GetDefaultDataStorage()->Add(node, dataNodePointer); if(m_Controls->m_OutputCoeffsImage->isChecked()) { mitk::Image::Pointer coeffsImage = mitk::Image::New(); coeffsImage->InitializeByItk( filter->GetCoefficientImage().GetPointer() ); coeffsImage->SetVolume( filter->GetCoefficientImage()->GetBufferPointer() ); mitk::DataNode::Pointer coeffsNode=mitk::DataNode::New(); coeffsNode->SetData( coeffsImage ); coeffsNode->SetProperty( "name", mitk::StringProperty::New(dataNodePointer->GetName()+"_SH-Coeffs") ); coeffsNode->SetVisibility(false); GetDefaultDataStorage()->Add(coeffsNode, node); } } void QmitkQBallReconstructionView::MultiQBallReconstruction(mitk::DataStorage::SetOfObjects::Pointer inImages) { try { itk::TimeProbe clock; int nrFiles = inImages->size(); if (!nrFiles) return; std::vector lambdas; float minLambda = m_Controls->m_QBallReconstructionLambdaLineEdit->value(); lambdas.push_back(minLambda); int nLambdas = lambdas.size(); QString status; mitk::ProgressBar::GetInstance()->AddStepsToDo(nrFiles*nLambdas); mitk::DataStorage::SetOfObjects::const_iterator itemiter( inImages->begin() ); mitk::DataStorage::SetOfObjects::const_iterator itemiterend( inImages->end() ); while ( itemiter != itemiterend ) // for all items { mitk::DataNode* nodePointer = (*itemiter).GetPointer(); std::string nodename; (*itemiter)->GetStringProperty("name",nodename); itemiter++; // QBALL RECONSTRUCTION clock.Start(); MITK_INFO << "QBall reconstruction "; - mitk::StatusBar::GetInstance()->DisplayText(status.sprintf("QBall reconstruction for %s", nodename.c_str()).toAscii()); + mitk::StatusBar::GetInstance()->DisplayText(status.sprintf("QBall reconstruction for %s", nodename.c_str()).toLatin1()); for(int i=0; im_QBallReconstructionMaxLLevelComboBox->currentIndex()) { case 0: { TemplatedMultiQBallReconstruction<2>(currentLambda, nodePointer); break; } case 1: { TemplatedMultiQBallReconstruction<4>(currentLambda, nodePointer); break; } case 2: { TemplatedMultiQBallReconstruction<6>(currentLambda, nodePointer); break; } case 3: { TemplatedMultiQBallReconstruction<8>(currentLambda, nodePointer); break; } case 4: { TemplatedMultiQBallReconstruction<10>(currentLambda, nodePointer); break; } case 5: { TemplatedMultiQBallReconstruction<12>(currentLambda, nodePointer); break; } } clock.Stop(); MITK_DEBUG << "took " << clock.GetMean() << "s." ; mitk::ProgressBar::GetInstance()->Progress(); } } m_MultiWidget->RequestUpdate(); - mitk::StatusBar::GetInstance()->DisplayText(status.sprintf("Finished Processing %d Files", nrFiles).toAscii()); + mitk::StatusBar::GetInstance()->DisplayText(status.sprintf("Finished Processing %d Files", nrFiles).toLatin1()); } catch (itk::ExceptionObject &ex) { MITK_INFO << ex ; QMessageBox::information(0, "Reconstruction not possible:", ex.GetDescription()); return ; } } template void QmitkQBallReconstructionView::TemplatedMultiQBallReconstruction(float lambda, mitk::DataNode* dataNodePointer) { typedef itk::DiffusionMultiShellQballReconstructionImageFilter FilterType; typename FilterType::Pointer filter = FilterType::New(); std::string nodename; dataNodePointer->GetStringProperty("name",nodename); mitk::DiffusionImage* dwi = dynamic_cast*>(dataNodePointer->GetData()); mitk::DiffusionImage::BValueMap currSelectionMap = m_ShellSelectorMap[dataNodePointer]->GetBValueSelctionMap(); if(currSelectionMap.size() != 4 && currSelectionMap.find(0) != currSelectionMap.end()) { QMessageBox::information(0, "Reconstruction not possible:" ,QString("Only three shells in a equidistant configuration is supported. (ImageName: " + QString(nodename.c_str()) + ")")); return; } mitk::DiffusionImage::BValueMap::reverse_iterator it1 = currSelectionMap.rbegin(); mitk::DiffusionImage::BValueMap::reverse_iterator it2 = currSelectionMap.rbegin(); ++it2; // Get average distance int avdistance = 0; for(; it2 != currSelectionMap.rend(); ++it1,++it2) avdistance += (int)it1->first - (int)it2->first; avdistance /= currSelectionMap.size()-1; // Check if all shells are using the same averae distance it1 = currSelectionMap.rbegin(); it2 = currSelectionMap.rbegin(); ++it2; for(; it2 != currSelectionMap.rend(); ++it1,++it2) if(avdistance != (int)it1->first - (int)it2->first) { QMessageBox::information(0, "Reconstruction not possible:" ,QString("Selected Shells are not in a equidistant configuration. (ImageName: " + QString(nodename.c_str()) + ")")); return; } filter->SetBValueMap(m_ShellSelectorMap[dataNodePointer]->GetBValueSelctionMap()); filter->SetGradientImage( dwi->GetDirections(), dwi->GetVectorImage(), dwi->GetReferenceBValue() ); filter->SetThreshold( m_Controls->m_QBallReconstructionThreasholdEdit->value() ); filter->SetLambda(lambda); filter->Update(); // ODFs TO DATATREE mitk::QBallImage::Pointer image = mitk::QBallImage::New(); image->InitializeByItk( filter->GetOutput() ); image->SetVolume( filter->GetOutput()->GetBufferPointer() ); mitk::DataNode::Pointer node=mitk::DataNode::New(); node->SetData( image ); SetDefaultNodeProperties(node, nodename+"_SphericalHarmonics_MultiShell_Qball"); GetDefaultDataStorage()->Add(node, dataNodePointer); if(m_Controls->m_OutputCoeffsImage->isChecked()) { mitk::Image::Pointer coeffsImage = mitk::Image::New(); coeffsImage->InitializeByItk( filter->GetCoefficientImage().GetPointer() ); coeffsImage->SetVolume( filter->GetCoefficientImage()->GetBufferPointer() ); mitk::DataNode::Pointer coeffsNode=mitk::DataNode::New(); coeffsNode->SetData( coeffsImage ); coeffsNode->SetProperty( "name", mitk::StringProperty::New( QString(nodename.c_str()).append("_SH-Coefficients").toStdString()) ); coeffsNode->SetVisibility(false); GetDefaultDataStorage()->Add(coeffsNode, node); } } void QmitkQBallReconstructionView::SetDefaultNodeProperties(mitk::DataNode::Pointer node, std::string name) { node->SetProperty( "ShowMaxNumber", mitk::IntProperty::New( 500 ) ); node->SetProperty( "Scaling", mitk::FloatProperty::New( 1.0 ) ); node->SetProperty( "Normalization", mitk::OdfNormalizationMethodProperty::New()); node->SetProperty( "ScaleBy", mitk::OdfScaleByProperty::New()); node->SetProperty( "IndexParam1", mitk::FloatProperty::New(2)); node->SetProperty( "IndexParam2", mitk::FloatProperty::New(1)); node->SetProperty( "visible", mitk::BoolProperty::New( true ) ); node->SetProperty( "VisibleOdfs", mitk::BoolProperty::New( false ) ); node->SetProperty ("layer", mitk::IntProperty::New(100)); node->SetProperty( "DoRefresh", mitk::BoolProperty::New( true ) ); node->SetProperty( "name", mitk::StringProperty::New(name) ); } void QmitkQBallReconstructionView::GenerateShellSelectionUI(mitk::DataStorage::SetOfObjects::Pointer set) { m_DiffusionImages = set; std::map tempMap; const mitk::DataStorage::SetOfObjects::iterator setEnd( set->end() ); mitk::DataStorage::SetOfObjects::iterator NodeIt( set->begin() ); while(NodeIt != setEnd) { if(m_ShellSelectorMap.find( (*NodeIt).GetPointer() ) != m_ShellSelectorMap.end()) { tempMap[(*NodeIt).GetPointer()] = m_ShellSelectorMap[(*NodeIt).GetPointer()]; m_ShellSelectorMap.erase((*NodeIt).GetPointer()); }else { tempMap[(*NodeIt).GetPointer()] = new QbrShellSelection(this, (*NodeIt) ); tempMap[(*NodeIt).GetPointer()]->SetVisible(true); } NodeIt++; } for(std::map::iterator it = m_ShellSelectorMap.begin(); it != m_ShellSelectorMap.end();it ++) { delete it->second; } m_ShellSelectorMap.clear(); m_ShellSelectorMap = tempMap; } void QmitkQBallReconstructionView::PreviewThreshold(int threshold) { mitk::DataStorage::SetOfObjects::const_iterator itemiter( m_DiffusionImages->begin() ); mitk::DataStorage::SetOfObjects::const_iterator itemiterend( m_DiffusionImages->end() ); while ( itemiter != itemiterend ) // for all items { mitk::DiffusionImage* vols = static_cast*>( (*itemiter)->GetData()); // Extract b0 image typedef itk::B0ImageExtractionImageFilter FilterType; FilterType::Pointer filterB0 = FilterType::New(); filterB0->SetInput(vols->GetVectorImage()); filterB0->SetDirections(vols->GetDirections()); filterB0->Update(); mitk::Image::Pointer mitkImage = mitk::Image::New(); typedef itk::Image ImageType; typedef itk::Image SegmentationType; typedef itk::BinaryThresholdImageFilter ThresholdFilterType; // apply threshold ThresholdFilterType::Pointer filterThreshold = ThresholdFilterType::New(); filterThreshold->SetInput(filterB0->GetOutput()); filterThreshold->SetLowerThreshold(threshold); filterThreshold->SetInsideValue(0); filterThreshold->SetOutsideValue(1); // mark cut off values red filterThreshold->Update(); mitkImage->InitializeByItk( filterThreshold->GetOutput() ); mitkImage->SetVolume( filterThreshold->GetOutput()->GetBufferPointer() ); mitk::DataNode::Pointer node; if (this->GetDefaultDataStorage()->GetNamedDerivedNode("ThresholdOverlay", *itemiter)) { node = this->GetDefaultDataStorage()->GetNamedDerivedNode("ThresholdOverlay", *itemiter); } else { // create a new node, to show thresholded values node = mitk::DataNode::New(); GetDefaultDataStorage()->Add( node, *itemiter ); node->SetProperty( "name", mitk::StringProperty::New("ThresholdOverlay")); node->SetBoolProperty("helper object", true); } node->SetData( mitkImage ); itemiter++; mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } } diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkTensorReconstructionView.cpp b/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkTensorReconstructionView.cpp index ccb3001bc4..bc98ff91f9 100644 --- a/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkTensorReconstructionView.cpp +++ b/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkTensorReconstructionView.cpp @@ -1,1049 +1,1054 @@ /*=================================================================== 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 "QmitkTensorReconstructionView.h" #include "mitkDiffusionImagingConfigure.h" // qt includes #include #include #include #include #include // itk includes #include "itkTimeProbe.h" //#include "itkTensor.h" // mitk includes #include "mitkProgressBar.h" #include "mitkStatusBar.h" #include "mitkNodePredicateDataType.h" #include "QmitkDataStorageComboBox.h" #include "QmitkStdMultiWidget.h" #include "mitkTeemDiffusionTensor3DReconstructionImageFilter.h" #include "itkDiffusionTensor3DReconstructionImageFilter.h" #include "itkTensorImageToDiffusionImageFilter.h" #include "itkPointShell.h" #include "itkVector.h" #include "itkB0ImageExtractionImageFilter.h" #include "itkTensorReconstructionWithEigenvalueCorrectionFilter.h" #include "mitkImageCast.h" #include "mitkImageAccessByItk.h" #include #include "mitkProperties.h" #include "mitkDataNodeObject.h" #include "mitkOdfNormalizationMethodProperty.h" #include "mitkOdfScaleByProperty.h" #include "mitkDiffusionImageMapper.h" #include "mitkLookupTableProperty.h" #include "mitkLookupTable.h" #include "mitkImageStatisticsHolder.h" #include #include #include #include const std::string QmitkTensorReconstructionView::VIEW_ID = "org.mitk.views.tensorreconstruction"; typedef float TTensorPixelType; typedef itk::DiffusionTensor3D< TTensorPixelType > TensorPixelType; typedef itk::Image< TensorPixelType, 3 > TensorImageType; using namespace berry; QmitkTensorReconstructionView::QmitkTensorReconstructionView() : QmitkFunctionality(), m_Controls(NULL), m_MultiWidget(NULL) { m_DiffusionImages = mitk::DataStorage::SetOfObjects::New(); m_TensorImages = mitk::DataStorage::SetOfObjects::New(); } QmitkTensorReconstructionView::~QmitkTensorReconstructionView() { } void QmitkTensorReconstructionView::CreateQtPartControl(QWidget *parent) { if (!m_Controls) { // create GUI widgets m_Controls = new Ui::QmitkTensorReconstructionViewControls; m_Controls->setupUi(parent); this->CreateConnections(); Advanced1CheckboxClicked(); } } void QmitkTensorReconstructionView::StdMultiWidgetAvailable (QmitkStdMultiWidget &stdMultiWidget) { m_MultiWidget = &stdMultiWidget; } void QmitkTensorReconstructionView::StdMultiWidgetNotAvailable() { m_MultiWidget = NULL; } void QmitkTensorReconstructionView::CreateConnections() { if ( m_Controls ) { connect( (QObject*)(m_Controls->m_StartReconstruction), SIGNAL(clicked()), this, SLOT(Reconstruct()) ); connect( (QObject*)(m_Controls->m_Advanced1), SIGNAL(clicked()), this, SLOT(Advanced1CheckboxClicked()) ); connect( (QObject*)(m_Controls->m_TensorsToDWIButton), SIGNAL(clicked()), this, SLOT(TensorsToDWI()) ); connect( (QObject*)(m_Controls->m_TensorsToQbiButton), SIGNAL(clicked()), this, SLOT(TensorsToQbi()) ); connect( (QObject*)(m_Controls->m_ResidualButton), SIGNAL(clicked()), this, SLOT(ResidualCalculation()) ); connect( (QObject*)(m_Controls->m_PerSliceView), SIGNAL(pointSelected(int, int)), this, SLOT(ResidualClicked(int, int)) ); connect( (QObject*)(m_Controls->m_TensorReconstructionThreshold), SIGNAL(valueChanged(int)), this, SLOT(PreviewThreshold(int)) ); } } void QmitkTensorReconstructionView::ResidualClicked(int slice, int volume) { // Use image coord to reset crosshair // Find currently selected diffusion image // Update Label // to do: This position should be modified in order to skip B0 volumes that are not taken into account // when calculating residuals // Find the diffusion image mitk::DiffusionImage* diffImage; mitk::DataNode::Pointer correctNode; mitk::BaseGeometry* geometry; if (m_DiffusionImage.IsNotNull()) { diffImage = static_cast*>(m_DiffusionImage->GetData()); geometry = diffImage->GetGeometry(); // Remember the node whose display index must be updated correctNode = mitk::DataNode::New(); correctNode = m_DiffusionImage; } if(diffImage != NULL) { typedef vnl_vector_fixed< double, 3 > GradientDirectionType; typedef itk::VectorContainer< unsigned int, GradientDirectionType > GradientDirectionContainerType; GradientDirectionContainerType::Pointer dirs = diffImage->GetDirections(); for(unsigned int i=0; iSize() && i<=volume; i++) { GradientDirectionType grad = dirs->ElementAt(i); // check if image is b0 weighted if(fabs(grad[0]) < 0.001 && fabs(grad[1]) < 0.001 && fabs(grad[2]) < 0.001) { volume++; } } QString pos = "Volume: "; pos.append(QString::number(volume)); pos.append(", Slice: "); pos.append(QString::number(slice)); m_Controls->m_PositionLabel->setText(pos); if(correctNode) { int oldDisplayVal; correctNode->GetIntProperty("DisplayChannel", oldDisplayVal); std::string oldVal = QString::number(oldDisplayVal).toStdString(); std::string newVal = QString::number(volume).toStdString(); correctNode->SetIntProperty("DisplayChannel",volume); correctNode->SetSelected(true); this->FirePropertyChanged("DisplayChannel", oldVal, newVal); correctNode->UpdateOutputInformation(); mitk::Point3D p3 = m_MultiWidget->GetCrossPosition(); itk::Index<3> ix; geometry->WorldToIndex(p3, ix); // ix[2] = slice; mitk::Vector3D vec; vec[0] = ix[0]; vec[1] = ix[1]; vec[2] = slice; mitk::Vector3D v3New; geometry->IndexToWorld(vec, v3New); mitk::Point3D origin = geometry->GetOrigin(); mitk::Point3D p3New; p3New[0] = v3New[0] + origin[0]; p3New[1] = v3New[1] + origin[1]; p3New[2] = v3New[2] + origin[2]; m_MultiWidget->MoveCrossToPosition(p3New); m_MultiWidget->RequestUpdate(); } } } void QmitkTensorReconstructionView::Advanced1CheckboxClicked() { bool check = m_Controls-> m_Advanced1->isChecked(); m_Controls->frame->setVisible(check); } void QmitkTensorReconstructionView::Activated() { QmitkFunctionality::Activated(); } void QmitkTensorReconstructionView::Deactivated() { // Get all current nodes mitk::DataStorage::SetOfObjects::ConstPointer objects = this->GetDefaultDataStorage()->GetAll(); mitk::DataStorage::SetOfObjects::const_iterator itemiter( objects->begin() ); mitk::DataStorage::SetOfObjects::const_iterator itemiterend( objects->end() ); while ( itemiter != itemiterend ) // for all items { mitk::DataNode::Pointer node = *itemiter; if (node.IsNull()) continue; // only look at interesting types if(dynamic_cast*>(node->GetData())) { if (this->GetDefaultDataStorage()->GetNamedDerivedNode("ThresholdOverlay", *itemiter)) { node = this->GetDefaultDataStorage()->GetNamedDerivedNode("ThresholdOverlay", *itemiter); this->GetDefaultDataStorage()->Remove(node); } } itemiter++; } mitk::RenderingManager::GetInstance()->RequestUpdateAll(); QmitkFunctionality::Deactivated(); } void QmitkTensorReconstructionView::ResidualCalculation() { // Extract dwi and dti from current selection // In case of multiple selections, take the first one, since taking all combinations is not meaningful mitk::DataStorage::SetOfObjects::Pointer set = mitk::DataStorage::SetOfObjects::New(); mitk::DiffusionImage::Pointer diffImage = mitk::DiffusionImage::New(); TensorImageType::Pointer tensorImage; std::string nodename; if(m_DiffusionImage.IsNotNull()) { diffImage = static_cast*>(m_DiffusionImage->GetData()); } else return; if(m_TensorImage.IsNotNull()) { mitk::TensorImage* mitkVol; mitkVol = static_cast(m_TensorImage->GetData()); mitk::CastToItkImage(mitkVol, tensorImage); m_TensorImage->GetStringProperty("name", nodename); } else return; typedef itk::TensorImageToDiffusionImageFilter< TTensorPixelType, DiffusionPixelType > FilterType; mitk::DiffusionImage::GradientDirectionContainerType* gradients = diffImage->GetDirections(); // Find the min and the max values from a baseline image mitk::ImageStatisticsHolder *stats = diffImage->GetStatistics(); //Initialize filter that calculates the modeled diffusion weighted signals FilterType::Pointer filter = FilterType::New(); filter->SetInput( tensorImage ); filter->SetBValue(diffImage->GetReferenceBValue()); filter->SetGradientList(gradients); filter->SetMin(stats->GetScalarValueMin()); filter->SetMax(stats->GetScalarValueMax()); filter->Update(); // TENSORS TO DATATREE mitk::DiffusionImage::Pointer image = mitk::DiffusionImage::New(); image->SetVectorImage( filter->GetOutput() ); image->SetReferenceBValue(diffImage->GetReferenceBValue()); image->SetDirections(gradients); image->InitializeFromVectorImage(); mitk::DataNode::Pointer node = mitk::DataNode::New(); node->SetData( image ); mitk::DiffusionImageMapper::SetDefaultProperties(node); node->SetName("Estimated DWI"); + QString newname; + newname = newname.append(nodename.c_str()); + newname = newname.append("_DWI"); + node->SetName(newname.toLatin1()); + GetDefaultDataStorage()->Add(node, m_TensorImage); mitk::DiffusionImage::BValueMap map =image->GetBValueMap(); mitk::DiffusionImage::IndicesVector b0Indices = map[0]; typedef itk::ResidualImageFilter ResidualImageFilterType; ResidualImageFilterType::Pointer residualFilter = ResidualImageFilterType::New(); residualFilter->SetInput(diffImage->GetVectorImage()); residualFilter->SetSecondDiffusionImage(image->GetVectorImage()); residualFilter->SetGradients(gradients); residualFilter->SetB0Index(b0Indices[0]); residualFilter->SetB0Threshold(30); residualFilter->Update(); itk::Image::Pointer residualImage = itk::Image::New(); residualImage = residualFilter->GetOutput(); mitk::Image::Pointer mitkResImg = mitk::Image::New(); mitk::CastToMitkImage(residualImage, mitkResImg); stats = mitkResImg->GetStatistics(); float min = stats->GetScalarValueMin(); float max = stats->GetScalarValueMax(); mitk::LookupTableProperty::Pointer lutProp = mitk::LookupTableProperty::New(); mitk::LookupTable::Pointer lut = mitk::LookupTable::New(); vtkSmartPointer lookupTable = vtkSmartPointer::New(); lookupTable->SetTableRange(min, max); // If you don't want to use the whole color range, you can use // SetValueRange, SetHueRange, and SetSaturationRange lookupTable->Build(); vtkSmartPointer reversedlookupTable = vtkSmartPointer::New(); reversedlookupTable->SetTableRange(min+1, max); reversedlookupTable->Build(); for(int i=0; i<256; i++) { double* rgba = reversedlookupTable->GetTableValue(255-i); lookupTable->SetTableValue(i, rgba[0], rgba[1], rgba[2], rgba[3]); } lut->SetVtkLookupTable(lookupTable); lutProp->SetLookupTable(lut); // Create lookuptable mitk::DataNode::Pointer resNode=mitk::DataNode::New(); resNode->SetData( mitkResImg ); resNode->SetName("Residuals"); resNode->SetProperty("LookupTable", lutProp); bool b; resNode->GetBoolProperty("use color", b); resNode->SetBoolProperty("use color", false); GetDefaultDataStorage()->Add(resNode, m_TensorImage); m_MultiWidget->RequestUpdate(); // Draw Graph std::vector means = residualFilter->GetMeans(); std::vector q1s = residualFilter->GetQ1(); std::vector q3s = residualFilter->GetQ3(); std::vector percentagesOfOUtliers = residualFilter->GetPercentagesOfOutliers(); m_Controls->m_ResidualAnalysis->SetMeans(means); m_Controls->m_ResidualAnalysis->SetQ1(q1s); m_Controls->m_ResidualAnalysis->SetQ3(q3s); m_Controls->m_ResidualAnalysis->SetPercentagesOfOutliers(percentagesOfOUtliers); if(m_Controls->m_PercentagesOfOutliers->isChecked()) { m_Controls->m_ResidualAnalysis->DrawPercentagesOfOutliers(); } else { m_Controls->m_ResidualAnalysis->DrawMeans(); } // Draw Graph for volumes per slice in the QGraphicsView std::vector< std::vector > outliersPerSlice = residualFilter->GetOutliersPerSlice(); int xSize = outliersPerSlice.size(); if(xSize == 0) { return; } int ySize = outliersPerSlice[0].size(); // Find maximum in outliersPerSlice double maxOutlier= 0.0; for(int i=0; imaxOutlier) { maxOutlier = outliersPerSlice[i][j]; } } } // Create some QImage QImage qImage(xSize, ySize, QImage::Format_RGB32); QImage legend(1, 256, QImage::Format_RGB32); QRgb value; vtkSmartPointer lookup = vtkSmartPointer::New(); lookup->SetTableRange(0.0, maxOutlier); lookup->Build(); reversedlookupTable->SetTableRange(0, maxOutlier); reversedlookupTable->Build(); for(int i=0; i<256; i++) { double* rgba = reversedlookupTable->GetTableValue(255-i); lookup->SetTableValue(i, rgba[0], rgba[1], rgba[2], rgba[3]); } // Fill qImage for(int i=0; iMapValue(out); int r, g, b; r = _rgba[0]; g = _rgba[1]; b = _rgba[2]; value = qRgb(r, g, b); qImage.setPixel(i,j,value); } } for(int i=0; i<256; i++) { double* rgba = lookup->GetTableValue(i); int r, g, b; r = rgba[0]*255; g = rgba[1]*255; b = rgba[2]*255; value = qRgb(r, g, b); legend.setPixel(0,255-i,value); } QString upper = QString::number(maxOutlier, 'g', 3); upper.append(" %"); QString lower = QString::number(0.0); lower.append(" %"); m_Controls->m_UpperLabel->setText(upper); m_Controls->m_LowerLabel->setText(lower); - QGraphicsScene* scene = new QGraphicsScene; - QGraphicsScene* scene2 = new QGraphicsScene; - - QPixmap pixmap(QPixmap::fromImage(qImage)); - QGraphicsPixmapItem *item = new QGraphicsPixmapItem( pixmap, 0, scene); - item->scale(10.0, 3.0); + QGraphicsPixmapItem *item = new QGraphicsPixmapItem(pixmap); + item->setTransform(QTransform::fromScale(10.0, 3.0), true); QPixmap pixmap2(QPixmap::fromImage(legend)); - QGraphicsPixmapItem *item2 = new QGraphicsPixmapItem( pixmap2, 0, scene2); - item2->scale(20.0, 1.0); + QGraphicsPixmapItem *item2 = new QGraphicsPixmapItem(pixmap2); + item2->setTransform(QTransform::fromScale(20.0, 1.0), true); m_Controls->m_PerSliceView->SetResidualPixmapItem(item); + QGraphicsScene* scene = new QGraphicsScene; + QGraphicsScene* scene2 = new QGraphicsScene; + scene->addItem(item); + scene2->addItem(item2); m_Controls->m_PerSliceView->setScene(scene); m_Controls->m_LegendView->setScene(scene2); m_Controls->m_PerSliceView->show(); m_Controls->m_PerSliceView->repaint(); m_Controls->m_LegendView->setHorizontalScrollBarPolicy ( Qt::ScrollBarAlwaysOff ); m_Controls->m_LegendView->setVerticalScrollBarPolicy ( Qt::ScrollBarAlwaysOff ); m_Controls->m_LegendView->show(); m_Controls->m_LegendView->repaint(); } void QmitkTensorReconstructionView::Reconstruct() { int method = m_Controls->m_ReconctructionMethodBox->currentIndex(); switch (method) { case 0: ItkTensorReconstruction(m_DiffusionImages); break; case 1: TensorReconstructionWithCorr(m_DiffusionImages); break; default: ItkTensorReconstruction(m_DiffusionImages); } } void QmitkTensorReconstructionView::TensorReconstructionWithCorr (mitk::DataStorage::SetOfObjects::Pointer inImages) { try { int nrFiles = inImages->size(); if (!nrFiles) return; QString status; mitk::ProgressBar::GetInstance()->AddStepsToDo(nrFiles); mitk::DataStorage::SetOfObjects::const_iterator itemiter( inImages->begin() ); mitk::DataStorage::SetOfObjects::const_iterator itemiterend( inImages->end() ); while ( itemiter != itemiterend ) // for all items { typedef mitk::DiffusionImage DiffusionImageType; typedef DiffusionImageType::GradientDirectionContainerType GradientDirectionContainerType; DiffusionImageType* vols = static_cast((*itemiter)->GetData()); std::string nodename; (*itemiter)->GetStringProperty("name", nodename); // TENSOR RECONSTRUCTION MITK_INFO << "Tensor reconstruction with correction for negative eigenvalues"; - mitk::StatusBar::GetInstance()->DisplayText(status.sprintf("Tensor reconstruction for %s", nodename.c_str()).toAscii()); + mitk::StatusBar::GetInstance()->DisplayText(status.sprintf("Tensor reconstruction for %s", nodename.c_str()).toLatin1()); typedef itk::TensorReconstructionWithEigenvalueCorrectionFilter< DiffusionPixelType, TTensorPixelType > ReconstructionFilter; float b0Threshold = m_Controls->m_TensorReconstructionThreshold->value(); GradientDirectionContainerType::Pointer gradientContainerCopy = GradientDirectionContainerType::New(); for(GradientDirectionContainerType::ConstIterator it = vols->GetDirections()->Begin(); it != vols->GetDirections()->End(); it++) { gradientContainerCopy->push_back(it.Value()); } ReconstructionFilter::Pointer reconFilter = ReconstructionFilter::New(); reconFilter->SetGradientImage( gradientContainerCopy, vols->GetVectorImage() ); reconFilter->SetBValue(vols->GetReferenceBValue()); reconFilter->SetB0Threshold(b0Threshold); reconFilter->Update(); typedef itk::Image, 3> TensorImageType; TensorImageType::Pointer outputTensorImg = reconFilter->GetOutput(); typedef itk::ImageRegionIterator TensorImageIteratorType; TensorImageIteratorType tensorIt(outputTensorImg, outputTensorImg->GetRequestedRegion()); tensorIt.GoToBegin(); int negatives = 0; while(!tensorIt.IsAtEnd()) { typedef itk::DiffusionTensor3D TensorType; TensorType tensor = tensorIt.Get(); TensorType::EigenValuesArrayType ev; tensor.ComputeEigenValues(ev); for(unsigned int i=0; iInitializeByItk( outputTensorImg.GetPointer() ); image->SetVolume( outputTensorImg->GetBufferPointer() ); mitk::DataNode::Pointer node=mitk::DataNode::New(); node->SetData( image ); SetDefaultNodeProperties(node, nodename+"_EigenvalueCorrected_DT"); GetDefaultDataStorage()->Add(node, *itemiter); mitk::ProgressBar::GetInstance()->Progress(); ++itemiter; } - mitk::StatusBar::GetInstance()->DisplayText(status.sprintf("Finished Processing %d Files", nrFiles).toAscii()); + mitk::StatusBar::GetInstance()->DisplayText(status.sprintf("Finished Processing %d Files", nrFiles).toLatin1()); m_MultiWidget->RequestUpdate(); } catch (itk::ExceptionObject &ex) { MITK_INFO << ex ; QMessageBox::information(0, "Reconstruction not possible:", ex.GetDescription()); } } void QmitkTensorReconstructionView::ItkTensorReconstruction(mitk::DataStorage::SetOfObjects::Pointer inImages) { try { itk::TimeProbe clock; int nrFiles = inImages->size(); if (!nrFiles) return; QString status; mitk::ProgressBar::GetInstance()->AddStepsToDo(nrFiles); mitk::DataStorage::SetOfObjects::const_iterator itemiter( inImages->begin() ); mitk::DataStorage::SetOfObjects::const_iterator itemiterend( inImages->end() ); while ( itemiter != itemiterend ) // for all items { mitk::DiffusionImage* vols = static_cast*>( (*itemiter)->GetData()); std::string nodename; (*itemiter)->GetStringProperty("name", nodename); // TENSOR RECONSTRUCTION clock.Start(); MITK_DEBUG << "Tensor reconstruction "; - mitk::StatusBar::GetInstance()->DisplayText(status.sprintf("Tensor reconstruction for %s", nodename.c_str()).toAscii()); + mitk::StatusBar::GetInstance()->DisplayText(status.sprintf("Tensor reconstruction for %s", nodename.c_str()).toLatin1()); typedef itk::DiffusionTensor3DReconstructionImageFilter< DiffusionPixelType, DiffusionPixelType, TTensorPixelType > TensorReconstructionImageFilterType; TensorReconstructionImageFilterType::Pointer tensorReconstructionFilter = TensorReconstructionImageFilterType::New(); typedef mitk::DiffusionImage DiffusionImageType; typedef DiffusionImageType::GradientDirectionContainerType GradientDirectionContainerType; GradientDirectionContainerType::Pointer gradientContainerCopy = GradientDirectionContainerType::New(); for(GradientDirectionContainerType::ConstIterator it = vols->GetDirections()->Begin(); it != vols->GetDirections()->End(); it++) { gradientContainerCopy->push_back(it.Value()); } tensorReconstructionFilter->SetGradientImage( gradientContainerCopy, vols->GetVectorImage() ); tensorReconstructionFilter->SetBValue(vols->GetReferenceBValue()); tensorReconstructionFilter->SetThreshold( m_Controls->m_TensorReconstructionThreshold->value() ); tensorReconstructionFilter->Update(); clock.Stop(); MITK_DEBUG << "took " << clock.GetMean() << "s."; // TENSORS TO DATATREE mitk::TensorImage::Pointer image = mitk::TensorImage::New(); typedef itk::Image, 3> TensorImageType; TensorImageType::Pointer tensorImage; tensorImage = tensorReconstructionFilter->GetOutput(); // Check the tensor for negative eigenvalues if(m_Controls->m_CheckNegativeEigenvalues->isChecked()) { typedef itk::ImageRegionIterator TensorImageIteratorType; TensorImageIteratorType tensorIt(tensorImage, tensorImage->GetRequestedRegion()); tensorIt.GoToBegin(); while(!tensorIt.IsAtEnd()) { typedef itk::DiffusionTensor3D TensorType; //typedef itk::Tensor TensorType2; TensorType tensor = tensorIt.Get(); TensorType::EigenValuesArrayType ev; tensor.ComputeEigenValues(ev); for(unsigned int i=0; iSetDirection( vols->GetVectorImage()->GetDirection() ); image->InitializeByItk( tensorImage.GetPointer() ); image->SetVolume( tensorReconstructionFilter->GetOutput()->GetBufferPointer() ); mitk::DataNode::Pointer node=mitk::DataNode::New(); node->SetData( image ); SetDefaultNodeProperties(node, nodename+"_LinearLeastSquares_DT"); GetDefaultDataStorage()->Add(node, *itemiter); mitk::ProgressBar::GetInstance()->Progress(); ++itemiter; } - mitk::StatusBar::GetInstance()->DisplayText(status.sprintf("Finished Processing %d Files", nrFiles).toAscii()); + mitk::StatusBar::GetInstance()->DisplayText(status.sprintf("Finished Processing %d Files", nrFiles).toLatin1()); m_MultiWidget->RequestUpdate(); } catch (itk::ExceptionObject &ex) { MITK_INFO << ex ; QMessageBox::information(0, "Reconstruction not possible:", ex.GetDescription()); return; } } void QmitkTensorReconstructionView::SetDefaultNodeProperties(mitk::DataNode::Pointer node, std::string name) { node->SetProperty( "ShowMaxNumber", mitk::IntProperty::New( 500 ) ); node->SetProperty( "Scaling", mitk::FloatProperty::New( 1.0 ) ); node->SetProperty( "Normalization", mitk::OdfNormalizationMethodProperty::New()); node->SetProperty( "ScaleBy", mitk::OdfScaleByProperty::New()); node->SetProperty( "IndexParam1", mitk::FloatProperty::New(2)); node->SetProperty( "IndexParam2", mitk::FloatProperty::New(1)); node->SetProperty( "visible", mitk::BoolProperty::New( true ) ); node->SetProperty( "VisibleOdfs", mitk::BoolProperty::New( false ) ); node->SetProperty ("layer", mitk::IntProperty::New(100)); node->SetProperty( "DoRefresh", mitk::BoolProperty::New( true ) ); node->SetProperty( "name", mitk::StringProperty::New(name) ); } void QmitkTensorReconstructionView::TensorsToDWI() { DoTensorsToDWI(m_TensorImages); } void QmitkTensorReconstructionView::TensorsToQbi() { for (unsigned int i=0; isize(); i++) { mitk::DataNode::Pointer tensorImageNode = m_TensorImages->at(i); MITK_INFO << "starting Q-Ball estimation"; typedef float TTensorPixelType; typedef itk::DiffusionTensor3D< TTensorPixelType > TensorPixelType; typedef itk::Image< TensorPixelType, 3 > TensorImageType; TensorImageType::Pointer itkvol = TensorImageType::New(); mitk::CastToItkImage(dynamic_cast(tensorImageNode->GetData()), itkvol); typedef itk::TensorImageToQBallImageFilter< TTensorPixelType, TTensorPixelType > FilterType; FilterType::Pointer filter = FilterType::New(); filter->SetInput( itkvol ); filter->Update(); typedef itk::Vector OutputPixelType; typedef itk::Image OutputImageType; mitk::QBallImage::Pointer image = mitk::QBallImage::New(); OutputImageType::Pointer outimg = filter->GetOutput(); image->InitializeByItk( outimg.GetPointer() ); image->SetVolume( outimg->GetBufferPointer() ); mitk::DataNode::Pointer node = mitk::DataNode::New(); node->SetData( image ); node->SetName(tensorImageNode->GetName()+"_Qball"); GetDefaultDataStorage()->Add(node, tensorImageNode); } } void QmitkTensorReconstructionView::OnSelectionChanged( std::vector nodes ) { m_DiffusionImages = mitk::DataStorage::SetOfObjects::New(); m_TensorImages = mitk::DataStorage::SetOfObjects::New(); bool foundDwiVolume = false; bool foundTensorVolume = false; m_Controls->m_DiffusionImageLabel->setText("mandatory"); m_DiffusionImage = NULL; m_TensorImage = NULL; m_Controls->m_InputData->setTitle("Please Select Input Data"); // iterate selection for( std::vector::iterator it = nodes.begin(); it != nodes.end(); ++it ) { mitk::DataNode::Pointer node = *it; if (node.IsNull()) continue; // only look at interesting types if(dynamic_cast*>(node->GetData())) { foundDwiVolume = true; m_Controls->m_DiffusionImageLabel->setText(node->GetName().c_str()); m_DiffusionImages->push_back(node); m_DiffusionImage = node; } else if(dynamic_cast(node->GetData())) { foundTensorVolume = true; m_Controls->m_DiffusionImageLabel->setText(node->GetName().c_str()); m_TensorImages->push_back(node); m_TensorImage = node; } } m_Controls->m_StartReconstruction->setEnabled(foundDwiVolume); m_Controls->m_TensorsToDWIButton->setEnabled(foundTensorVolume); m_Controls->m_TensorsToQbiButton->setEnabled(foundTensorVolume); if (foundDwiVolume || foundTensorVolume) m_Controls->m_InputData->setTitle("Input Data"); m_Controls->m_ResidualButton->setEnabled(foundDwiVolume && foundTensorVolume); m_Controls->m_PercentagesOfOutliers->setEnabled(foundDwiVolume && foundTensorVolume); m_Controls->m_PerSliceView->setEnabled(foundDwiVolume && foundTensorVolume); } template itk::VectorContainer >::Pointer QmitkTensorReconstructionView::MakeGradientList() { itk::VectorContainer >::Pointer retval = itk::VectorContainer >::New(); vnl_matrix_fixed* U = itk::PointShell >::DistributePointShell(); for(int i=0; i v; v[0] = U->get(0,i); v[1] = U->get(1,i); v[2] = U->get(2,i); retval->push_back(v); } // Add 0 vector for B0 vnl_vector_fixed v; v.fill(0.0); retval->push_back(v); return retval; } void QmitkTensorReconstructionView::DoTensorsToDWI(mitk::DataStorage::SetOfObjects::Pointer inImages) { try { itk::TimeProbe clock; int nrFiles = inImages->size(); if (!nrFiles) return; QString status; mitk::ProgressBar::GetInstance()->AddStepsToDo(nrFiles); mitk::DataStorage::SetOfObjects::const_iterator itemiter( inImages->begin() ); mitk::DataStorage::SetOfObjects::const_iterator itemiterend( inImages->end() ); while ( itemiter != itemiterend ) // for all items { std::string nodename; (*itemiter)->GetStringProperty("name", nodename); mitk::TensorImage* vol = static_cast((*itemiter)->GetData()); typedef float TTensorPixelType; typedef itk::DiffusionTensor3D< TTensorPixelType > TensorPixelType; typedef itk::Image< TensorPixelType, 3 > TensorImageType; TensorImageType::Pointer itkvol = TensorImageType::New(); mitk::CastToItkImage(vol, itkvol); typedef itk::TensorImageToDiffusionImageFilter< TTensorPixelType, DiffusionPixelType > FilterType; FilterType::GradientListPointerType gradientList = FilterType::GradientListType::New(); switch(m_Controls->m_TensorsToDWINumDirsSelect->currentIndex()) { case 0: gradientList = MakeGradientList<12>(); break; case 1: gradientList = MakeGradientList<42>(); break; case 2: gradientList = MakeGradientList<92>(); break; case 3: gradientList = MakeGradientList<162>(); break; case 4: gradientList = MakeGradientList<252>(); break; case 5: gradientList = MakeGradientList<362>(); break; case 6: gradientList = MakeGradientList<492>(); break; case 7: gradientList = MakeGradientList<642>(); break; case 8: gradientList = MakeGradientList<812>(); break; case 9: gradientList = MakeGradientList<1002>(); break; default: gradientList = MakeGradientList<92>(); } double bVal = m_Controls->m_TensorsToDWIBValueEdit->text().toDouble(); // DWI ESTIMATION clock.Start(); MBI_INFO << "DWI Estimation "; mitk::StatusBar::GetInstance()->DisplayText(status.sprintf( - "DWI Estimation for %s", nodename.c_str()).toAscii()); + "DWI Estimation for %s", nodename.c_str()).toLatin1()); FilterType::Pointer filter = FilterType::New(); filter->SetInput( itkvol ); filter->SetBValue(bVal); filter->SetGradientList(gradientList); //filter->SetNumberOfThreads(1); filter->Update(); clock.Stop(); MBI_DEBUG << "took " << clock.GetMean() << "s."; // TENSORS TO DATATREE mitk::DiffusionImage::Pointer image = mitk::DiffusionImage::New(); image->SetVectorImage( filter->GetOutput() ); image->SetReferenceBValue(bVal); image->SetDirections(gradientList); image->InitializeFromVectorImage(); mitk::DataNode::Pointer node=mitk::DataNode::New(); node->SetData( image ); mitk::DiffusionImageMapper::SetDefaultProperties(node); node->SetName(nodename+"_DWI"); GetDefaultDataStorage()->Add(node, *itemiter); mitk::ProgressBar::GetInstance()->Progress(); ++itemiter; } - mitk::StatusBar::GetInstance()->DisplayText(status.sprintf("Finished Processing %d Files", nrFiles).toAscii()); + mitk::StatusBar::GetInstance()->DisplayText(status.sprintf("Finished Processing %d Files", nrFiles).toLatin1()); m_MultiWidget->RequestUpdate(); } catch (itk::ExceptionObject &ex) { MITK_INFO << ex ; QMessageBox::information(0, "DWI estimation failed:", ex.GetDescription()); return ; } } void QmitkTensorReconstructionView::PreviewThreshold(int threshold) { mitk::DataStorage::SetOfObjects::const_iterator itemiter( m_DiffusionImages->begin() ); mitk::DataStorage::SetOfObjects::const_iterator itemiterend( m_DiffusionImages->end() ); while ( itemiter != itemiterend ) // for all items { mitk::DiffusionImage* vols = static_cast*>( (*itemiter)->GetData()); // Extract b0 image typedef itk::B0ImageExtractionImageFilter FilterType; FilterType::Pointer filterB0 = FilterType::New(); filterB0->SetInput(vols->GetVectorImage()); filterB0->SetDirections(vols->GetDirections()); filterB0->Update(); mitk::Image::Pointer mitkImage = mitk::Image::New(); typedef itk::Image ImageType; typedef itk::Image SegmentationType; typedef itk::BinaryThresholdImageFilter ThresholdFilterType; // apply threshold ThresholdFilterType::Pointer filterThreshold = ThresholdFilterType::New(); filterThreshold->SetInput(filterB0->GetOutput()); filterThreshold->SetLowerThreshold(threshold); filterThreshold->SetInsideValue(0); filterThreshold->SetOutsideValue(1); // mark cut off values red filterThreshold->Update(); mitkImage->InitializeByItk( filterThreshold->GetOutput() ); mitkImage->SetVolume( filterThreshold->GetOutput()->GetBufferPointer() ); mitk::DataNode::Pointer node; if (this->GetDefaultDataStorage()->GetNamedDerivedNode("ThresholdOverlay", *itemiter)) { node = this->GetDefaultDataStorage()->GetNamedDerivedNode("ThresholdOverlay", *itemiter); } else { // create a new node, to show thresholded values node = mitk::DataNode::New(); GetDefaultDataStorage()->Add( node, *itemiter ); node->SetProperty( "name", mitk::StringProperty::New("ThresholdOverlay")); node->SetBoolProperty("helper object", true); } node->SetData( mitkImage ); itemiter++; mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } } diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/mitkPluginActivator.cpp b/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/mitkPluginActivator.cpp index 36f711d20d..fe487b9901 100644 --- a/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/mitkPluginActivator.cpp +++ b/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/mitkPluginActivator.cpp @@ -1,104 +1,106 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "mitkPluginActivator.h" #include #include "src/internal/Perspectives/QmitkDiffusionImagingAppPerspective.h" #include "src/internal/Perspectives/QmitkDIAppIVIMPerspective.h" #include "src/internal/Perspectives/QmitkDIAppSyntheticDataGenerationPerspective.h" #include "src/internal/Perspectives/QmitkGibbsTractographyPerspective.h" #include "src/internal/Perspectives/QmitkStreamlineTractographyPerspective.h" #include "src/internal/Perspectives/QmitkProbabilisticTractographyPerspective.h" #include "src/internal/Perspectives/QmitkFiberProcessingPerspective.h" #include "src/internal/Perspectives/QmitkDiffusionDefaultPerspective.h" #include "src/internal/QmitkQBallReconstructionView.h" #include "src/internal/QmitkPreprocessingView.h" #include "src/internal/QmitkDiffusionDicomImportView.h" #include "src/internal/QmitkDiffusionQuantificationView.h" #include "src/internal/QmitkTensorReconstructionView.h" #include "src/internal/QmitkControlVisualizationPropertiesView.h" #include "src/internal/QmitkODFDetailsView.h" #include "src/internal/QmitkGibbsTrackingView.h" #include "src/internal/QmitkStochasticFiberTrackingView.h" #include "src/internal/QmitkFiberProcessingView.h" #include "src/internal/QmitkPartialVolumeAnalysisView.h" #include "src/internal/QmitkIVIMView.h" #include "src/internal/QmitkTractbasedSpatialStatisticsView.h" #include "src/internal/QmitkTbssSkeletonizationView.h" #include "src/internal/QmitkStreamlineTrackingView.h" #include "src/internal/Connectomics/QmitkConnectomicsDataView.h" #include "src/internal/Connectomics/QmitkConnectomicsNetworkOperationsView.h" #include "src/internal/Connectomics/QmitkConnectomicsStatisticsView.h" #include "src/internal/Connectomics/QmitkRandomParcellationView.h" #include "src/internal/QmitkOdfMaximaExtractionView.h" #include "src/internal/QmitkFiberfoxView.h" #include "src/internal/QmitkFiberExtractionView.h" #include "src/internal/QmitkFieldmapGeneratorView.h" #include "src/internal/QmitkDiffusionRegistrationView.h" #include "src/internal/QmitkDenoisingView.h" namespace mitk { void PluginActivator::start(ctkPluginContext* context) { BERRY_REGISTER_EXTENSION_CLASS(QmitkDiffusionImagingAppPerspective, context) BERRY_REGISTER_EXTENSION_CLASS(QmitkGibbsTractographyPerspective, context) BERRY_REGISTER_EXTENSION_CLASS(QmitkStreamlineTractographyPerspective, context) BERRY_REGISTER_EXTENSION_CLASS(QmitkProbabilisticTractographyPerspective, context) BERRY_REGISTER_EXTENSION_CLASS(QmitkDIAppSyntheticDataGenerationPerspective, context) BERRY_REGISTER_EXTENSION_CLASS(QmitkDIAppIVIMPerspective, context) BERRY_REGISTER_EXTENSION_CLASS(QmitkFiberProcessingPerspective, context) BERRY_REGISTER_EXTENSION_CLASS(QmitkDiffusionDefaultPerspective, context) BERRY_REGISTER_EXTENSION_CLASS(QmitkQBallReconstructionView, context) BERRY_REGISTER_EXTENSION_CLASS(QmitkPreprocessingView, context) BERRY_REGISTER_EXTENSION_CLASS(QmitkDiffusionDicomImport, context) BERRY_REGISTER_EXTENSION_CLASS(QmitkDiffusionQuantificationView, context) BERRY_REGISTER_EXTENSION_CLASS(QmitkTensorReconstructionView, context) BERRY_REGISTER_EXTENSION_CLASS(QmitkControlVisualizationPropertiesView, context) BERRY_REGISTER_EXTENSION_CLASS(QmitkODFDetailsView, context) BERRY_REGISTER_EXTENSION_CLASS(QmitkGibbsTrackingView, context) BERRY_REGISTER_EXTENSION_CLASS(QmitkStochasticFiberTrackingView, context) BERRY_REGISTER_EXTENSION_CLASS(QmitkFiberProcessingView, context) BERRY_REGISTER_EXTENSION_CLASS(QmitkPartialVolumeAnalysisView, context) BERRY_REGISTER_EXTENSION_CLASS(QmitkIVIMView, context) BERRY_REGISTER_EXTENSION_CLASS(QmitkTractbasedSpatialStatisticsView, context) BERRY_REGISTER_EXTENSION_CLASS(QmitkTbssSkeletonizationView, context) BERRY_REGISTER_EXTENSION_CLASS(QmitkConnectomicsDataView, context) BERRY_REGISTER_EXTENSION_CLASS(QmitkConnectomicsNetworkOperationsView, context) BERRY_REGISTER_EXTENSION_CLASS(QmitkConnectomicsStatisticsView, context) BERRY_REGISTER_EXTENSION_CLASS(QmitkStreamlineTrackingView, context) BERRY_REGISTER_EXTENSION_CLASS(QmitkOdfMaximaExtractionView, context) BERRY_REGISTER_EXTENSION_CLASS(QmitkFiberfoxView, context) BERRY_REGISTER_EXTENSION_CLASS(QmitkFiberExtractionView, context) BERRY_REGISTER_EXTENSION_CLASS(QmitkFieldmapGeneratorView, context) BERRY_REGISTER_EXTENSION_CLASS(QmitkDiffusionRegistrationView, context) BERRY_REGISTER_EXTENSION_CLASS(QmitkDenoisingView, context) BERRY_REGISTER_EXTENSION_CLASS(QmitkRandomParcellationView, context) } void PluginActivator::stop(ctkPluginContext* context) { Q_UNUSED(context) } } -Q_EXPORT_PLUGIN2(org_mitk_gui_qt_diffusionimaging, mitk::PluginActivator) +#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) + Q_EXPORT_PLUGIN2(org_mitk_gui_qt_diffusionimaging, mitk::PluginActivator) +#endif diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/mitkPluginActivator.h b/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/mitkPluginActivator.h index 489bd853ca..c99ace3fa1 100644 --- a/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/mitkPluginActivator.h +++ b/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/mitkPluginActivator.h @@ -1,40 +1,43 @@ /*=================================================================== 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 MITKPLUGINACTIVATOR_H #define MITKPLUGINACTIVATOR_H #include #include namespace mitk { class MITK_LOCAL PluginActivator : public QObject, public ctkPluginActivator { Q_OBJECT +#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) + Q_PLUGIN_METADATA(IID "org_mitk_gui_qt_diffusionimaging") +#endif Q_INTERFACES(ctkPluginActivator) public: void start(ctkPluginContext* context); void stop(ctkPluginContext* context); }; // PluginActivator } #endif // MITKPLUGINACTIVATOR_H diff --git a/Plugins/org.mitk.gui.qt.diffusionimagingapp/CMakeLists.txt b/Plugins/org.mitk.gui.qt.diffusionimagingapp/CMakeLists.txt index d2a1d8b798..8884b6c47a 100644 --- a/Plugins/org.mitk.gui.qt.diffusionimagingapp/CMakeLists.txt +++ b/Plugins/org.mitk.gui.qt.diffusionimagingapp/CMakeLists.txt @@ -1,14 +1,14 @@ # The project name must correspond to the directory name of your plug-in # and must not contain periods. project(org_mitk_gui_qt_diffusionimagingapp) MACRO_CREATE_MITK_CTK_PLUGIN( EXPORT_DIRECTIVE DIFFUSIONIMAGING_APP_EXPORT EXPORTED_INCLUDE_SUFFIXES src MODULE_DEPENDS MitkQtWidgets MitkSceneSerialization - PACKAGE_DEPENDS Qt4|QtWebKit + PACKAGE_DEPENDS Qt4|QtWebKit Qt5|WebKitWidgets ) if(QT_QTWEBKIT_FOUND) add_definitions(-DQT_WEBKIT) endif(QT_QTWEBKIT_FOUND) diff --git a/Plugins/org.mitk.gui.qt.diffusionimagingapp/documentation/UserManual/QmitkDiffusionImagingAppUserManual.dox b/Plugins/org.mitk.gui.qt.diffusionimagingapp/documentation/UserManual/QmitkDiffusionImagingAppUserManual.dox index 9f679c8296..dad1bdf580 100644 --- a/Plugins/org.mitk.gui.qt.diffusionimagingapp/documentation/UserManual/QmitkDiffusionImagingAppUserManual.dox +++ b/Plugins/org.mitk.gui.qt.diffusionimagingapp/documentation/UserManual/QmitkDiffusionImagingAppUserManual.dox @@ -1,10 +1,10 @@ /** \page org_mitk_gui_qt_diffusionimagingapp Using The Diffusion Imaging Application \section QMitkDiffusionApplicationManualOverview What is the Diffusion Imaging Application -The Diffusion Imaging Application contains selected views for the analysis of images of the human brain. These encompass the views developed by the Neuroimaging Group of the Division Medical and Biological Informatics as well as basic image processing views such as segmentation and volumevisualization. +The Diffusion Imaging Application contains selected views for the analysis of images of the human brain. These encompass the views developed by the Medical Image Computing Group of the Division Medical and Biological Informatics as well as basic image processing views such as segmentation and volumevisualization. For a basic guide to MITK see \ref MITKUserManualPage . */ diff --git a/Plugins/org.mitk.gui.qt.diffusionimagingapp/src/internal/QmitkDiffusionApplicationPlugin.cpp b/Plugins/org.mitk.gui.qt.diffusionimagingapp/src/internal/QmitkDiffusionApplicationPlugin.cpp index d3dd44ef81..33906841dd 100644 --- a/Plugins/org.mitk.gui.qt.diffusionimagingapp/src/internal/QmitkDiffusionApplicationPlugin.cpp +++ b/Plugins/org.mitk.gui.qt.diffusionimagingapp/src/internal/QmitkDiffusionApplicationPlugin.cpp @@ -1,88 +1,90 @@ /*=================================================================== 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 "QmitkDiffusionApplicationPlugin.h" #include "src/QmitkDiffusionImagingAppApplication.h" #include "src/internal/Perspectives/QmitkWelcomePerspective.h" #include "src/internal/QmitkDiffusionImagingAppIntroPart.h" #include #include #include #include #include #include #include QmitkDiffusionApplicationPlugin* QmitkDiffusionApplicationPlugin::inst = 0; QmitkDiffusionApplicationPlugin::QmitkDiffusionApplicationPlugin() { inst = this; } QmitkDiffusionApplicationPlugin::~QmitkDiffusionApplicationPlugin() { } QmitkDiffusionApplicationPlugin* QmitkDiffusionApplicationPlugin::GetDefault() { return inst; } void QmitkDiffusionApplicationPlugin::start(ctkPluginContext* context) { berry::AbstractUICTKPlugin::start(context); this->context = context; BERRY_REGISTER_EXTENSION_CLASS(QmitkDiffusionImagingAppApplication, context) BERRY_REGISTER_EXTENSION_CLASS(QmitkDiffusionImagingAppIntroPart, context) BERRY_REGISTER_EXTENSION_CLASS(QmitkWelcomePerspective, context) ctkServiceReference cmRef = context->getServiceReference(); ctkConfigurationAdmin* configAdmin = 0; if (cmRef) { configAdmin = context->getService(cmRef); } // Use the CTK Configuration Admin service to configure the BlueBerry help system if (configAdmin) { ctkConfigurationPtr conf = configAdmin->getConfiguration("org.blueberry.services.help", QString()); ctkDictionary helpProps; helpProps.insert("homePage", "qthelp://org.mitk.gui.qt.diffusionimagingapp/bundle/index.html"); conf->update(helpProps); context->ungetService(cmRef); } else { MITK_WARN << "Configuration Admin service unavailable, cannot set home page url."; } } ctkPluginContext* QmitkDiffusionApplicationPlugin::GetPluginContext() const { return context; } -Q_EXPORT_PLUGIN2(org_mitk_gui_qt_diffusionimagingapp, QmitkDiffusionApplicationPlugin) +#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) + Q_EXPORT_PLUGIN2(org_mitk_gui_qt_diffusionimagingapp, QmitkDiffusionApplicationPlugin) +#endif diff --git a/Plugins/org.mitk.gui.qt.diffusionimagingapp/src/internal/QmitkDiffusionApplicationPlugin.h b/Plugins/org.mitk.gui.qt.diffusionimagingapp/src/internal/QmitkDiffusionApplicationPlugin.h index bd57933803..9b8e79ef15 100644 --- a/Plugins/org.mitk.gui.qt.diffusionimagingapp/src/internal/QmitkDiffusionApplicationPlugin.h +++ b/Plugins/org.mitk.gui.qt.diffusionimagingapp/src/internal/QmitkDiffusionApplicationPlugin.h @@ -1,52 +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 QMITKDIFFUSIONAPPLICATIONPLUGIN_H_ #define QMITKDIFFUSIONAPPLICATIONPLUGIN_H_ #include #include #include class QmitkDiffusionApplicationPlugin : public QObject, public berry::AbstractUICTKPlugin { Q_OBJECT +#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) + Q_PLUGIN_METADATA(IID "org_mitk_gui_qt_diffusionimagingapp") +#endif Q_INTERFACES(ctkPluginActivator) public: QmitkDiffusionApplicationPlugin(); ~QmitkDiffusionApplicationPlugin(); static QmitkDiffusionApplicationPlugin* GetDefault(); ctkPluginContext* GetPluginContext() const; void start(ctkPluginContext*); QString GetQtHelpCollectionFile() const; private: static QmitkDiffusionApplicationPlugin* inst; ctkPluginContext* context; }; #endif /* QMITKDIFFUSIONAPPLICATIONPLUGIN_H_ */ diff --git a/Plugins/org.mitk.gui.qt.diffusionimagingapp/src/internal/QmitkDiffusionImagingAppIntroPart.cpp b/Plugins/org.mitk.gui.qt.diffusionimagingapp/src/internal/QmitkDiffusionImagingAppIntroPart.cpp index 1e2a24b0bb..e4afa76043 100644 --- a/Plugins/org.mitk.gui.qt.diffusionimagingapp/src/internal/QmitkDiffusionImagingAppIntroPart.cpp +++ b/Plugins/org.mitk.gui.qt.diffusionimagingapp/src/internal/QmitkDiffusionImagingAppIntroPart.cpp @@ -1,204 +1,215 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "QmitkDiffusionImagingAppIntroPart.h" #include "mitkNodePredicateDataType.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include +#if QT_VERSION >= QT_VERSION_CHECK(5,0,0) +# include +#endif #include #include #include #include #include #include #include "QmitkDiffusionApplicationPlugin.h" #include "mitkDataStorageEditorInput.h" #include #include "mitkBaseDataIOFactory.h" #include "mitkSceneIO.h" #include "mitkProgressBar.h" #include "mitkDataNodeFactory.h" #include "mitkNodePredicateNot.h" #include "mitkNodePredicateProperty.h" QmitkDiffusionImagingAppIntroPart::QmitkDiffusionImagingAppIntroPart() : m_Controls(NULL) { berry::IPreferences::Pointer workbenchPrefs = QmitkDiffusionApplicationPlugin::GetDefault()->GetPreferencesService()->GetSystemPreferences(); workbenchPrefs->PutBool(berry::WorkbenchPreferenceConstants::SHOW_INTRO, true); workbenchPrefs->Flush(); } QmitkDiffusionImagingAppIntroPart::~QmitkDiffusionImagingAppIntroPart() { // if the workbench is not closing (that means, welcome screen was closed explicitly), set "Show_intro" false if (!this->GetIntroSite()->GetPage()->GetWorkbenchWindow()->GetWorkbench()->IsClosing()) { berry::IPreferences::Pointer workbenchPrefs = QmitkDiffusionApplicationPlugin::GetDefault()->GetPreferencesService()->GetSystemPreferences(); workbenchPrefs->PutBool(berry::WorkbenchPreferenceConstants::SHOW_INTRO, false); workbenchPrefs->Flush(); } else { berry::IPreferences::Pointer workbenchPrefs = QmitkDiffusionApplicationPlugin::GetDefault()->GetPreferencesService()->GetSystemPreferences(); workbenchPrefs->PutBool(berry::WorkbenchPreferenceConstants::SHOW_INTRO, true); workbenchPrefs->Flush(); } // if workbench is not closing (Just welcome screen closing), open last used perspective if (this->GetIntroSite()->GetPage()->GetPerspective()->GetId() == "org.mitk.diffusionimagingapp.perspectives.welcome" && !this->GetIntroSite()->GetPage()->GetWorkbenchWindow()->GetWorkbench()->IsClosing()) { berry::IPerspectiveDescriptor::Pointer perspective = this->GetIntroSite()->GetWorkbenchWindow()->GetWorkbench()->GetPerspectiveRegistry()->FindPerspectiveWithId("org.mitk.perspectives.diffusiondefault"); if (perspective) { this->GetIntroSite()->GetPage()->SetPerspective(perspective); } } } void QmitkDiffusionImagingAppIntroPart::CreateQtPartControl(QWidget* parent) { if (!m_Controls) { // create GUI widgets m_Controls = new Ui::QmitkWelcomeScreenViewControls; m_Controls->setupUi(parent); // create a QWebView as well as a QWebPage and QWebFrame within the QWebview m_view = new QWebView(parent); m_view->page()->setLinkDelegationPolicy(QWebPage::DelegateAllLinks); QUrl urlQtResource(QString("qrc:/org.mitk.gui.qt.welcomescreen/mitkdiffusionimagingappwelcomeview.html"), QUrl::TolerantMode ); m_view->load( urlQtResource ); // adds the webview as a widget parent->layout()->addWidget(m_view); this->CreateConnections(); } } void QmitkDiffusionImagingAppIntroPart::CreateConnections() { if ( m_Controls ) { connect( (QObject*)(m_view->page()), SIGNAL(linkClicked(const QUrl& )), this, SLOT(DelegateMeTo(const QUrl& )) ); } } void QmitkDiffusionImagingAppIntroPart::DelegateMeTo(const QUrl& showMeNext) { QString scheme = showMeNext.scheme(); +#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) QByteArray urlHostname = showMeNext.encodedHost(); QByteArray urlPath = showMeNext.encodedPath(); QByteArray dataset = showMeNext.encodedQueryItemValue("dataset"); QByteArray clear = showMeNext.encodedQueryItemValue("clear"); +#else + QByteArray urlHostname = QUrl::toAce(showMeNext.host()); + QByteArray urlPath = showMeNext.path().toLatin1(); + QUrlQuery query(showMeNext); + QByteArray dataset = query.queryItemValue("dataset").toLatin1(); + QByteArray clear = query.queryItemValue("clear").toLatin1();//showMeNext.encodedQueryItemValue("clear"); +#endif if (scheme.isEmpty()) MITK_INFO << " empty scheme of the to be delegated link" ; // if the scheme is set to mitk, it is to be tested which action should be applied if (scheme.contains(QString("mitk")) ) { if(urlPath.isEmpty() ) MITK_INFO << " mitk path is empty " ; // searching for the perspective keyword within the host name if(urlHostname.contains(QByteArray("perspectives")) ) { // the simplified method removes every whitespace // ( whitespace means any character for which the standard C++ isspace() method returns true) urlPath = urlPath.simplified(); QString tmpPerspectiveId(urlPath.data()); tmpPerspectiveId.replace(QString("/"), QString("") ); std::string perspectiveId = tmpPerspectiveId.toStdString(); // is working fine as long as the perspective id is valid, if not the application crashes GetIntroSite()->GetWorkbenchWindow()->GetWorkbench()->ShowPerspective(perspectiveId, GetIntroSite()->GetWorkbenchWindow() ); // search the Workbench for opened StdMultiWidgets to ensure the focus does not stay on the welcome screen and is switched to // an StdMultiWidget if one available mitk::IDataStorageService::Pointer service = berry::Platform::GetServiceRegistry().GetServiceById(mitk::IDataStorageService::ID); berry::IEditorInput::Pointer editorInput; editorInput = new mitk::DataStorageEditorInput( service->GetActiveDataStorage() ); // the solution is not clean, but the dependency to the StdMultiWidget was removed in order to fix a crash problem // as described in Bug #11715 // This is the correct way : use the static string ID variable // berry::IEditorPart::Pointer editor = GetIntroSite()->GetPage()->FindEditors( editorInput, QmitkStdMultiWidgetEditor::EDITOR_ID ); // QuickFix: we use the same string for an local variable const std::string stdEditorID = "org.mitk.editors.stdmultiwidget"; // search for opened StdMultiWidgetEditors std::vector editorList = GetIntroSite()->GetPage()->FindEditors( editorInput, stdEditorID, 1 ); // if an StdMultiWidgetEditor open was found, give focus to it if(editorList.size()) { GetIntroSite()->GetPage()->Activate( editorList[0]->GetPart(true) ); } } } // if the scheme is set to http, by default no action is performed, if an external webpage needs to be // shown it should be implemented below else if (scheme.contains(QString("http")) ) { QDesktopServices::openUrl(showMeNext); // m_view->load( ) ; } else if(scheme.contains("qrc")) { m_view->load(showMeNext); } } void QmitkDiffusionImagingAppIntroPart::StandbyStateChanged(bool) { } void QmitkDiffusionImagingAppIntroPart::SetFocus() { } diff --git a/Plugins/org.mitk.gui.qt.dtiatlasapp/CMakeLists.txt b/Plugins/org.mitk.gui.qt.dtiatlasapp/CMakeLists.txt index 1ae889096d..6a242b4c90 100644 --- a/Plugins/org.mitk.gui.qt.dtiatlasapp/CMakeLists.txt +++ b/Plugins/org.mitk.gui.qt.dtiatlasapp/CMakeLists.txt @@ -1,14 +1,14 @@ # The project name must correspond to the directory name of your plug-in # and must not contain periods. project(org_mitk_gui_qt_dtiatlasapp) MACRO_CREATE_MITK_CTK_PLUGIN( EXPORT_DIRECTIVE DTIATLAS_APP_EXPORT EXPORTED_INCLUDE_SUFFIXES src MODULE_DEPENDS MitkQtWidgets MitkSceneSerialization - PACKAGE_DEPENDS Qt4|QtWebKit + PACKAGE_DEPENDS Qt4|QtWebKit Qt5|WebKitWidgets ) if(QT_QTWEBKIT_FOUND) add_definitions(-DQT_WEBKIT) endif(QT_QTWEBKIT_FOUND) diff --git a/Plugins/org.mitk.gui.qt.dtiatlasapp/src/internal/QmitkDTIAtlasAppApplicationPlugin.cpp b/Plugins/org.mitk.gui.qt.dtiatlasapp/src/internal/QmitkDTIAtlasAppApplicationPlugin.cpp index 337ece002c..cbc6c6d0cc 100644 --- a/Plugins/org.mitk.gui.qt.dtiatlasapp/src/internal/QmitkDTIAtlasAppApplicationPlugin.cpp +++ b/Plugins/org.mitk.gui.qt.dtiatlasapp/src/internal/QmitkDTIAtlasAppApplicationPlugin.cpp @@ -1,121 +1,121 @@ /*=================================================================== 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 "QmitkDTIAtlasAppApplicationPlugin.h" #include #include #include #include "src/QmitkDTIAtlasAppApplication.h" #include "src/internal/QmitkDTIAtlasAppIntroPart.h" #include "src/internal/QmitkDTIAtlasAppPerspective.h" #include "src/internal/QmitkWelcomePerspective.h" #include #include QmitkDTIAtlasAppApplicationPlugin* QmitkDTIAtlasAppApplicationPlugin::inst = 0; QmitkDTIAtlasAppApplicationPlugin::QmitkDTIAtlasAppApplicationPlugin() : pluginListener(0) { inst = this; } QmitkDTIAtlasAppApplicationPlugin::~QmitkDTIAtlasAppApplicationPlugin() { delete pluginListener; } QmitkDTIAtlasAppApplicationPlugin* QmitkDTIAtlasAppApplicationPlugin::GetDefault() { return inst; } void QmitkDTIAtlasAppApplicationPlugin::start(ctkPluginContext* context) { berry::AbstractUICTKPlugin::start(context); this->context = context; BERRY_REGISTER_EXTENSION_CLASS(QmitkDTIAtlasAppApplication, context) BERRY_REGISTER_EXTENSION_CLASS(QmitkDTIAtlasAppIntroPart, context) BERRY_REGISTER_EXTENSION_CLASS(QmitkDTIAtlasAppPerspective, context) BERRY_REGISTER_EXTENSION_CLASS(QmitkWelcomePerspective, context) // QString collectionFile = GetQtHelpCollectionFile(); // berry::QtAssistantUtil::SetHelpCollectionFile(collectionFile); // berry::QtAssistantUtil::SetDefaultHelpUrl("qthelp://org.mitk.gui.qt.dtiatlasapp/bundle/index.html"); delete pluginListener; pluginListener = new berry::QCHPluginListener(context); context->connectPluginListener(pluginListener, SLOT(pluginChanged(ctkPluginEvent)), Qt::DirectConnection); // register all QCH files from all the currently installed plugins pluginListener->processPlugins(); } QString QmitkDTIAtlasAppApplicationPlugin::GetQtHelpCollectionFile() const { if (!helpCollectionFile.isEmpty()) { return helpCollectionFile; } QString collectionFilename; QString na("n/a"); // if (na != MITK_REVISION) // collectionFilename = "MitkDTIAtlasAppQtHelpCollection_" MITK_REVISION ".qhc"; // else collectionFilename = "MitkDTIAtlasAppQtHelpCollection.qhc"; QFileInfo collectionFileInfo = context->getDataFile(collectionFilename); QFileInfo pluginFileInfo = QFileInfo(QUrl(context->getPlugin()->getLocation()).toLocalFile()); if (!collectionFileInfo.exists() || pluginFileInfo.lastModified() > collectionFileInfo.lastModified()) { // extract the qhc file from the plug-in QByteArray content = context->getPlugin()->getResource(collectionFilename); if (content.isEmpty()) { BERRY_WARN << "Could not get plug-in resource: " << collectionFilename.toStdString(); } else { QFile file(collectionFileInfo.absoluteFilePath()); file.open(QIODevice::WriteOnly); file.write(content); file.close(); } } if (QFile::exists(collectionFileInfo.absoluteFilePath())) { helpCollectionFile = collectionFileInfo.absoluteFilePath(); } return helpCollectionFile; } -Q_EXPORT_PLUGIN2(org_mitk_gui_qt_dtiatlasapp, QmitkDTIAtlasAppApplicationPlugin) - - +#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) + Q_EXPORT_PLUGIN2(org_mitk_gui_qt_dtiatlasapp, QmitkDTIAtlasAppApplicationPlugin) +#endif diff --git a/Plugins/org.mitk.gui.qt.dtiatlasapp/src/internal/QmitkDTIAtlasAppApplicationPlugin.h b/Plugins/org.mitk.gui.qt.dtiatlasapp/src/internal/QmitkDTIAtlasAppApplicationPlugin.h index 01b83066ba..c7b74966c2 100644 --- a/Plugins/org.mitk.gui.qt.dtiatlasapp/src/internal/QmitkDTIAtlasAppApplicationPlugin.h +++ b/Plugins/org.mitk.gui.qt.dtiatlasapp/src/internal/QmitkDTIAtlasAppApplicationPlugin.h @@ -1,57 +1,60 @@ /*=================================================================== 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 QMITKDTIATLASAPPAPPLICATIONPLUGIN_H_ #define QMITKDTIATLASAPPAPPLICATIONPLUGIN_H_ #include #include #include #include class QmitkDTIAtlasAppApplicationPlugin : public QObject, public berry::AbstractUICTKPlugin { Q_OBJECT +#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) + Q_PLUGIN_METADATA(IID "org_mitk_gui_qt_dtiatlasapp") +#endif Q_INTERFACES(ctkPluginActivator) public: QmitkDTIAtlasAppApplicationPlugin(); ~QmitkDTIAtlasAppApplicationPlugin(); static QmitkDTIAtlasAppApplicationPlugin* GetDefault(); ctkPluginContext* GetPluginContext() const; void start(ctkPluginContext*); QString GetQtHelpCollectionFile() const; private: static QmitkDTIAtlasAppApplicationPlugin* inst; ctkPluginContext* context; berry::QCHPluginListener* pluginListener; mutable QString helpCollectionFile; }; // QmitkDTIAtlasAppApplicationPlugin #endif // QMITKDTIATLASAPPAPPLICATIONPLUGIN_H_ diff --git a/Plugins/org.mitk.gui.qt.dtiatlasapp/src/internal/QmitkDTIAtlasAppIntroPart.cpp b/Plugins/org.mitk.gui.qt.dtiatlasapp/src/internal/QmitkDTIAtlasAppIntroPart.cpp index f0b21f3a28..c4406ff44d 100644 --- a/Plugins/org.mitk.gui.qt.dtiatlasapp/src/internal/QmitkDTIAtlasAppIntroPart.cpp +++ b/Plugins/org.mitk.gui.qt.dtiatlasapp/src/internal/QmitkDTIAtlasAppIntroPart.cpp @@ -1,293 +1,304 @@ /*=================================================================== 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 "QmitkDTIAtlasAppIntroPart.h" #include "mitkNodePredicateDataType.h" #include #include #include #include #include #include #include #include #include #include #include #ifdef QT_WEBKIT -#include -#include +# include +# include +# if QT_VERSION >= QT_VERSION_CHECK(5,0,0) +# include +# endif #endif #include #include #include #include #include #include #include "QmitkStdMultiWidget.h" #include "QmitkStdMultiWidgetEditor.h" #include "QmitkDTIAtlasAppApplicationPlugin.h" #include "mitkDataStorageEditorInput.h" #include "mitkBaseDataIOFactory.h" #include "mitkSceneIO.h" #include "mitkProgressBar.h" #include "mitkDataNodeFactory.h" #include "mitkNodePredicateNot.h" #include "mitkNodePredicateProperty.h" QmitkDTIAtlasAppIntroPart::QmitkDTIAtlasAppIntroPart() : m_Controls(NULL) { berry::IPreferences::Pointer workbenchPrefs = QmitkDTIAtlasAppApplicationPlugin::GetDefault()->GetPreferencesService()->GetSystemPreferences(); workbenchPrefs->PutBool(berry::WorkbenchPreferenceConstants::SHOW_INTRO, true); workbenchPrefs->Flush(); } QmitkDTIAtlasAppIntroPart::~QmitkDTIAtlasAppIntroPart() { // if the workbench is not closing (that means, welcome screen was closed explicitly), set "Show_intro" false if (!this->GetIntroSite()->GetPage()->GetWorkbenchWindow()->GetWorkbench()->IsClosing()) { berry::IPreferences::Pointer workbenchPrefs = QmitkDTIAtlasAppApplicationPlugin::GetDefault()->GetPreferencesService()->GetSystemPreferences(); workbenchPrefs->PutBool(berry::WorkbenchPreferenceConstants::SHOW_INTRO, false); workbenchPrefs->Flush(); } else { berry::IPreferences::Pointer workbenchPrefs = QmitkDTIAtlasAppApplicationPlugin::GetDefault()->GetPreferencesService()->GetSystemPreferences(); workbenchPrefs->PutBool(berry::WorkbenchPreferenceConstants::SHOW_INTRO, true); workbenchPrefs->Flush(); } // if workbench is not closing (Just welcome screen closing), open last used perspective if (this->GetIntroSite()->GetPage()->GetPerspective()->GetId() == "org.mitk.dtiatlasapp.perspectives.welcome" && !this->GetIntroSite()->GetPage()->GetWorkbenchWindow()->GetWorkbench()->IsClosing()) { berry::IPerspectiveDescriptor::Pointer perspective = this->GetIntroSite()->GetWorkbenchWindow()->GetWorkbench()->GetPerspectiveRegistry()->FindPerspectiveWithId("org.mitk.dtiatlasapp.perspectives.dtiatlasapp"); if (perspective) { this->GetIntroSite()->GetPage()->SetPerspective(perspective); } } } void QmitkDTIAtlasAppIntroPart::CreateQtPartControl(QWidget* parent) { if (!m_Controls) { // create GUI widgets m_Controls = new Ui::QmitkWelcomeScreenViewControls; m_Controls->setupUi(parent); #ifdef QT_WEBKIT // create a QWebView as well as a QWebPage and QWebFrame within the QWebview m_view = new QWebView(parent); m_view->page()->setLinkDelegationPolicy(QWebPage::DelegateAllLinks); QUrl urlQtResource(QString("qrc:/org.mitk.gui.qt.welcomescreen/mitkdtiatlasappwelcomeview.html"), QUrl::TolerantMode ); m_view->load( urlQtResource ); // adds the webview as a widget parent->layout()->addWidget(m_view); this->CreateConnections(); #else parent->layout()->addWidget(new QLabel("

Please install Qt with the WebKit option to see cool pictures!

")); #endif } } #ifdef QT_WEBKIT void QmitkDTIAtlasAppIntroPart::CreateConnections() { if ( m_Controls ) { connect( (QObject*)(m_view->page()), SIGNAL(linkClicked(const QUrl& )), this, SLOT(DelegateMeTo(const QUrl& )) ); } } void QmitkDTIAtlasAppIntroPart::DelegateMeTo(const QUrl& showMeNext) { QString scheme = showMeNext.scheme(); +#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) QByteArray urlHostname = showMeNext.encodedHost(); QByteArray urlPath = showMeNext.encodedPath(); QByteArray dataset = showMeNext.encodedQueryItemValue("dataset"); QByteArray clear = showMeNext.encodedQueryItemValue("clear"); +#else + QByteArray urlHostname = QUrl::toAce(showMeNext.host()); + QByteArray urlPath = showMeNext.path().toLatin1(); + QUrlQuery query(showMeNext); + QByteArray dataset = query.queryItemValue("dataset").toLatin1(); + QByteArray clear = query.queryItemValue("clear").toLatin1();//showMeNext.encodedQueryItemValue("clear"); +#endif if (scheme.isEmpty()) MITK_INFO << " empty scheme of the to be delegated link" ; // if the scheme is set to mitk, it is to be tested which action should be applied if (scheme.contains(QString("mitk")) ) { if(urlPath.isEmpty() ) MITK_INFO << " mitk path is empty " ; // searching for the perspective keyword within the host name if(urlHostname.contains(QByteArray("perspectives")) ) { // the simplified method removes every whitespace // ( whitespace means any character for which the standard C++ isspace() method returns true) urlPath = urlPath.simplified(); QString tmpPerspectiveId(urlPath.data()); tmpPerspectiveId.replace(QString("/"), QString("") ); std::string perspectiveId = tmpPerspectiveId.toStdString(); // is working fine as long as the perspective id is valid, if not the application crashes GetIntroSite()->GetWorkbenchWindow()->GetWorkbench()->ShowPerspective(perspectiveId, GetIntroSite()->GetWorkbenchWindow() ); mitk::DataStorageEditorInput::Pointer editorInput; editorInput = new mitk::DataStorageEditorInput(); berry::IEditorPart::Pointer editor = GetIntroSite()->GetPage()->OpenEditor(editorInput, QmitkStdMultiWidgetEditor::EDITOR_ID); QmitkStdMultiWidgetEditor::Pointer multiWidgetEditor; mitk::DataStorage::Pointer dataStorage; if (editor.Cast().IsNull()) { editorInput = new mitk::DataStorageEditorInput(); dataStorage = editorInput->GetDataStorageReference()->GetDataStorage(); } else { multiWidgetEditor = editor.Cast(); multiWidgetEditor->GetStdMultiWidget()->RequestUpdate(); dataStorage = multiWidgetEditor->GetEditorInput().Cast()->GetDataStorageReference()->GetDataStorage(); } bool dsmodified = false; QString *fileName = new QString(dataset.data()); if ( fileName->right(5) == ".mitk" ) { mitk::SceneIO::Pointer sceneIO = mitk::SceneIO::New(); bool clearDataStorageFirst(false); QString *sClear = new QString(clear.data()); if ( sClear->right(4) == "true" ) { clearDataStorageFirst = true; } mitk::ProgressBar::GetInstance()->AddStepsToDo(2); dataStorage = sceneIO->LoadScene( fileName->toLocal8Bit().constData(), dataStorage, clearDataStorageFirst ); dsmodified = true; mitk::ProgressBar::GetInstance()->Progress(2); } else { mitk::DataNodeFactory::Pointer nodeReader = mitk::DataNodeFactory::New(); try { nodeReader->SetFileName(fileName->toLocal8Bit().data()); nodeReader->Update(); for ( unsigned int i = 0 ; i < nodeReader->GetNumberOfOutputs( ); ++i ) { mitk::DataNode::Pointer node; node = nodeReader->GetOutput(i); if ( node->GetData() != NULL ) { dataStorage->Add(node); dsmodified = true; } } } catch(...) { MITK_INFO << "Could not open file!"; } } if(dataStorage.IsNotNull() && dsmodified) { // get all nodes that have not set "includeInBoundingBox" to false mitk::NodePredicateNot::Pointer pred = mitk::NodePredicateNot::New(mitk::NodePredicateProperty::New("includeInBoundingBox" , mitk::BoolProperty::New(false))); mitk::DataStorage::SetOfObjects::ConstPointer rs = dataStorage->GetSubset(pred); if(rs->Size() > 0) { // calculate bounding geometry of these nodes mitk::TimeGeometry::Pointer bounds = dataStorage->ComputeBoundingGeometry3D(rs); // initialize the views to the bounding geometry mitk::RenderingManager::GetInstance()->InitializeViews(bounds); } } } // searching for the load if(urlHostname.contains(QByteArray("perspectives")) ) { // the simplified method removes every whitespace // ( whitespace means any character for which the standard C++ isspace() method returns true) urlPath = urlPath.simplified(); QString tmpPerspectiveId(urlPath.data()); tmpPerspectiveId.replace(QString("/"), QString("") ); std::string perspectiveId = tmpPerspectiveId.toStdString(); // is working fine as long as the perspective id is valid, if not the application crashes GetIntroSite()->GetWorkbenchWindow()->GetWorkbench()->ShowPerspective(perspectiveId, GetIntroSite()->GetWorkbenchWindow() ); mitk::DataStorageEditorInput::Pointer editorInput; editorInput = new mitk::DataStorageEditorInput(); GetIntroSite()->GetPage()->OpenEditor(editorInput, QmitkStdMultiWidgetEditor::EDITOR_ID); } else { MITK_INFO << "Unkown mitk action keyword (see documentation for mitk links)" ; } } // if the scheme is set to http, by default no action is performed, if an external webpage needs to be // shown it should be implemented below else if (scheme.contains(QString("http")) ) { QDesktopServices::openUrl(showMeNext); // m_view->load( ) ; } else if(scheme.contains("qrc")) { m_view->load(showMeNext); } } #endif void QmitkDTIAtlasAppIntroPart::StandbyStateChanged(bool standby) { } void QmitkDTIAtlasAppIntroPart::SetFocus() { } diff --git a/Plugins/org.mitk.gui.qt.eventrecorder/src/internal/org_mitk_gui_qt_eventrecorder_Activator.cpp b/Plugins/org.mitk.gui.qt.eventrecorder/src/internal/org_mitk_gui_qt_eventrecorder_Activator.cpp index 3186d188e0..4dc0876202 100644 --- a/Plugins/org.mitk.gui.qt.eventrecorder/src/internal/org_mitk_gui_qt_eventrecorder_Activator.cpp +++ b/Plugins/org.mitk.gui.qt.eventrecorder/src/internal/org_mitk_gui_qt_eventrecorder_Activator.cpp @@ -1,38 +1,40 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "org_mitk_gui_qt_eventrecorder_Activator.h" #include #include "InteractionEventRecorder.h" namespace mitk { void org_mitk_gui_qt_eventrecorder_Activator::start(ctkPluginContext* context) { BERRY_REGISTER_EXTENSION_CLASS(InteractionEventRecorder, context) } void org_mitk_gui_qt_eventrecorder_Activator::stop(ctkPluginContext* context) { Q_UNUSED(context) } } -Q_EXPORT_PLUGIN2(org_mitk_gui_qt_eventrecorder, mitk::org_mitk_gui_qt_eventrecorder_Activator) +#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) + Q_EXPORT_PLUGIN2(org_mitk_gui_qt_eventrecorder, mitk::org_mitk_gui_qt_eventrecorder_Activator) +#endif \ No newline at end of file diff --git a/Plugins/org.mitk.gui.qt.eventrecorder/src/internal/org_mitk_gui_qt_eventrecorder_Activator.h b/Plugins/org.mitk.gui.qt.eventrecorder/src/internal/org_mitk_gui_qt_eventrecorder_Activator.h index a64fa7fcf5..b715022ba6 100644 --- a/Plugins/org.mitk.gui.qt.eventrecorder/src/internal/org_mitk_gui_qt_eventrecorder_Activator.h +++ b/Plugins/org.mitk.gui.qt.eventrecorder/src/internal/org_mitk_gui_qt_eventrecorder_Activator.h @@ -1,40 +1,43 @@ /*=================================================================== 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 org_mitk_gui_qt_eventrecorder_Activator_h #define org_mitk_gui_qt_eventrecorder_Activator_h #include namespace mitk { class org_mitk_gui_qt_eventrecorder_Activator : public QObject, public ctkPluginActivator { Q_OBJECT +#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) + Q_PLUGIN_METADATA(IID "org_mitk_gui_qt_eventrecorder") +#endif Q_INTERFACES(ctkPluginActivator) public: void start(ctkPluginContext* context); void stop(ctkPluginContext* context); }; // org_mitk_gui_qt_eventrecorder_Activator } #endif // org_mitk_gui_qt_eventrecorder_Activator_h diff --git a/Plugins/org.mitk.gui.qt.ext/resources/icons/tango/index.theme b/Plugins/org.mitk.gui.qt.ext/resources/icons/tango/index.theme index 4a3ff343c3..25c2b08bec 100644 --- a/Plugins/org.mitk.gui.qt.ext/resources/icons/tango/index.theme +++ b/Plugins/org.mitk.gui.qt.ext/resources/icons/tango/index.theme @@ -1,25 +1,46 @@ [Icon Theme] Name=tango Comment=An icon theme following the tango style guide Directories=scalable/actions scalable/status scalable/places [scalable/actions] Size=48 Type=Scalable MinSize=1 MaxSize=256 Context=Actions +[scalable/categories] +Size=48 +Type=Scalable +MinSize=1 +MaxSize=256 +Context=Categories + +[scalable/devices] +Size=48 +Type=Scalable +MinSize=1 +MaxSize=256 +Context=Devices + +[scalable/mimetypes] +Size=48 +Type=Scalable +MinSize=1 +MaxSize=256 +Context=MimeTypes + [scalable/status] Size=48 Type=Scalable MinSize=1 MaxSize=256 Context=Status [scalable/places] Size=48 Type=Scalable MinSize=1 MaxSize=256 Context=Places diff --git a/Plugins/org.mitk.gui.qt.ext/resources/icons/tango/scalable/actions/list-add.svg b/Plugins/org.mitk.gui.qt.ext/resources/icons/tango/scalable/actions/list-add.svg new file mode 100644 index 0000000000..6eaed44811 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.ext/resources/icons/tango/scalable/actions/list-add.svg @@ -0,0 +1,436 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + Add + 2006-01-04 + + + Andreas Nilsson + + + http://tango-project.org + + + add + plus + + + + + + + + + + + + + + + + + + diff --git a/Plugins/org.mitk.gui.qt.ext/resources/icons/tango/scalable/actions/list-remove.svg b/Plugins/org.mitk.gui.qt.ext/resources/icons/tango/scalable/actions/list-remove.svg new file mode 100644 index 0000000000..5f109a05c3 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.ext/resources/icons/tango/scalable/actions/list-remove.svg @@ -0,0 +1,424 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + Remove + 2006-01-04 + + + Andreas Nilsson + + + http://tango-project.org + + + remove + delete + + + + + + + + + + + + + + + + + diff --git a/Plugins/org.mitk.gui.qt.ext/resources/icons/tango/scalable/actions/media-playback-pause.svg b/Plugins/org.mitk.gui.qt.ext/resources/icons/tango/scalable/actions/media-playback-pause.svg new file mode 100644 index 0000000000..8a434cabb1 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.ext/resources/icons/tango/scalable/actions/media-playback-pause.svg @@ -0,0 +1,641 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + Media Playback Pause + + + Lapo Calamandrei + + + + + + media + pause + playback + video + music + + + + + Jakub Steiner + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Plugins/org.mitk.gui.qt.ext/resources/icons/tango/scalable/actions/media-playback-start.svg b/Plugins/org.mitk.gui.qt.ext/resources/icons/tango/scalable/actions/media-playback-start.svg new file mode 100644 index 0000000000..75616de46f --- /dev/null +++ b/Plugins/org.mitk.gui.qt.ext/resources/icons/tango/scalable/actions/media-playback-start.svg @@ -0,0 +1,319 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + Media Playback Start + + + Lapo Calamandrei + + + + + + play + media + music + video + player + + + + + Jakub Steiner + + + + + + + + + + + + + + + + + + + diff --git a/Plugins/org.mitk.gui.qt.ext/resources/icons/tango/scalable/actions/media-playback-stop.svg b/Plugins/org.mitk.gui.qt.ext/resources/icons/tango/scalable/actions/media-playback-stop.svg new file mode 100644 index 0000000000..24bbfb52e5 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.ext/resources/icons/tango/scalable/actions/media-playback-stop.svg @@ -0,0 +1,651 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + Media Playback Pause + + + Lapo Calamandrei + + + + + + media + stop + playback + video + music + + + + + Jakub Steiner + + + + + + + + + + + + + + + + + + diff --git a/Plugins/org.mitk.gui.qt.ext/resources/icons/tango/scalable/actions/media-record.svg b/Plugins/org.mitk.gui.qt.ext/resources/icons/tango/scalable/actions/media-record.svg new file mode 100644 index 0000000000..85bbb98f6e --- /dev/null +++ b/Plugins/org.mitk.gui.qt.ext/resources/icons/tango/scalable/actions/media-record.svg @@ -0,0 +1,337 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + Media Record + + + Lapo Calamandrei + + + + + + media + player + record + music + sound + video + + + + + + + + + + + + + + + + + + diff --git a/Plugins/org.mitk.gui.qt.ext/resources/icons/tango/scalable/actions/media-seek-backward.svg b/Plugins/org.mitk.gui.qt.ext/resources/icons/tango/scalable/actions/media-seek-backward.svg new file mode 100644 index 0000000000..75f49f1a82 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.ext/resources/icons/tango/scalable/actions/media-seek-backward.svg @@ -0,0 +1,374 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + Media Seek Backward + + + Lapo Calamandrei + + + + + + + + + + + + + + + + + + + + + + diff --git a/Plugins/org.mitk.gui.qt.ext/resources/icons/tango/scalable/actions/media-seek-forward.svg b/Plugins/org.mitk.gui.qt.ext/resources/icons/tango/scalable/actions/media-seek-forward.svg new file mode 100644 index 0000000000..b1b9fe950b --- /dev/null +++ b/Plugins/org.mitk.gui.qt.ext/resources/icons/tango/scalable/actions/media-seek-forward.svg @@ -0,0 +1,383 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + Media Seek Forward + + + Lapo Calamandrei + + + + + + Jakub Steiner + + + + + + + + + + + + + + + + + + + + + diff --git a/Plugins/org.mitk.gui.qt.ext/resources/icons/tango/scalable/actions/media-skip-backward.svg b/Plugins/org.mitk.gui.qt.ext/resources/icons/tango/scalable/actions/media-skip-backward.svg new file mode 100644 index 0000000000..fccd7762cd --- /dev/null +++ b/Plugins/org.mitk.gui.qt.ext/resources/icons/tango/scalable/actions/media-skip-backward.svg @@ -0,0 +1,1025 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + Media Skip Backward + + + Lapo Calamandrei + + + + + + Jakub Steiner + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Plugins/org.mitk.gui.qt.ext/resources/icons/tango/scalable/actions/media-skip-forward.svg b/Plugins/org.mitk.gui.qt.ext/resources/icons/tango/scalable/actions/media-skip-forward.svg new file mode 100644 index 0000000000..7c4d40054b --- /dev/null +++ b/Plugins/org.mitk.gui.qt.ext/resources/icons/tango/scalable/actions/media-skip-forward.svg @@ -0,0 +1,1013 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + Media Skip Forward + + + Lapo Calamandrei + + + + + + Jakub Steiner + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Plugins/org.mitk.gui.qt.ext/resources/icons/tango/scalable/categories/applications-multimedia.svg b/Plugins/org.mitk.gui.qt.ext/resources/icons/tango/scalable/categories/applications-multimedia.svg new file mode 100644 index 0000000000..6844e8db1a --- /dev/null +++ b/Plugins/org.mitk.gui.qt.ext/resources/icons/tango/scalable/categories/applications-multimedia.svg @@ -0,0 +1,498 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + Multimedia Category + + + Jakub Steiner + + + http://jimmac.musichall.cz + + + video + multimedia + category + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Plugins/org.mitk.gui.qt.ext/resources/icons/tango/scalable/devices/camera-photo.svg b/Plugins/org.mitk.gui.qt.ext/resources/icons/tango/scalable/devices/camera-photo.svg new file mode 100644 index 0000000000..4911410136 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.ext/resources/icons/tango/scalable/devices/camera-photo.svg @@ -0,0 +1,681 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + Jakub Steiner + + + http://jimmac.musichall.cz + Photo Camera + + + camera + photo + SLR + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Plugins/org.mitk.gui.qt.ext/resources/icons/tango/scalable/devices/camera-video.svg b/Plugins/org.mitk.gui.qt.ext/resources/icons/tango/scalable/devices/camera-video.svg new file mode 100644 index 0000000000..e24713457f --- /dev/null +++ b/Plugins/org.mitk.gui.qt.ext/resources/icons/tango/scalable/devices/camera-video.svg @@ -0,0 +1,1257 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + Camera / Video + + + Jakub Steiner + + + http://jimmac.musichall.cz/ + + + camera + camcorder + video + cam + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Plugins/org.mitk.gui.qt.ext/resources/icons/tango/scalable/mimetypes/image-x-generic.svg b/Plugins/org.mitk.gui.qt.ext/resources/icons/tango/scalable/mimetypes/image-x-generic.svg new file mode 100644 index 0000000000..45dd641ae7 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.ext/resources/icons/tango/scalable/mimetypes/image-x-generic.svg @@ -0,0 +1,581 @@ + + + + + + image/svg+xml + + + + + + + + Genric Image + + + Jakub Steiner + + + + imagepicturesnapshotphoto + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Plugins/org.mitk.gui.qt.ext/resources/icons/tango/scalable/mimetypes/video-x-generic.svg b/Plugins/org.mitk.gui.qt.ext/resources/icons/tango/scalable/mimetypes/video-x-generic.svg new file mode 100644 index 0000000000..1f3a8b95a8 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.ext/resources/icons/tango/scalable/mimetypes/video-x-generic.svg @@ -0,0 +1,319 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + Jakub Steiner + + + http://jimmac.musichall.cz + + Generic Video + + + video + audio + multimedia + movie + + + + + + + + + + + + + + + + + + + + + + diff --git a/Plugins/org.mitk.gui.qt.ext/resources/org_mitk_icons.qrc b/Plugins/org.mitk.gui.qt.ext/resources/org_mitk_icons.qrc index 56315b325f..08f6548161 100644 --- a/Plugins/org.mitk.gui.qt.ext/resources/org_mitk_icons.qrc +++ b/Plugins/org.mitk.gui.qt.ext/resources/org_mitk_icons.qrc @@ -1,51 +1,67 @@ icons/awesome/index.theme icons/awesome/scalable/actions/document-open.svg icons/awesome/scalable/actions/document-print.svg icons/awesome/scalable/actions/document-save.svg icons/awesome/scalable/actions/edit-delete.svg icons/awesome/scalable/actions/edit-redo.svg icons/awesome/scalable/actions/edit-undo.svg icons/awesome/scalable/actions/go-down.svg icons/awesome/scalable/actions/go-home.svg icons/awesome/scalable/actions/go-next.svg icons/awesome/scalable/actions/go-previous.svg icons/awesome/scalable/actions/go-up.svg icons/awesome/scalable/actions/system-log-out.svg icons/awesome/scalable/actions/view-list-details.svg icons/awesome/scalable/actions/view-list-icons.svg icons/awesome/scalable/actions/view-refresh.svg icons/awesome/scalable/places/folder.svg icons/awesome/scalable/status/dialog-error.svg icons/awesome/scalable/status/dialog-information.svg icons/awesome/scalable/status/dialog-question.svg icons/awesome/scalable/status/dialog-warning.svg icons/tango/index.theme icons/tango/scalable/actions/document-open.svg icons/tango/scalable/actions/document-print.svg icons/tango/scalable/actions/document-save.svg icons/tango/scalable/actions/edit-delete.svg icons/tango/scalable/actions/edit-redo.svg icons/tango/scalable/actions/edit-undo.svg icons/tango/scalable/actions/go-bottom.svg icons/tango/scalable/actions/go-down.svg icons/tango/scalable/actions/go-first.svg icons/tango/scalable/actions/go-home.svg icons/tango/scalable/actions/go-last.svg icons/tango/scalable/actions/go-next.svg icons/tango/scalable/actions/go-previous.svg icons/tango/scalable/actions/go-top.svg icons/tango/scalable/actions/go-up.svg icons/tango/scalable/actions/system-log-out.svg icons/tango/scalable/actions/view-list-details.svg icons/tango/scalable/actions/view-list-icons.svg icons/tango/scalable/actions/view-refresh.svg + icons/tango/scalable/actions/list-add.svg + icons/tango/scalable/actions/list-remove.svg + icons/tango/scalable/actions/media-playback-pause.svg + icons/tango/scalable/actions/media-playback-start.svg + icons/tango/scalable/actions/media-playback-stop.svg + icons/tango/scalable/actions/media-record.svg + icons/tango/scalable/actions/media-seek-backward.svg + icons/tango/scalable/actions/media-seek-forward.svg + icons/tango/scalable/actions/media-skip-backward.svg + icons/tango/scalable/actions/media-skip-forward.svg + icons/tango/scalable/actions/system-log-out.svg + icons/tango/scalable/categories/applications-multimedia.svg + icons/tango/scalable/devices/camera-photo.svg + icons/tango/scalable/devices/camera-video.svg + icons/tango/scalable/mimetypes/image-x-generic.svg + icons/tango/scalable/mimetypes/video-x-generic.svg icons/tango/scalable/places/folder.svg icons/tango/scalable/places/folder-remote.svg icons/tango/scalable/status/dialog-error.svg icons/tango/scalable/status/dialog-information.svg icons/tango/scalable/status/dialog-question.svg icons/tango/scalable/status/dialog-warning.svg diff --git a/Plugins/org.mitk.gui.qt.ext/src/internal/QmitkCommonExtPlugin.cpp b/Plugins/org.mitk.gui.qt.ext/src/internal/QmitkCommonExtPlugin.cpp index 4b5f8951d6..b28e27f6f2 100644 --- a/Plugins/org.mitk.gui.qt.ext/src/internal/QmitkCommonExtPlugin.cpp +++ b/Plugins/org.mitk.gui.qt.ext/src/internal/QmitkCommonExtPlugin.cpp @@ -1,257 +1,259 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "QmitkCommonExtPlugin.h" #include #include "QmitkAppInstancesPreferencePage.h" #include "QmitkExternalProgramsPreferencePage.h" #include "QmitkInputDevicesPrefPage.h" #include "QmitkModuleView.h" #include #include #include #include #include #include #include #include #include #include #include #include #include "berryPlatform.h" #include ctkPluginContext* QmitkCommonExtPlugin::_context = 0; void QmitkCommonExtPlugin::start(ctkPluginContext* context) { this->_context = context; QtWidgetsExtRegisterClasses(); BERRY_REGISTER_EXTENSION_CLASS(QmitkAppInstancesPreferencePage, context) BERRY_REGISTER_EXTENSION_CLASS(QmitkExternalProgramsPreferencePage, context) BERRY_REGISTER_EXTENSION_CLASS(QmitkInputDevicesPrefPage, context) BERRY_REGISTER_EXTENSION_CLASS(QmitkModuleView, context) if (qApp->metaObject()->indexOfSignal("messageReceived(QByteArray)") > -1) { connect(qApp, SIGNAL(messageReceived(QByteArray)), this, SLOT(handleIPCMessage(QByteArray))); } std::vector args = berry::Platform::GetApplicationArgs(); QStringList qargs; for (std::vector::const_iterator it = args.begin(); it != args.end(); ++it) { qargs << QString::fromStdString(*it); } // This is a potentially long running operation. loadDataFromDisk(qargs, true); } void QmitkCommonExtPlugin::stop(ctkPluginContext* context) { Q_UNUSED(context) this->_context = 0; } ctkPluginContext* QmitkCommonExtPlugin::getContext() { return _context; } void QmitkCommonExtPlugin::loadDataFromDisk(const QStringList &arguments, bool globalReinit) { if (!arguments.empty()) { ctkServiceReference serviceRef = _context->getServiceReference(); if (serviceRef) { mitk::IDataStorageService* dataStorageService = _context->getService(serviceRef); mitk::DataStorage::Pointer dataStorage = dataStorageService->GetDefaultDataStorage()->GetDataStorage(); int argumentsAdded = 0; for (int i = 0; i < arguments.size(); ++i) { if (arguments[i].right(5) == ".mitk") { mitk::SceneIO::Pointer sceneIO = mitk::SceneIO::New(); bool clearDataStorageFirst(false); mitk::ProgressBar::GetInstance()->AddStepsToDo(2); dataStorage = sceneIO->LoadScene( arguments[i].toLocal8Bit().constData(), dataStorage, clearDataStorageFirst ); mitk::ProgressBar::GetInstance()->Progress(2); argumentsAdded++; } else { mitk::DataNodeFactory::Pointer nodeReader = mitk::DataNodeFactory::New(); try { nodeReader->SetFileName(arguments[i].toStdString()); nodeReader->Update(); for (unsigned int j = 0 ; j < nodeReader->GetNumberOfOutputs( ); ++j) { mitk::DataNode::Pointer node = nodeReader->GetOutput(j); if (node->GetData() != 0) { dataStorage->Add(node); argumentsAdded++; } } } catch(...) { MITK_WARN << "Failed to load command line argument: " << arguments[i].toStdString(); } } } // end for each command line argument if (argumentsAdded > 0 && globalReinit) { // calculate bounding geometry mitk::RenderingManager::GetInstance()->InitializeViews(dataStorage->ComputeBoundingGeometry3D()); } } else { MITK_ERROR << "A service reference for mitk::IDataStorageService does not exist"; } } } void QmitkCommonExtPlugin::startNewInstance(const QStringList &args, const QStringList& files) { QStringList newArgs(args); #ifdef Q_OS_UNIX newArgs << QString("--") + QString::fromStdString(berry::Platform::ARG_NEWINSTANCE); #else newArgs << QString("/") + QString::fromStdString(berry::Platform::ARG_NEWINSTANCE); #endif newArgs << files; QProcess::startDetached(qApp->applicationFilePath(), newArgs); } void QmitkCommonExtPlugin::handleIPCMessage(const QByteArray& msg) { QDataStream ds(msg); QString msgType; ds >> msgType; // we only handle messages containing command line arguments if (msgType != "$cmdLineArgs") return; // activate the current workbench window berry::IWorkbenchWindow::Pointer window = berry::PlatformUI::GetWorkbench()->GetActiveWorkbenchWindow(); QMainWindow* mainWindow = static_cast (window->GetShell()->GetControl()); mainWindow->setWindowState(mainWindow->windowState() & ~Qt::WindowMinimized); mainWindow->raise(); mainWindow->activateWindow(); // Get the preferences for the instantiation behavior berry::IPreferencesService::Pointer prefService = berry::Platform::GetServiceRegistry() .GetServiceById(berry::IPreferencesService::ID); berry::IPreferences::Pointer prefs = prefService->GetSystemPreferences()->Node("/General"); bool newInstanceAlways = prefs->GetBool("newInstance.always", false); bool newInstanceScene = prefs->GetBool("newInstance.scene", true); QStringList args; ds >> args; QStringList fileArgs; QStringList sceneArgs; Poco::Util::OptionSet os; berry::Platform::GetOptionSet(os); Poco::Util::OptionProcessor processor(os); #if !defined(POCO_OS_FAMILY_UNIX) processor.setUnixStyle(false); #endif args.pop_front(); QStringList::Iterator it = args.begin(); while (it != args.end()) { std::string name; std::string value; if (processor.process(it->toStdString(), name, value)) { ++it; } else { if (it->endsWith(".mitk")) { sceneArgs << *it; } else { fileArgs << *it; } it = args.erase(it); } } if (newInstanceAlways) { if (newInstanceScene) { startNewInstance(args, fileArgs); foreach(QString sceneFile, sceneArgs) { startNewInstance(args, QStringList(sceneFile)); } } else { fileArgs.append(sceneArgs); startNewInstance(args, fileArgs); } } else { loadDataFromDisk(fileArgs, false); if (newInstanceScene) { foreach(QString sceneFile, sceneArgs) { startNewInstance(args, QStringList(sceneFile)); } } else { loadDataFromDisk(sceneArgs, false); } } } -Q_EXPORT_PLUGIN2(org_mitk_gui_qt_ext, QmitkCommonExtPlugin) +#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) + Q_EXPORT_PLUGIN2(org_mitk_gui_qt_ext, QmitkCommonExtPlugin) +#endif diff --git a/Plugins/org.mitk.gui.qt.ext/src/internal/QmitkCommonExtPlugin.h b/Plugins/org.mitk.gui.qt.ext/src/internal/QmitkCommonExtPlugin.h index 82a93125a5..54835551cd 100644 --- a/Plugins/org.mitk.gui.qt.ext/src/internal/QmitkCommonExtPlugin.h +++ b/Plugins/org.mitk.gui.qt.ext/src/internal/QmitkCommonExtPlugin.h @@ -1,50 +1,53 @@ /*=================================================================== 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 QMITKCOMMONEXTPLUGIN_H_ #define QMITKCOMMONEXTPLUGIN_H_ #include class QmitkCommonExtPlugin : public QObject, public ctkPluginActivator { Q_OBJECT +#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) + Q_PLUGIN_METADATA(IID "org_mitk_gui_qt_ext") +#endif Q_INTERFACES(ctkPluginActivator) public: void start(ctkPluginContext* context); void stop(ctkPluginContext* context); static ctkPluginContext* getContext(); private: void loadDataFromDisk(const QStringList& args, bool globalReinit); void startNewInstance(const QStringList& args, const QStringList &files); private Q_SLOTS: void handleIPCMessage(const QByteArray &msg); private: static ctkPluginContext* _context; }; #endif /* QMITKCOMMONEXTPLUGIN_H_ */ diff --git a/Plugins/org.mitk.gui.qt.ext/src/internal/QmitkExternalProgramsPreferencePage.cpp b/Plugins/org.mitk.gui.qt.ext/src/internal/QmitkExternalProgramsPreferencePage.cpp index af8e485885..6e1f622a3c 100644 --- a/Plugins/org.mitk.gui.qt.ext/src/internal/QmitkExternalProgramsPreferencePage.cpp +++ b/Plugins/org.mitk.gui.qt.ext/src/internal/QmitkExternalProgramsPreferencePage.cpp @@ -1,136 +1,190 @@ /*=================================================================== 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 #include #include #include #include #include #include #include #include "QmitkExternalProgramsPreferencePage.h" static berry::IPreferences::Pointer GetPreferences() { berry::IPreferencesService::Pointer preferencesService = berry::Platform::GetServiceRegistry().GetServiceById(berry::IPreferencesService::ID); if (preferencesService.IsNotNull()) { berry::IPreferences::Pointer systemPreferences = preferencesService->GetSystemPreferences(); if (systemPreferences.IsNotNull()) return systemPreferences->Node("/org.mitk.gui.qt.ext.externalprograms"); } mitkThrow(); } QmitkExternalProgramsPreferencePage::QmitkExternalProgramsPreferencePage() : m_Preferences(GetPreferences()), m_Ui(new Ui::QmitkExternalProgramsPreferencePage), m_Control(NULL), + m_FFmpegProcess(NULL), m_GnuplotProcess(NULL) { } QmitkExternalProgramsPreferencePage::~QmitkExternalProgramsPreferencePage() { } void QmitkExternalProgramsPreferencePage::CreateQtControl(QWidget* parent) { m_Control = new QWidget(parent); + m_FFmpegProcess = new QProcess(m_Control); m_GnuplotProcess = new QProcess(m_Control); m_Ui->setupUi(m_Control); + connect(m_FFmpegProcess, SIGNAL(error(QProcess::ProcessError)), this, SLOT(OnFFmpegProcessError(QProcess::ProcessError))); + connect(m_FFmpegProcess, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(OnFFmpegProcessFinished(int, QProcess::ExitStatus))); + connect(m_Ui->ffmpegButton, SIGNAL(clicked()), this, SLOT(OnFFmpegButtonClicked())); + connect(m_GnuplotProcess, SIGNAL(error(QProcess::ProcessError)), this, SLOT(OnGnuplotProcessError(QProcess::ProcessError))); connect(m_GnuplotProcess, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(OnGnuplotProcessFinished(int, QProcess::ExitStatus))); connect(m_Ui->gnuplotButton, SIGNAL(clicked()), this, SLOT(OnGnuplotButtonClicked())); this->Update(); } +void QmitkExternalProgramsPreferencePage::OnFFmpegButtonClicked() +{ + QString filter = "ffmpeg/avconv executable "; + +#if defined(WIN32) + filter += "(ffmpeg.exe avconv.exe)"; +#else + filter += "(ffmpeg avconv)"; +#endif + + QString ffmpegPath = QFileDialog::getOpenFileName(m_Control, "FFmpeg/Libav", "", filter); + + if (!ffmpegPath.isEmpty()) + { + m_FFmpegPath = ffmpegPath; + m_FFmpegProcess->start(ffmpegPath, QStringList() << "-version", QProcess::ReadOnly); + } +} + +void QmitkExternalProgramsPreferencePage::OnFFmpegProcessError(QProcess::ProcessError) +{ + m_FFmpegPath.clear(); + m_Ui->ffmpegLineEdit->clear(); +} + +void QmitkExternalProgramsPreferencePage::OnFFmpegProcessFinished(int exitCode, QProcess::ExitStatus exitStatus) +{ + if (exitStatus == QProcess::NormalExit && exitCode == 0) + { + QString output = QTextCodec::codecForName("UTF-8")->toUnicode(m_FFmpegProcess->readAllStandardOutput()); + + if (output.startsWith("ffmpeg") || output.startsWith("avconv")) + { + m_Ui->ffmpegLineEdit->setText(m_FFmpegPath); + return; + } + } + + m_FFmpegPath.clear(); + m_Ui->ffmpegLineEdit->clear(); +} + void QmitkExternalProgramsPreferencePage::OnGnuplotButtonClicked() { - QString filter = "Gnuplot executable "; + QString filter = "gnuplot executable "; #if defined(WIN32) filter += "(gnuplot.exe)"; #else filter += "(gnuplot)"; #endif QString gnuplotPath = QFileDialog::getOpenFileName(m_Control, "Gnuplot", "", filter); if (!gnuplotPath.isEmpty()) { m_GnuplotPath = gnuplotPath; m_GnuplotProcess->start(gnuplotPath, QStringList() << "--version", QProcess::ReadOnly); } } void QmitkExternalProgramsPreferencePage::OnGnuplotProcessError(QProcess::ProcessError) { m_GnuplotPath.clear(); m_Ui->gnuplotLineEdit->clear(); } void QmitkExternalProgramsPreferencePage::OnGnuplotProcessFinished(int exitCode, QProcess::ExitStatus exitStatus) { if (exitStatus == QProcess::NormalExit && exitCode == 0) { - QString version = QTextCodec::codecForName("UTF-8")->toUnicode(m_GnuplotProcess->readAllStandardOutput()).trimmed(); + QString output = QTextCodec::codecForName("UTF-8")->toUnicode(m_GnuplotProcess->readAllStandardOutput()); - if (version.startsWith("gnuplot")) + if (output.startsWith("gnuplot")) { - m_Ui->gnuplotLineEdit->setText(QString("%1 (%2)").arg(m_GnuplotPath).arg(version.trimmed())); + m_Ui->gnuplotLineEdit->setText(m_GnuplotPath); return; } } m_GnuplotPath.clear(); m_Ui->gnuplotLineEdit->clear(); } QWidget* QmitkExternalProgramsPreferencePage::GetQtControl() const { return m_Control; } void QmitkExternalProgramsPreferencePage::Init(berry::IWorkbench::Pointer) { } void QmitkExternalProgramsPreferencePage::PerformCancel() { } bool QmitkExternalProgramsPreferencePage::PerformOk() { + m_Preferences->Put("ffmpeg", m_FFmpegPath.toStdString()); m_Preferences->Put("gnuplot", m_GnuplotPath.toStdString()); return true; } void QmitkExternalProgramsPreferencePage::Update() { + m_FFmpegPath = QString::fromStdString(m_Preferences->Get("ffmpeg", "")); + + if (!m_FFmpegPath.isEmpty()) + m_FFmpegProcess->start(m_FFmpegPath, QStringList() << "-version", QProcess::ReadOnly); + m_GnuplotPath = QString::fromStdString(m_Preferences->Get("gnuplot", "")); if (!m_GnuplotPath.isEmpty()) m_GnuplotProcess->start(m_GnuplotPath, QStringList() << "--version", QProcess::ReadOnly); } diff --git a/Plugins/org.mitk.gui.qt.ext/src/internal/QmitkExternalProgramsPreferencePage.h b/Plugins/org.mitk.gui.qt.ext/src/internal/QmitkExternalProgramsPreferencePage.h index e766b3b400..fb4da45609 100644 --- a/Plugins/org.mitk.gui.qt.ext/src/internal/QmitkExternalProgramsPreferencePage.h +++ b/Plugins/org.mitk.gui.qt.ext/src/internal/QmitkExternalProgramsPreferencePage.h @@ -1,59 +1,67 @@ /*=================================================================== 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 QmitkExternalProgramsPreferencePage_h #define QmitkExternalProgramsPreferencePage_h #include #include #include #include namespace Ui { class QmitkExternalProgramsPreferencePage; } class QmitkExternalProgramsPreferencePage : public QObject, public berry::IQtPreferencePage { Q_OBJECT Q_INTERFACES(berry::IPreferencePage) public: QmitkExternalProgramsPreferencePage(); ~QmitkExternalProgramsPreferencePage(); void CreateQtControl(QWidget* parent); QWidget* GetQtControl() const; void Init(berry::IWorkbench::Pointer); void PerformCancel(); bool PerformOk(); void Update(); private slots: + void OnFFmpegButtonClicked(); + void OnFFmpegProcessError(QProcess::ProcessError error); + void OnFFmpegProcessFinished(int exitCode, QProcess::ExitStatus exitStatus); + void OnGnuplotButtonClicked(); void OnGnuplotProcessError(QProcess::ProcessError error); void OnGnuplotProcessFinished(int exitCode, QProcess::ExitStatus exitStatus); private: berry::IPreferences::Pointer m_Preferences; QScopedPointer m_Ui; QWidget* m_Control; + + QProcess* m_FFmpegProcess; + QString m_FFmpegPath; + QProcess* m_GnuplotProcess; QString m_GnuplotPath; }; #endif diff --git a/Plugins/org.mitk.gui.qt.ext/src/internal/QmitkExternalProgramsPreferencePage.ui b/Plugins/org.mitk.gui.qt.ext/src/internal/QmitkExternalProgramsPreferencePage.ui index ace9d303c8..428b27c526 100644 --- a/Plugins/org.mitk.gui.qt.ext/src/internal/QmitkExternalProgramsPreferencePage.ui +++ b/Plugins/org.mitk.gui.qt.ext/src/internal/QmitkExternalProgramsPreferencePage.ui @@ -1,65 +1,92 @@ QmitkExternalProgramsPreferencePage 0 0 400 300 External Programs - - + + + + + FFmpeg/Libav: + + + Qt::PlainText + + + gnuplotButton + + + + + + + true + + + + + + + ... + + + + - Gnuplot &executable: + gnuplot: Qt::PlainText gnuplotButton - + true - + ... Qt::Vertical 20 248 diff --git a/Plugins/org.mitk.gui.qt.ext/src/internal/QmitkModuleView.cpp b/Plugins/org.mitk.gui.qt.ext/src/internal/QmitkModuleView.cpp index 05fbff3d5f..0e7b708225 100644 --- a/Plugins/org.mitk.gui.qt.ext/src/internal/QmitkModuleView.cpp +++ b/Plugins/org.mitk.gui.qt.ext/src/internal/QmitkModuleView.cpp @@ -1,100 +1,105 @@ /*=================================================================== 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 "QmitkModuleView.h" #include #include #include #include #include #include QmitkModuleView::QmitkModuleView() : tableView(0) { } void QmitkModuleView::SetFocus() { //tableView->setFocus(); } void QmitkModuleView::CreateQtPartControl(QWidget *parent) { QHBoxLayout* layout = new QHBoxLayout(); layout->setMargin(0); parent->setLayout(layout); tableView = new QTableView(parent); QmitkModuleTableModel* tableModel = new QmitkModuleTableModel(tableView); QSortFilterProxyModel* sortProxyModel = new QSortFilterProxyModel(tableView); sortProxyModel->setSourceModel(tableModel); sortProxyModel->setDynamicSortFilter(true); tableView->setModel(sortProxyModel); tableView->verticalHeader()->hide(); tableView->setHorizontalScrollMode(QAbstractItemView::ScrollPerPixel); tableView->setSelectionBehavior(QAbstractItemView::SelectRows); tableView->setSelectionMode(QAbstractItemView::ExtendedSelection); tableView->setTextElideMode(Qt::ElideMiddle); tableView->setSortingEnabled(true); tableView->sortByColumn(0, Qt::AscendingOrder); +#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) // Fixed size for "Id" column tableView->horizontalHeader()->setResizeMode(0, QHeaderView::ResizeToContents); // Fixed size for "Version" column tableView->horizontalHeader()->setResizeMode(2, QHeaderView::ResizeToContents); +#else + tableView->horizontalHeader()->setSectionResizeMode(0, QHeaderView::ResizeToContents); + tableView->horizontalHeader()->setSectionResizeMode(2, QHeaderView::ResizeToContents); +#endif tableView->horizontalHeader()->setStretchLastSection(true); tableView->horizontalHeader()->setCascadingSectionResizes(true); layout->addWidget(tableView); if (viewState) { berry::IMemento::Pointer tableHeaderState = viewState->GetChild("tableHeader"); if (tableHeaderState) { std::string key; tableHeaderState->GetString("qsettings-key", key); if (!key.empty()) { QSettings settings; QByteArray ba = settings.value(QString::fromStdString(key)).toByteArray(); tableView->horizontalHeader()->restoreState(ba); } } } } void QmitkModuleView::Init(berry::IViewSite::Pointer site, berry::IMemento::Pointer memento) { berry::QtViewPart::Init(site, memento); viewState = memento; } void QmitkModuleView::SaveState(berry::IMemento::Pointer memento) { QString key = "QmitkModuleView_tableHeader"; QByteArray ba = tableView->horizontalHeader()->saveState(); QSettings settings; settings.setValue(key, ba); berry::IMemento::Pointer tableHeaderState = memento->CreateChild("tableHeader"); tableHeaderState->PutString("qsettings-key", key.toStdString()); } diff --git a/Plugins/org.mitk.gui.qt.extapplication/CMakeLists.txt b/Plugins/org.mitk.gui.qt.extapplication/CMakeLists.txt index 8ffe39bbf9..4f0146d128 100644 --- a/Plugins/org.mitk.gui.qt.extapplication/CMakeLists.txt +++ b/Plugins/org.mitk.gui.qt.extapplication/CMakeLists.txt @@ -1,11 +1,17 @@ project(org_mitk_gui_qt_extapplication) MACRO_CREATE_MITK_CTK_PLUGIN( EXPORT_DIRECTIVE MITK_QT_EXTAPP EXPORTED_INCLUDE_SUFFIXES src - PACKAGE_DEPENDS Qt4|QtWebKit + PACKAGE_DEPENDS Qt4|QtWebKit Qt5|WebKit ) -if(QT_QTWEBKIT_FOUND) - add_definitions(-DQT_WEBKIT) -endif(QT_QTWEBKIT_FOUND) +if (DESIRED_QT_VERSION MATCHES "5") + if (Qt5WebKit_DIR) + add_definitions(-DQT_WEBKIT) + endif() +else() + if(QT_QTWEBKIT_FOUND) + add_definitions(-DQT_WEBKIT) + endif(QT_QTWEBKIT_FOUND) +endif() diff --git a/Plugins/org.mitk.gui.qt.extapplication/src/internal/QmitkExtApplicationPlugin.cpp b/Plugins/org.mitk.gui.qt.extapplication/src/internal/QmitkExtApplicationPlugin.cpp index 55d66f1e9e..76a334ca60 100644 --- a/Plugins/org.mitk.gui.qt.extapplication/src/internal/QmitkExtApplicationPlugin.cpp +++ b/Plugins/org.mitk.gui.qt.extapplication/src/internal/QmitkExtApplicationPlugin.cpp @@ -1,90 +1,92 @@ /*=================================================================== 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 "QmitkExtApplicationPlugin.h" #include "perspectives/QmitkExtDefaultPerspective.h" #include "perspectives/QmitkEditorPerspective.h" #include "perspectives/QmitkVisualizationPerspective.h" #include "QmitkMitkWorkbenchIntroPart.h" #include "QmitkExtApplication.h" #include #include #include #include #include #include #include QmitkExtApplicationPlugin* QmitkExtApplicationPlugin::inst = 0; QmitkExtApplicationPlugin::QmitkExtApplicationPlugin() { inst = this; } QmitkExtApplicationPlugin::~QmitkExtApplicationPlugin() { } QmitkExtApplicationPlugin* QmitkExtApplicationPlugin::GetDefault() { return inst; } void QmitkExtApplicationPlugin::start(ctkPluginContext* context) { berry::AbstractUICTKPlugin::start(context); this->context = context; BERRY_REGISTER_EXTENSION_CLASS(QmitkExtDefaultPerspective, context); BERRY_REGISTER_EXTENSION_CLASS(QmitkEditorPerspective, context); BERRY_REGISTER_EXTENSION_CLASS(QmitkMitkWorkbenchIntroPart, context); BERRY_REGISTER_EXTENSION_CLASS(QmitkExtApplication, context); BERRY_REGISTER_EXTENSION_CLASS(QmitkVisualizationPerspective, context); ctkServiceReference cmRef = context->getServiceReference(); ctkConfigurationAdmin* configAdmin = 0; if (cmRef) { configAdmin = context->getService(cmRef); } // Use the CTK Configuration Admin service to configure the BlueBerry help system if (configAdmin) { ctkConfigurationPtr conf = configAdmin->getConfiguration("org.blueberry.services.help", QString()); ctkDictionary helpProps; helpProps.insert("homePage", "qthelp://org.mitk.gui.qt.extapplication/bundle/index.html"); conf->update(helpProps); context->ungetService(cmRef); } else { MITK_WARN << "Configuration Admin service unavailable, cannot set home page url."; } } ctkPluginContext* QmitkExtApplicationPlugin::GetPluginContext() const { return context; } -Q_EXPORT_PLUGIN2(org_mitk_gui_qt_extapplication, QmitkExtApplicationPlugin) +#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) + Q_EXPORT_PLUGIN2(org_mitk_gui_qt_extapplication, QmitkExtApplicationPlugin) +#endif diff --git a/Plugins/org.mitk.gui.qt.extapplication/src/internal/QmitkExtApplicationPlugin.h b/Plugins/org.mitk.gui.qt.extapplication/src/internal/QmitkExtApplicationPlugin.h index 168124b30f..0387cc5af9 100644 --- a/Plugins/org.mitk.gui.qt.extapplication/src/internal/QmitkExtApplicationPlugin.h +++ b/Plugins/org.mitk.gui.qt.extapplication/src/internal/QmitkExtApplicationPlugin.h @@ -1,52 +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 QMITKEXTAPPLICATIONPLUGIN_H_ #define QMITKEXTAPPLICATIONPLUGIN_H_ #include #include #include class QmitkExtApplicationPlugin : public QObject, public berry::AbstractUICTKPlugin { Q_OBJECT +#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) + Q_PLUGIN_METADATA(IID "org_mitk_gui_qt_extapplication") +#endif Q_INTERFACES(ctkPluginActivator) public: QmitkExtApplicationPlugin(); ~QmitkExtApplicationPlugin(); static QmitkExtApplicationPlugin* GetDefault(); ctkPluginContext* GetPluginContext() const; void start(ctkPluginContext*); QString GetQtHelpCollectionFile() const; private: static QmitkExtApplicationPlugin* inst; ctkPluginContext* context; }; #endif /* QMITKEXTAPPLICATIONPLUGIN_H_ */ diff --git a/Plugins/org.mitk.gui.qt.extapplication/src/internal/QmitkMitkWorkbenchIntroPart.cpp b/Plugins/org.mitk.gui.qt.extapplication/src/internal/QmitkMitkWorkbenchIntroPart.cpp index b415c12118..093d3dac13 100644 --- a/Plugins/org.mitk.gui.qt.extapplication/src/internal/QmitkMitkWorkbenchIntroPart.cpp +++ b/Plugins/org.mitk.gui.qt.extapplication/src/internal/QmitkMitkWorkbenchIntroPart.cpp @@ -1,203 +1,214 @@ /*=================================================================== 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 "QmitkMitkWorkbenchIntroPart.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef QT_WEBKIT -#include -#include +# include +# include +# if QT_VERSION >= QT_VERSION_CHECK(5,0,0) +# include +# endif #endif #include #include #include #include #include #include #include "QmitkExtApplicationPlugin.h" #include "mitkDataStorageEditorInput.h" #include QmitkMitkWorkbenchIntroPart::QmitkMitkWorkbenchIntroPart() : m_Controls(NULL) { berry::IPreferences::Pointer workbenchPrefs = QmitkExtApplicationPlugin::GetDefault()->GetPreferencesService()->GetSystemPreferences(); workbenchPrefs->PutBool(berry::WorkbenchPreferenceConstants::SHOW_INTRO, true); workbenchPrefs->Flush(); } QmitkMitkWorkbenchIntroPart::~QmitkMitkWorkbenchIntroPart() { // if the workbench is not closing (that means, welcome screen was closed explicitly), set "Show_intro" false if (!this->GetIntroSite()->GetPage()->GetWorkbenchWindow()->GetWorkbench()->IsClosing()) { berry::IPreferences::Pointer workbenchPrefs = QmitkExtApplicationPlugin::GetDefault()->GetPreferencesService()->GetSystemPreferences(); workbenchPrefs->PutBool(berry::WorkbenchPreferenceConstants::SHOW_INTRO, false); workbenchPrefs->Flush(); } else { berry::IPreferences::Pointer workbenchPrefs = QmitkExtApplicationPlugin::GetDefault()->GetPreferencesService()->GetSystemPreferences(); workbenchPrefs->PutBool(berry::WorkbenchPreferenceConstants::SHOW_INTRO, true); workbenchPrefs->Flush(); } // if workbench is not closing (Just welcome screen closing), open last used perspective if (this->GetIntroSite()->GetPage()->GetPerspective()->GetId() == "org.mitk.mitkworkbench.perspectives.editor" && !this->GetIntroSite()->GetPage()->GetWorkbenchWindow()->GetWorkbench()->IsClosing()) { berry::IPerspectiveDescriptor::Pointer perspective = this->GetIntroSite()->GetWorkbenchWindow()->GetWorkbench()->GetPerspectiveRegistry()->FindPerspectiveWithId("org.mitk.mitkworkbench.perspectives.editor"); if (perspective) { this->GetIntroSite()->GetPage()->SetPerspective(perspective); } } } void QmitkMitkWorkbenchIntroPart::CreateQtPartControl(QWidget* parent) { if (!m_Controls) { // create GUI widgets m_Controls = new Ui::QmitkWelcomeScreenViewControls; m_Controls->setupUi(parent); #ifdef QT_WEBKIT // create a QWebView as well as a QWebPage and QWebFrame within the QWebview m_view = new QWebView(parent); m_view->page()->setLinkDelegationPolicy(QWebPage::DelegateAllLinks); QUrl urlQtResource(QString("qrc:/org.mitk.gui.qt.welcomescreen/mitkworkbenchwelcomeview.html"), QUrl::TolerantMode ); m_view->load( urlQtResource ); // adds the webview as a widget parent->layout()->addWidget(m_view); this->CreateConnections(); #else parent->layout()->addWidget(new QLabel("

Please install Qt with the WebKit option to see cool pictures!

")); #endif } } #ifdef QT_WEBKIT void QmitkMitkWorkbenchIntroPart::CreateConnections() { if ( m_Controls ) { connect( (QObject*)(m_view->page()), SIGNAL(linkClicked(const QUrl& )), this, SLOT(DelegateMeTo(const QUrl& )) ); } } void QmitkMitkWorkbenchIntroPart::DelegateMeTo(const QUrl& showMeNext) { QString scheme = showMeNext.scheme(); +#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) QByteArray urlHostname = showMeNext.encodedHost(); QByteArray urlPath = showMeNext.encodedPath(); QByteArray dataset = showMeNext.encodedQueryItemValue("dataset"); QByteArray clear = showMeNext.encodedQueryItemValue("clear"); +#else + QByteArray urlHostname = QUrl::toAce(showMeNext.host()); + QByteArray urlPath = showMeNext.path().toLatin1(); + QUrlQuery query(showMeNext); + QByteArray dataset = query.queryItemValue("dataset").toLatin1(); + QByteArray clear = query.queryItemValue("clear").toLatin1();//showMeNext.encodedQueryItemValue("clear"); +#endif if (scheme.isEmpty()) MITK_INFO << " empty scheme of the to be delegated link" ; // if the scheme is set to mitk, it is to be tested which action should be applied if (scheme.contains(QString("mitk")) ) { if(urlPath.isEmpty() ) MITK_INFO << " mitk path is empty " ; // searching for the perspective keyword within the host name if(urlHostname.contains(QByteArray("perspectives")) ) { // the simplified method removes every whitespace // ( whitespace means any character for which the standard C++ isspace() method returns true) urlPath = urlPath.simplified(); QString tmpPerspectiveId(urlPath.data()); tmpPerspectiveId.replace(QString("/"), QString("") ); std::string perspectiveId = tmpPerspectiveId.toStdString(); // is working fine as long as the perspective id is valid, if not the application crashes GetIntroSite()->GetWorkbenchWindow()->GetWorkbench()->ShowPerspective(perspectiveId, GetIntroSite()->GetWorkbenchWindow() ); // search the Workbench for opened StdMultiWidgets to ensure the focus does not stay on the welcome screen and is switched to // an StdMultiWidget if one available mitk::IDataStorageService::Pointer service = berry::Platform::GetServiceRegistry().GetServiceById(mitk::IDataStorageService::ID); berry::IEditorInput::Pointer editorInput; editorInput = new mitk::DataStorageEditorInput( service->GetActiveDataStorage() ); // the solution is not clean, but the dependency to the StdMultiWidget was removed in order to fix a crash problem // as described in Bug #11715 // This is the correct way : use the static string ID variable // berry::IEditorPart::Pointer editor = GetIntroSite()->GetPage()->FindEditors( editorInput, QmitkStdMultiWidgetEditor::EDITOR_ID ); // QuickFix: we use the same string for an local variable const std::string stdEditorID = "org.mitk.editors.stdmultiwidget"; // search for opened StdMultiWidgetEditors std::vector editorList = GetIntroSite()->GetPage()->FindEditors( editorInput, stdEditorID, 1 ); // if an StdMultiWidgetEditor open was found, give focus to it if(editorList.size()) { GetIntroSite()->GetPage()->Activate( editorList[0]->GetPart(true) ); } } } // if the scheme is set to http, by default no action is performed, if an external webpage needs to be // shown it should be implemented below else if (scheme.contains(QString("http")) ) { QDesktopServices::openUrl(showMeNext); // m_view->load( ) ; } else if(scheme.contains("qrc")) { m_view->load(showMeNext); } } #endif void QmitkMitkWorkbenchIntroPart::StandbyStateChanged(bool standby) { } void QmitkMitkWorkbenchIntroPart::SetFocus() { } diff --git a/Plugins/org.mitk.gui.qt.igtexamples/src/internal/mitkPluginActivator.cpp b/Plugins/org.mitk.gui.qt.igtexamples/src/internal/mitkPluginActivator.cpp index f81bd5e67b..1bcd8603be 100644 --- a/Plugins/org.mitk.gui.qt.igtexamples/src/internal/mitkPluginActivator.cpp +++ b/Plugins/org.mitk.gui.qt.igtexamples/src/internal/mitkPluginActivator.cpp @@ -1,37 +1,39 @@ /*=================================================================== 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 "mitkPluginActivator.h" #include "QmitkIGTTutorialView.h" #include "QmitkIGTTrackingLabView.h" #include namespace mitk { void PluginActivator::start(ctkPluginContext* context) { BERRY_REGISTER_EXTENSION_CLASS(QmitkIGTTutorialView, context) BERRY_REGISTER_EXTENSION_CLASS(QmitkIGTTrackingLabView, context) } void PluginActivator::stop(ctkPluginContext* context) { Q_UNUSED(context) } } -Q_EXPORT_PLUGIN2(org_mitk_gui_qt_igtexamples, mitk::PluginActivator) +#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) + Q_EXPORT_PLUGIN2(org_mitk_gui_qt_igtexamples, mitk::PluginActivator) +#endif diff --git a/Plugins/org.mitk.gui.qt.igtexamples/src/internal/mitkPluginActivator.h b/Plugins/org.mitk.gui.qt.igtexamples/src/internal/mitkPluginActivator.h index 12053e09e3..e6e9d7b23e 100644 --- a/Plugins/org.mitk.gui.qt.igtexamples/src/internal/mitkPluginActivator.h +++ b/Plugins/org.mitk.gui.qt.igtexamples/src/internal/mitkPluginActivator.h @@ -1,39 +1,42 @@ /*=================================================================== 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 MITKPLUGINACTIVATOR_H #define MITKPLUGINACTIVATOR_H #include #include namespace mitk { class MITK_LOCAL PluginActivator : public QObject, public ctkPluginActivator { Q_OBJECT +#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) + Q_PLUGIN_METADATA(IID "org_mitk_gui_qt_igtexamples") +#endif Q_INTERFACES(ctkPluginActivator) public: void start(ctkPluginContext* context); void stop(ctkPluginContext* context); }; // PluginActivator } #endif // MITKPLUGINACTIVATOR_H diff --git a/Plugins/org.mitk.gui.qt.igttracking/src/internal/mitkPluginActivator.cpp b/Plugins/org.mitk.gui.qt.igttracking/src/internal/mitkPluginActivator.cpp index dac2744b3f..578dae18ac 100644 --- a/Plugins/org.mitk.gui.qt.igttracking/src/internal/mitkPluginActivator.cpp +++ b/Plugins/org.mitk.gui.qt.igttracking/src/internal/mitkPluginActivator.cpp @@ -1,52 +1,54 @@ /*=================================================================== 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 "mitkPluginActivator.h" #include #include "QmitkMITKIGTNavigationToolManagerView.h" #include "QmitkMITKIGTTrackingToolboxView.h" #include "QmitkNavigationDataPlayerView.h" //#include //Workaround for bug in persistence module (see bug 16643 for details) //CAN BE REMOVED WHEN THE BUG IS FIXED namespace mitk { void PluginActivator::start(ctkPluginContext* context) { // mitk::PersistenceService::LoadModule(); //Workaround for bug in persistence module (see bug 16643 for details) //CAN BE REMOVED WHEN THE BUG IS FIXED BERRY_REGISTER_EXTENSION_CLASS(QmitkMITKIGTNavigationToolManagerView, context) BERRY_REGISTER_EXTENSION_CLASS( QmitkMITKIGTTrackingToolboxView , context) BERRY_REGISTER_EXTENSION_CLASS( QmitkNavigationDataPlayerView , context) } void PluginActivator::stop(ctkPluginContext* context) { Q_UNUSED(context) } } -Q_EXPORT_PLUGIN2(org_mitk_gui_qt_igttracking, mitk::PluginActivator) +#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) + Q_EXPORT_PLUGIN2(org_mitk_gui_qt_igttracking, mitk::PluginActivator) +#endif diff --git a/Plugins/org.mitk.gui.qt.igttracking/src/internal/mitkPluginActivator.h b/Plugins/org.mitk.gui.qt.igttracking/src/internal/mitkPluginActivator.h index bcc0aed5a2..968e2aad26 100644 --- a/Plugins/org.mitk.gui.qt.igttracking/src/internal/mitkPluginActivator.h +++ b/Plugins/org.mitk.gui.qt.igttracking/src/internal/mitkPluginActivator.h @@ -1,40 +1,43 @@ /*=================================================================== 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 MITKPLUGINACTIVATOR_H #define MITKPLUGINACTIVATOR_H #include namespace mitk { class PluginActivator : public QObject, public ctkPluginActivator { Q_OBJECT +#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) + Q_PLUGIN_METADATA(IID "org_mitk_gui_qt_igttracking") +#endif Q_INTERFACES(ctkPluginActivator) public: void start(ctkPluginContext* context); void stop(ctkPluginContext* context); }; // PluginActivator } #endif // MITKPLUGINACTIVATOR_H diff --git a/Plugins/org.mitk.gui.qt.imagecropper/src/internal/mitkImageCropperPluginActivator.cpp b/Plugins/org.mitk.gui.qt.imagecropper/src/internal/mitkImageCropperPluginActivator.cpp index c3f9c4dec9..874d543673 100644 --- a/Plugins/org.mitk.gui.qt.imagecropper/src/internal/mitkImageCropperPluginActivator.cpp +++ b/Plugins/org.mitk.gui.qt.imagecropper/src/internal/mitkImageCropperPluginActivator.cpp @@ -1,35 +1,37 @@ /*=================================================================== 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 "mitkImageCropperPluginActivator.h" #include "QmitkImageCropper.h" #include namespace mitk { void ImageCropperPluginActivator::start(ctkPluginContext* context) { BERRY_REGISTER_EXTENSION_CLASS( QmitkImageCropper, context ) } void ImageCropperPluginActivator::stop(ctkPluginContext* context) { Q_UNUSED(context) } } -Q_EXPORT_PLUGIN2(org_mitk_gui_qt_imagecropper, mitk::ImageCropperPluginActivator) +#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) + Q_EXPORT_PLUGIN2(org_mitk_gui_qt_imagecropper, mitk::ImageCropperPluginActivator) +#endif diff --git a/Plugins/org.mitk.gui.qt.imagecropper/src/internal/mitkImageCropperPluginActivator.h b/Plugins/org.mitk.gui.qt.imagecropper/src/internal/mitkImageCropperPluginActivator.h index 395a280167..3d77c1ee15 100644 --- a/Plugins/org.mitk.gui.qt.imagecropper/src/internal/mitkImageCropperPluginActivator.h +++ b/Plugins/org.mitk.gui.qt.imagecropper/src/internal/mitkImageCropperPluginActivator.h @@ -1,38 +1,41 @@ /*=================================================================== 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 MITKPLUGINACTIVATOR_H #define MITKPLUGINACTIVATOR_H #include namespace mitk { class ImageCropperPluginActivator : public QObject, public ctkPluginActivator { Q_OBJECT +#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) + Q_PLUGIN_METADATA(IID "org_mitk_gui_qt_imagecropper") +#endif Q_INTERFACES(ctkPluginActivator) public: void start(ctkPluginContext* context); void stop(ctkPluginContext* context); }; // PluginActivator } #endif // MITKPLUGINACTIVATOR_H diff --git a/Plugins/org.mitk.gui.qt.imagenavigator/src/internal/mitkImageNavigatorPluginActivator.cpp b/Plugins/org.mitk.gui.qt.imagenavigator/src/internal/mitkImageNavigatorPluginActivator.cpp index 5dafa9f935..c2312a81d2 100644 --- a/Plugins/org.mitk.gui.qt.imagenavigator/src/internal/mitkImageNavigatorPluginActivator.cpp +++ b/Plugins/org.mitk.gui.qt.imagenavigator/src/internal/mitkImageNavigatorPluginActivator.cpp @@ -1,36 +1,38 @@ /*=================================================================== 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 "mitkImageNavigatorPluginActivator.h" #include "QmitkImageNavigatorView.h" #include namespace mitk { void ImageNavigatorPluginActivator::start(ctkPluginContext* context) { BERRY_REGISTER_EXTENSION_CLASS(QmitkImageNavigatorView, context) } void ImageNavigatorPluginActivator::stop(ctkPluginContext* context) { Q_UNUSED(context) } } -Q_EXPORT_PLUGIN2(org_mitk_gui_qt_imagenavigator, mitk::ImageNavigatorPluginActivator) +#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) + Q_EXPORT_PLUGIN2(org_mitk_gui_qt_imagenavigator, mitk::ImageNavigatorPluginActivator) +#endif diff --git a/Plugins/org.mitk.gui.qt.imagenavigator/src/internal/mitkImageNavigatorPluginActivator.h b/Plugins/org.mitk.gui.qt.imagenavigator/src/internal/mitkImageNavigatorPluginActivator.h index f01e093d00..27dabb9f00 100644 --- a/Plugins/org.mitk.gui.qt.imagenavigator/src/internal/mitkImageNavigatorPluginActivator.h +++ b/Plugins/org.mitk.gui.qt.imagenavigator/src/internal/mitkImageNavigatorPluginActivator.h @@ -1,38 +1,41 @@ /*=================================================================== 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 MITKIMAGENAVIGATORPLUGINACTIVATOR_H #define MITKIMAGENAVIGATORPLUGINACTIVATOR_H #include namespace mitk { class ImageNavigatorPluginActivator : public QObject, public ctkPluginActivator { Q_OBJECT - Q_INTERFACES(ctkPluginActivator) +#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) + Q_PLUGIN_METADATA(IID "org_mitk_gui_qt_imagenavigator") +#endif + Q_INTERFACES(ctkPluginActivator) public: void start(ctkPluginContext* context); void stop(ctkPluginContext* context); }; // ImageNavigatorPluginActivator } #endif // MITKIMAGENAVIGATORPLUGINACTIVATOR_H diff --git a/Plugins/org.mitk.gui.qt.materialeditor/src/internal/mitkMaterialEditorPluginActivator.cpp b/Plugins/org.mitk.gui.qt.materialeditor/src/internal/mitkMaterialEditorPluginActivator.cpp index b137a40f5c..2b93d4e8f6 100644 --- a/Plugins/org.mitk.gui.qt.materialeditor/src/internal/mitkMaterialEditorPluginActivator.cpp +++ b/Plugins/org.mitk.gui.qt.materialeditor/src/internal/mitkMaterialEditorPluginActivator.cpp @@ -1,36 +1,38 @@ /*=================================================================== 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 "mitkMaterialEditorPluginActivator.h" #include "QmitkMITKSurfaceMaterialEditorView.h" #include namespace mitk { void MaterialEditorPluginActivator::start(ctkPluginContext* context) { BERRY_REGISTER_EXTENSION_CLASS(QmitkMITKSurfaceMaterialEditorView, context) } void MaterialEditorPluginActivator::stop(ctkPluginContext* context) { Q_UNUSED(context) } } -Q_EXPORT_PLUGIN2(org_mitk_gui_qt_materialeditor, mitk::MaterialEditorPluginActivator) +#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) + Q_EXPORT_PLUGIN2(org_mitk_gui_qt_materialeditor, mitk::MaterialEditorPluginActivator) +#endif diff --git a/Plugins/org.mitk.gui.qt.materialeditor/src/internal/mitkMaterialEditorPluginActivator.h b/Plugins/org.mitk.gui.qt.materialeditor/src/internal/mitkMaterialEditorPluginActivator.h index adbb283970..6151f14c5a 100644 --- a/Plugins/org.mitk.gui.qt.materialeditor/src/internal/mitkMaterialEditorPluginActivator.h +++ b/Plugins/org.mitk.gui.qt.materialeditor/src/internal/mitkMaterialEditorPluginActivator.h @@ -1,38 +1,41 @@ /*=================================================================== 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 MITKMATERIALEDITORPLUGINACTIVATOR_H #define MITKMATERIALEDITORPLUGINACTIVATOR_H #include namespace mitk { class MaterialEditorPluginActivator : public QObject, public ctkPluginActivator { Q_OBJECT - Q_INTERFACES(ctkPluginActivator) +#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) + Q_PLUGIN_METADATA(IID "org_mitk_gui_qt_materialeditor") +#endif + Q_INTERFACES(ctkPluginActivator) public: void start(ctkPluginContext* context); void stop(ctkPluginContext* context); }; // MaterialEditorPluginActivator } #endif // MITKMATERIALEDITORPLUGINACTIVATOR_H diff --git a/Plugins/org.mitk.gui.qt.measurementtoolbox/src/internal/QmitkImageStatisticsView.cpp b/Plugins/org.mitk.gui.qt.measurementtoolbox/src/internal/QmitkImageStatisticsView.cpp index 7624375be4..1c09429e5f 100644 --- a/Plugins/org.mitk.gui.qt.measurementtoolbox/src/internal/QmitkImageStatisticsView.cpp +++ b/Plugins/org.mitk.gui.qt.measurementtoolbox/src/internal/QmitkImageStatisticsView.cpp @@ -1,992 +1,998 @@ /*=================================================================== 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 "QmitkImageStatisticsView.h" // Qt includes #include #include // berry includes #include // mitk includes #include "mitkNodePredicateDataType.h" #include "mitkPlanarFigureInteractor.h" // itk includes #include "itksys/SystemTools.hxx" #include #include const std::string QmitkImageStatisticsView::VIEW_ID = "org.mitk.views.imagestatistics"; const int QmitkImageStatisticsView::STAT_TABLE_BASE_HEIGHT = 180; QmitkImageStatisticsView::QmitkImageStatisticsView(QObject* /*parent*/, const char* /*name*/) : m_Controls( NULL ), m_TimeStepperAdapter( NULL ), m_SelectedImage( NULL ), m_SelectedImageMask( NULL ), m_SelectedPlanarFigure( NULL ), m_ImageObserverTag( -1 ), m_ImageMaskObserverTag( -1 ), m_PlanarFigureObserverTag( -1 ), m_TimeObserverTag( -1 ), m_CurrentStatisticsValid( false ), m_StatisticsUpdatePending( false ), m_DataNodeSelectionChanged ( false ), m_Visible(false) { this->m_CalculationThread = new QmitkImageStatisticsCalculationThread; } QmitkImageStatisticsView::~QmitkImageStatisticsView() { if ( m_SelectedImage != NULL ) m_SelectedImage->RemoveObserver( m_ImageObserverTag ); if ( m_SelectedImageMask != NULL ) m_SelectedImageMask->RemoveObserver( m_ImageMaskObserverTag ); if ( m_SelectedPlanarFigure != NULL ) m_SelectedPlanarFigure->RemoveObserver( m_PlanarFigureObserverTag ); while(this->m_CalculationThread->isRunning()) // wait until thread has finished { itksys::SystemTools::Delay(100); } delete this->m_CalculationThread; } void QmitkImageStatisticsView::CreateQtPartControl(QWidget *parent) { if (m_Controls == NULL) { m_Controls = new Ui::QmitkImageStatisticsViewControls; m_Controls->setupUi(parent); CreateConnections(); m_Controls->m_ErrorMessageLabel->hide(); m_Controls->m_StatisticsWidgetStack->setCurrentIndex( 0 ); m_Controls->m_BinSizeFrame->setVisible(false); } } void QmitkImageStatisticsView::CreateConnections() { if ( m_Controls ) { connect( (QObject*)(this->m_Controls->m_ButtonCopyHistogramToClipboard), SIGNAL(clicked()),(QObject*) this, SLOT(OnClipboardHistogramButtonClicked()) ); connect( (QObject*)(this->m_Controls->m_ButtonCopyStatisticsToClipboard), SIGNAL(clicked()),(QObject*) this, SLOT(OnClipboardStatisticsButtonClicked()) ); connect( (QObject*)(this->m_Controls->m_IgnoreZerosCheckbox), SIGNAL(clicked()),(QObject*) this, SLOT(OnIgnoreZerosCheckboxClicked()) ); connect( (QObject*) this->m_CalculationThread, SIGNAL(finished()),this, SLOT( OnThreadedStatisticsCalculationEnds()),Qt::QueuedConnection); connect( (QObject*) this, SIGNAL(StatisticsUpdate()),this, SLOT( RequestStatisticsUpdate()), Qt::QueuedConnection); connect( (QObject*) this->m_Controls->m_StatisticsTable, SIGNAL(cellDoubleClicked(int,int)),this, SLOT( JumpToCoordinates(int,int)) ); connect( (QObject*) (this->m_Controls->m_barRadioButton), SIGNAL(clicked()), (QObject*) (this->m_Controls->m_JSHistogram), SLOT(OnBarRadioButtonSelected())); connect( (QObject*) (this->m_Controls->m_lineRadioButton), SIGNAL(clicked()), (QObject*) (this->m_Controls->m_JSHistogram), SLOT(OnLineRadioButtonSelected())); connect( (QObject*) (this->m_Controls->m_HistogramBinSizeSpinbox), SIGNAL(editingFinished()), this, SLOT(OnHistogramBinSizeBoxValueChanged())); connect( (QObject*)(this->m_Controls->m_UseDefaultBinSizeBox), SIGNAL(clicked()),(QObject*) this, SLOT(OnDefaultBinSizeBoxChanged()) ); } } void QmitkImageStatisticsView::OnDefaultBinSizeBoxChanged() { if (m_CalculationThread!=NULL) m_Controls->m_HistogramBinSizeSpinbox->setValue(m_CalculationThread->GetHistogramBinSize()); if (m_Controls->m_UseDefaultBinSizeBox->isChecked()) m_Controls->m_BinSizeFrame->setVisible(false); else m_Controls->m_BinSizeFrame->setVisible(true); } void QmitkImageStatisticsView::PartClosed( berry::IWorkbenchPartReference::Pointer ) { } void QmitkImageStatisticsView::OnTimeChanged(const itk::EventObject& e) { if (this->m_SelectedDataNodes.isEmpty() || this->m_SelectedImage == NULL) return; const mitk::SliceNavigationController::GeometryTimeEvent* timeEvent = dynamic_cast(&e); assert(timeEvent != NULL); unsigned int timestep = timeEvent->GetPos(); if (this->m_SelectedImage->GetTimeSteps() > 1) { for (unsigned int x = 0; x < this->m_Controls->m_StatisticsTable->columnCount(); x++) { for (unsigned int y = 0; y < this->m_Controls->m_StatisticsTable->rowCount(); y++) { QTableWidgetItem* item = this->m_Controls->m_StatisticsTable->item(y, x); if (item == NULL) break; if (x == timestep) { item->setBackgroundColor(Qt::yellow); } else { if (y % 2 == 0) item->setBackground(this->m_Controls->m_StatisticsTable->palette().base()); else item->setBackground(this->m_Controls->m_StatisticsTable->palette().alternateBase()); } } } this->m_Controls->m_StatisticsTable->viewport()->update(); } if ((this->m_SelectedImage->GetTimeSteps() == 1 && timestep == 0) || this->m_SelectedImage->GetTimeSteps() > 1) { // display histogram for selected timestep this->m_Controls->m_JSHistogram->ClearHistogram(); QmitkImageStatisticsCalculationThread::HistogramType::Pointer histogram = this->m_CalculationThread->GetTimeStepHistogram(timestep); if (histogram.IsNotNull()) { this->m_Controls->m_JSHistogram->ComputeHistogram(histogram.GetPointer()); // this->m_Controls->m_JSHistogram->SignalGraphChanged(); // hacky way to make sure the protected SignalGraphChanged() is called if (this->m_Controls->m_JSHistogram->GetUseLineGraph()) { this->m_Controls->m_JSHistogram->OnBarRadioButtonSelected(); this->m_Controls->m_JSHistogram->OnLineRadioButtonSelected(); } else { this->m_Controls->m_JSHistogram->OnLineRadioButtonSelected(); this->m_Controls->m_JSHistogram->OnBarRadioButtonSelected(); } } } } void QmitkImageStatisticsView::JumpToCoordinates(int row ,int col) { if(m_SelectedDataNodes.isEmpty()) { MITK_WARN("QmitkImageStatisticsView") << "No data node selected for statistics calculation." ; return; } mitk::Point3D world; if (row==4 && !m_WorldMinList.empty()) world = m_WorldMinList[col]; else if (row==3 && !m_WorldMaxList.empty()) world = m_WorldMaxList[col]; else return; mitk::IRenderWindowPart* part = this->GetRenderWindowPart(); if (part) { part->GetQmitkRenderWindow("axial")->GetSliceNavigationController()->SelectSliceByPoint(world); part->GetQmitkRenderWindow("sagittal")->GetSliceNavigationController()->SelectSliceByPoint(world); part->GetQmitkRenderWindow("coronal")->GetSliceNavigationController()->SelectSliceByPoint(world); mitk::SliceNavigationController::GeometryTimeEvent timeEvent(this->m_SelectedImage->GetTimeGeometry(), col); part->GetQmitkRenderWindow("axial")->GetSliceNavigationController()->SetGeometryTime(timeEvent); } } void QmitkImageStatisticsView::OnIgnoreZerosCheckboxClicked() { emit StatisticsUpdate(); } void QmitkImageStatisticsView::OnClipboardHistogramButtonClicked() { if ( m_CurrentStatisticsValid ) { const unsigned int t = this->GetRenderWindowPart()->GetTimeNavigationController()->GetTime()->GetPos(); typedef mitk::ImageStatisticsCalculator::HistogramType HistogramType; const HistogramType *histogram = this->m_CalculationThread->GetTimeStepHistogram(t).GetPointer(); QString clipboard( "Measurement \t Frequency\n" ); for ( HistogramType::ConstIterator it = histogram->Begin(); it != histogram->End(); ++it ) { if( m_Controls->m_HistogramBinSizeSpinbox->value() == 1) { clipboard = clipboard.append( "%L1 \t %L2\n" ) .arg( it.GetMeasurementVector()[0], 0, 'f', 0 ) .arg( it.GetFrequency() ); } else { clipboard = clipboard.append( "%L1 \t %L2\n" ) .arg( it.GetMeasurementVector()[0], 0, 'f', 2 ) .arg( it.GetFrequency() ); } } QApplication::clipboard()->setText( clipboard, QClipboard::Clipboard ); } else { QApplication::clipboard()->clear(); } } void QmitkImageStatisticsView::OnClipboardStatisticsButtonClicked() { QLocale tempLocal; QLocale::setDefault(QLocale(QLocale::English, QLocale::UnitedStates)); if ( this->m_CurrentStatisticsValid ) { const std::vector &statistics = this->m_CalculationThread->GetStatisticsData(); const unsigned int t = this->GetRenderWindowPart()->GetTimeNavigationController()->GetTime()-> GetPos(); // Copy statistics to clipboard ("%Ln" will use the default locale for // number formatting) QString clipboard( "Mean \t StdDev \t RMS \t Max \t Min \t N \t V (mm³)\n" ); clipboard = clipboard.append( "%L1 \t %L2 \t %L3 \t %L4 \t %L5 \t %L6 \t %L7" ) .arg( statistics[t].GetMean(), 0, 'f', 10 ) .arg( statistics[t].GetSigma(), 0, 'f', 10 ) .arg( statistics[t].GetRMS(), 0, 'f', 10 ) .arg( statistics[t].GetMax(), 0, 'f', 10 ) .arg( statistics[t].GetMin(), 0, 'f', 10 ) .arg( statistics[t].GetN() ) .arg( m_Controls->m_StatisticsTable->item( 0, 6 )->text().toDouble(), 0, 'f', 10 ); QApplication::clipboard()->setText( clipboard, QClipboard::Clipboard ); } else { QApplication::clipboard()->clear(); } QLocale::setDefault(tempLocal); } void QmitkImageStatisticsView::OnSelectionChanged( berry::IWorkbenchPart::Pointer /*part*/, const QList &selectedNodes ) { if (this->m_Visible) { this->SelectionChanged( selectedNodes ); } else { this->m_DataNodeSelectionChanged = true; } } void QmitkImageStatisticsView::SelectionChanged(const QList &selectedNodes) { if( this->m_StatisticsUpdatePending ) { this->m_DataNodeSelectionChanged = true; return; // not ready for new data now! } if (selectedNodes.size() == this->m_SelectedDataNodes.size()) { int i = 0; for (; i < selectedNodes.size(); ++i) { if (selectedNodes.at(i) != this->m_SelectedDataNodes.at(i)) { break; } } // node selection did not change if (i == selectedNodes.size()) return; } + //reset the feature image and image mask field + m_Controls->m_SelectedFeatureImageLabel->setText("None"); + m_Controls->m_SelectedMaskLabel->setText("None"); + this->ReinitData(); if (selectedNodes.isEmpty()) { m_Controls->m_JSHistogram->ClearHistogram(); m_Controls->m_lineRadioButton->setEnabled(true); m_Controls->m_barRadioButton->setEnabled(true); m_Controls->m_HistogramBinSizeSpinbox->setEnabled(true); m_Controls->m_HistogramBinSizeCaptionLabel->setEnabled(true); // m_Controls->m_HistogramBinSizeLabel->setEnabled(true); m_Controls->m_InfoLabel->setText(QString("")); // m_Controls->horizontalLayout_3->setEnabled(false); m_Controls->groupBox->setEnabled(false); m_Controls->groupBox_3->setEnabled(false); } else { // m_Controls->horizontalLayout_3->setEnabled(true); m_Controls->groupBox->setEnabled(true); m_Controls->groupBox_3->setEnabled(true); } if(selectedNodes.size() == 1 || selectedNodes.size() == 2) { bool isBinary = false; selectedNodes.value(0)->GetBoolProperty("binary",isBinary); if(isBinary) { m_Controls->m_JSHistogram->ClearHistogram(); m_Controls->m_lineRadioButton->setEnabled(true); m_Controls->m_barRadioButton->setEnabled(true); m_Controls->m_HistogramBinSizeSpinbox->setEnabled(true); m_Controls->m_HistogramBinSizeCaptionLabel->setEnabled(true); // m_Controls->m_HistogramBinSizeLabel->setEnabled(true); m_Controls->m_InfoLabel->setText(QString("")); } for (int i= 0; i< selectedNodes.size(); ++i) { this->m_SelectedDataNodes.push_back(selectedNodes.at(i)); } this->m_DataNodeSelectionChanged = false; this->m_Controls->m_ErrorMessageLabel->setText( "" ); this->m_Controls->m_ErrorMessageLabel->hide(); emit StatisticsUpdate(); } else { this->m_DataNodeSelectionChanged = false; } } void QmitkImageStatisticsView::ReinitData() { while( this->m_CalculationThread->isRunning()) // wait until thread has finished { itksys::SystemTools::Delay(100); } if(this->m_SelectedImage != NULL) { this->m_SelectedImage->RemoveObserver( this->m_ImageObserverTag); this->m_SelectedImage = NULL; } if(this->m_SelectedImageMask != NULL) { this->m_SelectedImageMask->RemoveObserver( this->m_ImageMaskObserverTag); this->m_SelectedImageMask = NULL; } if(this->m_SelectedPlanarFigure != NULL) { this->m_SelectedPlanarFigure->RemoveObserver( this->m_PlanarFigureObserverTag); this->m_SelectedPlanarFigure = NULL; } this->m_SelectedDataNodes.clear(); this->m_StatisticsUpdatePending = false; m_Controls->m_ErrorMessageLabel->setText( "" ); m_Controls->m_ErrorMessageLabel->hide(); this->InvalidateStatisticsTableView(); m_Controls->m_JSHistogram->ClearHistogram(); m_Controls->m_StatisticsWidgetStack->setCurrentIndex( 0 ); } void QmitkImageStatisticsView::OnThreadedStatisticsCalculationEnds() { std::stringstream message; message << ""; m_Controls->m_ErrorMessageLabel->setText( message.str().c_str() ); m_Controls->m_ErrorMessageLabel->hide(); this->WriteStatisticsToGUI(); } void QmitkImageStatisticsView::UpdateStatistics() { mitk::IRenderWindowPart* renderPart = this->GetRenderWindowPart(); if ( renderPart == NULL ) { this->m_StatisticsUpdatePending = false; return; } m_WorldMinList.clear(); m_WorldMaxList.clear(); // classify selected nodes mitk::NodePredicateDataType::Pointer imagePredicate = mitk::NodePredicateDataType::New("Image"); std::string maskName = std::string(); std::string maskType = std::string(); std::string featureImageName = std::string(); unsigned int maskDimension = 0; // reset data from last run ITKCommandType::Pointer changeListener = ITKCommandType::New(); changeListener->SetCallbackFunction( this, &QmitkImageStatisticsView::SelectedDataModified ); mitk::DataNode::Pointer planarFigureNode; for( int i= 0 ; i < this->m_SelectedDataNodes.size(); ++i) { mitk::PlanarFigure::Pointer planarFig = dynamic_cast(this->m_SelectedDataNodes.at(i)->GetData()); if( imagePredicate->CheckNode(this->m_SelectedDataNodes.at(i)) ) { bool isMask = false; this->m_SelectedDataNodes.at(i)->GetPropertyValue("binary", isMask); if( this->m_SelectedImageMask == NULL && isMask) { this->m_SelectedImageMask = dynamic_cast(this->m_SelectedDataNodes.at(i)->GetData()); this->m_ImageMaskObserverTag = this->m_SelectedImageMask->AddObserver(itk::ModifiedEvent(), changeListener); maskName = this->m_SelectedDataNodes.at(i)->GetName(); maskType = m_SelectedImageMask->GetNameOfClass(); maskDimension = 3; } else if( !isMask ) { if(this->m_SelectedImage == NULL) { this->m_SelectedImage = static_cast(this->m_SelectedDataNodes.at(i)->GetData()); this->m_ImageObserverTag = this->m_SelectedImage->AddObserver(itk::ModifiedEvent(), changeListener); } featureImageName = this->m_SelectedDataNodes.at(i)->GetName(); } } else if (planarFig.IsNotNull()) { if(this->m_SelectedPlanarFigure == NULL) { this->m_SelectedPlanarFigure = planarFig; this->m_PlanarFigureObserverTag = this->m_SelectedPlanarFigure->AddObserver(mitk::EndInteractionPlanarFigureEvent(), changeListener); maskName = this->m_SelectedDataNodes.at(i)->GetName(); maskType = this->m_SelectedPlanarFigure->GetNameOfClass(); maskDimension = 2; planarFigureNode = m_SelectedDataNodes.at(i); } } else { std::stringstream message; message << "" << "Invalid data node type!" << ""; m_Controls->m_ErrorMessageLabel->setText( message.str().c_str() ); m_Controls->m_ErrorMessageLabel->show(); } } if(maskName == "") { maskName = "None"; maskType = ""; maskDimension = 0; } if(featureImageName == "") { featureImageName = "None"; } if (m_SelectedPlanarFigure != NULL && m_SelectedImage == NULL) { mitk::DataStorage::SetOfObjects::ConstPointer parentSet = this->GetDataStorage()->GetSources(planarFigureNode); for (int i=0; iSize(); i++) { mitk::DataNode::Pointer node = parentSet->ElementAt(i); if( imagePredicate->CheckNode(node) ) { bool isMask = false; node->GetPropertyValue("binary", isMask); if( !isMask ) { if(this->m_SelectedImage == NULL) { this->m_SelectedImage = static_cast(node->GetData()); this->m_ImageObserverTag = this->m_SelectedImage->AddObserver(itk::ModifiedEvent(), changeListener); } } } } } unsigned int timeStep = renderPart->GetTimeNavigationController()->GetTime()->GetPos(); if ( m_SelectedImage != NULL && m_SelectedImage->IsInitialized()) { // Check if a the selected image is a multi-channel image. If yes, statistics // cannot be calculated currently. if ( m_SelectedImage->GetPixelType().GetNumberOfComponents() > 1 ) { std::stringstream message; message << "Multi-component images not supported."; m_Controls->m_ErrorMessageLabel->setText( message.str().c_str() ); m_Controls->m_ErrorMessageLabel->show(); this->InvalidateStatisticsTableView(); m_Controls->m_StatisticsWidgetStack->setCurrentIndex( 0 ); m_Controls->m_JSHistogram->ClearHistogram(); m_CurrentStatisticsValid = false; this->m_StatisticsUpdatePending = false; m_Controls->m_lineRadioButton->setEnabled(true); m_Controls->m_barRadioButton->setEnabled(true); m_Controls->m_HistogramBinSizeSpinbox->setEnabled(true); m_Controls->m_HistogramBinSizeCaptionLabel->setEnabled(true); // m_Controls->m_HistogramBinSizeLabel->setEnabled(true); m_Controls->m_InfoLabel->setText(QString("")); return; } std::stringstream maskLabel; maskLabel << maskName; if ( maskDimension > 0 ) { maskLabel << " [" << maskDimension << "D " << maskType << "]"; } m_Controls->m_SelectedMaskLabel->setText( maskLabel.str().c_str() ); m_Controls->m_SelectedFeatureImageLabel->setText(featureImageName.c_str()); // check time step validity if(m_SelectedImage->GetDimension() <= 3 && timeStep > m_SelectedImage->GetDimension(3)-1) { timeStep = m_SelectedImage->GetDimension(3)-1; } // Add the used mask time step to the mask label so the user knows which mask time step was used // if the image time step is bigger than the total number of mask time steps (see // ImageStatisticsCalculator::ExtractImageAndMask) if (m_SelectedImageMask != NULL) { unsigned int maskTimeStep = timeStep; if (maskTimeStep >= m_SelectedImageMask->GetTimeSteps()) { maskTimeStep = m_SelectedImageMask->GetTimeSteps() - 1; } m_Controls->m_SelectedMaskLabel->setText(m_Controls->m_SelectedMaskLabel->text() + QString(" (t=") + QString::number(maskTimeStep) + QString(")")); } //// initialize thread and trigger it this->m_CalculationThread->SetIgnoreZeroValueVoxel( m_Controls->m_IgnoreZerosCheckbox->isChecked() ); this->m_CalculationThread->Initialize( m_SelectedImage, m_SelectedImageMask, m_SelectedPlanarFigure ); this->m_CalculationThread->SetTimeStep( timeStep ); this->m_CalculationThread->SetHistogramBinSize(m_Controls->m_HistogramBinSizeSpinbox->value()); std::stringstream message; message << "Calculating statistics..."; m_Controls->m_ErrorMessageLabel->setText( message.str().c_str() ); m_Controls->m_ErrorMessageLabel->show(); try { // Compute statistics this->m_CalculationThread->SetUseDefaultBinSize(m_Controls->m_UseDefaultBinSizeBox->isChecked()); this->m_CalculationThread->start(); } catch ( const mitk::Exception& e) { std::stringstream message; message << "" << e.GetDescription() << ""; m_Controls->m_ErrorMessageLabel->setText( message.str().c_str() ); m_Controls->m_ErrorMessageLabel->show(); this->m_StatisticsUpdatePending = false; } catch ( const std::runtime_error &e ) { // In case of exception, print error message on GUI std::stringstream message; message << "" << e.what() << ""; m_Controls->m_ErrorMessageLabel->setText( message.str().c_str() ); m_Controls->m_ErrorMessageLabel->show(); this->m_StatisticsUpdatePending = false; } catch ( const std::exception &e ) { MITK_ERROR << "Caught exception: " << e.what(); // In case of exception, print error message on GUI std::stringstream message; message << "Error! Unequal Dimensions of Image and Segmentation. No recompute possible "; m_Controls->m_ErrorMessageLabel->setText( message.str().c_str() ); m_Controls->m_ErrorMessageLabel->show(); this->m_StatisticsUpdatePending = false; } } else { this->m_StatisticsUpdatePending = false; } } void QmitkImageStatisticsView::SelectedDataModified() { if( !m_StatisticsUpdatePending ) { emit StatisticsUpdate(); } } void QmitkImageStatisticsView::NodeRemoved(const mitk::DataNode *node) { while(this->m_CalculationThread->isRunning()) // wait until thread has finished { itksys::SystemTools::Delay(100); } if (node->GetData() == m_SelectedImage) { m_SelectedImage = NULL; } } void QmitkImageStatisticsView::RequestStatisticsUpdate() { if ( !m_StatisticsUpdatePending ) { if(this->m_DataNodeSelectionChanged) { this->SelectionChanged(this->GetCurrentSelection()); } else { this->m_StatisticsUpdatePending = true; this->UpdateStatistics(); } } if (this->GetRenderWindowPart()) this->GetRenderWindowPart()->RequestUpdate(); } void QmitkImageStatisticsView::OnHistogramBinSizeBoxValueChanged() { this->UpdateStatistics(); } void QmitkImageStatisticsView::WriteStatisticsToGUI() { m_Controls->m_lineRadioButton->setEnabled(true); m_Controls->m_barRadioButton->setEnabled(true); m_Controls->m_HistogramBinSizeSpinbox->setEnabled(true); m_Controls->m_HistogramBinSizeCaptionLabel->setEnabled(true); // m_Controls->m_HistogramBinSizeLabel->setEnabled(true); m_Controls->m_InfoLabel->setText(QString("")); if(m_DataNodeSelectionChanged) { this->m_StatisticsUpdatePending = false; this->RequestStatisticsUpdate(); return; // stop visualization of results and calculate statistics of new selection } if ( this->m_CalculationThread->GetStatisticsUpdateSuccessFlag()) { if ( this->m_CalculationThread->GetStatisticsChangedFlag() ) { // Do not show any error messages m_Controls->m_ErrorMessageLabel->hide(); m_CurrentStatisticsValid = true; } if (m_Controls->m_barRadioButton->isChecked()) { m_Controls->m_JSHistogram->OnBarRadioButtonSelected(); } m_Controls->m_StatisticsWidgetStack->setCurrentIndex( 0 ); m_Controls->m_HistogramBinSizeSpinbox->setValue( this->m_CalculationThread->GetHistogramBinSize() ); //m_Controls->m_JSHistogram->ComputeHistogram( this->m_CalculationThread->GetTimeStepHistogram(this->m_CalculationThread->GetTimeStep()).GetPointer() ); this->FillStatisticsTableView( this->m_CalculationThread->GetStatisticsData(), this->m_CalculationThread->GetStatisticsImage()); } else { m_Controls->m_SelectedMaskLabel->setText( "None" ); m_Controls->m_ErrorMessageLabel->setText( m_CalculationThread->GetLastErrorMessage().c_str() ); m_Controls->m_ErrorMessageLabel->show(); // Clear statistics and histogram this->InvalidateStatisticsTableView(); m_Controls->m_StatisticsWidgetStack->setCurrentIndex( 0 ); //m_Controls->m_JSHistogram->clearHistogram(); m_CurrentStatisticsValid = false; // If a (non-closed) PlanarFigure is selected, display a line profile widget if ( m_SelectedPlanarFigure != NULL ) { // Check if the (closed) planar figure is out of bounds and so no image mask could be calculated--> Intensity Profile can not be calculated bool outOfBounds = false; if ( m_SelectedPlanarFigure->IsClosed() && m_SelectedImageMask == NULL) { outOfBounds = true; std::stringstream message; message << "Planar figure is on a rotated image plane or outside the image bounds."; m_Controls->m_InfoLabel->setText(message.str().c_str()); } // check whether PlanarFigure is initialized const mitk::PlaneGeometry *planarFigurePlaneGeometry = m_SelectedPlanarFigure->GetPlaneGeometry(); if ( planarFigurePlaneGeometry == NULL || outOfBounds) { // Clear statistics, histogram, and GUI this->InvalidateStatisticsTableView(); m_Controls->m_StatisticsWidgetStack->setCurrentIndex( 0 ); m_Controls->m_JSHistogram->ClearHistogram(); m_CurrentStatisticsValid = false; m_Controls->m_ErrorMessageLabel->hide(); m_Controls->m_SelectedMaskLabel->setText( "None" ); this->m_StatisticsUpdatePending = false; m_Controls->m_lineRadioButton->setEnabled(true); m_Controls->m_barRadioButton->setEnabled(true); m_Controls->m_HistogramBinSizeSpinbox->setEnabled(true); m_Controls->m_HistogramBinSizeCaptionLabel->setEnabled(true); // m_Controls->m_HistogramBinSizeLabel->setEnabled(true); if (!outOfBounds) m_Controls->m_InfoLabel->setText(QString("")); return; } unsigned int timeStep = this->GetRenderWindowPart()->GetTimeNavigationController()->GetTime()->GetPos(); m_Controls->m_JSHistogram->SetImage(this->m_CalculationThread->GetStatisticsImage()); m_Controls->m_JSHistogram->SetPlanarFigure(m_SelectedPlanarFigure); m_Controls->m_JSHistogram->ComputeIntensityProfile(timeStep); m_Controls->m_lineRadioButton->setEnabled(false); m_Controls->m_barRadioButton->setEnabled(false); m_Controls->m_HistogramBinSizeSpinbox->setEnabled(false); m_Controls->m_HistogramBinSizeCaptionLabel->setEnabled(false); // m_Controls->m_HistogramBinSizeLabel->setEnabled(false); std::stringstream message; message << "Only linegraph available for an intesityprofile!"; m_Controls->m_InfoLabel->setText(message.str().c_str()); } } this->m_StatisticsUpdatePending = false; } void QmitkImageStatisticsView::FillStatisticsTableView( const std::vector &s, const mitk::Image *image ) { this->m_Controls->m_StatisticsTable->setColumnCount(image->GetTimeSteps()); this->m_Controls->m_StatisticsTable->horizontalHeader()->setVisible(image->GetTimeSteps() > 1); int decimals = 2; mitk::PixelType doublePix = mitk::MakeScalarPixelType< double >(); mitk::PixelType floatPix = mitk::MakeScalarPixelType< float >(); if (image->GetPixelType()==doublePix || image->GetPixelType()==floatPix) { decimals = 5; } for (unsigned int t = 0; t < image->GetTimeSteps(); t++) { this->m_Controls->m_StatisticsTable->setHorizontalHeaderItem(t, new QTableWidgetItem(QString::number(t))); if (s[t].GetMaxIndex().size()==3) { mitk::Point3D index, max, min; index[0] = s[t].GetMaxIndex()[0]; index[1] = s[t].GetMaxIndex()[1]; index[2] = s[t].GetMaxIndex()[2]; m_SelectedImage->GetGeometry()->IndexToWorld(index, max); this->m_WorldMaxList.push_back(max); index[0] = s[t].GetMinIndex()[0]; index[1] = s[t].GetMinIndex()[1]; index[2] = s[t].GetMinIndex()[2]; m_SelectedImage->GetGeometry()->IndexToWorld(index, min); this->m_WorldMinList.push_back(min); } this->m_Controls->m_StatisticsTable->setItem( 0, t, new QTableWidgetItem( QString("%1").arg(s[t].GetMean(), 0, 'f', decimals) ) ); this->m_Controls->m_StatisticsTable->setItem( 1, t, new QTableWidgetItem( QString("%1").arg(s[t].GetSigma(), 0, 'f', decimals) ) ); this->m_Controls->m_StatisticsTable->setItem( 2, t, new QTableWidgetItem( QString("%1").arg(s[t].GetRMS(), 0, 'f', decimals) ) ); QString max; max.append(QString("%1").arg(s[t].GetMax(), 0, 'f', decimals)); max += " ("; for (int i=0; im_Controls->m_StatisticsTable->setItem( 3, t, new QTableWidgetItem( max ) ); QString min; min.append(QString("%1").arg(s[t].GetMin(), 0, 'f', decimals)); min += " ("; for (int i=0; im_Controls->m_StatisticsTable->setItem( 4, t, new QTableWidgetItem( min ) ); this->m_Controls->m_StatisticsTable->setItem( 5, t, new QTableWidgetItem( QString("%1").arg(s[t].GetN()) ) ); const mitk::BaseGeometry *geometry = image->GetGeometry(); if ( geometry != NULL ) { const mitk::Vector3D &spacing = image->GetGeometry()->GetSpacing(); double volume = spacing[0] * spacing[1] * spacing[2] * (double) s[t].GetN(); this->m_Controls->m_StatisticsTable->setItem( 6, t, new QTableWidgetItem( QString("%1").arg(volume, 0, 'f', decimals) ) ); } else { this->m_Controls->m_StatisticsTable->setItem( 6, t, new QTableWidgetItem( "NA" ) ); } } this->m_Controls->m_StatisticsTable->resizeColumnsToContents(); int height = STAT_TABLE_BASE_HEIGHT; if (this->m_Controls->m_StatisticsTable->horizontalHeader()->isVisible()) height += this->m_Controls->m_StatisticsTable->horizontalHeader()->height(); if (this->m_Controls->m_StatisticsTable->horizontalScrollBar()->isVisible()) height += this->m_Controls->m_StatisticsTable->horizontalScrollBar()->height(); this->m_Controls->m_StatisticsTable->setMinimumHeight(height); // make sure the current timestep's column is highlighted (and the correct histogram is displayed) unsigned int t = this->GetRenderWindowPart()->GetTimeNavigationController()->GetTime()-> GetPos(); mitk::SliceNavigationController::GeometryTimeEvent timeEvent(this->m_SelectedImage->GetTimeGeometry(), t); this->OnTimeChanged(timeEvent); + t = std::min(image->GetTimeSteps() - 1, t); + QString hotspotMean; hotspotMean.append(QString("%1").arg(s[t].GetHotspotStatistics().GetMean(), 0, 'f', decimals)); hotspotMean += " ("; for (int i=0; im_Controls->m_StatisticsTable->setItem( 7, t, new QTableWidgetItem( hotspotMean ) ); QString hotspotMax; hotspotMax.append(QString("%1").arg(s[t].GetHotspotStatistics().GetMax(), 0, 'f', decimals)); hotspotMax += " ("; for (int i=0; im_Controls->m_StatisticsTable->setItem( 8, t, new QTableWidgetItem( hotspotMax ) ); QString hotspotMin; hotspotMin.append(QString("%1").arg(s[t].GetHotspotStatistics().GetMin(), 0, 'f', decimals)); hotspotMin += " ("; for (int i=0; im_Controls->m_StatisticsTable->setItem( 9, t, new QTableWidgetItem( hotspotMin ) ); } void QmitkImageStatisticsView::InvalidateStatisticsTableView() { this->m_Controls->m_StatisticsTable->horizontalHeader()->setVisible(false); this->m_Controls->m_StatisticsTable->setColumnCount(1); for ( unsigned int i = 0; i < this->m_Controls->m_StatisticsTable->rowCount(); ++i ) { { this->m_Controls->m_StatisticsTable->setItem( i, 0, new QTableWidgetItem( "NA" ) ); } } this->m_Controls->m_StatisticsTable->setMinimumHeight(STAT_TABLE_BASE_HEIGHT); } void QmitkImageStatisticsView::Activated() { } void QmitkImageStatisticsView::Deactivated() { } void QmitkImageStatisticsView::Visible() { m_Visible = true; mitk::IRenderWindowPart* renderWindow = GetRenderWindowPart(); if (renderWindow) { itk::ReceptorMemberCommand::Pointer cmdTimeEvent = itk::ReceptorMemberCommand::New(); cmdTimeEvent->SetCallbackFunction(this, &QmitkImageStatisticsView::OnTimeChanged); // It is sufficient to add the observer to the axial render window since the GeometryTimeEvent // is always triggered by all views. m_TimeObserverTag = renderWindow->GetQmitkRenderWindow("axial")-> GetSliceNavigationController()-> AddObserver(mitk::SliceNavigationController::GeometryTimeEvent(NULL, 0), cmdTimeEvent); } if (m_DataNodeSelectionChanged) { if (this->IsCurrentSelectionValid()) { this->SelectionChanged(this->GetCurrentSelection()); } else { this->SelectionChanged(this->GetDataManagerSelection()); } m_DataNodeSelectionChanged = false; } } void QmitkImageStatisticsView::Hidden() { m_Visible = false; // The slice navigation controller observer is removed here instead of in the destructor. // If it was called in the destructor, the application would freeze because the view's // destructor gets called after the render windows have been destructed. if ( m_TimeObserverTag != NULL ) { mitk::IRenderWindowPart* renderWindow = GetRenderWindowPart(); if (renderWindow) { renderWindow->GetQmitkRenderWindow("axial")->GetSliceNavigationController()-> RemoveObserver( m_TimeObserverTag ); } m_TimeObserverTag = NULL; } } void QmitkImageStatisticsView::SetFocus() { } diff --git a/Plugins/org.mitk.gui.qt.measurementtoolbox/src/internal/QmitkMeasurementView.cpp b/Plugins/org.mitk.gui.qt.measurementtoolbox/src/internal/QmitkMeasurementView.cpp index 060183b87f..e7466fae1f 100644 --- a/Plugins/org.mitk.gui.qt.measurementtoolbox/src/internal/QmitkMeasurementView.cpp +++ b/Plugins/org.mitk.gui.qt.measurementtoolbox/src/internal/QmitkMeasurementView.cpp @@ -1,958 +1,967 @@ /*=================================================================== 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. ===================================================================*/ #define MEASUREMENT_DEBUG MITK_DEBUG("QmitkMeasurementView") << __LINE__ << ": " #include "QmitkMeasurementView.h" -#include +#include +#include +#include +#include +#include +#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "mitkPluginActivator.h" #include "usModuleRegistry.h" template static T* GetService() { ctkPluginContext* context = mitk::PluginActivator::GetContext(); ctkServiceReference serviceRef = context->getServiceReference(); return serviceRef ? context->getService(serviceRef) : NULL; } struct QmitkPlanarFigureData { QmitkPlanarFigureData() : m_Figure(0), m_EndPlacementObserverTag(0), m_SelectObserverTag(0), m_StartInteractionObserverTag(0), m_EndInteractionObserverTag(0) { } mitk::PlanarFigure* m_Figure; unsigned int m_EndPlacementObserverTag; unsigned int m_SelectObserverTag; unsigned int m_StartInteractionObserverTag; unsigned int m_EndInteractionObserverTag; }; struct QmitkMeasurementViewData { QmitkMeasurementViewData() : m_LineCounter(0), m_PathCounter(0), m_AngleCounter(0), m_FourPointAngleCounter(0), m_CircleCounter(0), m_EllipseCounter(0), m_DoubleEllipseCounter(0), m_RectangleCounter(0), m_PolygonCounter(0), m_BezierCurveCounter(0), m_SubdivisionPolygonCounter(0), m_UnintializedPlanarFigure(false) { } // internal vars unsigned int m_LineCounter; unsigned int m_PathCounter; unsigned int m_AngleCounter; unsigned int m_FourPointAngleCounter; unsigned int m_CircleCounter; unsigned int m_EllipseCounter; unsigned int m_DoubleEllipseCounter; unsigned int m_RectangleCounter; unsigned int m_PolygonCounter; unsigned int m_BezierCurveCounter; unsigned int m_SubdivisionPolygonCounter; QList m_CurrentSelection; std::map m_DataNodeToPlanarFigureData; mitk::WeakPointer m_SelectedImageNode; bool m_UnintializedPlanarFigure; // WIDGETS QWidget* m_Parent; QLabel* m_SelectedImageLabel; QAction* m_DrawLine; QAction* m_DrawPath; QAction* m_DrawAngle; QAction* m_DrawFourPointAngle; QAction* m_DrawRectangle; QAction* m_DrawPolygon; QAction* m_DrawCircle; QAction* m_DrawEllipse; QAction* m_DrawDoubleEllipse; QAction* m_DrawBezierCurve; QAction* m_DrawSubdivisionPolygon; QToolBar* m_DrawActionsToolBar; QActionGroup* m_DrawActionsGroup; QTextBrowser* m_SelectedPlanarFiguresText; QPushButton* m_CopyToClipboard; QGridLayout* m_Layout; }; const std::string QmitkMeasurementView::VIEW_ID = "org.mitk.views.measurement"; QmitkMeasurementView::QmitkMeasurementView() : d( new QmitkMeasurementViewData ) { } QmitkMeasurementView::~QmitkMeasurementView() { this->RemoveAllInteractors(); delete d; } void QmitkMeasurementView::CreateQtPartControl(QWidget* parent) { d->m_Parent = parent; // image label QLabel* selectedImageLabel = new QLabel("Reference Image: "); d->m_SelectedImageLabel = new QLabel; d->m_SelectedImageLabel->setStyleSheet("font-weight: bold;"); d->m_DrawActionsToolBar = new QToolBar; d->m_DrawActionsGroup = new QActionGroup(this); d->m_DrawActionsGroup->setExclusive(true); //# add actions MEASUREMENT_DEBUG << "Draw Line"; QAction* currentAction = d->m_DrawActionsToolBar->addAction(QIcon(":/measurement/line.png"), "Draw Line"); currentAction->setCheckable(true); d->m_DrawLine = currentAction; d->m_DrawActionsToolBar->addAction(currentAction); d->m_DrawActionsGroup->addAction(currentAction); MEASUREMENT_DEBUG << "Draw Path"; currentAction = d->m_DrawActionsToolBar->addAction(QIcon(":/measurement/path.png"), "Draw Path"); currentAction->setCheckable(true); d->m_DrawPath = currentAction; d->m_DrawActionsToolBar->addAction(currentAction); d->m_DrawActionsGroup->addAction(currentAction); MEASUREMENT_DEBUG << "Draw Angle"; currentAction = d->m_DrawActionsToolBar->addAction(QIcon(":/measurement/angle.png"), "Draw Angle"); currentAction->setCheckable(true); d->m_DrawAngle = currentAction; d->m_DrawActionsToolBar->addAction(currentAction); d->m_DrawActionsGroup->addAction(currentAction); MEASUREMENT_DEBUG << "Draw Four Point Angle"; currentAction = d->m_DrawActionsToolBar->addAction(QIcon(":/measurement/four-point-angle.png"), "Draw Four Point Angle"); currentAction->setCheckable(true); d->m_DrawFourPointAngle = currentAction; d->m_DrawActionsToolBar->addAction(currentAction); d->m_DrawActionsGroup->addAction(currentAction); MEASUREMENT_DEBUG << "Draw Circle"; currentAction = d->m_DrawActionsToolBar->addAction(QIcon(":/measurement/circle.png"), "Draw Circle"); currentAction->setCheckable(true); d->m_DrawCircle = currentAction; d->m_DrawActionsToolBar->addAction(currentAction); d->m_DrawActionsGroup->addAction(currentAction); MEASUREMENT_DEBUG << "Draw Ellipse"; currentAction = d->m_DrawActionsToolBar->addAction(QIcon(":/measurement/ellipse.png"), "Draw Ellipse"); currentAction->setCheckable(true); d->m_DrawEllipse = currentAction; d->m_DrawActionsToolBar->addAction(currentAction); d->m_DrawActionsGroup->addAction(currentAction); MEASUREMENT_DEBUG << "Draw Double Ellipse"; currentAction = d->m_DrawActionsToolBar->addAction(QIcon(":/measurement/doubleellipse.png"), "Draw Double Ellipse"); currentAction->setCheckable(true); d->m_DrawDoubleEllipse = currentAction; d->m_DrawActionsToolBar->addAction(currentAction); d->m_DrawActionsGroup->addAction(currentAction); MEASUREMENT_DEBUG << "Draw Rectangle"; currentAction = d->m_DrawActionsToolBar->addAction(QIcon(":/measurement/rectangle.png"), "Draw Rectangle"); currentAction->setCheckable(true); d->m_DrawRectangle = currentAction; d->m_DrawActionsToolBar->addAction(currentAction); d->m_DrawActionsGroup->addAction(currentAction); MEASUREMENT_DEBUG << "Draw Polygon"; currentAction = d->m_DrawActionsToolBar->addAction(QIcon(":/measurement/polygon.png"), "Draw Polygon"); currentAction->setCheckable(true); d->m_DrawPolygon = currentAction; d->m_DrawActionsToolBar->addAction(currentAction); d->m_DrawActionsGroup->addAction(currentAction); MEASUREMENT_DEBUG << "Draw Bezier Curve"; currentAction = d->m_DrawActionsToolBar->addAction(QIcon(":/measurement/beziercurve.png"), "Draw Bezier Curve"); currentAction->setCheckable(true); d->m_DrawBezierCurve = currentAction; d->m_DrawActionsToolBar->addAction(currentAction); d->m_DrawActionsGroup->addAction(currentAction); MEASUREMENT_DEBUG << "Draw Subdivision Polygon"; currentAction = d->m_DrawActionsToolBar->addAction(QIcon(":/measurement/subdivisionpolygon.png"), "Draw Subdivision Polygon"); currentAction->setCheckable(true); d->m_DrawSubdivisionPolygon = currentAction; d->m_DrawActionsToolBar->addAction(currentAction); d->m_DrawActionsGroup->addAction(currentAction); // planar figure details text d->m_SelectedPlanarFiguresText = new QTextBrowser; // copy to clipboard button d->m_CopyToClipboard = new QPushButton("Copy to Clipboard"); d->m_Layout = new QGridLayout; d->m_Layout->addWidget(selectedImageLabel, 0, 0, 1, 1); d->m_Layout->addWidget(d->m_SelectedImageLabel, 0, 1, 1, 1); d->m_Layout->addWidget(d->m_DrawActionsToolBar, 1, 0, 1, 2); d->m_Layout->addWidget(d->m_SelectedPlanarFiguresText, 2, 0, 1, 2); d->m_Layout->addWidget(d->m_CopyToClipboard, 3, 0, 1, 2); d->m_Parent->setLayout(d->m_Layout); // create connections this->CreateConnections(); // readd interactors and observers this->AddAllInteractors(); } void QmitkMeasurementView::CreateConnections() { QObject::connect( d->m_DrawLine, SIGNAL( triggered(bool) ), this, SLOT( ActionDrawLineTriggered(bool) ) ); QObject::connect( d->m_DrawPath, SIGNAL( triggered(bool) ), this, SLOT( ActionDrawPathTriggered(bool) ) ); QObject::connect( d->m_DrawAngle, SIGNAL( triggered(bool) ), this, SLOT( ActionDrawAngleTriggered(bool) ) ); QObject::connect( d->m_DrawFourPointAngle, SIGNAL( triggered(bool) ), this, SLOT( ActionDrawFourPointAngleTriggered(bool) ) ); QObject::connect( d->m_DrawCircle, SIGNAL( triggered(bool) ), this, SLOT( ActionDrawCircleTriggered(bool) ) ); QObject::connect( d->m_DrawEllipse, SIGNAL( triggered(bool) ), this, SLOT( ActionDrawEllipseTriggered(bool) ) ); QObject::connect( d->m_DrawDoubleEllipse, SIGNAL( triggered(bool) ), this, SLOT( ActionDrawDoubleEllipseTriggered(bool) ) ); QObject::connect( d->m_DrawRectangle, SIGNAL( triggered(bool) ), this, SLOT( ActionDrawRectangleTriggered(bool) ) ); QObject::connect( d->m_DrawPolygon, SIGNAL( triggered(bool) ), this, SLOT( ActionDrawPolygonTriggered(bool) ) ); QObject::connect( d->m_DrawBezierCurve, SIGNAL( triggered(bool) ), this, SLOT( ActionDrawBezierCurveTriggered(bool) ) ); QObject::connect( d->m_DrawSubdivisionPolygon, SIGNAL( triggered(bool) ), this, SLOT( ActionDrawSubdivisionPolygonTriggered(bool) ) ); QObject::connect( d->m_CopyToClipboard, SIGNAL( clicked(bool) ), this, SLOT( CopyToClipboard(bool) ) ); } void QmitkMeasurementView::NodeAdded( const mitk::DataNode* node ) { // add observer for selection in renderwindow mitk::PlanarFigure* figure = dynamic_cast(node->GetData()); bool isPositionMarker (false); node->GetBoolProperty("isContourMarker", isPositionMarker); if( figure && !isPositionMarker ) { MEASUREMENT_DEBUG << "figure added. will add interactor if needed."; mitk::PlanarFigureInteractor::Pointer figureInteractor = dynamic_cast(node->GetDataInteractor().GetPointer() ); mitk::DataNode* nonConstNode = const_cast( node ); if(figureInteractor.IsNull()) { figureInteractor = mitk::PlanarFigureInteractor::New(); us::Module* planarFigureModule = us::ModuleRegistry::GetModule( "MitkPlanarFigure" ); figureInteractor->LoadStateMachine("PlanarFigureInteraction.xml", planarFigureModule ); figureInteractor->SetEventConfig( "PlanarFigureConfig.xml", planarFigureModule ); figureInteractor->SetDataNode( nonConstNode ); // nonConstNode->SetBoolProperty( "planarfigure.isextendable", true ); } else { // just to be sure that the interactor is not added twice // mitk::GlobalInteraction::GetInstance()->RemoveInteractor(figureInteractor); } MEASUREMENT_DEBUG << "adding interactor to globalinteraction"; // mitk::GlobalInteraction::GetInstance()->AddInteractor(figureInteractor); MEASUREMENT_DEBUG << "will now add observers for planarfigure"; QmitkPlanarFigureData data; data.m_Figure = figure; // add observer for event when figure has been placed typedef itk::SimpleMemberCommand< QmitkMeasurementView > SimpleCommandType; SimpleCommandType::Pointer initializationCommand = SimpleCommandType::New(); initializationCommand->SetCallbackFunction( this, &QmitkMeasurementView::PlanarFigureInitialized ); data.m_EndPlacementObserverTag = figure->AddObserver( mitk::EndPlacementPlanarFigureEvent(), initializationCommand ); // add observer for event when figure is picked (selected) typedef itk::MemberCommand< QmitkMeasurementView > MemberCommandType; MemberCommandType::Pointer selectCommand = MemberCommandType::New(); selectCommand->SetCallbackFunction( this, &QmitkMeasurementView::PlanarFigureSelected ); data.m_SelectObserverTag = figure->AddObserver( mitk::SelectPlanarFigureEvent(), selectCommand ); // add observer for event when interaction with figure starts SimpleCommandType::Pointer startInteractionCommand = SimpleCommandType::New(); startInteractionCommand->SetCallbackFunction( this, &QmitkMeasurementView::DisableCrosshairNavigation); data.m_StartInteractionObserverTag = figure->AddObserver( mitk::StartInteractionPlanarFigureEvent(), startInteractionCommand ); // add observer for event when interaction with figure starts SimpleCommandType::Pointer endInteractionCommand = SimpleCommandType::New(); endInteractionCommand->SetCallbackFunction( this, &QmitkMeasurementView::EnableCrosshairNavigation); data.m_EndInteractionObserverTag = figure->AddObserver( mitk::EndInteractionPlanarFigureEvent(), endInteractionCommand ); // adding to the map of tracked planarfigures d->m_DataNodeToPlanarFigureData[nonConstNode] = data; } this->CheckForTopMostVisibleImage(); } void QmitkMeasurementView::NodeChanged(const mitk::DataNode* node) { // DETERMINE IF WE HAVE TO RENEW OUR DETAILS TEXT (ANY NODE CHANGED IN OUR SELECTION?) bool renewText = false; for( int i=0; i < d->m_CurrentSelection.size(); ++i ) { if( node == d->m_CurrentSelection.at(i) ) { renewText = true; break; } } if(renewText) { MEASUREMENT_DEBUG << "Selected nodes changed. Refreshing text."; this->UpdateMeasurementText(); } this->CheckForTopMostVisibleImage(); } void QmitkMeasurementView::CheckForTopMostVisibleImage(mitk::DataNode* _NodeToNeglect) { d->m_SelectedImageNode = this->DetectTopMostVisibleImage().GetPointer(); if( d->m_SelectedImageNode.GetPointer() == _NodeToNeglect ) d->m_SelectedImageNode = 0; if( d->m_SelectedImageNode.IsNotNull() && d->m_UnintializedPlanarFigure == false ) { MEASUREMENT_DEBUG << "Reference image found"; d->m_SelectedImageLabel->setText( QString::fromStdString( d->m_SelectedImageNode->GetName() ) ); d->m_DrawActionsToolBar->setEnabled(true); MEASUREMENT_DEBUG << "Updating Measurement text"; } else { MEASUREMENT_DEBUG << "No reference image available. Will disable actions for creating new planarfigures"; if( d->m_UnintializedPlanarFigure == false ) d->m_SelectedImageLabel->setText( "No visible image available." ); d->m_DrawActionsToolBar->setEnabled(false); } } void QmitkMeasurementView::NodeRemoved(const mitk::DataNode* node) { MEASUREMENT_DEBUG << "node removed from data storage"; mitk::DataNode* nonConstNode = const_cast(node); std::map::iterator it = d->m_DataNodeToPlanarFigureData.find(nonConstNode); bool isFigureFinished = false; bool isPlaced = false; if( it != d->m_DataNodeToPlanarFigureData.end() ) { QmitkPlanarFigureData& data = it->second; // remove observers data.m_Figure->RemoveObserver( data.m_EndPlacementObserverTag ); data.m_Figure->RemoveObserver( data.m_SelectObserverTag ); data.m_Figure->RemoveObserver( data.m_StartInteractionObserverTag ); data.m_Figure->RemoveObserver( data.m_EndInteractionObserverTag ); MEASUREMENT_DEBUG << "removing from the list of tracked planar figures"; isFigureFinished = data.m_Figure->GetPropertyList()->GetBoolProperty("initiallyplaced",isPlaced); if (!isFigureFinished) { // if the property does not yet exist or is false, drop the datanode PlanarFigureInitialized(); // normally called when a figure is finished, to reset all buttons } d->m_DataNodeToPlanarFigureData.erase( it ); } mitk::TNodePredicateDataType::Pointer isPlanarFigure = mitk::TNodePredicateDataType::New(); mitk::DataStorage::SetOfObjects::ConstPointer nodes = GetDataStorage()->GetDerivations(node,isPlanarFigure); for (unsigned int x = 0; x < nodes->size(); x++) { mitk::PlanarFigure* planarFigure = dynamic_cast (nodes->at(x)->GetData()); if (planarFigure != NULL) { isFigureFinished = planarFigure->GetPropertyList()->GetBoolProperty("initiallyplaced",isPlaced); if (!isFigureFinished) { // if the property does not yet exist or is false, drop the datanode GetDataStorage()->Remove(nodes->at(x)); if( !d->m_DataNodeToPlanarFigureData.empty() ) { std::map::iterator it2 = d->m_DataNodeToPlanarFigureData.find(nodes->at(x)); //check if returned it2 valid if( it2 != d->m_DataNodeToPlanarFigureData.end() ) { d->m_DataNodeToPlanarFigureData.erase( it2 );// removing planar figure from tracked figure list PlanarFigureInitialized(); // normally called when a figure is finished, to reset all buttons EnableCrosshairNavigation(); } } } } } this->CheckForTopMostVisibleImage(nonConstNode); } void QmitkMeasurementView::PlanarFigureSelected( itk::Object* object, const itk::EventObject& ) { MEASUREMENT_DEBUG << "planar figure " << object << " selected"; std::map::iterator it = d->m_DataNodeToPlanarFigureData.begin(); d->m_CurrentSelection.clear(); while( it != d->m_DataNodeToPlanarFigureData.end()) { mitk::DataNode* node = it->first; QmitkPlanarFigureData& data = it->second; if( data.m_Figure == object ) { MITK_DEBUG << "selected node found. enabling selection"; node->SetSelected(true); d->m_CurrentSelection.push_back( node ); } else { node->SetSelected(false); } ++it; } this->UpdateMeasurementText(); this->RequestRenderWindowUpdate(); } void QmitkMeasurementView::PlanarFigureInitialized() { MEASUREMENT_DEBUG << "planar figure initialized"; d->m_UnintializedPlanarFigure = false; d->m_DrawActionsToolBar->setEnabled(true); d->m_DrawLine->setChecked(false); d->m_DrawPath->setChecked(false); d->m_DrawAngle->setChecked(false); d->m_DrawFourPointAngle->setChecked(false); d->m_DrawCircle->setChecked(false); d->m_DrawEllipse->setChecked(false); d->m_DrawDoubleEllipse->setChecked(false); d->m_DrawRectangle->setChecked(false); d->m_DrawPolygon->setChecked(false); d->m_DrawBezierCurve->setChecked(false); d->m_DrawSubdivisionPolygon->setChecked(false); } void QmitkMeasurementView::SetFocus() { d->m_SelectedImageLabel->setFocus(); } void QmitkMeasurementView::OnSelectionChanged(berry::IWorkbenchPart::Pointer /*part*/, const QList &nodes) { MEASUREMENT_DEBUG << "Determine the top most visible image"; MEASUREMENT_DEBUG << "The PlanarFigure interactor will take the currently visible PlaneGeometry from the slice navigation controller"; this->CheckForTopMostVisibleImage(); MEASUREMENT_DEBUG << "refreshing selection and detailed text"; d->m_CurrentSelection = nodes; this->UpdateMeasurementText(); // bug 16600: deselecting all planarfigures by clicking on datamanager when no node is selected if(d->m_CurrentSelection.size() == 0) { + // bug 18440: resetting the selected image label here because unselecting the + // current node did not reset the label + d->m_SelectedImageLabel->setText( "No visible image available." ); + mitk::TNodePredicateDataType::Pointer isPlanarFigure = mitk::TNodePredicateDataType::New(); mitk::DataStorage::SetOfObjects::ConstPointer planarFigures = this->GetDataStorage()->GetSubset( isPlanarFigure ); // setting all planar figures which are not helper objects not selected for(mitk::DataStorage::SetOfObjects::ConstIterator it=planarFigures->Begin(); it!=planarFigures->End(); it++) { mitk::DataNode* node = it.Value(); bool isHelperObject(false); node->GetBoolProperty("helper object", isHelperObject); if(!isHelperObject) { node->SetSelected(false); } } } for( int i=d->m_CurrentSelection.size()-1; i>= 0; --i) { mitk::DataNode* node = d->m_CurrentSelection.at(i); mitk::PlanarFigure* _PlanarFigure = dynamic_cast (node->GetData()); // the last selected planar figure if (_PlanarFigure && _PlanarFigure->GetPlaneGeometry()) { QmitkRenderWindow* selectedRenderWindow = 0; bool PlanarFigureInitializedWindow = false; mitk::ILinkedRenderWindowPart* linkedRenderWindow = dynamic_cast(this->GetRenderWindowPart()); if(! linkedRenderWindow ) { return; } QmitkRenderWindow* RenderWindow1 = linkedRenderWindow->GetQmitkRenderWindow( "axial") ; QmitkRenderWindow* RenderWindow2 = linkedRenderWindow->GetQmitkRenderWindow( "sagittal") ; QmitkRenderWindow* RenderWindow3 = linkedRenderWindow->GetQmitkRenderWindow( "coronal") ; QmitkRenderWindow* RenderWindow4 = linkedRenderWindow->GetQmitkRenderWindow( "3d") ; if (node->GetBoolProperty("PlanarFigureInitializedWindow", PlanarFigureInitializedWindow, RenderWindow1->GetRenderer())) { selectedRenderWindow = RenderWindow1; } if (!selectedRenderWindow && node->GetBoolProperty("PlanarFigureInitializedWindow", PlanarFigureInitializedWindow, RenderWindow2->GetRenderer())) { selectedRenderWindow = RenderWindow2; } if (!selectedRenderWindow && node->GetBoolProperty("PlanarFigureInitializedWindow", PlanarFigureInitializedWindow,RenderWindow3->GetRenderer())) { selectedRenderWindow = RenderWindow3; } if (!selectedRenderWindow && node->GetBoolProperty("PlanarFigureInitializedWindow", PlanarFigureInitializedWindow, RenderWindow4->GetRenderer())) { selectedRenderWindow = RenderWindow4; } const mitk::PlaneGeometry* _PlaneGeometry = dynamic_cast (_PlanarFigure->GetPlaneGeometry()); mitk::VnlVector normal = _PlaneGeometry->GetNormalVnl(); mitk::PlaneGeometry::ConstPointer _Plane1 = RenderWindow1->GetRenderer()->GetCurrentWorldPlaneGeometry(); mitk::VnlVector normal1 = _Plane1->GetNormalVnl(); mitk::PlaneGeometry::ConstPointer _Plane2 = RenderWindow2->GetRenderer()->GetCurrentWorldPlaneGeometry(); mitk::VnlVector normal2 = _Plane2->GetNormalVnl(); mitk::PlaneGeometry::ConstPointer _Plane3 = RenderWindow3->GetRenderer()->GetCurrentWorldPlaneGeometry(); mitk::VnlVector normal3 = _Plane3->GetNormalVnl(); normal[0] = fabs(normal[0]); normal[1] = fabs(normal[1]); normal[2] = fabs(normal[2]); normal1[0] = fabs(normal1[0]); normal1[1] = fabs(normal1[1]); normal1[2] = fabs(normal1[2]); normal2[0] = fabs(normal2[0]); normal2[1] = fabs(normal2[1]); normal2[2] = fabs(normal2[2]); normal3[0] = fabs(normal3[0]); normal3[1] = fabs(normal3[1]); normal3[2] = fabs(normal3[2]); double ang1 = angle(normal, normal1); double ang2 = angle(normal, normal2); double ang3 = angle(normal, normal3); if(ang1 < ang2 && ang1 < ang3) { selectedRenderWindow = RenderWindow1; } else { if(ang2 < ang3) { selectedRenderWindow = RenderWindow2; } else { selectedRenderWindow = RenderWindow3; } } // re-orient view if (selectedRenderWindow) { const mitk::Point3D& centerP = _PlaneGeometry->GetOrigin(); selectedRenderWindow->GetSliceNavigationController()->ReorientSlices(centerP, _PlaneGeometry->GetNormal()); } } break; } this->RequestRenderWindowUpdate(); } void QmitkMeasurementView::ActionDrawLineTriggered(bool checked) { Q_UNUSED(checked) mitk::PlanarLine::Pointer figure = mitk::PlanarLine::New(); QString qString = QString("Line%1").arg(++d->m_LineCounter); this->AddFigureToDataStorage(figure, qString); MEASUREMENT_DEBUG << "PlanarLine initialized..."; } void QmitkMeasurementView::ActionDrawPathTriggered(bool checked) { Q_UNUSED(checked) mitk::IPropertyFilters* propertyFilters = GetService(); if (propertyFilters != NULL) { mitk::PropertyFilter filter; filter.AddEntry("ClosedPlanarPolygon", mitk::PropertyFilter::Blacklist); propertyFilters->AddFilter(filter, "PlanarPolygon"); } mitk::PlanarPolygon::Pointer figure = mitk::PlanarPolygon::New(); figure->ClosedOff(); QString qString = QString("Path%1").arg(++d->m_PathCounter); mitk::DataNode::Pointer node = this->AddFigureToDataStorage(figure, qString); mitk::BoolProperty::Pointer closedProperty = mitk::BoolProperty::New( false ); node->SetProperty("ClosedPlanarPolygon", closedProperty); node->SetProperty("planarfigure.isextendable",mitk::BoolProperty::New(true)); MEASUREMENT_DEBUG << "PlanarPath initialized..."; } void QmitkMeasurementView::ActionDrawAngleTriggered(bool checked) { Q_UNUSED(checked) mitk::PlanarAngle::Pointer figure = mitk::PlanarAngle::New(); QString qString = QString("Angle%1").arg(++d->m_AngleCounter); this->AddFigureToDataStorage(figure, qString); MEASUREMENT_DEBUG << "PlanarAngle initialized..."; } void QmitkMeasurementView::ActionDrawFourPointAngleTriggered(bool checked) { Q_UNUSED(checked) mitk::PlanarFourPointAngle::Pointer figure = mitk::PlanarFourPointAngle::New(); QString qString = QString("Four Point Angle%1").arg(++d->m_FourPointAngleCounter); this->AddFigureToDataStorage(figure, qString); MEASUREMENT_DEBUG << "PlanarFourPointAngle initialized..."; } void QmitkMeasurementView::ActionDrawCircleTriggered(bool checked) { Q_UNUSED(checked) mitk::PlanarCircle::Pointer figure = mitk::PlanarCircle::New(); QString qString = QString("Circle%1").arg(++d->m_CircleCounter); this->AddFigureToDataStorage(figure, qString); MEASUREMENT_DEBUG << "PlanarCircle initialized..."; } void QmitkMeasurementView::ActionDrawEllipseTriggered(bool checked) { Q_UNUSED(checked) mitk::PlanarEllipse::Pointer figure = mitk::PlanarEllipse::New(); QString qString = QString("Ellipse%1").arg(++d->m_EllipseCounter); this->AddFigureToDataStorage(figure, qString); MEASUREMENT_DEBUG << "PlanarEllipse initialized..."; } void QmitkMeasurementView::ActionDrawDoubleEllipseTriggered(bool checked) { Q_UNUSED(checked) mitk::PlanarDoubleEllipse::Pointer figure = mitk::PlanarDoubleEllipse::New(); QString qString = QString("DoubleEllipse%1").arg(++d->m_DoubleEllipseCounter); this->AddFigureToDataStorage(figure, qString); MEASUREMENT_DEBUG << "PlanarDoubleEllipse initialized..."; } void QmitkMeasurementView::ActionDrawBezierCurveTriggered(bool checked) { Q_UNUSED(checked) mitk::PlanarBezierCurve::Pointer figure = mitk::PlanarBezierCurve::New(); QString qString = QString("BezierCurve%1").arg(++d->m_BezierCurveCounter); this->AddFigureToDataStorage(figure, qString); MEASUREMENT_DEBUG << "PlanarBezierCurve initialized..."; } void QmitkMeasurementView::ActionDrawSubdivisionPolygonTriggered(bool checked) { Q_UNUSED(checked) mitk::PlanarSubdivisionPolygon::Pointer figure = mitk::PlanarSubdivisionPolygon::New(); QString qString = QString("SubdivisionPolygon%1").arg(++d->m_SubdivisionPolygonCounter); this->AddFigureToDataStorage(figure, qString); MEASUREMENT_DEBUG << "PlanarSubdivisionPolygon initialized..."; } void QmitkMeasurementView::ActionDrawRectangleTriggered(bool checked) { Q_UNUSED(checked) mitk::PlanarRectangle::Pointer figure = mitk::PlanarRectangle::New(); QString qString = QString("Rectangle%1").arg(++d->m_RectangleCounter); this->AddFigureToDataStorage(figure, qString); MEASUREMENT_DEBUG << "PlanarRectangle initialized..."; } void QmitkMeasurementView::ActionDrawPolygonTriggered(bool checked) { Q_UNUSED(checked) mitk::PlanarPolygon::Pointer figure = mitk::PlanarPolygon::New(); figure->ClosedOn(); QString qString = QString("Polygon%1").arg(++d->m_PolygonCounter); mitk::DataNode::Pointer node = this->AddFigureToDataStorage(figure, qString); node->SetProperty("planarfigure.isextendable",mitk::BoolProperty::New(true)); MEASUREMENT_DEBUG << "PlanarPolygon initialized..."; } void QmitkMeasurementView::CopyToClipboard( bool checked ) { Q_UNUSED(checked) MEASUREMENT_DEBUG << "Copying current Text to clipboard..."; QString clipboardText = d->m_SelectedPlanarFiguresText->toPlainText(); QApplication::clipboard()->setText(clipboardText, QClipboard::Clipboard); } mitk::DataNode::Pointer QmitkMeasurementView::AddFigureToDataStorage( mitk::PlanarFigure* figure, const QString& name) { // add as MEASUREMENT_DEBUG << "Adding new figure to datastorage..."; if( d->m_SelectedImageNode.IsNull() ) { MITK_ERROR << "No reference image available"; return 0; } mitk::DataNode::Pointer newNode = mitk::DataNode::New(); newNode->SetName(name.toStdString()); newNode->SetData(figure); // set as selected newNode->SetSelected( true ); this->GetDataStorage()->Add(newNode, d->m_SelectedImageNode); // set all others in selection as deselected for( int i=0; im_CurrentSelection.size(); ++i) d->m_CurrentSelection.at(i)->SetSelected(false); d->m_CurrentSelection.clear(); d->m_CurrentSelection.push_back( newNode ); this->UpdateMeasurementText(); this->DisableCrosshairNavigation(); d->m_DrawActionsToolBar->setEnabled(false); d->m_UnintializedPlanarFigure = true; return newNode; } void QmitkMeasurementView::UpdateMeasurementText() { d->m_SelectedPlanarFiguresText->clear(); QString infoText; QString plainInfoText; int j = 1; mitk::PlanarFigure* _PlanarFigure = 0; mitk::PlanarAngle* planarAngle = 0; mitk::PlanarFourPointAngle* planarFourPointAngle = 0; mitk::DataNode::Pointer node = 0; for (int i=0; im_CurrentSelection.size(); ++i, ++j) { plainInfoText.clear(); node = d->m_CurrentSelection.at(i); _PlanarFigure = dynamic_cast (node->GetData()); if( !_PlanarFigure ) continue; if(j>1) infoText.append("
"); infoText.append(QString("%1
").arg(QString::fromStdString( node->GetName()))); plainInfoText.append(QString("%1").arg(QString::fromStdString( node->GetName()))); planarAngle = dynamic_cast (_PlanarFigure); if(!planarAngle) { planarFourPointAngle = dynamic_cast (_PlanarFigure); } double featureQuantity = 0.0; for (unsigned int k = 0; k < _PlanarFigure->GetNumberOfFeatures(); ++k) { if ( !_PlanarFigure->IsFeatureActive( k ) ) continue; featureQuantity = _PlanarFigure->GetQuantity(k); if ((planarAngle && k == planarAngle->FEATURE_ID_ANGLE) || (planarFourPointAngle && k == planarFourPointAngle->FEATURE_ID_ANGLE)) featureQuantity = featureQuantity * 180 / vnl_math::pi; infoText.append( QString("%1: %2 %3") .arg(QString( _PlanarFigure->GetFeatureName(k))) .arg(featureQuantity, 0, 'f', 2) .arg(QString(_PlanarFigure->GetFeatureUnit(k)))); plainInfoText.append( QString("\n%1: %2 %3") .arg(QString(_PlanarFigure->GetFeatureName(k))) .arg( featureQuantity, 0, 'f', 2) .arg(QString( _PlanarFigure->GetFeatureUnit(k)))); if(k+1 != _PlanarFigure->GetNumberOfFeatures()) infoText.append("
"); } if (j != d->m_CurrentSelection.size()) infoText.append("
"); } d->m_SelectedPlanarFiguresText->setHtml(infoText); } void QmitkMeasurementView::AddAllInteractors() { MEASUREMENT_DEBUG << "Adding interactors and observers to all planar figures"; mitk::DataStorage::SetOfObjects::ConstPointer planarFigures = this->GetAllPlanarFigures(); for(mitk::DataStorage::SetOfObjects::ConstIterator it=planarFigures->Begin(); it!=planarFigures->End(); it++) { this->NodeAdded( it.Value() ); } } void QmitkMeasurementView::RemoveAllInteractors() { MEASUREMENT_DEBUG << "Removing interactors and observers from all planar figures"; mitk::DataStorage::SetOfObjects::ConstPointer planarFigures = this->GetAllPlanarFigures(); for(mitk::DataStorage::SetOfObjects::ConstIterator it=planarFigures->Begin(); it!=planarFigures->End(); it++) { this->NodeRemoved( it.Value() ); } } mitk::DataNode::Pointer QmitkMeasurementView::DetectTopMostVisibleImage() { // get all images from the data storage which are not a segmentation mitk::TNodePredicateDataType::Pointer isImage = mitk::TNodePredicateDataType::New(); mitk::NodePredicateProperty::Pointer isBinary = mitk::NodePredicateProperty::New("binary", mitk::BoolProperty::New(true)); mitk::NodePredicateNot::Pointer isNotBinary = mitk::NodePredicateNot::New( isBinary ); mitk::NodePredicateAnd::Pointer isNormalImage = mitk::NodePredicateAnd::New( isImage, isNotBinary ); mitk::DataStorage::SetOfObjects::ConstPointer Images = this->GetDataStorage()->GetSubset( isNormalImage ); mitk::DataNode::Pointer currentNode; int maxLayer = itk::NumericTraits::min(); // iterate over selection for (mitk::DataStorage::SetOfObjects::ConstIterator sofIt = Images->Begin(); sofIt != Images->End(); ++sofIt) { mitk::DataNode::Pointer node = sofIt->Value(); if ( node.IsNull() ) continue; if (node->IsVisible(NULL) == false) continue; // we also do not want to assign planar figures to helper objects ( even if they are of type image ) if (node->GetProperty("helper object")) continue; int layer = 0; node->GetIntProperty("layer", layer); if ( layer < maxLayer ) { continue; } else { maxLayer = layer; currentNode = node; } } return currentNode; } void QmitkMeasurementView::EnableCrosshairNavigation() { MEASUREMENT_DEBUG << "EnableCrosshairNavigation"; // enable the crosshair navigation if (mitk::ILinkedRenderWindowPart* linkedRenderWindow = dynamic_cast(this->GetRenderWindowPart())) { MEASUREMENT_DEBUG << "enabling linked navigation"; linkedRenderWindow->EnableLinkedNavigation(true); linkedRenderWindow->EnableSlicingPlanes(true); } } void QmitkMeasurementView::DisableCrosshairNavigation() { MEASUREMENT_DEBUG << "DisableCrosshairNavigation"; // disable the crosshair navigation during the drawing if (mitk::ILinkedRenderWindowPart* linkedRenderWindow = dynamic_cast(this->GetRenderWindowPart())) { MEASUREMENT_DEBUG << "disabling linked navigation"; linkedRenderWindow->EnableLinkedNavigation(false); linkedRenderWindow->EnableSlicingPlanes(false); } } mitk::DataStorage::SetOfObjects::ConstPointer QmitkMeasurementView::GetAllPlanarFigures() const { mitk::TNodePredicateDataType::Pointer isPlanarFigure = mitk::TNodePredicateDataType::New(); mitk::NodePredicateProperty::Pointer isNotHelperObject = mitk::NodePredicateProperty::New("helper object", mitk::BoolProperty::New(false)); mitk::NodePredicateAnd::Pointer isNotHelperButPlanarFigure = mitk::NodePredicateAnd::New( isPlanarFigure, isNotHelperObject ); return this->GetDataStorage()->GetSubset( isPlanarFigure ); } diff --git a/Plugins/org.mitk.gui.qt.measurementtoolbox/src/internal/mitkPluginActivator.cpp b/Plugins/org.mitk.gui.qt.measurementtoolbox/src/internal/mitkPluginActivator.cpp index a471351f45..aa05373988 100644 --- a/Plugins/org.mitk.gui.qt.measurementtoolbox/src/internal/mitkPluginActivator.cpp +++ b/Plugins/org.mitk.gui.qt.measurementtoolbox/src/internal/mitkPluginActivator.cpp @@ -1,42 +1,44 @@ /*=================================================================== 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 "mitkPluginActivator.h" #include "QmitkMeasurementView.h" #include "QmitkImageStatisticsView.h" #include ctkPluginContext* mitk::PluginActivator::m_Context = NULL; ctkPluginContext* mitk::PluginActivator::GetContext() { return m_Context; } void mitk::PluginActivator::start(ctkPluginContext* context) { BERRY_REGISTER_EXTENSION_CLASS(QmitkMeasurementView, context) BERRY_REGISTER_EXTENSION_CLASS(QmitkImageStatisticsView, context) m_Context = context; } void mitk::PluginActivator::stop(ctkPluginContext* context) { Q_UNUSED(context) m_Context = NULL; } -Q_EXPORT_PLUGIN2(org.mitk.gui.qt.measurementtoolbox, mitk::PluginActivator) +#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) + Q_EXPORT_PLUGIN2(org.mitk.gui.qt.measurementtoolbox, mitk::PluginActivator) +#endif diff --git a/Plugins/org.mitk.gui.qt.measurementtoolbox/src/internal/mitkPluginActivator.h b/Plugins/org.mitk.gui.qt.measurementtoolbox/src/internal/mitkPluginActivator.h index 46e55e4329..789098ce7d 100644 --- a/Plugins/org.mitk.gui.qt.measurementtoolbox/src/internal/mitkPluginActivator.h +++ b/Plugins/org.mitk.gui.qt.measurementtoolbox/src/internal/mitkPluginActivator.h @@ -1,40 +1,43 @@ /*=================================================================== 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 MITKPLUGINACTIVATOR_H #define MITKPLUGINACTIVATOR_H #include #include namespace mitk { class PluginActivator : public QObject, public ctkPluginActivator { Q_OBJECT +#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) + Q_PLUGIN_METADATA(IID "org.mitk.gui.qt.measurementtoolbox") +#endif Q_INTERFACES(ctkPluginActivator) public: static ctkPluginContext* GetContext(); void start(ctkPluginContext* context); void stop(ctkPluginContext* context); private: static ctkPluginContext* m_Context; }; } #endif diff --git a/Plugins/org.mitk.gui.qt.moviemaker/documentation/UserManual/QmitkMovieMaker.dox b/Plugins/org.mitk.gui.qt.moviemaker/documentation/UserManual/QmitkMovieMaker.dox deleted file mode 100644 index 878627bddb..0000000000 --- a/Plugins/org.mitk.gui.qt.moviemaker/documentation/UserManual/QmitkMovieMaker.dox +++ /dev/null @@ -1,44 +0,0 @@ -/** - -\page org_mitk_views_moviemaker The Movie Maker View - -\imageMacro{QmitkMovieMaker_Icon.png,"Icon of the Movie Maker View",2.00} - -Available sections: - - \ref QmitkMovieMakerUserManualOverview - - \ref QmitkMovieMakerUserManualFeatures - - \ref QmitkMovieMakerUserManualUsage - -\section QmitkMovieMakerUserManualOverview Overview - -MovieMaker is a functionality for easily creating fancy movies from scenes displayed in MITK widgets. -It is also possible to slide through your data, automatically rotate 3D scenes and take screenshots of widgets. - -\section QmitkMovieMakerUserManualFeatures Features - - The Movie Maker allows you to create movies and screenshots from within MITK. It can automatically scroll thorugh timesteps and slices while recording a movie. This way, you can record visualizations like a beating heart or a rotating skull. - -\section QmitkMovieMakerUserManualUsage Usage - -\imageMacro{QmitkMovieMaker_ControlArea.png,"A view of the command area of QmitkMovieMaker",9.84} - -\subsection QmitkMovieMakerUserManualWindowSelection Window selection -With the first two drop down boxes, you can choose which window you want to step through and which window you want to record in. Left clicking inside a window will set both drop down boxes to that window, but you can choose different windows for stepping and recording. - -The first drop down box defines the window along which slices will be stepped through if stepping is set to spatial (see below). The second denotes the window from which the content will be recorded. - -\subsection QmitkMovieMakerUserManualRecordingOptions Recording Options - -The slider can be used to step through the slices manually while not recording. Start and stop control a preview of what a video would look like. - -The buttons in the bottom part of this section can be used to create movies (windows only) or screenshots. Clicking opens a file %dialog where a name can be selected. After confirmation, a screenshot or movie is created according to the playing options. - -\subsection QmitkMovieMakerUserManualPlayingOptions Playing Options - -The first section controls whether the movie steps through slices (if a 2D view is selected), rotate the shown scene (if a 3D view is selected), or step through time steps (if set to temporal and a time resolved dataset is selected). If set to combined, a combination of both above options is used, with their speed relation set via the S/T Relation Spinbox. - -In the second section the direction of stepping can be set. Options are: Forward, backward and Ping-Pong, which is back-and-forth.The stepping speed can be set via the spinbox(total time in seconds). - -Although stepping speed is a total time in sec., this can not always be achieved. As a minimal frame rate of 25 fps is assumed to provide smooth movies, a dataset with only 25 slices will always be stepped through in 1 sec or faster. - -*/ diff --git a/Plugins/org.mitk.gui.qt.moviemaker/documentation/UserManual/QmitkMovieMaker_ControlArea.png b/Plugins/org.mitk.gui.qt.moviemaker/documentation/UserManual/QmitkMovieMaker_ControlArea.png deleted file mode 100644 index ec8c0b8dca..0000000000 Binary files a/Plugins/org.mitk.gui.qt.moviemaker/documentation/UserManual/QmitkMovieMaker_ControlArea.png and /dev/null differ diff --git a/Plugins/org.mitk.gui.qt.moviemaker/documentation/UserManual/QmitkMovieMaker_Icon.png b/Plugins/org.mitk.gui.qt.moviemaker/documentation/UserManual/QmitkMovieMaker_Icon.png deleted file mode 100644 index 92c8276a2a..0000000000 Binary files a/Plugins/org.mitk.gui.qt.moviemaker/documentation/UserManual/QmitkMovieMaker_Icon.png and /dev/null differ diff --git a/Plugins/org.mitk.gui.qt.moviemaker/documentation/UserManual/QmitkMovieMaker_ScreenshotMakerInterface.png b/Plugins/org.mitk.gui.qt.moviemaker/documentation/UserManual/QmitkMovieMaker_ScreenshotMakerInterface.png deleted file mode 100644 index 085dcbdea6..0000000000 Binary files a/Plugins/org.mitk.gui.qt.moviemaker/documentation/UserManual/QmitkMovieMaker_ScreenshotMakerInterface.png and /dev/null differ diff --git a/Plugins/org.mitk.gui.qt.moviemaker/documentation/UserManual/QmitkScreenshotMaker.dox b/Plugins/org.mitk.gui.qt.moviemaker/documentation/UserManual/QmitkScreenshotMaker.dox deleted file mode 100644 index 05b657bdeb..0000000000 --- a/Plugins/org.mitk.gui.qt.moviemaker/documentation/UserManual/QmitkScreenshotMaker.dox +++ /dev/null @@ -1,19 +0,0 @@ -/** -\page org_mitk_views_screenshotmaker The Screenshot Maker - -This view provides the functionality to create and save screenshots of the data. - -Available sections: - - \ref QmitkScreenshotMakerUserManualUse - -\imageMacro{QmitkMovieMaker_ScreenshotMakerInterface.png,"The Screenshot Maker User Interface",7.09} - -\section QmitkScreenshotMakerUserManualUse Usage - -The first section offers the option of creating a screenshot of the last activated render window (thus the one, which was last clicked into). Upon clicking the button, the Screenshot Maker asks for a filename in which the screenshot is to be stored. The multiplanar Screenshot button asks for a folder, where screenshots of the three 2D views will be stored with default names. - -The high resolution screenshot section works the same as the simple screenshot section, aside from the fact, that the user can choose a magnification factor. - -In the option section one can rotate the camera in the 3D view by using the buttons. Furthermore one can choose the background colour for the screenshots, default is black. - -*/ diff --git a/Plugins/org.mitk.gui.qt.moviemaker/documentation/doxygen/modules.dox b/Plugins/org.mitk.gui.qt.moviemaker/documentation/doxygen/modules.dox deleted file mode 100644 index 07f1421b2a..0000000000 --- a/Plugins/org.mitk.gui.qt.moviemaker/documentation/doxygen/modules.dox +++ /dev/null @@ -1,16 +0,0 @@ -/** - \defgroup org_mitk_gui_qt_moviemaker org.mitk.gui.qt.moviemaker - \ingroup MITKPlugins - - \brief Describe your plugin here. - -*/ - -/** - \defgroup org_mitk_gui_qt_moviemaker_internal Internal - \ingroup org_mitk_gui_qt_moviemaker - - \brief This subcategory includes the internal classes of the org.mitk.gui.qt.moviemaker plugin. Other - plugins must not rely on these classes. They contain implementation details and their interface - may change at any time. We mean it. -*/ diff --git a/Plugins/org.mitk.gui.qt.moviemaker/files.cmake b/Plugins/org.mitk.gui.qt.moviemaker/files.cmake index c4e28db992..11d7677e23 100644 --- a/Plugins/org.mitk.gui.qt.moviemaker/files.cmake +++ b/Plugins/org.mitk.gui.qt.moviemaker/files.cmake @@ -1,46 +1,53 @@ set(SRC_CPP_FILES - ) set(INTERNAL_CPP_FILES - QmitkMovieMaker.cpp + QmitkAnimationItem.cpp + QmitkAnimationItemDelegate.cpp + QmitkAnimationWidget.cpp + QmitkFFmpegWriter.cpp + QmitkMovieMakerView.cpp + QmitkOrbitAnimationItem.cpp + QmitkOrbitAnimationWidget.cpp + QmitkSliceAnimationItem.cpp + QmitkSliceAnimationWidget.cpp mitkMovieMakerPluginActivator.cpp QmitkScreenshotMaker.cpp - ) set(UI_FILES - src/internal/QmitkMovieMakerControls.ui + src/internal/QmitkMovieMakerView.ui + src/internal/QmitkOrbitAnimationWidget.ui + src/internal/QmitkSliceAnimationWidget.ui src/internal/QmitkScreenshotMakerControls.ui ) set(MOC_H_FILES src/internal/mitkMovieMakerPluginActivator.h - src/internal/QmitkMovieMaker.h + src/internal/QmitkAnimationItemDelegate.h + src/internal/QmitkAnimationWidget.h + src/internal/QmitkFFmpegWriter.h + src/internal/QmitkMovieMakerView.h + src/internal/QmitkOrbitAnimationWidget.h + src/internal/QmitkSliceAnimationWidget.h src/internal/QmitkScreenshotMaker.h ) set(CACHED_RESOURCE_FILES - resources/icon.xpm - plugin.xml - resources/play.xpm - resources/stop.xpm - resources/pause.xpm + resources/camera-video.png resources/screenshot_maker.png + plugin.xml ) -set(RES_FILES +set(QRC_FILES resources/QmitkMovieMaker.qrc - resources/play.xpm - resources/stop.xpm - resources/pause.xpm ) 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.moviemaker/manifest_headers.cmake b/Plugins/org.mitk.gui.qt.moviemaker/manifest_headers.cmake index 33c96b326e..0273e2802e 100644 --- a/Plugins/org.mitk.gui.qt.moviemaker/manifest_headers.cmake +++ b/Plugins/org.mitk.gui.qt.moviemaker/manifest_headers.cmake @@ -1,5 +1,5 @@ set(Plugin-Name "MITK Movie Maker") set(Plugin-Version "0.9") set(Plugin-Vendor "DKFZ, Medical and Biological Informatics") set(Plugin-ContactAddress "http://www.mitk.org") -set(Require-Plugin org.mitk.gui.qt.common.legacy) \ No newline at end of file +set(Require-Plugin org.mitk.gui.qt.common org.mitk.gui.qt.common.legacy org.mitk.gui.qt.ext) \ No newline at end of file diff --git a/Plugins/org.mitk.gui.qt.moviemaker/plugin.xml b/Plugins/org.mitk.gui.qt.moviemaker/plugin.xml index 32c792be7d..d3fe235aa5 100644 --- a/Plugins/org.mitk.gui.qt.moviemaker/plugin.xml +++ b/Plugins/org.mitk.gui.qt.moviemaker/plugin.xml @@ -1,35 +1,35 @@ + class="QmitkMovieMakerView" + icon="resources/camera-video.png" > Take movies of your data Take screenshots of your data diff --git a/Plugins/org.mitk.gui.qt.moviemaker/resources/QmitkMovieMaker.qrc b/Plugins/org.mitk.gui.qt.moviemaker/resources/QmitkMovieMaker.qrc index 8bdb515e34..61ad433b67 100644 --- a/Plugins/org.mitk.gui.qt.moviemaker/resources/QmitkMovieMaker.qrc +++ b/Plugins/org.mitk.gui.qt.moviemaker/resources/QmitkMovieMaker.qrc @@ -1,10 +1,6 @@ - QmitkMovieMakerClasses.png - QmitkMovieMakerGUI.png - icon.xpm - pause.xpm - play.xpm - stop.xpm + delay.svg + duration.svg diff --git a/Plugins/org.mitk.gui.qt.moviemaker/resources/QmitkMovieMakerClasses.png b/Plugins/org.mitk.gui.qt.moviemaker/resources/QmitkMovieMakerClasses.png deleted file mode 100644 index 9c26381a09..0000000000 Binary files a/Plugins/org.mitk.gui.qt.moviemaker/resources/QmitkMovieMakerClasses.png and /dev/null differ diff --git a/Plugins/org.mitk.gui.qt.moviemaker/resources/QmitkMovieMakerGUI.png b/Plugins/org.mitk.gui.qt.moviemaker/resources/QmitkMovieMakerGUI.png deleted file mode 100644 index 02af724a9e..0000000000 Binary files a/Plugins/org.mitk.gui.qt.moviemaker/resources/QmitkMovieMakerGUI.png and /dev/null differ diff --git a/Plugins/org.mitk.gui.qt.moviemaker/resources/camera-video.png b/Plugins/org.mitk.gui.qt.moviemaker/resources/camera-video.png new file mode 100644 index 0000000000..d9d484927f Binary files /dev/null and b/Plugins/org.mitk.gui.qt.moviemaker/resources/camera-video.png differ diff --git a/Plugins/org.mitk.gui.qt.moviemaker/resources/delay.svg b/Plugins/org.mitk.gui.qt.moviemaker/resources/delay.svg new file mode 100644 index 0000000000..75e2310861 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.moviemaker/resources/delay.svg @@ -0,0 +1,404 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + Jakub Steiner + + + http://jimmac.musichall.cz + + + + + appointment + new + meeting + rvsp + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Plugins/org.mitk.gui.qt.moviemaker/resources/duration.svg b/Plugins/org.mitk.gui.qt.moviemaker/resources/duration.svg new file mode 100644 index 0000000000..01b1d129bd --- /dev/null +++ b/Plugins/org.mitk.gui.qt.moviemaker/resources/duration.svg @@ -0,0 +1,392 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + Jakub Steiner + + + http://jimmac.musichall.cz + + + + + appointment + new + meeting + rvsp + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Plugins/org.mitk.gui.qt.moviemaker/resources/icon.png b/Plugins/org.mitk.gui.qt.moviemaker/resources/icon.png deleted file mode 100644 index 6ad519ea65..0000000000 Binary files a/Plugins/org.mitk.gui.qt.moviemaker/resources/icon.png and /dev/null differ diff --git a/Plugins/org.mitk.gui.qt.moviemaker/resources/icon.xpm b/Plugins/org.mitk.gui.qt.moviemaker/resources/icon.xpm deleted file mode 100644 index 103ebf4b01..0000000000 --- a/Plugins/org.mitk.gui.qt.moviemaker/resources/icon.xpm +++ /dev/null @@ -1,47 +0,0 @@ -/* XPM */ -static const char * icon_xpm[] = { -"28 28 16 1", -" c None", -". c #000000", -"+ c #555555", -"@ c #222222", -"# c #777777", -"$ c #444444", -"% c #BBBBBB", -"& c #DDDDDD", -"* c #AAAAAA", -"= c #FFFFFF", -"- c #888888", -"; c #993366", -"> c #CC6666", -", c #663300", -"' c #440000", -") c #FFFF00", -" ... ", -" ..+@@. ", -" ..++@+@.. ", -" ..+++##@@.. ", -" ..+++##@@@@.. ", -" ..+++##@@@$$.. ", -" ..#++##@@@$...$ ", -" ..##++#@@@%&&.$ ", -" ...*@@+#@@%&&==&. ", -" ...*++++@@%&&==&&@@. ", -" ..$$==+#-%&&==&&@@$$@. ", -" .+##..=-&&==&&@@@$$+@. ", -" .##---*.=%=&&@@@@$$++@. ", -" .===%**%%$=*@@@@@$$+++@. ", -".=-@+=&%&&.&-@@@@$$++++@. ", -".&.;.+=&%%.%#@@@$$+++++@. ", -".&.>,.=&**.*+@$$====++@. ", -".&.,,.&&--.*+=$$&&&&====... ", -".&+.'.&%##.-=&$+%%%%&&&&===.", -".&%+.*&*++$=&$======%%%%&&&.", -" .&&&&&-++&**$&&&+++%===%%%.", -" .&==&*+++&*--.%%@))++++===.", -" .&**&*+++&-+@@@*+@@)))@&&&.", -" .@&&&*+++@@@@..----@@@+%%%.", -" .+@@$*+@@@@.. .....----***.", -" .+++$@@@.. ....---.", -" ..@+$@.. ... ", -" .... "}; diff --git a/Plugins/org.mitk.gui.qt.moviemaker/resources/pause.xpm b/Plugins/org.mitk.gui.qt.moviemaker/resources/pause.xpm deleted file mode 100644 index 0ad2e7421c..0000000000 --- a/Plugins/org.mitk.gui.qt.moviemaker/resources/pause.xpm +++ /dev/null @@ -1,57 +0,0 @@ -/* XPM */ -static const char * pause_xpm[] = { -"24 24 30 1", -" c None", -". c #000000", -"+ c #FFFFFF", -"@ c #737372", -"# c #848483", -"$ c #888887", -"% c #7E7E7D", -"& c #A8A7A6", -"* c #A4A4A3", -"= c #A6A5A4", -"- c #B5B4B3", -"; c #858483", -"> c #AAA9A7", -", c #C0BFBE", -"' c #91908E", -") c #AFAEAC", -"! c #CACAC8", -"~ c #A6A5A2", -"{ c #BBBAB7", -"] c #D4D3D2", -"^ c #AEADA9", -"/ c #BFBDBA", -"( c #D7D5D3", -"_ c #B2B0AD", -": c #C3C1BE", -"< c #D9D8D6", -"[ c #B5B3B0", -"} c #D1CFCC", -"| c #DEDDDB", -"1 c #F3F3F3", -" ", -" ", -" ", -" ", -" ", -" .....+.....+ ", -" .@#$.+.@#$.+ ", -" .%&*.+.%&*.+ ", -" .%=-.+.%=-.+ ", -" .;>,.+.;>,.+ ", -" .')!.+.')!.+ ", -" .')!.+.')!.+ ", -" .')!.+.')!.+ ", -" .~{].+.~{].+ ", -" .~{].+.~{].+ ", -" .^/(.+.^/(.+ ", -" ._:<.+._:<.+ ", -" .[}|.+.[}|.+ ", -" .....+.....+ ", -" +++++1++++++ ", -" ", -" ", -" ", -" "}; diff --git a/Plugins/org.mitk.gui.qt.moviemaker/resources/play.xpm b/Plugins/org.mitk.gui.qt.moviemaker/resources/play.xpm deleted file mode 100644 index 0bcda4f454..0000000000 --- a/Plugins/org.mitk.gui.qt.moviemaker/resources/play.xpm +++ /dev/null @@ -1,64 +0,0 @@ -/* XPM */ -static const char * play_xpm[] = { -"24 24 37 1", -" c None", -". c #000000", -"+ c #727170", -"@ c #7B7B7A", -"# c #6C6B6A", -"$ c #7F7E7D", -"% c #999996", -"& c #7D7C7B", -"* c #828180", -"= c #9D9C9A", -"- c #B0AFAC", -"; c #908F8D", -"> c #868583", -", c #A1A09E", -"' c #B4B3B1", -") c #B6B4B2", -"! c #A5A4A1", -"~ c #898886", -"{ c #B9B7B4", -"] c #BAB9B6", -"^ c #BCBAB7", -"/ c #C3C2BF", -"( c #FFFFFF", -"_ c #8C8B89", -": c #A9A8A5", -"< c #BDBCB9", -"[ c #C5C3C0", -"} c #D0CECC", -"| c #8F8E8C", -"1 c #B5B3B1", -"2 c #C7C6C3", -"3 c #D2D1CE", -"4 c #B9B6B4", -"5 c #D8D7D5", -"6 c #A19F9D", -"7 c #C7C6C4", -"8 c #A7A6A3", -" ", -" ", -" ", -" ", -" . ", -" .. ", -" .+. ", -" .@#. ", -" .$%&. ", -" .*=-;. ", -" .>,')!. ", -" .~!{]^/.( ", -" ._:<[}.( ", -" .|123.( ", -" .=45.( ", -" .67.( ", -" .8.( ", -" ..( ", -" .( ", -" ( ", -" ", -" ", -" ", -" "}; diff --git a/Plugins/org.mitk.gui.qt.moviemaker/resources/stop.xpm b/Plugins/org.mitk.gui.qt.moviemaker/resources/stop.xpm deleted file mode 100644 index 3b76b26157..0000000000 --- a/Plugins/org.mitk.gui.qt.moviemaker/resources/stop.xpm +++ /dev/null @@ -1,56 +0,0 @@ -/* XPM */ -static const char * stop_xpm[] = { -"24 24 29 1", -" c None", -". c #000000", -"+ c #FFFFFF", -"@ c #737372", -"# c #848483", -"$ c #888887", -"% c #7E7E7D", -"& c #A8A7A6", -"* c #A4A4A3", -"= c #A6A5A4", -"- c #B5B4B3", -"; c #858483", -"> c #AAA9A7", -", c #C0BFBE", -"' c #91908E", -") c #AFAEAC", -"! c #CACAC8", -"~ c #A6A5A2", -"{ c #BBBAB7", -"] c #D4D3D2", -"^ c #AEADA9", -"/ c #BFBDBA", -"( c #D7D5D3", -"_ c #B2B0AD", -": c #C3C1BE", -"< c #D9D8D6", -"[ c #B5B3B0", -"} c #D1CFCC", -"| c #DEDDDB", -" ", -" ", -" ", -" ", -" ", -" .............+ ", -" .@#$$$$$$$$$.+ ", -" .%&*********.+ ", -" .%=---------.+ ", -" .;>,,,,,,,,,.+ ", -" .')!!!!!!!!!.+ ", -" .')!!!!!!!!!.+ ", -" .~{]]]]]]]]].+ ", -" .~{]]]]]]]]].+ ", -" .^/(((((((((.+ ", -" ._:<<<<<<<<<.+ ", -" .[}|||||||||.+ ", -" .............+ ", -" ++++++++++++++ ", -" ", -" ", -" ", -" ", -" "}; diff --git a/Plugins/org.mitk.gui.qt.moviemaker/src/internal/QmitkAnimationItem.cpp b/Plugins/org.mitk.gui.qt.moviemaker/src/internal/QmitkAnimationItem.cpp new file mode 100644 index 0000000000..c55bb0808a --- /dev/null +++ b/Plugins/org.mitk.gui.qt.moviemaker/src/internal/QmitkAnimationItem.cpp @@ -0,0 +1,71 @@ +/*=================================================================== + +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 "QmitkAnimationItem.h" + +QmitkAnimationItem::QmitkAnimationItem(const QString& widgetKey, double duration, double delay, bool startWithPrevious) +{ + this->SetWidgetKey(widgetKey); + this->SetDuration(duration); + this->SetDelay(delay); + this->SetStartWithPrevious(startWithPrevious); + + this->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled); +} + +QmitkAnimationItem::~QmitkAnimationItem() +{ +} + +QString QmitkAnimationItem::GetWidgetKey() const +{ + return this->data(WidgetKeyRole).toString(); +} + +void QmitkAnimationItem::SetWidgetKey(const QString& widgetKey) +{ + this->setData(widgetKey, WidgetKeyRole); +} + +double QmitkAnimationItem::GetDuration() const +{ + return this->data(DurationRole).toDouble(); +} + +void QmitkAnimationItem::SetDuration(double duration) +{ + this->setData(duration, DurationRole); +} + +double QmitkAnimationItem::GetDelay() const +{ + return this->data(DelayRole).toDouble(); +} + +void QmitkAnimationItem::SetDelay(double delay) +{ + this->setData(delay, DelayRole); +} + +bool QmitkAnimationItem::GetStartWithPrevious() const +{ + return this->data(StartWithPreviousRole).toBool(); +} + +void QmitkAnimationItem::SetStartWithPrevious(bool startWithPrevious) +{ + this->setData(startWithPrevious, StartWithPreviousRole); +} diff --git a/Plugins/org.mitk.gui.qt.moviemaker/src/internal/QmitkAnimationItem.h b/Plugins/org.mitk.gui.qt.moviemaker/src/internal/QmitkAnimationItem.h new file mode 100644 index 0000000000..9e7fcec130 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.moviemaker/src/internal/QmitkAnimationItem.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 QmitkAnimationItem_h +#define QmitkAnimationItem_h + +#include + +class QmitkAnimationItem : public QStandardItem +{ +public: + enum AnimationItemDataRole + { + WidgetKeyRole = Qt::UserRole + 2, + DurationRole, + DelayRole, + StartWithPreviousRole, + RenderWindowRole, + FromRole, + ToRole, + ReverseRole, + StartAngleRole, + OrbitRole + }; + + explicit QmitkAnimationItem(const QString& widgetKey, double duration = 2.0, double delay = 0.0, bool startWithPrevious = false); + virtual ~QmitkAnimationItem(); + + QString GetWidgetKey() const; + void SetWidgetKey(const QString& widgetKey); + + double GetDuration() const; + void SetDuration(double duration); + + double GetDelay() const; + void SetDelay(double delay); + + bool GetStartWithPrevious() const; + void SetStartWithPrevious(bool startWithPrevious); + + virtual void Animate(double s) = 0; +}; + +#endif diff --git a/Plugins/org.mitk.gui.qt.moviemaker/src/internal/QmitkAnimationItemDelegate.cpp b/Plugins/org.mitk.gui.qt.moviemaker/src/internal/QmitkAnimationItemDelegate.cpp new file mode 100644 index 0000000000..781aeb37af --- /dev/null +++ b/Plugins/org.mitk.gui.qt.moviemaker/src/internal/QmitkAnimationItemDelegate.cpp @@ -0,0 +1,123 @@ +/*=================================================================== + +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 "QmitkAnimationItem.h" +#include "QmitkAnimationItemDelegate.h" +#include +#include +#include +#include + +QmitkAnimationItemDelegate::QmitkAnimationItemDelegate(QObject* parent) + : QStyledItemDelegate(parent) +{ +} + +QmitkAnimationItemDelegate::~QmitkAnimationItemDelegate() +{ +} + +void QmitkAnimationItemDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const +{ + painter->save(); + + if (option.state & QStyle::State_Selected) + painter->fillRect(option.rect, option.palette.highlight()); + + if (index.column() == 0) + { + QStyleOptionViewItem opt = option; + this->initStyleOption(&opt, index); + + QRect rect = QRect(opt.rect.x() + 3, opt.rect.y(), opt.rect.width() - 6, opt.rect.height()); + QString text = option.fontMetrics.elidedText(index.data().toString(), Qt::ElideRight, rect.width()); + QPalette::ColorRole colorRole = (option.state & QStyle::State_Selected) + ? QPalette::HighlightedText + : QPalette::Text; + + QApplication::style()->drawItemText(painter, rect, 0, option.palette, true, text, colorRole); + } + else if (index.column() == 1) + { + const QStandardItemModel* model = dynamic_cast(index.model()); + const QmitkAnimationItem* thisItem = dynamic_cast(model->item(index.row(), 1)); + QList items; + + const int rowCount = model->rowCount(); + + for (int i = 0; i < rowCount; ++i) + items << dynamic_cast(model->item(i, 1)); + + double totalDuration = 0.0; + double previousStart = 0.0; + double thisStart = 0.0; + + Q_FOREACH(const QmitkAnimationItem* item, items) + { + if (item->GetStartWithPrevious()) + { + totalDuration = std::max(totalDuration, previousStart + item->GetDelay() + item->GetDuration()); + } + else + { + previousStart = totalDuration; + totalDuration += item->GetDelay() + item->GetDuration(); + } + + if (item == thisItem) + thisStart = previousStart; + } + + const QRect& rect = option.rect; + const double widthPerSecond = rect.width() / totalDuration; + + QColor color = thisItem->GetStartWithPrevious() + ? QColor("DarkGray") + : QColor("DimGray"); + + painter->setBrush(color); + painter->setPen(Qt::NoPen); + + painter->drawRect( + rect.x() + static_cast(widthPerSecond * (thisStart + thisItem->GetDelay())), + rect.y() + 1, + static_cast(widthPerSecond * thisItem->GetDuration()), + rect.height() - 2); + + if (thisItem->GetDelay() > std::numeric_limits::min()) + { + QPen pen(color); + painter->setPen(pen); + + painter->drawLine( + rect.x() + static_cast(widthPerSecond * thisStart), + rect.y() + 1, + rect.x() + static_cast(widthPerSecond * thisStart), + rect.y() + rect.height() - 2); + + pen.setStyle(Qt::DashLine); + painter->setPen(pen); + + painter->drawLine( + rect.x() + static_cast(widthPerSecond * thisStart), + rect.y() + rect.height() / 2, + rect.x() + static_cast(widthPerSecond * (thisStart + thisItem->GetDelay())) - 1, + rect.y() + rect.height() / 2); + } + } + + painter->restore(); +} diff --git a/Plugins/org.mitk.gui.qt.igttracking/src/internal/mitkPluginActivator.h b/Plugins/org.mitk.gui.qt.moviemaker/src/internal/QmitkAnimationItemDelegate.h similarity index 58% copy from Plugins/org.mitk.gui.qt.igttracking/src/internal/mitkPluginActivator.h copy to Plugins/org.mitk.gui.qt.moviemaker/src/internal/QmitkAnimationItemDelegate.h index bcc0aed5a2..b1ad53c99a 100644 --- a/Plugins/org.mitk.gui.qt.igttracking/src/internal/mitkPluginActivator.h +++ b/Plugins/org.mitk.gui.qt.moviemaker/src/internal/QmitkAnimationItemDelegate.h @@ -1,40 +1,33 @@ /*=================================================================== 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 QmitkAnimationItemDelegate_h +#define QmitkAnimationItemDelegate_h -#ifndef MITKPLUGINACTIVATOR_H -#define MITKPLUGINACTIVATOR_H +#include -#include - -namespace mitk { - -class PluginActivator : - public QObject, public ctkPluginActivator +class QmitkAnimationItemDelegate : public QStyledItemDelegate { Q_OBJECT - Q_INTERFACES(ctkPluginActivator) public: + explicit QmitkAnimationItemDelegate(QObject* parent = NULL); + ~QmitkAnimationItemDelegate(); - void start(ctkPluginContext* context); - void stop(ctkPluginContext* context); - -}; // PluginActivator - -} + void paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const; +}; -#endif // MITKPLUGINACTIVATOR_H +#endif diff --git a/Modules/SegmentationUI/Qmitk/QmitkToolGUIArea.cpp b/Plugins/org.mitk.gui.qt.moviemaker/src/internal/QmitkAnimationWidget.cpp similarity index 71% copy from Modules/SegmentationUI/Qmitk/QmitkToolGUIArea.cpp copy to Plugins/org.mitk.gui.qt.moviemaker/src/internal/QmitkAnimationWidget.cpp index 08fffdd694..45c861d9ab 100644 --- a/Modules/SegmentationUI/Qmitk/QmitkToolGUIArea.cpp +++ b/Plugins/org.mitk.gui.qt.moviemaker/src/internal/QmitkAnimationWidget.cpp @@ -1,28 +1,26 @@ /*=================================================================== 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 "QmitkToolGUIArea.h" +#include "QmitkAnimationWidget.h" -QmitkToolGUIArea::QmitkToolGUIArea( QWidget* parent, Qt::WFlags f ) -:QWidget(parent,f) +QmitkAnimationWidget::QmitkAnimationWidget(QWidget* parent) + : QWidget(parent) { - QWidget::setContentsMargins(0, 0, 0, 0); } -QmitkToolGUIArea::~QmitkToolGUIArea() +QmitkAnimationWidget::~QmitkAnimationWidget() { } - diff --git a/Plugins/org.mitk.gui.qt.igttracking/src/internal/mitkPluginActivator.h b/Plugins/org.mitk.gui.qt.moviemaker/src/internal/QmitkAnimationWidget.h similarity index 59% copy from Plugins/org.mitk.gui.qt.igttracking/src/internal/mitkPluginActivator.h copy to Plugins/org.mitk.gui.qt.moviemaker/src/internal/QmitkAnimationWidget.h index bcc0aed5a2..103a7b5f6e 100644 --- a/Plugins/org.mitk.gui.qt.igttracking/src/internal/mitkPluginActivator.h +++ b/Plugins/org.mitk.gui.qt.moviemaker/src/internal/QmitkAnimationWidget.h @@ -1,40 +1,35 @@ /*=================================================================== 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 QmitkAnimationWidget_h +#define QmitkAnimationWidget_h -#ifndef MITKPLUGINACTIVATOR_H -#define MITKPLUGINACTIVATOR_H +#include -#include +class QmitkAnimationItem; -namespace mitk { - -class PluginActivator : - public QObject, public ctkPluginActivator +class QmitkAnimationWidget : public QWidget { Q_OBJECT - Q_INTERFACES(ctkPluginActivator) public: + explicit QmitkAnimationWidget(QWidget* parent = NULL); + virtual ~QmitkAnimationWidget(); - void start(ctkPluginContext* context); - void stop(ctkPluginContext* context); - -}; // PluginActivator - -} + virtual void SetAnimationItem(QmitkAnimationItem* animationItem) = 0; +}; -#endif // MITKPLUGINACTIVATOR_H +#endif diff --git a/Plugins/org.mitk.gui.qt.moviemaker/src/internal/QmitkFFmpegWriter.cpp b/Plugins/org.mitk.gui.qt.moviemaker/src/internal/QmitkFFmpegWriter.cpp new file mode 100644 index 0000000000..ae332ba296 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.moviemaker/src/internal/QmitkFFmpegWriter.cpp @@ -0,0 +1,176 @@ +/*=================================================================== + +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 "QmitkFFmpegWriter.h" +#include +#include +#include + +QmitkFFmpegWriter::QmitkFFmpegWriter(QObject* parent) + : QObject(parent), + m_Process(new QProcess(this)), + m_Framerate(0), + m_IsRunning(false) +{ + this->connect(m_Process, SIGNAL(error(QProcess::ProcessError)), + this, SLOT(OnProcessError(QProcess::ProcessError))); + + this->connect(m_Process, SIGNAL(finished(int, QProcess::ExitStatus)), + this, SLOT(OnProcessFinished(int, QProcess::ExitStatus))); +} + +QmitkFFmpegWriter::~QmitkFFmpegWriter() +{ +} + +QString QmitkFFmpegWriter::GetFFmpegPath() const +{ + return m_FFmpegPath; +} + +void QmitkFFmpegWriter::SetFFmpegPath(const QString& path) +{ + m_FFmpegPath = path; +} + +QSize QmitkFFmpegWriter::GetSize() const +{ + return m_Size; +} + +void QmitkFFmpegWriter::SetSize(const QSize& size) +{ + m_Size = size; +} + +void QmitkFFmpegWriter::SetSize(int width, int height) +{ + m_Size = QSize(width, height); +} + +int QmitkFFmpegWriter::GetFramerate() const +{ + return m_Framerate; +} + +void QmitkFFmpegWriter::SetFramerate(int framerate) +{ + m_Framerate = framerate; +} + +QString QmitkFFmpegWriter::GetOutputPath() const +{ + return m_OutputPath; +} + +void QmitkFFmpegWriter::SetOutputPath(const QString& path) +{ + m_OutputPath = path; +} + +void QmitkFFmpegWriter::Start() +{ + if (m_FFmpegPath.isEmpty()) + mitkThrow() << "FFmpeg/Libav path is empty!"; + + if (m_Size.isNull()) + mitkThrow() << "Invalid video frame size!"; + + if (m_Framerate <= 0) + mitkThrow() << "Invalid framerate!"; + + if (m_OutputPath.isEmpty()) + mitkThrow() << "Output path is empty!"; + + m_Process->start(m_FFmpegPath, QStringList() + << "-y" + << "-f" << "rawvideo" + << "-pix_fmt" << "rgb24" + << "-s" << QString("%1x%2").arg(m_Size.width()).arg(m_Size.height()) + << "-r" << QString("%1").arg(m_Framerate) + << "-i" << "-" + << "-vf" << "vflip" + << "-pix_fmt" << "yuv420p" + << "-crf" << "18" + << m_OutputPath); + + m_Process->waitForStarted(); + m_IsRunning = true; +} + +bool QmitkFFmpegWriter::IsRunning() const +{ + return m_IsRunning; +} + +void QmitkFFmpegWriter::WriteFrame(const unsigned char* frame) +{ + if (frame == NULL || !m_Process->isOpen()) + return; + + m_Process->write(reinterpret_cast(frame), m_Size.width() * m_Size.height() * 3); + m_Process->waitForBytesWritten(); +} + +void QmitkFFmpegWriter::Stop() +{ + m_IsRunning = false; + m_Process->closeWriteChannel(); +} + +void QmitkFFmpegWriter::OnProcessError(QProcess::ProcessError error) +{ + m_IsRunning = false; + + MITK_ERROR << QString::fromLatin1(m_Process->readAllStandardError()).toStdString(); + + switch (error) + { + case QProcess::FailedToStart: + mitkThrow() << "FFmpeg/Libav failed to start!"; + + case QProcess::Crashed: + mitkThrow() << "FFmpeg/Libav crashed!"; + + case QProcess::Timedout: + mitkThrow() << "FFmpeg/Libav timed out!"; + + case QProcess::WriteError: + mitkThrow() << "Could not write to FFmpeg/Libav!"; + + case QProcess::ReadError: + mitkThrow() << "Could not read from FFmpeg/Libav!"; + + default: + mitkThrow() << "An unknown error occurred!"; + } +} + +void QmitkFFmpegWriter::OnProcessFinished(int exitCode, QProcess::ExitStatus exitStatus) +{ + m_IsRunning = false; + + if (exitStatus != QProcess::CrashExit) + { + if (exitCode != 0) + { + m_Process->close(); + mitkThrow() << QString("FFmpeg/Libav exit code: %1").arg(exitCode).toStdString().c_str(); + } + } + + m_Process->close(); +} diff --git a/Plugins/org.mitk.gui.qt.moviemaker/src/internal/QmitkFFmpegWriter.h b/Plugins/org.mitk.gui.qt.moviemaker/src/internal/QmitkFFmpegWriter.h new file mode 100644 index 0000000000..5527edb538 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.moviemaker/src/internal/QmitkFFmpegWriter.h @@ -0,0 +1,62 @@ +/*=================================================================== + +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 QmitkFFmpegWriter_h +#define QmitkFFmpegWriter_h + +#include +#include + +class QmitkFFmpegWriter : public QObject +{ + Q_OBJECT + +public: + explicit QmitkFFmpegWriter(QObject* parent = NULL); + ~QmitkFFmpegWriter(); + + QString GetFFmpegPath() const; + void SetFFmpegPath(const QString& path); + + QSize GetSize() const; + void SetSize(const QSize& size); + void SetSize(int width, int height); + + int GetFramerate() const; + void SetFramerate(int framerate); + + QString GetOutputPath() const; + void SetOutputPath(const QString& path); + + void Start(); + bool IsRunning() const; + void WriteFrame(const unsigned char* frame); + void Stop(); + +private slots: + void OnProcessError(QProcess::ProcessError error); + void OnProcessFinished(int exitCode, QProcess::ExitStatus exitStatus); + +private: + QProcess* m_Process; + QString m_FFmpegPath; + QSize m_Size; + int m_Framerate; + QString m_OutputPath; + bool m_IsRunning; +}; + +#endif diff --git a/Plugins/org.mitk.gui.qt.moviemaker/src/internal/QmitkMovieMaker.cpp b/Plugins/org.mitk.gui.qt.moviemaker/src/internal/QmitkMovieMaker.cpp deleted file mode 100644 index 0d78c15e3c..0000000000 --- a/Plugins/org.mitk.gui.qt.moviemaker/src/internal/QmitkMovieMaker.cpp +++ /dev/null @@ -1,769 +0,0 @@ -/*=================================================================== - -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 "QmitkMovieMaker.h" -//#include "QmitkMovieMakerControls.h" -#include "QmitkStepperAdapter.h" -#include "QmitkStdMultiWidget.h" -#include "QmitkMovieMaker.h" -//#include "QmitkMovieMakerControls.h" -#include "QmitkStepperAdapter.h" -#include "QmitkStdMultiWidget.h" - -#include "mitkVtkPropRenderer.h" -#include "mitkGlobalInteraction.h" - -#include - -#include -#include - -#include -#include -#include -#include -#include -#include - -#include "qapplication.h" - -#include "vtkImageWriter.h" -#include "vtkJPEGWriter.h" -#include "vtkPNGWriter.h" -#include "vtkRenderLargeImage.h" -#include "vtkRenderWindowInteractor.h" -#include "vtkRenderer.h" -#include "vtkTestUtilities.h" - -#include -#include "vtkMitkRenderProp.h" - -#include -#include -#include "vtkRenderWindowInteractor.h" -#include - -QmitkMovieMaker::QmitkMovieMaker(QObject *parent, const char * /*name*/) - -: - QmitkFunctionality(), m_Controls(NULL), - m_StepperAdapter(NULL), - m_FocusManagerCallback(0), m_Looping(true), m_Direction(0), m_Aspect(0) -{ - - parentWidget = parent; - - m_Timer = new QTimer(this); - m_Time = new QTime(); - - m_FocusManagerCallback = MemberCommand::New(); - m_FocusManagerCallback->SetCallbackFunction(this, &QmitkMovieMaker::FocusChange); - - m_movieGenerator = mitk::MovieGenerator::New(); - - if (m_movieGenerator.IsNull()) - { - MITK_ERROR << "Either mitk::MovieGenerator is not implemented for your"; - MITK_ERROR << " platform or an error occurred during"; - MITK_ERROR << " mitk::MovieGenerator::New()" ; - } - -} - -QmitkMovieMaker::~QmitkMovieMaker() -{ - delete m_StepperAdapter; - delete m_Timer; - delete m_Time; - //delete m_RecordingRenderer; - -} - -mitk::BaseController* QmitkMovieMaker::GetSpatialController() -{ - mitk::BaseRenderer* focusedRenderer = mitk::GlobalInteraction::GetInstance()->GetFocus(); - - if (mitk::BaseRenderer::GetInstance(GetActiveStdMultiWidget()->mitkWidget1->GetRenderWindow()) - == focusedRenderer) - { - return GetActiveStdMultiWidget()->mitkWidget1->GetController(); - } - else if (mitk::BaseRenderer::GetInstance( - GetActiveStdMultiWidget()->mitkWidget2->GetRenderWindow()) == focusedRenderer) - { - return GetActiveStdMultiWidget()->mitkWidget2->GetController(); - } - else if (mitk::BaseRenderer::GetInstance( - GetActiveStdMultiWidget()->mitkWidget3->GetRenderWindow()) == focusedRenderer) - { - return GetActiveStdMultiWidget()->mitkWidget3->GetController(); - } - else if (mitk::BaseRenderer::GetInstance( - GetActiveStdMultiWidget()->mitkWidget4->GetRenderWindow()) == focusedRenderer) - { - return GetActiveStdMultiWidget()->mitkWidget4->GetController(); - } - - return GetActiveStdMultiWidget()->mitkWidget4->GetController(); -} - -mitk::BaseController* QmitkMovieMaker::GetTemporalController() -{ - return GetActiveStdMultiWidget()->GetTimeNavigationController(); -} - -void QmitkMovieMaker::CreateConnections() -{ - if (m_Controls) - { - // start / pause / stop playing - connect((QObject*) m_Controls->btnPlay, SIGNAL(clicked()), (QObject*) this, - SLOT(StartPlaying())); - connect((QObject*) m_Controls->btnPause, SIGNAL(clicked()), this, SLOT(PausePlaying())); - connect((QObject*) m_Controls->btnStop, SIGNAL(clicked()), this, SLOT(StopPlaying())); - - connect((QObject*) m_Controls->rbtnForward, SIGNAL(clicked()), this, SLOT(RBTNForward())); - connect((QObject*) m_Controls->rbtnBackward, SIGNAL(clicked()), this, SLOT(RBTNBackward())); - connect((QObject*) m_Controls->rbtnPingPong, SIGNAL(clicked()), this, SLOT(RBTNPingPong())); - - // radio button group: forward, backward, ping-pong - connect( this, SIGNAL(SwitchDirection(int)), this, SLOT(SetDirection(int)) ); - - // radio button group: spatial, temporal - connect((QObject*) m_Controls->rbtnSpatial, SIGNAL(clicked()), this, SLOT(RBTNSpatial())); - connect((QObject*) m_Controls->rbtnTemporal, SIGNAL(clicked()), this, SLOT(RBTNTemporal())); - connect((QObject*) m_Controls->rbtnCombined, SIGNAL(clicked()), this, SLOT(RBTNCombined())); - connect( this, SIGNAL(SwitchAspect(int)), this, SLOT(SetAspect(int)) ); - - // stepper window selection - connect((QObject*) (m_Controls->cmbSelectedStepperWindow), SIGNAL ( activated ( int) ), (QObject*) this, SLOT ( SetStepperWindow (int) ) ); - - // recording window selection - connect((QObject*) (m_Controls->cmbSelectedRecordingWindow), SIGNAL ( activated ( int) ), (QObject*) this, SLOT ( SetRecordingWindow (int) ) ); - - // advance the animation - // every timer tick - connect((QObject*) m_Timer, SIGNAL(timeout()), this, SLOT(AdvanceAnimation())); - - // movie generation - // when the movie button is clicked - connect((QObject*) m_Controls->btnMovie, SIGNAL(clicked()), this, SLOT(GenerateMovie())); - - connect((QObject*) m_Controls->btnScreenshot, SIGNAL(clicked()), this, SLOT( - GenerateScreenshot())); - connect((QObject*) m_Controls->m_HRScreenshot, SIGNAL(clicked()), this, SLOT( - GenerateHR3DScreenshot())); - - // blocking of ui elements during movie generation - connect((QObject*) this, SIGNAL(StartBlockControls()), (QObject*) this, SLOT(BlockControls())); - - connect((QObject*) this, SIGNAL(EndBlockControls()), (QObject*) this, SLOT(UnBlockControls())); - - connect((QObject*) this, SIGNAL(EndBlockControlsMovieDeactive()), (QObject*) this, SLOT( - UnBlockControlsMovieDeactive())); - - // allow for change of spatialtime relation - connect((QObject*) m_Controls->spatialTimeRelation, SIGNAL(valueChanged ( int ) ), this, SLOT( DeleteMStepper() ) ); - - - m_Controls->btnScreenshot->setVisible(false); - m_Controls->m_HRScreenshot->setVisible(false); - } -} - -void QmitkMovieMaker::Activated() -{ - QmitkFunctionality::Activated(); - - // create a member command that will be executed from the observer - itk::SimpleMemberCommand::Pointer stepperChangedCommand; - stepperChangedCommand = itk::SimpleMemberCommand::New(); - // set the callback function of the member command - stepperChangedCommand->SetCallbackFunction(this, &QmitkMovieMaker::UpdateGUI); - // add an observer to the data tree node pointer connected to the above member command - MITK_INFO << "Add observer on insertion point node in NavigationPathController::AddObservers"; - m_StepperObserverTag = this->GetTemporalController()->GetTime()->AddObserver( - itk::ModifiedEvent(), stepperChangedCommand); - - m_FocusManagerObserverTag - = mitk::GlobalInteraction::GetInstance()->GetFocusManager()->AddObserver(mitk::FocusEvent(), - m_FocusManagerCallback); - this->UpdateGUI(); - // Initialize steppers etc. - this->FocusChange(); -} - -void QmitkMovieMaker::Deactivated() -{ - QmitkFunctionality::Deactivated(); - this->GetTemporalController()->GetTime()->RemoveObserver(m_StepperObserverTag); - mitk::GlobalInteraction::GetInstance()->GetFocusManager()->RemoveObserver( - m_FocusManagerObserverTag); // remove (if tag is invalid, nothing is removed) -} - -void QmitkMovieMaker::FocusChange() -{ - mitk::Stepper *stepper = this->GetAspectStepper(); - m_StepperAdapter->SetStepper(stepper); - - // Make the stepper movement non-inverted - stepper->InverseDirectionOff(); - - // Set stepping direction and aspect (spatial / temporal) for new stepper - this->UpdateLooping(); - this->UpdateDirection(); - - // Set newly focused window as active in "Selected Window" combo box - const mitk::RenderingManager::RenderWindowVector rwv = - mitk::RenderingManager::GetInstance()->GetAllRegisteredRenderWindows(); - - int i; - mitk::RenderingManager::RenderWindowVector::const_iterator iter; - for (iter = rwv.begin(), i = 0; iter != rwv.end(); ++iter, ++i) - { - mitk::BaseRenderer* focusedRenderer = - mitk::GlobalInteraction::GetInstance()->GetFocusManager()->GetFocused(); - - if (focusedRenderer == mitk::BaseRenderer::GetInstance((*iter))) - { - m_Controls->cmbSelectedStepperWindow->setCurrentIndex(i); - // this->cmbSelectedStepperWindow_activated(i); - this->SetStepperWindow(i); - m_Controls->cmbSelectedRecordingWindow->setCurrentIndex(i); - // this->cmbSelectedRecordWindow_activated(i); - this->SetRecordingWindow(i); - break; - } - } -} - -void QmitkMovieMaker::AdvanceAnimation() -{ - // This method is called when a timer timeout occurs. It increases the - // stepper value according to the elapsed time and the stepper interval. - // Note that a screen refresh is not forced, but merely requested, and may - // occur only after more calls to AdvanceAnimation(). - - mitk::Stepper* stepper = this->GetAspectStepper(); - - m_StepperAdapter->SetStepper(stepper); - - int elapsedTime = m_Time->elapsed(); - m_Time->restart(); - - static double increment = 0.0; - increment = increment - static_cast (increment); - increment += elapsedTime * stepper->GetSteps() / (m_Controls->spnDuration->value() * 1000.0); - - int i, n = static_cast (increment); - for (i = 0; i < n; ++i) - { - stepper->Next(); - } -} - -void QmitkMovieMaker::RenderSlot() -{ - int *i = widget->GetRenderWindow()->GetSize(); - m_PropRenderer->Resize(i[0], i[1]); - - widget->GetRenderWindow()->Render(); -} - -void QmitkMovieMaker::PausePlaying() -{ - - m_Controls->slidAngle->setDisabled(false); - m_Controls->btnMovie->setEnabled(true); - m_Controls->btnPlay->setEnabled(true); - m_Controls->btnScreenshot->setEnabled(true); - - m_Timer->stop(); - - m_Controls->btnPlay->setHidden(false); - m_Controls->btnPause->setHidden(true); - if (m_movieGenerator.IsNull()) - m_Controls->btnMovie->setEnabled(false); -} - -void QmitkMovieMaker::StopPlaying() -{ - m_Controls->slidAngle->setDisabled(false); - m_Controls->btnMovie->setEnabled(true); - m_Controls->btnPlay->setEnabled(true); - m_Controls->btnScreenshot->setEnabled(true); - - m_Controls->btnPlay->setHidden(false); - m_Controls->btnPause->setHidden(true); - - m_Timer->stop(); - switch (m_Direction) - { - case 0: - case 2: - this->GetAspectStepper()->First(); - break; - - case 1: - this->GetAspectStepper()->Last(); - break; - } - - // Reposition slider GUI element - m_StepperAdapter->SetStepper(this->GetAspectStepper()); - - if (m_movieGenerator.IsNull()) - m_Controls->btnMovie->setEnabled(false); - -} - -void QmitkMovieMaker::SetLooping(bool looping) -{ - m_Looping = looping; - this->UpdateLooping(); -} - -void QmitkMovieMaker::SetDirection(int direction) -{ - m_Direction = direction; - this->UpdateDirection(); -} - -void QmitkMovieMaker::SetAspect(int aspect) -{ - m_Aspect = aspect; - - m_StepperAdapter->SetStepper(this->GetAspectStepper()); - this->UpdateLooping(); - this->UpdateDirection(); -} - -void QmitkMovieMaker::SetStepperWindow(int window) -{ - // Set newly selected window / renderer as focused - const mitk::RenderingManager::RenderWindowVector rwv = - mitk::RenderingManager::GetInstance()->GetAllRegisteredRenderWindows(); - - //Delete MultiStepper - DeleteMStepper(); - - int i; - mitk::RenderingManager::RenderWindowVector::const_iterator iter; - for (iter = rwv.begin(), i = 0; iter != rwv.end(); ++iter, ++i) - { - if (i == window) - { - mitk::GlobalInteraction::GetInstance()->GetFocusManager() ->SetFocused( - mitk::BaseRenderer::GetInstance((*iter))); - break; - } - } -} - -void QmitkMovieMaker::SetRecordingWindow(int window) -{ - // Set newly selected window for recording - const mitk::RenderingManager::RenderWindowVector rwv = - mitk::RenderingManager::GetInstance()->GetAllRegisteredRenderWindows(); - - //Delete MultiStepper - DeleteMStepper(); - - int i; - mitk::RenderingManager::RenderWindowVector::const_iterator iter; - for (iter = rwv.begin(), i = 0; iter != rwv.end(); ++iter, ++i) - { - if (i == window) - { - m_RecordingRenderer = mitk::BaseRenderer::GetInstance((*iter)); - break; - } - } -} - -void QmitkMovieMaker::UpdateLooping() -{ - this->GetAspectStepper()->SetAutoRepeat(m_Looping); -} - -void QmitkMovieMaker::UpdateDirection() -{ - mitk::Stepper* stepper = this->GetAspectStepper(); - - switch (m_Direction) - { - case 0: - stepper->InverseDirectionOff(); - stepper->PingPongOff(); - break; - - case 1: - stepper->InverseDirectionOn(); - stepper->PingPongOff(); - break; - - case 2: - stepper->PingPongOn(); - break; - } -} - -mitk::Stepper* QmitkMovieMaker::GetAspectStepper() -{ - if (m_Aspect == 0) - { - m_Stepper = NULL; - return this->GetSpatialController()->GetSlice(); - } - else if (m_Aspect == 1) - { - m_Stepper = NULL; - return this->GetTemporalController()->GetTime(); - } - else if (m_Aspect == 2) - { - if (m_Stepper.IsNull()) - { - int rel = m_Controls->spatialTimeRelation->value(); - int timeRepeat = 1; - int sliceRepeat = 1; - if (rel < 0) - { - sliceRepeat = -rel; - } - else if (rel > 0) - { - timeRepeat = rel; - } - m_Stepper = mitk::MultiStepper::New(); - m_Stepper->AddStepper(this->GetSpatialController()->GetSlice(), sliceRepeat); - m_Stepper->AddStepper(this->GetTemporalController()->GetTime(), timeRepeat); - } - - return m_Stepper.GetPointer(); - } - else - { - // should never get here - return 0; - } -} - -void QmitkMovieMaker::GenerateMovie() -{ - emit StartBlockControls(); - - // provide the movie generator with the stepper and rotate the camera each step - if (m_movieGenerator.IsNotNull()) - { - m_movieGenerator->SetStepper(this->GetAspectStepper()); - m_movieGenerator->SetRenderer(m_RecordingRenderer); - m_movieGenerator->SetFrameRate(static_cast (360 - / (m_Controls->spnDuration->value()))); - - // QString movieFileName = QFileDialog::getSaveFileName( QString::null, "Movie (*.avi)", 0, "movie file dialog", "Choose a file name" ); - - QString movieFileName = QFileDialog::getSaveFileName(0, "Choose a file name", QString::null, - "Movie (*.avi)", 0, 0); - - if (movieFileName.isEmpty() == false) - { - mitk::RenderingManager::GetInstance()->RequestUpdateAll(); - m_movieGenerator->SetFileName(movieFileName.toAscii()); - m_movieGenerator->WriteMovie(); - } - - emit EndBlockControls(); - } - else - { - MITK_ERROR << "Either mitk::MovieGenerator is not implemented for your"; - MITK_ERROR << " platform or an error occurred during"; - MITK_ERROR << " mitk::MovieGenerator::New()"; - - emit EndBlockControlsMovieDeactive(); - } -} - -void QmitkMovieMaker::GenerateScreenshot() -{ - emit StartBlockControls(); - - QString fileName = QFileDialog::getSaveFileName(NULL, "Save screenshot to...", QDir::currentPath(), "JPEG file (*.jpg);;PNG file (*.png)"); - - vtkRenderer* renderer = mitk::GlobalInteraction::GetInstance()->GetFocus()->GetVtkRenderer(); - if (renderer == NULL) - return; - this->TakeScreenshot(renderer, 1, fileName); - - if (m_movieGenerator.IsNotNull()) - emit EndBlockControls(); - else - emit EndBlockControlsMovieDeactive(); -} - -void QmitkMovieMaker::GenerateHR3DScreenshot() -{ - emit StartBlockControls(); - - QString fileName = QFileDialog::getSaveFileName(NULL, "Save screenshot to...", QDir::currentPath(), "JPEG file (*.jpg);;PNG file (*.png)"); - - // only works correctly for 3D RenderWindow - vtkRenderer* renderer = m_MultiWidget->mitkWidget4->GetRenderer()->GetVtkRenderer(); - if (renderer == NULL) - return; - this->TakeScreenshot(renderer, 4, fileName); - - if (m_movieGenerator.IsNotNull()) - emit EndBlockControls(); - else - emit EndBlockControlsMovieDeactive(); -} - -void QmitkMovieMaker::UpdateGUI() -{ - int bla = this->GetTemporalController()->GetTime()->GetSteps(); - if (bla < 2) - { - m_Controls->rbtnTemporal->setEnabled(false); - m_Controls->rbtnCombined->setEnabled(false); - m_Controls->spatialTimeRelation->setEnabled(false); - } - else - { - m_Controls->rbtnTemporal->setEnabled(true); - m_Controls->rbtnCombined->setEnabled(true); - m_Controls->spatialTimeRelation->setEnabled(true); - } - -} - -void QmitkMovieMaker::DataStorageChanged() -{ - // UpdateGUI(); -} - -void QmitkMovieMaker::CreateQtPartControl(QWidget *parent) -{ - if (!m_Controls) - { - m_Controls = new Ui::QmitkMovieMakerControls; - m_Controls->setupUi(parent); - - m_StepperAdapter = new QmitkStepperAdapter((QObject*) m_Controls->slidAngle, - this->GetSpatialController()->GetSlice(), "AngleStepperToMovieMakerFunctionality"); - - // Initialize "Selected Window" combo box - const mitk::RenderingManager::RenderWindowVector rwv = - mitk::RenderingManager::GetInstance()->GetAllRegisteredRenderWindows(); - - mitk::RenderingManager::RenderWindowVector::const_iterator iter; - unsigned int i = 0; - for (iter = rwv.begin(); iter != rwv.end(); ++iter) - { - QString name(mitk::BaseRenderer::GetInstance((*iter))->GetName()); - if (name=="stdmulti.widget1") - { - m_Controls->cmbSelectedStepperWindow->insertItem(i, "Axial"); - m_Controls->cmbSelectedRecordingWindow->insertItem(i++, "Axial"); - } - else if (name=="stdmulti.widget2") - { - m_Controls->cmbSelectedStepperWindow->insertItem(i, "Sagittal"); - m_Controls->cmbSelectedRecordingWindow->insertItem(i++, "Sagittal"); - } - else if (name=="stdmulti.widget3") - { - m_Controls->cmbSelectedStepperWindow->insertItem(i, "Coronal"); - m_Controls->cmbSelectedRecordingWindow->insertItem(i++, "Coronal"); - } - else if (name=="stdmulti.widget4") - { - m_Controls->cmbSelectedStepperWindow->insertItem(i, "3D Window"); - m_Controls->cmbSelectedRecordingWindow->insertItem(i++, "3D Window"); - } - else - { - m_Controls->cmbSelectedStepperWindow->insertItem(i, name); - m_Controls->cmbSelectedRecordingWindow->insertItem(i++, name); - } - } - - m_Controls->btnPause->setHidden(true); - if (m_movieGenerator.IsNull()) - m_Controls->btnMovie->setEnabled(false); - } - - this->CreateConnections(); - -} - -void QmitkMovieMaker::StartPlaying() -{ - m_Controls->slidAngle->setDisabled(true); - m_Controls->btnMovie->setEnabled(false); - m_Controls->btnPlay->setEnabled(false); - m_Controls->btnScreenshot->setEnabled(false); - - // Restart timer with 5 msec interval - this should be fine-grained enough - // even for high display refresh frequencies - m_Timer->start(5); - - m_Time->restart(); - - m_Controls->btnPlay->setHidden(true); - m_Controls->btnPause->setHidden(false); - if (m_movieGenerator.IsNull()) - m_Controls->btnMovie->setEnabled(false); - -} - -void QmitkMovieMaker::RBTNForward() -{ - emit SwitchDirection(0); -} - -void QmitkMovieMaker::RBTNBackward() -{ - emit SwitchDirection(1); -} - -void QmitkMovieMaker::RBTNPingPong() -{ - emit SwitchDirection(2); -} - -void QmitkMovieMaker::RBTNSpatial() -{ - emit SwitchAspect(0); -} - -void QmitkMovieMaker::RBTNTemporal() -{ - emit SwitchAspect(1); -} - -void QmitkMovieMaker::RBTNCombined() -{ - emit SwitchAspect(2); -} - -void QmitkMovieMaker::BlockControls() -{ - BlockControls(true); -} - -void QmitkMovieMaker::UnBlockControls() -{ - BlockControls(false); -} - -void QmitkMovieMaker::UnBlockControlsMovieDeactive() -{ - BlockControls(false); - - m_Controls->btnMovie->setEnabled(false); -} - -void QmitkMovieMaker::BlockControls(bool blocked) -{ - m_Controls->slidAngle->setDisabled(blocked); - m_Controls->spnDuration->setEnabled(!blocked); - m_Controls->btnPlay->setEnabled(!blocked); - m_Controls->btnMovie->setEnabled(!blocked); - m_Controls->btnScreenshot->setEnabled(!blocked); -} - -void QmitkMovieMaker::StdMultiWidgetAvailable(QmitkStdMultiWidget& stdMultiWidget) -{ - m_MultiWidget = &stdMultiWidget; - m_Parent->setEnabled(true); -} - -void QmitkMovieMaker::StdMultiWidgetNotAvailable() -{ - m_MultiWidget = NULL; - m_Parent->setEnabled(false); -} - -void QmitkMovieMaker::TakeScreenshot(vtkRenderer* renderer, unsigned int magnificationFactor, QString fileName) -{ - if ((renderer == NULL) ||(magnificationFactor < 1) || fileName.isEmpty()) - return; - - bool doubleBuffering( renderer->GetRenderWindow()->GetDoubleBuffer() ); - renderer->GetRenderWindow()->DoubleBufferOff(); - - vtkImageWriter* fileWriter; - - QFileInfo fi(fileName); - QString suffix = fi.suffix(); - if (suffix.compare("png", Qt::CaseInsensitive) == 0) - { - fileWriter = vtkPNGWriter::New(); - } - else // default is jpeg - { - vtkJPEGWriter* w = vtkJPEGWriter::New(); - w->SetQuality(100); - w->ProgressiveOff(); - fileWriter = w; - } - vtkRenderLargeImage* magnifier = vtkRenderLargeImage::New(); - magnifier->SetInput(renderer); - magnifier->SetMagnification(magnificationFactor); - //magnifier->Update(); - fileWriter->SetInputConnection(magnifier->GetOutputPort()); - fileWriter->SetFileName(fileName.toLatin1()); - - // vtkRenderLargeImage has problems with different layers, therefore we have to - // temporarily deactivate all other layers. - // we set the background to white, because it is nicer than black... - double oldBackground[3]; - renderer->GetBackground(oldBackground); - double white[] = {1.0, 1.0, 1.0}; - renderer->SetBackground(white); - m_MultiWidget->DisableColoredRectangles(); - m_MultiWidget->DisableDepartmentLogo(); - m_MultiWidget->DisableGradientBackground(); - - m_MultiWidget->mitkWidget1->ActivateMenuWidget( false ); - m_MultiWidget->mitkWidget2->ActivateMenuWidget( false ); - m_MultiWidget->mitkWidget3->ActivateMenuWidget( false ); - m_MultiWidget->mitkWidget4->ActivateMenuWidget( false ); - - fileWriter->Write(); - fileWriter->Delete(); - - m_MultiWidget->mitkWidget1->ActivateMenuWidget( true ); - m_MultiWidget->mitkWidget2->ActivateMenuWidget( true ); - m_MultiWidget->mitkWidget3->ActivateMenuWidget( true ); - m_MultiWidget->mitkWidget4->ActivateMenuWidget( true ); - - m_MultiWidget->EnableColoredRectangles(); - m_MultiWidget->EnableDepartmentLogo(); - m_MultiWidget->EnableGradientBackground(); - renderer->SetBackground(oldBackground); - - renderer->GetRenderWindow()->SetDoubleBuffer(doubleBuffering); -} - -void QmitkMovieMaker::DeleteMStepper() -{ - m_Stepper = NULL; - UpdateLooping(); -} diff --git a/Plugins/org.mitk.gui.qt.moviemaker/src/internal/QmitkMovieMaker.h b/Plugins/org.mitk.gui.qt.moviemaker/src/internal/QmitkMovieMaker.h deleted file mode 100644 index ea91684197..0000000000 --- a/Plugins/org.mitk.gui.qt.moviemaker/src/internal/QmitkMovieMaker.h +++ /dev/null @@ -1,300 +0,0 @@ -/*=================================================================== - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center, -Division of Medical and Biological Informatics. -All rights reserved. - -This software is distributed WITHOUT ANY WARRANTY; without -even the implied warranty of MERCHANTABILITY or FITNESS FOR -A PARTICULAR PURPOSE. - -See LICENSE.txt or http://www.mitk.org for details. - -===================================================================*/ - -#if !defined(QMITK_MOVIEMAKER_H__INCLUDED) -#define QMITK_MOVIEMAKER_H__INCLUDED - -#include "QmitkFunctionality.h" -#include "mitkCameraRotationController.h" -#include "mitkStepper.h" -#include "mitkMultiStepper.h" -#include "mitkMovieGenerator.h" -#include "itkCommand.h" - -#include "QVTKWidget.h" -#include "vtkEventQtSlotConnect.h" -#include "vtkRenderWindow.h" -#include "mitkVtkPropRenderer.h" - -#include "ui_QmitkMovieMakerControls.h" -//#include "../MovieMakerDll.h" - -//class QmitkStdMultiWidget; -//class QmitkMovieMakerControls; -class QmitkStepperAdapter; -class vtkCamera; -class QTimer; -class QTime; - -/** - * \brief Functionality for creating movies (AVIs) - * \ingroup Functionalities - * - * - * - \ref QmitkMovieMakerOverview - * - \ref QmitkMovieMakerImplementation - * - \ref QmitkMovieMakerTodo - * - * \section QmitkMovieMakerOverview Overview - * - * The MovieMaker functionality extends existing modes of data visualization - * with animation capabilities. The animation aspect determines which - * aspect of a visualization gets animated. This aspect can be spatial - * (i.e. the camera position and orientation in a 3D view, or the selected - * slice in a 2D view), temporal (the time step in a time-based dataset), or - * something more sophisticated (for example, volume rendering transfer - * functions might be changed dynamically as part of an animation to produce - * interesting effects). Currently, the following animation modes are - * supported: - * - * - Rotation of the camera around the dataset (3D views) - * - Stepping through the dataset slice by slice (2D views) - * - Stepping through a time-based dataset (2D and 3D views) - * - * As can be seen in the screenshot below, the functionality provides cine - * controls to start, pause and stop the animation. The direction of the - * animation can be selected (forward, backward or ping-pong). The animation - * can be set to either the spatial or the temporal aspect, or to both - * aspects combined. The cycle time determines the duration of one animation - * loop. - * - * In a multi-view scenario, the animation is applied to the currently - * focussed view. Other views which display the same data may be affected as - * well. - * - * Animations can be written on disk; the corresponding button creates an - * animation consisting of one single loop and writes every animation frame - * into an AVI file. - * - * \image html QmitkMovieMakerGUI.png - * - * \section QmitkMovieMakerImplementation Implementation - * - * The following diagram provides an overview over the classes collaborating - * with QmitkMovieMaker. - * - * \image html QmitkMovieMakerClasses.png - * - * The respective roles of these classes are: - * - QmitkMovieMaker - * - Provides a class interface for configuring and controlling the - * animation - * - Is associated with the user interface - * - As a Functionality, controls initialization and maintainance of the - * involved components - * - mitk::BaseController - * - Controls an animation aspect (slice selection, camera angle, ...) - * - Subclass mitk::SliceNavigationController: Transfers the animation - * requests to the associated Renderer for selecting a slice in a 3D - * dataset - * - Subclass mitk::CameraRotationController: Modifies the camera angle - * - mitk::Stepper - * - Link between MovieMaker and Controller - * - Holds the current step position of the associated animation aspect - * (e.g. the camera rotation angle, or the slice number) - * - mitk::FocusManager - * - Determines which of the available RenderWindows (and thereby which - * Renderers) the animation shall be applied to - * - mitk::BaseRenderer - * - Controls the rendering of a dataset - * - Target class of the animation - * - mitk::MovieGenerator - * - Writes an AVI file - * - * - * \section QmitkMovieMakerTodo Future plans - * - * The basic animation capabilities of this functionality could be extended - * to allow the creation of more sophisticated animations. Potentially useful - * features include: - * - * - Camera paths: Allow the definition of complex camera paths along - * which the camera can then be moved during an animation. This might be - * done by defining camera keyframes between which camera movements are - * interpolated (as in standard 3D animation applications). Paths derived - * from anatomical features (e.g. vessel graphs) could also serve as a - * basis for camera movements. - * - Color / transfer function animation: Choosing suitable color - * and transfer functions is critical to the quality and benefit of volume - * rendering. Dynamically changing transfer functions could visually enrich - * an animation. One way of achieving this could be to define transfer - * function keyframes between which an animation interpolates. - * - */ -class QmitkMovieMaker: public QmitkFunctionality -{ - Q_OBJECT - -public: - /** \brief Constructor. */ - QmitkMovieMaker(QObject *parent=0, const char *name=0); - - /** \brief Destructor. */ - virtual ~QmitkMovieMaker(); - - /** \brief Method for creating the widget containing the application - * controls, like sliders, buttons etc. - */ - void CreateQtPartControl(QWidget *parent); - // virtual QWidget * CreateControlWidget(QWidget *parent); - - /** \brief Method for creating the connections of main and control widget. - */ - virtual void CreateConnections(); - - /** \brief Method for creating an QAction object, i.e. button & menu entry. - * @param parent the parent QWidget - */ - // virtual QAction * CreateAction(QActionGroup *parent); - - virtual void Activated(); - - virtual void Deactivated(); - - /** \brief Called when another window receives the focus. */ - void FocusChange(); - - virtual void DataStorageChanged(); - - /// - /// Called when a StdMultiWidget is available. - /// - virtual void StdMultiWidgetAvailable(QmitkStdMultiWidget& stdMultiWidget); - /// - /// Called when no StdMultiWidget is available. - /// - virtual void StdMultiWidgetNotAvailable(); - - signals: - void StartBlockControls(); - void EndBlockControls(); - void EndBlockControlsMovieDeactive(); - -public slots: - - /** \brief Start playing the animation by restarting the timer. */ - void StartPlaying(); - - /** \brief Pauses playing the animation by stopping the timer. */ - void PausePlaying(); - - /** \brief Stops playing the animation and resets the stepper. */ - void StopPlaying(); - - /** \brief Sets animation looping ON/OFF. */ - void SetLooping(bool looping); - - /** \brief Sets the direction: 0 = forward, 1 = backward, 2 = pingpong. */ - void SetDirection(int direction); - - /** \brief Sets the animation aspect: - * 0 = spatial, 1 = temporal, 2 = combined. - */ - void SetAspect(int aspect); - - /** \brief Sets a specified stepper window, which is moving. */ - void SetStepperWindow(int window); - - /** \brief Sets a specified recording window, from which the movie is generated. */ - void SetRecordingWindow(int window); - - /** \brief Advances the animation by one frame. - * Exactly how much the stepper advances depends on the time elapsed since - * the last call to this function. - */ - void AdvanceAnimation(); - -protected slots: - - void RenderSlot(); - void GenerateMovie(); - - void GenerateScreenshot(); - void GenerateHR3DScreenshot(); - void RBTNForward(); - void RBTNBackward(); - void RBTNPingPong(); - void RBTNSpatial(); - void RBTNTemporal(); - void RBTNCombined(); - void BlockControls(); - void UnBlockControls(); - void UnBlockControlsMovieDeactive(); - void BlockControls(bool blocked); - - void DeleteMStepper(); - - signals: - - void SwitchDirection(int); - void SwitchAspect(int); - void SwitchSelectedStepperWindow(int); - void SwitchSelectedRecordingWindow(int); - -protected: - - QObject *parentWidget; - QVTKWidget * widget; - QmitkStdMultiWidget* m_MultiWidget; - vtkEventQtSlotConnect * connections; - vtkRenderWindow * renderWindow; - mitk::VtkPropRenderer::Pointer m_PropRenderer; - - Ui::QmitkMovieMakerControls* m_Controls; - -private: - mitk::BaseController* GetSpatialController(); - - mitk::BaseController* GetTemporalController(); - - void UpdateLooping(); - - void UpdateDirection(); - - void UpdateGUI(); - - mitk::Stepper* GetAspectStepper(); - - /*! - \brief taking a screenshot "from" the specified renderer - \param magnificationFactor specifying the quality of the screenshot (the magnification of the actual RenderWindow size) - \param fileName file location and name where the screenshot should be saved - */ - void TakeScreenshot(vtkRenderer* renderer, unsigned int magnificationFactor, QString fileName); - - QmitkStepperAdapter* m_StepperAdapter; - - typedef itk::SimpleMemberCommand MemberCommand; - MemberCommand::Pointer m_FocusManagerCallback; - - QTimer* m_Timer; - - QTime* m_Time; - - bool m_Looping; - int m_Direction; - - int m_Aspect; - mitk::MultiStepper::Pointer m_Stepper; - mitk::BaseRenderer * m_RecordingRenderer; - - mitk::MovieGenerator::Pointer m_movieGenerator; - - unsigned long m_FocusManagerObserverTag; - unsigned long m_StepperObserverTag; - -}; -#endif // !defined(QMITK_MOVIEMAKER_H__INCLUDED) diff --git a/Plugins/org.mitk.gui.qt.moviemaker/src/internal/QmitkMovieMakerControls.ui b/Plugins/org.mitk.gui.qt.moviemaker/src/internal/QmitkMovieMakerControls.ui deleted file mode 100644 index 68dd4a6fa2..0000000000 --- a/Plugins/org.mitk.gui.qt.moviemaker/src/internal/QmitkMovieMakerControls.ui +++ /dev/null @@ -1,454 +0,0 @@ - - - QmitkMovieMakerControls - - - - 0 - 0 - 423 - 665 - - - - MovieMaker - - - - - - - 0 - 0 - - - - - 75 - true - - - - Window for stepping - - - false - - - - - - - - 0 - 0 - - - - - - - - - 0 - 0 - - - - - 75 - true - - - - Window for recording - - - false - - - - - - - - 0 - 0 - - - - - - - - - 75 - true - - - - Recording options - - - - - - - - - 0 - 0 - - - - - - - Step - - - false - - - - - - - - - - - - - - - 0 - 0 - - - - - - - Start stepper - - - - - - - :/org.mitk.gui.qt.moviemaker/resources/play.xpm:/org.mitk.gui.qt.moviemaker/resources/play.xpm - - - - - - - - 0 - 0 - - - - - - - Pause stepper - - - - - - - :/org.mitk.gui.qt.moviemaker/resources/pause.xpm:/org.mitk.gui.qt.moviemaker/resources/pause.xpm - - - - - - - - 0 - 0 - - - - - - - Stop stepper - - - - - - - :/org.mitk.gui.qt.moviemaker/resources/stop.xpm:/org.mitk.gui.qt.moviemaker/resources/stop.xpm - - - - - - - - - - 0 - 0 - - - - - - - Write Movie (MS Windows only) ... - - - - - - - - 0 - 0 - - - - - - - Writes a screenshot of the selected window. - - - Write Screenshot - - - - - - - - 0 - 0 - - - - - - - Writes a screenshot of the selected window. - - - Write high resolution 3D Screenshot - - - - - - - - - - - 75 - true - - - - Playing options - - - - - - - - - - - - Spatial - - - true - - - - - - - - - - Temporal - - - - - - - - - - Combined - - - - - - - - - - - - S/T Relation - - - false - - - - - - - - - - -10 - - - 10 - - - 0 - - - - - - - - - - - - QFrame::HLine - - - QFrame::Sunken - - - - - - - - - - - - - Forward - - - true - - - - - - - - - - Backward - - - - - - - - - - Ping-Pong - - - - - - - - - - - - Cycle (sec) - - - false - - - - - - - - - - 1 - - - 200 - - - 5 - - - - - - - - - - - - - - - Qt::Vertical - - - - 20 - 31 - - - - - - - - - - QmitkSliderNavigatorWidget - QWidget -
QmitkSliderNavigatorWidget.h
- 1 -
-
- - rbtnForward - rbtnBackward - rbtnPingPong - rbtnSpatial - rbtnTemporal - cmbSelectedStepperWindow - - - - - -
diff --git a/Plugins/org.mitk.gui.qt.moviemaker/src/internal/QmitkMovieMakerView.cpp b/Plugins/org.mitk.gui.qt.moviemaker/src/internal/QmitkMovieMakerView.cpp new file mode 100644 index 0000000000..2e6735528a --- /dev/null +++ b/Plugins/org.mitk.gui.qt.moviemaker/src/internal/QmitkMovieMakerView.cpp @@ -0,0 +1,666 @@ +/*=================================================================== + +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 "QmitkAnimationItemDelegate.h" +#include "QmitkFFmpegWriter.h" +#include "QmitkMovieMakerView.h" +#include "QmitkOrbitAnimationItem.h" +#include "QmitkOrbitAnimationWidget.h" +#include "QmitkSliceAnimationItem.h" +#include "QmitkSliceAnimationWidget.h" +#include +#include +#include +#include +#include +#include +#include +#include + +static QmitkAnimationItem* CreateDefaultAnimation(const QString& widgetKey) +{ + if (widgetKey == "Orbit") + return new QmitkOrbitAnimationItem; + + if (widgetKey == "Slice") + return new QmitkSliceAnimationItem; + + return NULL; +} + +static QString GetFFmpegPath() +{ + berry::IPreferencesService::Pointer preferencesService = + berry::Platform::GetServiceRegistry().GetServiceById(berry::IPreferencesService::ID); + + berry::IPreferences::Pointer preferences = preferencesService->GetSystemPreferences()->Node("/org.mitk.gui.qt.ext.externalprograms"); + + return QString::fromStdString(preferences->Get("ffmpeg", "")); +} + +static unsigned char* ReadPixels(vtkRenderWindow* renderWindow, int x, int y, int width, int height) +{ + if (renderWindow == NULL) + return NULL; + + unsigned char* frame = new unsigned char[width * height * 3]; + + renderWindow->MakeCurrent(); + glReadPixels(x, y, width, height, GL_RGB, GL_UNSIGNED_BYTE, frame); + + return frame; +} + +const std::string QmitkMovieMakerView::VIEW_ID = "org.mitk.views.moviemaker"; + +QmitkMovieMakerView::QmitkMovieMakerView() + : m_FFmpegWriter(NULL), + m_Ui(new Ui::QmitkMovieMakerView), + m_AnimationModel(NULL), + m_AddAnimationMenu(NULL), + m_RecordMenu(NULL), + m_Timer(NULL), + m_TotalDuration(0.0), + m_NumFrames(0), + m_CurrentFrame(0) +{ +} + +QmitkMovieMakerView::~QmitkMovieMakerView() +{ +} + +void QmitkMovieMakerView::CreateQtPartControl(QWidget* parent) +{ + m_FFmpegWriter = new QmitkFFmpegWriter(parent); + + m_Ui->setupUi(parent); + + this->InitializeAnimationWidgets(); + this->InitializeAnimationTreeViewWidgets(); + this->InitializePlaybackAndRecordWidgets(); + this->InitializeTimer(parent); + + m_Ui->animationWidgetGroupBox->setVisible(false); +} + +void QmitkMovieMakerView::InitializeAnimationWidgets() +{ + m_AnimationWidgets["Orbit"] = new QmitkOrbitAnimationWidget; + m_AnimationWidgets["Slice"] = new QmitkSliceAnimationWidget; + + Q_FOREACH(QWidget* widget, m_AnimationWidgets.values()) + { + if (widget != NULL) + { + widget->setVisible(false); + m_Ui->animationWidgetGroupBoxLayout->addWidget(widget); + } + } + + this->ConnectAnimationWidgets(); +} + +void QmitkMovieMakerView::InitializeAnimationTreeViewWidgets() +{ + this->InitializeAnimationModel(); + this->InitializeAddAnimationMenu(); + this->ConnectAnimationTreeViewWidgets(); +} + +void QmitkMovieMakerView::InitializePlaybackAndRecordWidgets() +{ + this->InitializeRecordMenu(); + this->ConnectPlaybackAndRecordWidgets(); +} + +void QmitkMovieMakerView::InitializeAnimationModel() +{ + m_AnimationModel = new QStandardItemModel(m_Ui->animationTreeView); + m_AnimationModel->setHorizontalHeaderLabels(QStringList() << "Animation" << "Timeline"); + m_Ui->animationTreeView->setModel(m_AnimationModel); + + m_Ui->animationTreeView->setItemDelegate(new QmitkAnimationItemDelegate(m_Ui->animationTreeView)); +} + +void QmitkMovieMakerView::InitializeAddAnimationMenu() +{ + m_AddAnimationMenu = new QMenu(m_Ui->addAnimationButton); + + Q_FOREACH(const QString& key, m_AnimationWidgets.keys()) + { + m_AddAnimationMenu->addAction(key); + } +} + +void QmitkMovieMakerView::InitializeRecordMenu() +{ + typedef QPair PairOfStrings; + + m_RecordMenu = new QMenu(m_Ui->recordButton); + + QVector renderWindows; + renderWindows.push_back(qMakePair(QString("Axial"), QString("stdmulti.widget1"))); + renderWindows.push_back(qMakePair(QString("Sagittal"), QString("stdmulti.widget2"))); + renderWindows.push_back(qMakePair(QString("Coronal"), QString("stdmulti.widget3"))); + renderWindows.push_back(qMakePair(QString("3D"), QString("stdmulti.widget4"))); + + Q_FOREACH(const PairOfStrings& renderWindow, renderWindows) + { + QAction* action = new QAction(m_RecordMenu); + action->setText(renderWindow.first); + action->setData(renderWindow.second); + + m_RecordMenu->addAction(action); + } +} + +void QmitkMovieMakerView::InitializeTimer(QWidget* parent) +{ + m_Timer = new QTimer(parent); + + this->OnFPSSpinBoxValueChanged(m_Ui->fpsSpinBox->value()); + this->ConnectTimer(); +} + +void QmitkMovieMakerView::ConnectAnimationTreeViewWidgets() +{ + this->connect(m_AnimationModel, SIGNAL(rowsInserted(const QModelIndex&, int, int)), + this, SLOT(OnAnimationTreeViewRowsInserted(const QModelIndex&, int, int))); + + this->connect(m_AnimationModel, SIGNAL(rowsRemoved(const QModelIndex&, int, int)), + this, SLOT(OnAnimationTreeViewRowsRemoved(const QModelIndex&, int, int))); + + this->connect(m_Ui->animationTreeView->selectionModel(), SIGNAL(selectionChanged(const QItemSelection&, const QItemSelection&)), + this, SLOT(OnAnimationTreeViewSelectionChanged(const QItemSelection&, const QItemSelection&))); + + this->connect(m_Ui->moveAnimationUpButton, SIGNAL(clicked()), + this, SLOT(OnMoveAnimationUpButtonClicked())); + + this->connect(m_Ui->moveAnimationDownButton, SIGNAL(clicked()), + this, SLOT(OnMoveAnimationDownButtonClicked())); + + this->connect(m_Ui->addAnimationButton, SIGNAL(clicked()), + this, SLOT(OnAddAnimationButtonClicked())); + + this->connect(m_Ui->removeAnimationButton, SIGNAL(clicked()), + this, SLOT(OnRemoveAnimationButtonClicked())); +} + +void QmitkMovieMakerView::ConnectAnimationWidgets() +{ + this->connect(m_Ui->startComboBox, SIGNAL(currentIndexChanged(int)), + this, SLOT(OnStartComboBoxCurrentIndexChanged(int))); + + this->connect(m_Ui->durationSpinBox, SIGNAL(valueChanged(double)), + this, SLOT(OnDurationSpinBoxValueChanged(double))); + + this->connect(m_Ui->delaySpinBox, SIGNAL(valueChanged(double)), + this, SLOT(OnDelaySpinBoxValueChanged(double))); +} + +void QmitkMovieMakerView::ConnectPlaybackAndRecordWidgets() +{ + this->connect(m_Ui->playButton, SIGNAL(toggled(bool)), + this, SLOT(OnPlayButtonToggled(bool))); + + this->connect(m_Ui->stopButton, SIGNAL(clicked()), + this, SLOT(OnStopButtonClicked())); + + this->connect(m_Ui->recordButton, SIGNAL(clicked()), + this, SLOT(OnRecordButtonClicked())); + + this->connect(m_Ui->fpsSpinBox, SIGNAL(valueChanged(int)), + this, SLOT(OnFPSSpinBoxValueChanged(int))); +} + +void QmitkMovieMakerView::ConnectTimer() +{ + this->connect(m_Timer, SIGNAL(timeout()), + this, SLOT(OnTimerTimeout())); +} + +void QmitkMovieMakerView::SetFocus() +{ + m_Ui->addAnimationButton->setFocus(); +} + +void QmitkMovieMakerView::OnMoveAnimationUpButtonClicked() +{ + const QItemSelection selection = m_Ui->animationTreeView->selectionModel()->selection(); + + if (!selection.isEmpty()) + { + const int selectedRow = selection[0].top(); + + if (selectedRow > 0) + m_AnimationModel->insertRow(selectedRow - 1, m_AnimationModel->takeRow(selectedRow)); + } + + this->CalculateTotalDuration(); +} + +void QmitkMovieMakerView::OnMoveAnimationDownButtonClicked() +{ + const QItemSelection selection = m_Ui->animationTreeView->selectionModel()->selection(); + + if (!selection.isEmpty()) + { + const int rowCount = m_AnimationModel->rowCount(); + const int selectedRow = selection[0].top(); + + if (selectedRow < rowCount - 1) + m_AnimationModel->insertRow(selectedRow + 1, m_AnimationModel->takeRow(selectedRow)); + } + + this->CalculateTotalDuration(); +} + +void QmitkMovieMakerView::OnAddAnimationButtonClicked() +{ + QAction* action = m_AddAnimationMenu->exec(QCursor::pos()); + + if (action != NULL) + { + const QString widgetKey = action->text(); + + m_AnimationModel->appendRow(QList() + << new QStandardItem(widgetKey) + << CreateDefaultAnimation(widgetKey)); + + m_Ui->playbackAndRecordingGroupBox->setEnabled(true); + } +} + +void QmitkMovieMakerView::OnPlayButtonToggled(bool checked) +{ + if (checked) + { + m_Ui->playButton->setIcon(QIcon(":/org_mitk_icons/icons/tango/scalable/actions/media-playback-pause.svg")); + m_Ui->playButton->repaint(); + + m_Timer->start(static_cast(1000.0 / m_Ui->fpsSpinBox->value())); + } + else + { + m_Timer->stop(); + + m_Ui->playButton->setIcon(QIcon(":/org_mitk_icons/icons/tango/scalable/actions/media-playback-start.svg")); + m_Ui->playButton->repaint(); + } +} + +void QmitkMovieMakerView::OnStopButtonClicked() +{ + m_Ui->playButton->setChecked(false); + m_Ui->stopButton->setEnabled(false); + + m_CurrentFrame = 0; + this->RenderCurrentFrame(); +} + +void QmitkMovieMakerView::OnRecordButtonClicked() // TODO: Refactor +{ + const QString ffmpegPath = GetFFmpegPath(); + + if (ffmpegPath.isEmpty()) + { + QMessageBox::information(NULL, "Movie Maker", "Set path to FFmpeg or Libav (avconv) in preferences (Window -> Preferences... (Ctrl+P) -> External Programs) to be able to record your movies to video files."); + return; + } + + m_FFmpegWriter->SetFFmpegPath(GetFFmpegPath()); + + QAction* action = m_RecordMenu->exec(QCursor::pos()); + + if (action == NULL) + return; + + vtkRenderWindow* renderWindow = mitk::BaseRenderer::GetRenderWindowByName(action->data().toString().toStdString()); + + if (renderWindow == NULL) + return; + + const int border = 3; + const int x = border; + const int y = border; + int width = renderWindow->GetSize()[0] - border * 2; + int height = renderWindow->GetSize()[1] - border * 2; + + if (width & 1) + --width; + + if (height & 1) + --height; + + if (width < 16 || height < 16) + return; + + m_FFmpegWriter->SetSize(width, height); + m_FFmpegWriter->SetFramerate(m_Ui->fpsSpinBox->value()); + + QString saveFileName = QFileDialog::getSaveFileName(NULL, "Specify a filename", "", "Movie (*.mp4)"); + + if (saveFileName.isEmpty()) + return; + + if(!saveFileName.endsWith(".mp4")) + saveFileName += ".mp4"; + + m_FFmpegWriter->SetOutputPath(saveFileName); + + try + { + m_FFmpegWriter->Start(); + + for (m_CurrentFrame = 0; m_CurrentFrame < m_NumFrames; ++m_CurrentFrame) + { + this->RenderCurrentFrame(); + + renderWindow->MakeCurrent(); + unsigned char* frame = ReadPixels(renderWindow, x, y, width, height); + m_FFmpegWriter->WriteFrame(frame); + delete[] frame; + } + + m_FFmpegWriter->Stop(); + + m_CurrentFrame = 0; + this->RenderCurrentFrame(); + } + catch (const mitk::Exception& exception) + { + m_CurrentFrame = 0; + this->RenderCurrentFrame(); + + QMessageBox::critical(NULL, "Movie Maker", exception.GetDescription()); + } +} + +void QmitkMovieMakerView::OnRemoveAnimationButtonClicked() +{ + const QItemSelection selection = m_Ui->animationTreeView->selectionModel()->selection(); + + if (!selection.isEmpty()) + m_AnimationModel->removeRow(selection[0].top()); +} + +void QmitkMovieMakerView::OnAnimationTreeViewRowsInserted(const QModelIndex& parent, int start, int) +{ + this->CalculateTotalDuration(); + + m_Ui->animationTreeView->selectionModel()->select( + m_AnimationModel->index(start, 0, parent), + QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows); +} + +void QmitkMovieMakerView::OnAnimationTreeViewRowsRemoved(const QModelIndex&, int, int) +{ + this->CalculateTotalDuration(); + this->UpdateWidgets(); +} + +void QmitkMovieMakerView::OnAnimationTreeViewSelectionChanged(const QItemSelection&, const QItemSelection&) +{ + this->UpdateWidgets(); +} + +void QmitkMovieMakerView::OnStartComboBoxCurrentIndexChanged(int index) +{ + QmitkAnimationItem* item = this->GetSelectedAnimationItem(); + + if (item != NULL) + { + item->SetStartWithPrevious(index); + this->RedrawTimeline(); + this->CalculateTotalDuration(); + } +} + +void QmitkMovieMakerView::OnDurationSpinBoxValueChanged(double value) +{ + QmitkAnimationItem* item = this->GetSelectedAnimationItem(); + + if (item != NULL) + { + item->SetDuration(value); + this->RedrawTimeline(); + this->CalculateTotalDuration(); + } +} + +void QmitkMovieMakerView::OnDelaySpinBoxValueChanged(double value) +{ + QmitkAnimationItem* item = this->GetSelectedAnimationItem(); + + if (item != NULL) + { + item->SetDelay(value); + this->RedrawTimeline(); + this->CalculateTotalDuration(); + } +} + +void QmitkMovieMakerView::OnFPSSpinBoxValueChanged(int value) +{ + this->CalculateTotalDuration(); + m_Timer->setInterval(static_cast(1000.0 / value)); +} + +void QmitkMovieMakerView::OnTimerTimeout() +{ + this->RenderCurrentFrame(); + + m_CurrentFrame = std::min(m_NumFrames, m_CurrentFrame + 1); + + if (m_CurrentFrame >= m_NumFrames) + { + m_Ui->playButton->setChecked(false); + + m_CurrentFrame = 0; + this->RenderCurrentFrame(); + } + + m_Ui->stopButton->setEnabled(m_CurrentFrame != 0); +} + +void QmitkMovieMakerView::RenderCurrentFrame() +{ + typedef QPair AnimationIterpolationFactorPair; + + const double deltaT = m_TotalDuration / (m_NumFrames - 1); + const QVector activeAnimations = this->GetActiveAnimations(m_CurrentFrame * deltaT); + + Q_FOREACH(const AnimationIterpolationFactorPair& animation, activeAnimations) + { + animation.first->Animate(animation.second); + } + + mitk::RenderingManager::GetInstance()->ForceImmediateUpdateAll(); +} + +void QmitkMovieMakerView::UpdateWidgets() +{ + const QItemSelection selection = m_Ui->animationTreeView->selectionModel()->selection(); + + if (selection.isEmpty()) + { + m_Ui->moveAnimationUpButton->setEnabled(false); + m_Ui->moveAnimationDownButton->setEnabled(false); + m_Ui->removeAnimationButton->setEnabled(false); + m_Ui->playbackAndRecordingGroupBox->setEnabled(false); + + this->HideCurrentAnimationWidget(); + } + else + { + const int rowCount = m_AnimationModel->rowCount(); + const int selectedRow = selection[0].top(); + + m_Ui->moveAnimationUpButton->setEnabled(rowCount > 1 && selectedRow != 0); + m_Ui->moveAnimationDownButton->setEnabled(rowCount > 1 && selectedRow < rowCount - 1); + m_Ui->removeAnimationButton->setEnabled(true); + m_Ui->playbackAndRecordingGroupBox->setEnabled(true); + + this->ShowAnimationWidget(dynamic_cast(m_AnimationModel->item(selectedRow, 1))); + } + + this->UpdateAnimationWidgets(); +} + +void QmitkMovieMakerView::UpdateAnimationWidgets() +{ + QmitkAnimationItem* item = this->GetSelectedAnimationItem(); + + if (item != NULL) + { + m_Ui->startComboBox->setCurrentIndex(item->GetStartWithPrevious()); + m_Ui->durationSpinBox->setValue(item->GetDuration()); + m_Ui->delaySpinBox->setValue(item->GetDelay()); + + m_Ui->animationGroupBox->setEnabled(true); + } + else + { + m_Ui->animationGroupBox->setEnabled(false); + } +} + +void QmitkMovieMakerView::HideCurrentAnimationWidget() +{ + if (m_Ui->animationWidgetGroupBox->isVisible()) + { + m_Ui->animationWidgetGroupBox->setVisible(false); + + int numWidgets = m_Ui->animationWidgetGroupBoxLayout->count(); + + for (int i = 0; i < numWidgets; ++i) + m_Ui->animationWidgetGroupBoxLayout->itemAt(i)->widget()->setVisible(false); + } +} + +void QmitkMovieMakerView::ShowAnimationWidget(QmitkAnimationItem* animationItem) +{ + this->HideCurrentAnimationWidget(); + + if (animationItem == NULL) + return; + + const QString widgetKey = animationItem->GetWidgetKey(); + QmitkAnimationWidget* animationWidget = NULL; + + if (m_AnimationWidgets.contains(widgetKey)) + { + animationWidget = m_AnimationWidgets[widgetKey]; + + if (animationWidget != NULL) + { + m_Ui->animationWidgetGroupBox->setTitle(widgetKey); + animationWidget->SetAnimationItem(animationItem); + animationWidget->setVisible(true); + } + } + + m_Ui->animationWidgetGroupBox->setVisible(animationWidget != NULL); +} + +void QmitkMovieMakerView::RedrawTimeline() +{ + if (m_AnimationModel->rowCount() > 1) + { + m_Ui->animationTreeView->dataChanged( + m_AnimationModel->index(0, 1), + m_AnimationModel->index(m_AnimationModel->rowCount() - 1, 1)); + } +} + +QmitkAnimationItem* QmitkMovieMakerView::GetSelectedAnimationItem() const +{ + const QItemSelection selection = m_Ui->animationTreeView->selectionModel()->selection(); + + return !selection.isEmpty() + ? dynamic_cast(m_AnimationModel->item(selection[0].top(), 1)) + : NULL; +} + +void QmitkMovieMakerView::CalculateTotalDuration() +{ + const int rowCount = m_AnimationModel->rowCount(); + + double totalDuration = 0.0; + double previousStart = 0.0; + + for (int i = 0; i < rowCount; ++i) + { + QmitkAnimationItem* item = dynamic_cast(m_AnimationModel->item(i, 1)); + + if (item == NULL) + continue; + + if (item->GetStartWithPrevious()) + { + totalDuration = std::max(totalDuration, previousStart + item->GetDelay() + item->GetDuration()); + } + else + { + previousStart = totalDuration; + totalDuration += item->GetDelay() + item->GetDuration(); + } + } + + m_TotalDuration = totalDuration; // TODO totalDuration == 0 + m_NumFrames = static_cast(totalDuration * m_Ui->fpsSpinBox->value()); // TODO numFrames < 2 +} + +QVector > QmitkMovieMakerView::GetActiveAnimations(double t) const +{ + const int rowCount = m_AnimationModel->rowCount(); + + QVector > activeAnimations; + + double totalDuration = 0.0; + double previousStart = 0.0; + + for (int i = 0; i < rowCount; ++i) + { + QmitkAnimationItem* item = dynamic_cast(m_AnimationModel->item(i, 1)); + + if (item == NULL) + continue; + + if (item->GetDuration() > 0.0) + { + double start = item->GetStartWithPrevious() + ? previousStart + item->GetDelay() + : totalDuration + item->GetDelay(); + + if (start <= t && t <= start + item->GetDuration()) + activeAnimations.push_back(qMakePair(item, (t - start) / item->GetDuration())); + } + + if (item->GetStartWithPrevious()) + { + totalDuration = std::max(totalDuration, previousStart + item->GetDelay() + item->GetDuration()); + } + else + { + previousStart = totalDuration; + totalDuration += item->GetDelay() + item->GetDuration(); + } + } + + return activeAnimations; +} diff --git a/Plugins/org.mitk.gui.qt.moviemaker/src/internal/QmitkMovieMakerView.h b/Plugins/org.mitk.gui.qt.moviemaker/src/internal/QmitkMovieMakerView.h new file mode 100644 index 0000000000..f686ba79b9 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.moviemaker/src/internal/QmitkMovieMakerView.h @@ -0,0 +1,98 @@ +/*=================================================================== + +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 QmitkMovieMakerView_h +#define QmitkMovieMakerView_h + +#include + +class QmitkAnimationItem; +class QmitkAnimationWidget; +class QmitkFFmpegWriter; +class QMenu; +class QStandardItemModel; +class QTimer; + +namespace Ui +{ + class QmitkMovieMakerView; +} + +class QmitkMovieMakerView : public QmitkAbstractView +{ + Q_OBJECT + +public: + static const std::string VIEW_ID; + + QmitkMovieMakerView(); + ~QmitkMovieMakerView(); + + void CreateQtPartControl(QWidget* parent); + void SetFocus(); + +private slots: + void OnMoveAnimationUpButtonClicked(); + void OnMoveAnimationDownButtonClicked(); + void OnAddAnimationButtonClicked(); + void OnRemoveAnimationButtonClicked(); + void OnAnimationTreeViewRowsInserted(const QModelIndex& parent, int start, int end); + void OnAnimationTreeViewRowsRemoved(const QModelIndex& parent, int start, int end); + void OnAnimationTreeViewSelectionChanged(const QItemSelection& selected, const QItemSelection& deselected); + void OnStartComboBoxCurrentIndexChanged(int index); + void OnDurationSpinBoxValueChanged(double value); + void OnDelaySpinBoxValueChanged(double value); + void OnPlayButtonToggled(bool checked); + void OnStopButtonClicked(); + void OnRecordButtonClicked(); + void OnFPSSpinBoxValueChanged(int value); + void OnTimerTimeout(); + +private: + void InitializeAnimationWidgets(); + void InitializeAnimationTreeViewWidgets(); + void InitializeAnimationModel(); + void InitializeAddAnimationMenu(); + void InitializePlaybackAndRecordWidgets(); + void InitializeRecordMenu(); + void InitializeTimer(QWidget* parent); + void ConnectAnimationTreeViewWidgets(); + void ConnectAnimationWidgets(); + void ConnectPlaybackAndRecordWidgets(); + void ConnectTimer(); + void RenderCurrentFrame(); + void UpdateWidgets(); + void UpdateAnimationWidgets(); + void HideCurrentAnimationWidget(); + void ShowAnimationWidget(QmitkAnimationItem* animationItem); + void RedrawTimeline(); + void CalculateTotalDuration(); + QmitkAnimationItem* GetSelectedAnimationItem() const; + QVector > GetActiveAnimations(double t) const; + + QmitkFFmpegWriter* m_FFmpegWriter; + Ui::QmitkMovieMakerView* m_Ui; + QStandardItemModel* m_AnimationModel; + QMap m_AnimationWidgets; + QMenu* m_AddAnimationMenu; + QMenu* m_RecordMenu; + QTimer* m_Timer; + double m_TotalDuration; + int m_NumFrames; + int m_CurrentFrame; +}; + +#endif diff --git a/Plugins/org.mitk.gui.qt.moviemaker/src/internal/QmitkMovieMakerView.ui b/Plugins/org.mitk.gui.qt.moviemaker/src/internal/QmitkMovieMakerView.ui new file mode 100644 index 0000000000..ccbd70bb83 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.moviemaker/src/internal/QmitkMovieMakerView.ui @@ -0,0 +1,507 @@ + + + QmitkMovieMakerView + + + true + + + + 0 + 0 + 320 + 640 + + + + Movie Maker + + + + + + + + false + + + Move animation up + + + + :/org_mitk_icons/icons/tango/scalable/actions/go-up.svg:/org_mitk_icons/icons/tango/scalable/actions/go-up.svg + + + + 24 + 24 + + + + true + + + + + + + false + + + Move animation down + + + + :/org_mitk_icons/icons/tango/scalable/actions/go-down.svg:/org_mitk_icons/icons/tango/scalable/actions/go-down.svg + + + + 24 + 24 + + + + true + + + + + + + Add animation + + + + :/org_mitk_icons/icons/tango/scalable/actions/list-add.svg:/org_mitk_icons/icons/tango/scalable/actions/list-add.svg + + + + 24 + 24 + + + + true + + + + + + + false + + + Remove animation + + + + :/org_mitk_icons/icons/tango/scalable/actions/list-remove.svg:/org_mitk_icons/icons/tango/scalable/actions/list-remove.svg + + + + 24 + 24 + + + + true + + + + + + + + 0 + 0 + + + + + 0 + 100 + + + + + 16777215 + 100 + + + + false + + + true + + + 80 + + + + + + + + + false + + + Animation + + + + + + + 0 + 0 + + + + + 24 + 24 + + + + + 24 + 24 + + + + + + + :/org_mitk_icons/icons/tango/scalable/actions/media-playback-start.svg + + + true + + + + + + + + 0 + 0 + + + + Start: + + + startComboBox + + + + + + + + 0 + 0 + + + + + After previous + + + + + With previous + + + + + + + + + 0 + 0 + + + + + 24 + 24 + + + + + 24 + 24 + + + + + + + :/QmitkMovieMakerView/duration.svg + + + true + + + + + + + + 0 + 0 + + + + Duration: + + + durationSpinBox + + + + + + + + 0 + 0 + + + + s + + + 100.000000000000000 + + + 0.500000000000000 + + + 2.000000000000000 + + + + + + + + 0 + 0 + + + + + 24 + 24 + + + + + 24 + 24 + + + + + + + :/QmitkMovieMakerView/delay.svg + + + true + + + + + + + + 0 + 0 + + + + Delay: + + + delaySpinBox + + + + + + + + 0 + 0 + + + + s + + + 100.000000000000000 + + + 0.500000000000000 + + + + + + + + + + + + + + + false + + + Playback && Recording + + + + + + Play + + + + :/org_mitk_icons/icons/tango/scalable/actions/media-playback-start.svg:/org_mitk_icons/icons/tango/scalable/actions/media-playback-start.svg + + + + 24 + 24 + + + + true + + + true + + + + + + + false + + + Stop + + + + :/org_mitk_icons/icons/tango/scalable/actions/media-playback-stop.svg:/org_mitk_icons/icons/tango/scalable/actions/media-playback-stop.svg + + + + 24 + 24 + + + + true + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Record + + + + :/org_mitk_icons/icons/tango/scalable/actions/media-record.svg:/org_mitk_icons/icons/tango/scalable/actions/media-record.svg + + + + 24 + 24 + + + + true + + + + + + + Frames per second + + + FPS + + + 1 + + + 120 + + + 30 + + + + + + + + + + Qt::Vertical + + + + 20 + 227 + + + + + + + + animationTreeView + moveAnimationUpButton + moveAnimationDownButton + addAnimationButton + removeAnimationButton + startComboBox + durationSpinBox + delaySpinBox + playButton + stopButton + recordButton + fpsSpinBox + + + + + + + diff --git a/Plugins/org.mitk.gui.qt.moviemaker/src/internal/QmitkOrbitAnimationItem.cpp b/Plugins/org.mitk.gui.qt.moviemaker/src/internal/QmitkOrbitAnimationItem.cpp new file mode 100644 index 0000000000..a65c898f31 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.moviemaker/src/internal/QmitkOrbitAnimationItem.cpp @@ -0,0 +1,85 @@ +/*=================================================================== + +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 "QmitkOrbitAnimationItem.h" +#include + +QmitkOrbitAnimationItem::QmitkOrbitAnimationItem(int startAngle, int orbit, bool reverse, double duration, double delay, bool startWithPrevious) + : QmitkAnimationItem("Orbit", duration, delay, startWithPrevious) +{ + this->SetStartAngle(startAngle); + this->SetOrbit(orbit); + this->SetReverse(reverse); +} + +QmitkOrbitAnimationItem::~QmitkOrbitAnimationItem() +{ +} + +int QmitkOrbitAnimationItem::GetStartAngle() const +{ + return this->data(StartAngleRole).toInt(); +} + +void QmitkOrbitAnimationItem::SetStartAngle(int angle) +{ + this->setData(angle, StartAngleRole); +} + +int QmitkOrbitAnimationItem::GetOrbit() const +{ + return this->data(OrbitRole).toInt(); +} + +void QmitkOrbitAnimationItem::SetOrbit(int angle) +{ + this->setData(angle, OrbitRole); +} + +bool QmitkOrbitAnimationItem::GetReverse() const +{ + return this->data(ReverseRole).toBool(); +} + +void QmitkOrbitAnimationItem::SetReverse(bool reverse) +{ + this->setData(reverse, ReverseRole); +} + +void QmitkOrbitAnimationItem::Animate(double s) +{ + vtkRenderWindow* renderWindow = mitk::BaseRenderer::GetRenderWindowByName("stdmulti.widget4"); + + if (renderWindow == NULL) + return; + + mitk::Stepper* stepper = mitk::BaseRenderer::GetInstance(renderWindow)->GetCameraRotationController()->GetSlice(); + + if (stepper == NULL) + return; + + int newPos = this->GetReverse() + ? this->GetStartAngle() - this->GetOrbit() * s + : this->GetStartAngle() + this->GetOrbit() * s; + + while (newPos < 0) + newPos += 360; + + while (newPos > 360) + newPos -= 360; + + stepper->SetPos(static_cast(newPos)); +} diff --git a/Plugins/org.mitk.gui.qt.moviemaker/src/internal/QmitkOrbitAnimationItem.h b/Plugins/org.mitk.gui.qt.moviemaker/src/internal/QmitkOrbitAnimationItem.h new file mode 100644 index 0000000000..4198afba73 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.moviemaker/src/internal/QmitkOrbitAnimationItem.h @@ -0,0 +1,40 @@ +/*=================================================================== + +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 QmitkOrbitAnimationItem_h +#define QmitkOrbitAnimationItem_h + +#include "QmitkAnimationItem.h" + +class QmitkOrbitAnimationItem : public QmitkAnimationItem +{ +public: + explicit QmitkOrbitAnimationItem(int startAngle = 180, int orbit = 360, bool reverse = false, double duration = 2.0, double delay = 0.0, bool startWithPrevious = false); + virtual ~QmitkOrbitAnimationItem(); + + int GetStartAngle() const; + void SetStartAngle(int angle); + + int GetOrbit() const; + void SetOrbit(int angle); + + bool GetReverse() const; + void SetReverse(bool reverse); + + void Animate(double s); +}; + +#endif diff --git a/Plugins/org.mitk.gui.qt.moviemaker/src/internal/QmitkOrbitAnimationWidget.cpp b/Plugins/org.mitk.gui.qt.moviemaker/src/internal/QmitkOrbitAnimationWidget.cpp new file mode 100644 index 0000000000..0daae05426 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.moviemaker/src/internal/QmitkOrbitAnimationWidget.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 "QmitkOrbitAnimationItem.h" +#include "QmitkOrbitAnimationWidget.h" +#include +#include + +QmitkOrbitAnimationWidget::QmitkOrbitAnimationWidget(QWidget* parent) + : QmitkAnimationWidget(parent), + m_Ui(new Ui::QmitkOrbitAnimationWidget) +{ + m_Ui->setupUi(this); + + m_Ui->orbitLineEdit->setValidator(new QIntValidator(0, std::numeric_limits::max(), this)); + + this->connect(m_Ui->startAngleSlider, SIGNAL(valueChanged(int)), + m_Ui->startAngleSpinBox, SLOT(setValue(int))); + + this->connect(m_Ui->startAngleSpinBox, SIGNAL(valueChanged(int)), + m_Ui->startAngleSlider, SLOT(setValue(int))); + + this->connect(m_Ui->startAngleSpinBox, SIGNAL(valueChanged(int)), + this, SLOT(OnStartAngleChanged(int))); + + this->connect(m_Ui->orbitLineEdit, SIGNAL(editingFinished()), + this, SLOT(OnOrbitEditingFinished())); + + this->connect(m_Ui->reverseCheckBox, SIGNAL(clicked(bool)), + this, SLOT(OnReverseChanged(bool))); +} + +QmitkOrbitAnimationWidget::~QmitkOrbitAnimationWidget() +{ +} + +void QmitkOrbitAnimationWidget::SetAnimationItem(QmitkAnimationItem* orbitAnimationItem) +{ + m_AnimationItem = dynamic_cast(orbitAnimationItem); + + if (m_AnimationItem == NULL) + return; + + m_Ui->startAngleSlider->setValue(m_AnimationItem->GetStartAngle()); + m_Ui->orbitLineEdit->setText(QString("%1").arg(m_AnimationItem->GetOrbit())); + m_Ui->reverseCheckBox->setChecked(m_AnimationItem->GetReverse()); +} + +void QmitkOrbitAnimationWidget::OnStartAngleChanged(int angle) +{ + if (m_AnimationItem == NULL) + return; + + if (m_AnimationItem->GetStartAngle() != angle) + m_AnimationItem->SetStartAngle(angle); +} + +void QmitkOrbitAnimationWidget::OnOrbitEditingFinished() +{ + if (m_AnimationItem == NULL) + return; + + int angle = m_Ui->orbitLineEdit->text().toInt(); + + if (m_AnimationItem->GetOrbit() != angle) + m_AnimationItem->SetOrbit(angle); +} + +void QmitkOrbitAnimationWidget::OnReverseChanged(bool reverse) +{ + if (m_AnimationItem == NULL) + return; + + if (m_AnimationItem->GetReverse() != reverse) + m_AnimationItem->SetReverse(reverse); +} diff --git a/Plugins/org.mitk.gui.qt.moviemaker/src/internal/QmitkOrbitAnimationWidget.h b/Plugins/org.mitk.gui.qt.moviemaker/src/internal/QmitkOrbitAnimationWidget.h new file mode 100644 index 0000000000..e343cfd47f --- /dev/null +++ b/Plugins/org.mitk.gui.qt.moviemaker/src/internal/QmitkOrbitAnimationWidget.h @@ -0,0 +1,49 @@ +/*=================================================================== + +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 QmitkOrbitAnimationWidget_h +#define QmitkOrbitAnimationWidget_h + +#include "QmitkAnimationWidget.h" + +class QmitkOrbitAnimationItem; + +namespace Ui +{ + class QmitkOrbitAnimationWidget; +} + +class QmitkOrbitAnimationWidget : public QmitkAnimationWidget +{ + Q_OBJECT + +public: + explicit QmitkOrbitAnimationWidget(QWidget* parent = NULL); + ~QmitkOrbitAnimationWidget(); + + void SetAnimationItem(QmitkAnimationItem* orbitAnimationItem); + +private slots: + void OnStartAngleChanged(int angle); + void OnOrbitEditingFinished(); + void OnReverseChanged(bool reverse); + +private: + Ui::QmitkOrbitAnimationWidget* m_Ui; + QmitkOrbitAnimationItem* m_AnimationItem; +}; + +#endif diff --git a/Plugins/org.mitk.gui.qt.moviemaker/src/internal/QmitkOrbitAnimationWidget.ui b/Plugins/org.mitk.gui.qt.moviemaker/src/internal/QmitkOrbitAnimationWidget.ui new file mode 100644 index 0000000000..d07661f51c --- /dev/null +++ b/Plugins/org.mitk.gui.qt.moviemaker/src/internal/QmitkOrbitAnimationWidget.ui @@ -0,0 +1,107 @@ + + + QmitkOrbitAnimationWidget + + + + 0 + 0 + 192 + 87 + + + + QmitkOrbitAnimationWidget + + + + + + + 0 + 0 + + + + Start angle: + + + startAngleSlider + + + + + + + 360 + + + 180 + + + Qt::Horizontal + + + + + + + + 0 + 0 + + + + 360 + + + 180 + + + + + + + + 0 + 0 + + + + Orbit: + + + startAngleSlider + + + + + + + 360 + + + + + + + + 0 + 0 + + + + Reverse + + + + + + + startAngleSlider + startAngleSpinBox + reverseCheckBox + + + + diff --git a/Plugins/org.mitk.gui.qt.moviemaker/src/internal/QmitkSliceAnimationItem.cpp b/Plugins/org.mitk.gui.qt.moviemaker/src/internal/QmitkSliceAnimationItem.cpp new file mode 100644 index 0000000000..624512a7ec --- /dev/null +++ b/Plugins/org.mitk.gui.qt.moviemaker/src/internal/QmitkSliceAnimationItem.cpp @@ -0,0 +1,91 @@ +/*=================================================================== + +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 "QmitkSliceAnimationItem.h" +#include + +QmitkSliceAnimationItem::QmitkSliceAnimationItem(int renderWindow, int from, int to, bool reverse, double duration, double delay, bool startWithPrevious) + : QmitkAnimationItem("Slice", duration, delay, startWithPrevious) +{ + this->SetRenderWindow(renderWindow); + this->SetFrom(from); + this->SetTo(to); + this->SetReverse(reverse); +} + +QmitkSliceAnimationItem::~QmitkSliceAnimationItem() +{ +} + +int QmitkSliceAnimationItem::GetRenderWindow() const +{ + return this->data(RenderWindowRole).toInt(); +} + +void QmitkSliceAnimationItem::SetRenderWindow(int renderWindow) +{ + this->setData(renderWindow, RenderWindowRole); +} + +int QmitkSliceAnimationItem::GetFrom() const +{ + return this->data(FromRole).toInt(); +} + +void QmitkSliceAnimationItem::SetFrom(int from) +{ + this->setData(from, FromRole); +} + +int QmitkSliceAnimationItem::GetTo() const +{ + return this->data(ToRole).toInt(); +} + +void QmitkSliceAnimationItem::SetTo(int to) +{ + this->setData(to, ToRole); +} + +bool QmitkSliceAnimationItem::GetReverse() const +{ + return this->data(ReverseRole).toBool(); +} + +void QmitkSliceAnimationItem::SetReverse(bool reverse) +{ + this->setData(reverse, ReverseRole); +} + +void QmitkSliceAnimationItem::Animate(double s) +{ + const QString renderWindowName = QString("stdmulti.widget%1").arg(this->GetRenderWindow() + 1); + vtkRenderWindow* renderWindow = mitk::BaseRenderer::GetRenderWindowByName(renderWindowName.toStdString()); + + if (renderWindow == NULL) + return; + + mitk::Stepper* stepper = mitk::BaseRenderer::GetInstance(renderWindow)->GetSliceNavigationController()->GetSlice(); + + if (stepper == NULL) + return; + + int newPos = this->GetReverse() + ? this->GetTo() - static_cast((this->GetTo() - this->GetFrom()) * s) + : this->GetFrom() + static_cast((this->GetTo() - this->GetFrom()) * s); + + stepper->SetPos(static_cast(newPos)); +} diff --git a/Plugins/org.mitk.gui.qt.moviemaker/src/internal/QmitkSliceAnimationItem.h b/Plugins/org.mitk.gui.qt.moviemaker/src/internal/QmitkSliceAnimationItem.h new file mode 100644 index 0000000000..2626740387 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.moviemaker/src/internal/QmitkSliceAnimationItem.h @@ -0,0 +1,43 @@ +/*=================================================================== + +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 QmitkSliceAnimationItem_h +#define QmitkSliceAnimationItem_h + +#include "QmitkAnimationItem.h" + +class QmitkSliceAnimationItem : public QmitkAnimationItem +{ +public: + explicit QmitkSliceAnimationItem(int renderWindow = 0, int from = 0, int to = 0, bool reverse = false, double duration = 2.0, double delay = 0.0, bool startWithPrevious = false); + virtual ~QmitkSliceAnimationItem(); + + int GetRenderWindow() const; + void SetRenderWindow(int renderWindow); + + int GetFrom() const; + void SetFrom(int from); + + int GetTo() const; + void SetTo(int to); + + bool GetReverse() const; + void SetReverse(bool reverse); + + void Animate(double s); +}; + +#endif diff --git a/Plugins/org.mitk.gui.qt.moviemaker/src/internal/QmitkSliceAnimationWidget.cpp b/Plugins/org.mitk.gui.qt.moviemaker/src/internal/QmitkSliceAnimationWidget.cpp new file mode 100644 index 0000000000..525022fd49 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.moviemaker/src/internal/QmitkSliceAnimationWidget.cpp @@ -0,0 +1,120 @@ +/*=================================================================== + +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 "QmitkSliceAnimationItem.h" +#include "QmitkSliceAnimationWidget.h" +#include +#include + +static unsigned int GetNumberOfSlices(int renderWindow) +{ + const QString renderWindowName = QString("stdmulti.widget%1").arg(renderWindow + 1); + vtkRenderWindow* theRenderWindow = mitk::BaseRenderer::GetRenderWindowByName(renderWindowName.toStdString()); + + if (theRenderWindow != NULL) + { + mitk::Stepper* stepper = mitk::BaseRenderer::GetInstance(theRenderWindow)->GetSliceNavigationController()->GetSlice(); + + if (stepper != NULL) + return std::max(1U, stepper->GetSteps()); + } + + return 1; +} + +QmitkSliceAnimationWidget::QmitkSliceAnimationWidget(QWidget* parent) + : QmitkAnimationWidget(parent), + m_Ui(new Ui::QmitkSliceAnimationWidget) +{ + m_Ui->setupUi(this); + + this->connect(m_Ui->windowComboBox, SIGNAL(currentIndexChanged(int)), + this, SLOT(OnRenderWindowChanged(int))); + + this->connect(m_Ui->sliceRangeWidget, SIGNAL(minimumValueChanged(double)), + this, SLOT(OnFromChanged(double))); + + this->connect(m_Ui->sliceRangeWidget, SIGNAL(maximumValueChanged(double)), + this, SLOT(OnToChanged(double))); + + this->connect(m_Ui->reverseCheckBox, SIGNAL(clicked(bool)), + this, SLOT(OnReverseChanged(bool))); +} + +QmitkSliceAnimationWidget::~QmitkSliceAnimationWidget() +{ +} + +void QmitkSliceAnimationWidget::SetAnimationItem(QmitkAnimationItem* sliceAnimationItem) +{ + m_AnimationItem = dynamic_cast(sliceAnimationItem); + + if (m_AnimationItem == NULL) + return; + + m_Ui->windowComboBox->setCurrentIndex(m_AnimationItem->GetRenderWindow()); + m_Ui->sliceRangeWidget->setMaximum(GetNumberOfSlices(m_AnimationItem->GetRenderWindow()) - 1); + m_Ui->sliceRangeWidget->setValues(m_AnimationItem->GetFrom(), m_AnimationItem->GetTo()); + m_Ui->reverseCheckBox->setChecked(m_AnimationItem->GetReverse()); +} + +void QmitkSliceAnimationWidget::OnRenderWindowChanged(int renderWindow) +{ + if (m_AnimationItem == NULL) + return; + + const int lastSlice = static_cast(GetNumberOfSlices(renderWindow) - 1); + + m_AnimationItem->SetFrom(0); + m_AnimationItem->SetTo(lastSlice); + + m_Ui->sliceRangeWidget->setMaximum(lastSlice); + m_Ui->sliceRangeWidget->setValues(m_AnimationItem->GetFrom(), m_AnimationItem->GetTo()); + + if (m_AnimationItem->GetRenderWindow() != renderWindow) + m_AnimationItem->SetRenderWindow(renderWindow); +} + +void QmitkSliceAnimationWidget::OnFromChanged(double from) +{ + if (m_AnimationItem == NULL) + return; + + int intFrom = static_cast(from); + + if (m_AnimationItem->GetFrom() != intFrom) + m_AnimationItem->SetFrom(intFrom); +} + +void QmitkSliceAnimationWidget::OnToChanged(double to) +{ + if (m_AnimationItem == NULL) + return; + + int intTo = static_cast(to); + + if (m_AnimationItem->GetTo() != intTo) + m_AnimationItem->SetTo(intTo); +} + +void QmitkSliceAnimationWidget::OnReverseChanged(bool reverse) +{ + if (m_AnimationItem == NULL) + return; + + if (m_AnimationItem->GetReverse() != reverse) + m_AnimationItem->SetReverse(reverse); +} diff --git a/Plugins/org.mitk.gui.qt.moviemaker/src/internal/QmitkSliceAnimationWidget.h b/Plugins/org.mitk.gui.qt.moviemaker/src/internal/QmitkSliceAnimationWidget.h new file mode 100644 index 0000000000..a12de9ed58 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.moviemaker/src/internal/QmitkSliceAnimationWidget.h @@ -0,0 +1,50 @@ +/*=================================================================== + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) German Cancer Research Center, +Division of Medical and Biological Informatics. +All rights reserved. + +This software is distributed WITHOUT ANY WARRANTY; without +even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. + +See LICENSE.txt or http://www.mitk.org for details. + +===================================================================*/ + +#ifndef QmitkSliceAnimationWidget_h +#define QmitkSliceAnimationWidget_h + +#include "QmitkAnimationWidget.h" + +class QmitkSliceAnimationItem; + +namespace Ui +{ + class QmitkSliceAnimationWidget; +} + +class QmitkSliceAnimationWidget : public QmitkAnimationWidget +{ + Q_OBJECT + +public: + explicit QmitkSliceAnimationWidget(QWidget* parent = NULL); + ~QmitkSliceAnimationWidget(); + + void SetAnimationItem(QmitkAnimationItem* sliceAnimationItem); + +private slots: + void OnRenderWindowChanged(int renderWindow); + void OnFromChanged(double from); + void OnToChanged(double to); + void OnReverseChanged(bool reverse); + +private: + Ui::QmitkSliceAnimationWidget* m_Ui; + QmitkSliceAnimationItem* m_AnimationItem; +}; + +#endif diff --git a/Plugins/org.mitk.gui.qt.moviemaker/src/internal/QmitkSliceAnimationWidget.ui b/Plugins/org.mitk.gui.qt.moviemaker/src/internal/QmitkSliceAnimationWidget.ui new file mode 100644 index 0000000000..86f72fc9d9 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.moviemaker/src/internal/QmitkSliceAnimationWidget.ui @@ -0,0 +1,112 @@ + + + QmitkSliceAnimationWidget + + + + 0 + 0 + 304 + 96 + + + + QmitkSliceAnimationWidget + + + + + + + 0 + 0 + + + + Window: + + + windowComboBox + + + + + + + + 0 + 0 + + + + + Axial + + + + + Sagittal + + + + + Coronal + + + + + + + + + 0 + 0 + + + + Slice range: + + + + + + + 0 + + + 999.000000000000000 + + + 999.000000000000000 + + + + + + + + 0 + 0 + + + + Reverse + + + + + + + + ctkRangeWidget + QWidget +
ctkRangeWidget.h
+
+
+ + windowComboBox + reverseCheckBox + + + +
diff --git a/Plugins/org.mitk.gui.qt.moviemaker/src/internal/mitkMovieMakerPluginActivator.cpp b/Plugins/org.mitk.gui.qt.moviemaker/src/internal/mitkMovieMakerPluginActivator.cpp index 6becf27540..81f7742a7b 100644 --- a/Plugins/org.mitk.gui.qt.moviemaker/src/internal/mitkMovieMakerPluginActivator.cpp +++ b/Plugins/org.mitk.gui.qt.moviemaker/src/internal/mitkMovieMakerPluginActivator.cpp @@ -1,38 +1,40 @@ /*=================================================================== 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 "mitkMovieMakerPluginActivator.h" -#include "QmitkMovieMaker.h" +#include "QmitkMovieMakerView.h" #include "QmitkScreenshotMaker.h" #include namespace mitk { void MovieMakerPluginActivator::start(ctkPluginContext* context) { - BERRY_REGISTER_EXTENSION_CLASS(QmitkMovieMaker, context) + BERRY_REGISTER_EXTENSION_CLASS(QmitkMovieMakerView, context) BERRY_REGISTER_EXTENSION_CLASS(QmitkScreenshotMaker, context) } void MovieMakerPluginActivator::stop(ctkPluginContext* context) { Q_UNUSED(context) } } -Q_EXPORT_PLUGIN2(org_mitk_gui_qt_moviemaker, mitk::MovieMakerPluginActivator) +#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) + Q_EXPORT_PLUGIN2(org_mitk_gui_qt_moviemaker, mitk::MovieMakerPluginActivator) +#endif diff --git a/Plugins/org.mitk.gui.qt.moviemaker/src/internal/mitkMovieMakerPluginActivator.h b/Plugins/org.mitk.gui.qt.moviemaker/src/internal/mitkMovieMakerPluginActivator.h index 380e629689..be23ecec69 100644 --- a/Plugins/org.mitk.gui.qt.moviemaker/src/internal/mitkMovieMakerPluginActivator.h +++ b/Plugins/org.mitk.gui.qt.moviemaker/src/internal/mitkMovieMakerPluginActivator.h @@ -1,38 +1,41 @@ /*=================================================================== 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 MITKMOVIEMAKERPLUGINACTIVATOR_H #define MITKMOVIEMAKERPLUGINACTIVATOR_H #include namespace mitk { class MovieMakerPluginActivator : public QObject, public ctkPluginActivator { Q_OBJECT - Q_INTERFACES(ctkPluginActivator) +#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) + Q_PLUGIN_METADATA(IID "org_mitk_gui_qt_moviemaker") +#endif + Q_INTERFACES(ctkPluginActivator) public: void start(ctkPluginContext* context); void stop(ctkPluginContext* context); }; // MovieMakerPluginActivator } #endif // MITKMOVIEMAKERPLUGINACTIVATOR_H diff --git a/Plugins/org.mitk.gui.qt.pointsetinteraction/src/internal/mitkPluginActivator.cpp b/Plugins/org.mitk.gui.qt.pointsetinteraction/src/internal/mitkPluginActivator.cpp index 05cadbea0a..69cab01fdb 100644 --- a/Plugins/org.mitk.gui.qt.pointsetinteraction/src/internal/mitkPluginActivator.cpp +++ b/Plugins/org.mitk.gui.qt.pointsetinteraction/src/internal/mitkPluginActivator.cpp @@ -1,36 +1,38 @@ /*=================================================================== 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 "mitkPluginActivator.h" #include "QmitkPointSetInteractionView.h" #include namespace mitk { void PluginActivator::start(ctkPluginContext* context) { BERRY_REGISTER_EXTENSION_CLASS(QmitkPointSetInteractionView, context) } void PluginActivator::stop(ctkPluginContext* context) { Q_UNUSED(context) } } -Q_EXPORT_PLUGIN2(org_mitk_gui_qt_pointsetinteraction, mitk::PluginActivator) +#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) + Q_EXPORT_PLUGIN2(org_mitk_gui_qt_pointsetinteraction, mitk::PluginActivator) +#endif diff --git a/Plugins/org.mitk.gui.qt.pointsetinteraction/src/internal/mitkPluginActivator.h b/Plugins/org.mitk.gui.qt.pointsetinteraction/src/internal/mitkPluginActivator.h index 28a2aa0fdc..030dad599d 100644 --- a/Plugins/org.mitk.gui.qt.pointsetinteraction/src/internal/mitkPluginActivator.h +++ b/Plugins/org.mitk.gui.qt.pointsetinteraction/src/internal/mitkPluginActivator.h @@ -1,39 +1,42 @@ /*=================================================================== 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 MITKPLUGINACTIVATOR_H #define MITKPLUGINACTIVATOR_H #include #include namespace mitk { class MITK_LOCAL PluginActivator : public QObject, public ctkPluginActivator { Q_OBJECT - Q_INTERFACES(ctkPluginActivator) +#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) + Q_PLUGIN_METADATA(IID "org_mitk_gui_qt_pointsetinteraction") +#endif + Q_INTERFACES(ctkPluginActivator) public: void start(ctkPluginContext* context); void stop(ctkPluginContext* context); }; // PluginActivator } #endif // MITKPLUGINACTIVATOR_H diff --git a/Plugins/org.mitk.gui.qt.properties/src/internal/QmitkAddNewPropertyDialog.cpp b/Plugins/org.mitk.gui.qt.properties/src/internal/QmitkAddNewPropertyDialog.cpp index 55e6f2c830..31846956ed 100644 --- a/Plugins/org.mitk.gui.qt.properties/src/internal/QmitkAddNewPropertyDialog.cpp +++ b/Plugins/org.mitk.gui.qt.properties/src/internal/QmitkAddNewPropertyDialog.cpp @@ -1,172 +1,172 @@ /*=================================================================== 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 "QmitkAddNewPropertyDialog.h" #include #include #include QmitkAddNewPropertyDialog::QmitkAddNewPropertyDialog(mitk::DataNode::Pointer dataNode, mitk::BaseRenderer::Pointer renderer, QWidget* parent) : QDialog(parent), m_DataNode(dataNode), m_Renderer(renderer) { m_Controls.setupUi(this); QStringList types; types << "bool" << "double" << "float" << "int" << "string"; m_Controls.typeComboBox->addItems(types); connect(m_Controls.typeComboBox, SIGNAL(currentIndexChanged(const QString&)), this, SLOT(ShowAdequateValueWidget(const QString&))); connect(m_Controls.addButton, SIGNAL(clicked()), this, SLOT(AddNewProperty())); connect(m_Controls.cancelButton, SIGNAL(clicked()), this, SLOT(reject())); this->ShowAdequateValueWidget(types[0]); } QmitkAddNewPropertyDialog::~QmitkAddNewPropertyDialog() { } void QmitkAddNewPropertyDialog::AddNewProperty() { if (m_Controls.nameLineEdit->text().isEmpty()) { QMessageBox::critical(this, "No name specified", "Enter a property name."); return; } if (!this->ValidateValue()) { QMessageBox::critical(this, "Invalid value", "Enter a valid " + m_Controls.typeComboBox->currentText() + " value."); return; } - m_DataNode->SetProperty(m_Controls.nameLineEdit->text().toAscii(), this->CreateProperty(), m_Renderer); + m_DataNode->SetProperty(m_Controls.nameLineEdit->text().toLatin1(), this->CreateProperty(), m_Renderer); this->accept(); } mitk::BaseProperty::Pointer QmitkAddNewPropertyDialog::CreateProperty() const { QString type = m_Controls.typeComboBox->currentText(); if (type == "bool") { return mitk::BoolProperty::New(m_Controls.valueCheckBox->isChecked()).GetPointer(); } else if (type == "double") { return mitk::DoubleProperty::New(m_Controls.valueLineEdit->text().toDouble()).GetPointer(); } else if (type == "float") { return mitk::FloatProperty::New(m_Controls.valueLineEdit->text().toFloat()).GetPointer(); } else if (type == "int") { return mitk::IntProperty::New(m_Controls.valueLineEdit->text().toInt()).GetPointer(); } else if (type == "string") { return mitk::StringProperty::New(m_Controls.valueLineEdit->text().toStdString()).GetPointer(); } else { assert(false && "Property creation for selected type not implemented!"); } return NULL; } bool QmitkAddNewPropertyDialog::ValidateValue() { QString type = m_Controls.typeComboBox->currentText(); if (type == "bool") { return true; } else if (type == "double") { bool ok = false; m_Controls.valueLineEdit->text().toDouble(&ok); return ok; } else if (type == "float") { bool ok = false; m_Controls.valueLineEdit->text().toFloat(&ok); return ok; } else if (type == "int") { bool ok = false; m_Controls.valueLineEdit->text().toInt(&ok); return ok; } else if (type == "string") { return true; } else { assert(false && "Value validation for selected type not implemented!"); } return false; } void QmitkAddNewPropertyDialog::ShowAdequateValueWidget(const QString& type) { m_Controls.valueLineEdit->clear(); m_Controls.valueLineEdit->hide(); m_Controls.valueCheckBox->setChecked(false); m_Controls.valueCheckBox->hide(); if (type == "bool") { m_Controls.valueCheckBox->show(); } else if (type == "double") { m_Controls.valueLineEdit->setText("0"); m_Controls.valueLineEdit->show(); } else if (type == "float") { m_Controls.valueLineEdit->setText("0"); m_Controls.valueLineEdit->show(); } else if (type == "int") { m_Controls.valueLineEdit->setText("0"); m_Controls.valueLineEdit->show(); } else if (type == "string") { m_Controls.valueLineEdit->show(); } else { assert(false && "No adequate value widget specified for selected type!"); } } \ No newline at end of file diff --git a/Plugins/org.mitk.gui.qt.properties/src/internal/QmitkPropertyItemModel.cpp b/Plugins/org.mitk.gui.qt.properties/src/internal/QmitkPropertyItemModel.cpp index f57e188d6a..d792bfea83 100644 --- a/Plugins/org.mitk.gui.qt.properties/src/internal/QmitkPropertyItemModel.cpp +++ b/Plugins/org.mitk.gui.qt.properties/src/internal/QmitkPropertyItemModel.cpp @@ -1,520 +1,521 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "mitkGetPropertyService.h" #include "QmitkPropertiesPreferencePage.h" #include "QmitkPropertyItem.h" #include "QmitkPropertyItemModel.h" #include #include #include #include #include #include #include #include static QColor MitkToQt(const mitk::Color &color) { return QColor(color.GetRed() * 255, color.GetGreen() * 255, color.GetBlue() * 255); } static mitk::BaseProperty* GetBaseProperty(const QVariant& data) { return data.isValid() ? reinterpret_cast(data.value()) : NULL; } static mitk::Color QtToMitk(const QColor &color) { mitk::Color mitkColor; mitkColor.SetRed(color.red() / 255.0f); mitkColor.SetGreen(color.green() / 255.0f); mitkColor.SetBlue(color.blue() / 255.0f); return mitkColor; } class PropertyEqualTo { public: PropertyEqualTo(const mitk::BaseProperty* property) : m_Property(property) { } bool operator()(const mitk::PropertyList::PropertyMapElementType& pair) const { return pair.second.GetPointer() == m_Property; } private: const mitk::BaseProperty* m_Property; }; QmitkPropertyItemModel::QmitkPropertyItemModel(QObject* parent) : QAbstractItemModel(parent), m_PropertyAliases(NULL), m_PropertyFilters(NULL) { this->CreateRootItem(); } QmitkPropertyItemModel::~QmitkPropertyItemModel() { this->SetNewPropertyList(NULL); } int QmitkPropertyItemModel::columnCount(const QModelIndex& parent) const { if (parent.isValid()) return static_cast(parent.internalPointer())->GetColumnCount(); else return m_RootItem->GetColumnCount(); } void QmitkPropertyItemModel::CreateRootItem() { QList rootData; rootData << "Property" << "Value"; m_RootItem.reset(new QmitkPropertyItem(rootData)); - this->reset(); + this->beginResetModel(); + this->endResetModel(); } QVariant QmitkPropertyItemModel::data(const QModelIndex& index, int role) const { if(!index.isValid()) return QVariant(); mitk::BaseProperty* property = index.column() == 1 ? GetBaseProperty(static_cast(index.internalPointer())->GetData(1)) : NULL; if (role == Qt::DisplayRole) { if (index.column() == 0) { return static_cast(index.internalPointer())->GetData(0); } else if (index.column() == 1 && property != NULL) { if (mitk::ColorProperty* colorProperty = dynamic_cast(property)) return MitkToQt(colorProperty->GetValue()); else if (dynamic_cast(property) == NULL) return QString::fromStdString(property->GetValueAsString()); } } else if (index.column() == 1 && property != NULL) { if (role == Qt::CheckStateRole) { if (mitk::BoolProperty* boolProperty = dynamic_cast(property)) return boolProperty->GetValue() ? Qt::Checked : Qt::Unchecked; } else if (role == Qt::EditRole) { if (dynamic_cast(property) != NULL) { return QString::fromStdString(property->GetValueAsString()); } else if (mitk::IntProperty* intProperty = dynamic_cast(property)) { return intProperty->GetValue(); } else if (mitk::FloatProperty* floatProperty = dynamic_cast(property)) { return floatProperty->GetValue(); } else if (mitk::DoubleProperty* doubleProperty = dynamic_cast(property)) { return doubleProperty->GetValue(); } else if (mitk::EnumerationProperty* enumProperty = dynamic_cast(property)) { QStringList values; for (mitk::EnumerationProperty::EnumConstIterator it = enumProperty->Begin(); it != enumProperty->End(); it++) values << QString::fromStdString(it->second); return values; } else if (mitk::ColorProperty* colorProperty = dynamic_cast(property)) { return MitkToQt(colorProperty->GetValue()); } } else if (role == mitk::PropertyRole) { return QVariant::fromValue(property); } } return QVariant(); } QModelIndex QmitkPropertyItemModel::FindProperty(const mitk::BaseProperty* property) { if (property == NULL) return QModelIndex(); typedef mitk::PropertyList::PropertyMap PropertyMap; const PropertyMap* propertyMap = m_PropertyList->GetMap(); PropertyMap::const_iterator it = std::find_if(propertyMap->begin(), propertyMap->end(), PropertyEqualTo(property)); if (it == propertyMap->end()) return QModelIndex(); QString name = QString::fromStdString(it->first); if (!name.contains('.')) { QModelIndexList item = this->match(index(0, 0), Qt::DisplayRole, name, 1, Qt::MatchExactly); if (!item.empty()) return item[0]; } else { QStringList names = name.split('.'); QModelIndexList items = this->match(index(0, 0), Qt::DisplayRole, names.last(), -1, Qt::MatchRecursive | Qt::MatchExactly); foreach(QModelIndex item, items) { QModelIndex candidate = item; for (int i = names.length() - 1; i != 0; --i) { QModelIndex parent = item.parent(); if (parent.parent() == QModelIndex()) { if (parent.data() != names.first()) break; return candidate; } if (parent.data() != names[i - 1]) break; item = parent; } } } return QModelIndex(); } Qt::ItemFlags QmitkPropertyItemModel::flags(const QModelIndex& index) const { Qt::ItemFlags flags = QAbstractItemModel::flags(index); if (index.column() == 1) { if (index.data(Qt::EditRole).isValid()) flags |= Qt::ItemIsEditable; if (index.data(Qt::CheckStateRole).isValid()) flags |= Qt::ItemIsUserCheckable; } return flags; } mitk::PropertyList* QmitkPropertyItemModel::GetPropertyList() const { return m_PropertyList.GetPointer(); } QVariant QmitkPropertyItemModel::headerData(int section, Qt::Orientation orientation, int role) const { if (orientation == Qt::Horizontal && role == Qt::DisplayRole) return m_RootItem->GetData(section); return QVariant(); } QModelIndex QmitkPropertyItemModel::index(int row, int column, const QModelIndex& parent) const { if (!this->hasIndex(row, column, parent)) return QModelIndex(); QmitkPropertyItem* parentItem = parent.isValid() ? static_cast(parent.internalPointer()) : m_RootItem.get(); QmitkPropertyItem* childItem = parentItem->GetChild(row); return childItem != NULL ? this->createIndex(row, column, childItem) : QModelIndex(); } void QmitkPropertyItemModel::OnPreferencesChanged(const berry::IBerryPreferences* preferences) { bool showAliases = preferences->GetBool(QmitkPropertiesPreferencePage::SHOW_ALIASES, true); bool filterProperties = preferences->GetBool(QmitkPropertiesPreferencePage::FILTER_PROPERTIES, true); bool updateAliases = showAliases != (m_PropertyAliases != NULL); bool updateFilters = filterProperties != (m_PropertyFilters != NULL); bool resetPropertyList = false; if (updateAliases) { m_PropertyAliases = showAliases ? mitk::GetPropertyService() : NULL; resetPropertyList = m_PropertyList.IsNotNull(); } if (updateFilters) { m_PropertyFilters = filterProperties ? mitk::GetPropertyService() : NULL; if (!resetPropertyList) resetPropertyList = m_PropertyList.IsNotNull(); } if (resetPropertyList) this->SetNewPropertyList(m_PropertyList.GetPointer()); } void QmitkPropertyItemModel::OnPropertyDeleted(const itk::Object* property, const itk::EventObject&) { /*QModelIndex index = this->FindProperty(static_cast(property)); if (index != QModelIndex()) this->reset();*/ } void QmitkPropertyItemModel::OnPropertyListDeleted(const itk::Object*) { this->CreateRootItem(); } void QmitkPropertyItemModel::OnPropertyModified(const itk::Object* property, const itk::EventObject&) { QModelIndex index = this->FindProperty(static_cast(property)); if (index != QModelIndex()) emit dataChanged(index, index); } QModelIndex QmitkPropertyItemModel::parent(const QModelIndex& child) const { if (!child.isValid()) return QModelIndex(); QmitkPropertyItem* parentItem = static_cast(child.internalPointer())->GetParent(); if (parentItem == m_RootItem.get()) return QModelIndex(); return this->createIndex(parentItem->GetRow(), 0, parentItem); } int QmitkPropertyItemModel::rowCount(const QModelIndex& parent) const { if (parent.column() > 0) return 0; QmitkPropertyItem *parentItem = parent.isValid() ? static_cast(parent.internalPointer()) : m_RootItem.get(); return parentItem->GetChildCount(); } bool QmitkPropertyItemModel::setData(const QModelIndex& index, const QVariant& value, int role) { if (!index.isValid() || index.column() != 1 || (role != Qt::EditRole && role != Qt::CheckStateRole)) return false; mitk::BaseProperty* property = GetBaseProperty(static_cast(index.internalPointer())->GetData(1)); if (property == NULL) return false; if (mitk::BoolProperty* boolProperty = dynamic_cast(property)) { boolProperty->SetValue(value.toInt() == Qt::Checked ? true : false); } else if (mitk::StringProperty* stringProperty = dynamic_cast(property)) { stringProperty->SetValue(value.toString().toStdString()); } else if (mitk::IntProperty* intProperty = dynamic_cast(property)) { intProperty->SetValue(value.toInt()); } else if (mitk::FloatProperty* floatProperty = dynamic_cast(property)) { floatProperty->SetValue(value.toFloat()); } else if (mitk::DoubleProperty* doubleProperty = dynamic_cast(property)) { doubleProperty->SetValue(value.toDouble()); } else if (mitk::EnumerationProperty* enumProperty = dynamic_cast(property)) { std::string selection = value.toString().toStdString(); if (selection != enumProperty->GetValueAsString() && enumProperty->IsValidEnumerationValue(selection)) enumProperty->SetValue(selection); } else if (mitk::ColorProperty* colorProperty = dynamic_cast(property)) { colorProperty->SetValue(QtToMitk(value.value())); } m_PropertyList->InvokeEvent(itk::ModifiedEvent()); m_PropertyList->Modified(); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); return true; } void QmitkPropertyItemModel::SetNewPropertyList(mitk::PropertyList* propertyList) { typedef mitk::PropertyList::PropertyMap PropertyMap; this->beginResetModel(); if (m_PropertyList.IsNotNull()) { mitk::MessageDelegate1 delegate(this, &QmitkPropertyItemModel::OnPropertyListDeleted); m_PropertyList.ObjectDelete.RemoveListener(delegate); const PropertyMap* propertyMap = m_PropertyList->GetMap(); for (PropertyMap::const_iterator propertyIt = propertyMap->begin(); propertyIt != propertyMap->end(); ++propertyIt) { std::map::const_iterator tagIt = m_PropertyModifiedTags.find(propertyIt->first); if (tagIt != m_PropertyModifiedTags.end()) propertyIt->second->RemoveObserver(tagIt->second); tagIt = m_PropertyDeletedTags.find(propertyIt->first); if (tagIt != m_PropertyDeletedTags.end()) propertyIt->second->RemoveObserver(tagIt->second); } m_PropertyModifiedTags.clear(); } m_PropertyList = propertyList; if (m_PropertyList.IsNotNull()) { mitk::MessageDelegate1 delegate(this, &QmitkPropertyItemModel::OnPropertyListDeleted); m_PropertyList.ObjectDelete.AddListener(delegate); mitk::MessageDelegate2 propertyDelegate(this, &QmitkPropertyItemModel::OnPropertyModified); itk::MemberCommand::Pointer modifiedCommand = itk::MemberCommand::New(); modifiedCommand->SetCallbackFunction(this, &QmitkPropertyItemModel::OnPropertyModified); const PropertyMap* propertyMap = m_PropertyList->GetMap(); for (PropertyMap::const_iterator it = propertyMap->begin(); it != propertyMap->end(); ++it) m_PropertyModifiedTags.insert(std::make_pair(it->first, it->second->AddObserver(itk::ModifiedEvent(), modifiedCommand))); itk::MemberCommand::Pointer deletedCommand = itk::MemberCommand::New(); deletedCommand->SetCallbackFunction(this, &QmitkPropertyItemModel::OnPropertyDeleted); for (PropertyMap::const_iterator it = propertyMap->begin(); it != propertyMap->end(); ++it) m_PropertyDeletedTags.insert(std::make_pair(it->first, it->second->AddObserver(itk::DeleteEvent(), deletedCommand))); } this->CreateRootItem(); if (m_PropertyList != NULL && !m_PropertyList->IsEmpty()) { mitk::PropertyList::PropertyMap filteredProperties; bool filterProperties = false; if (m_PropertyFilters != NULL && (m_PropertyFilters->HasFilter() || m_PropertyFilters->HasFilter(m_ClassName.toStdString()))) { filteredProperties = m_PropertyFilters->ApplyFilter(*m_PropertyList->GetMap(), m_ClassName.toStdString()); filterProperties = true; } const mitk::PropertyList::PropertyMap* propertyMap = !filterProperties ? m_PropertyList->GetMap() : &filteredProperties; mitk::PropertyList::PropertyMap::const_iterator end = propertyMap->end(); for (mitk::PropertyList::PropertyMap::const_iterator iter = propertyMap->begin(); iter != end; ++iter) { std::vector aliases; if (m_PropertyAliases != NULL) { aliases = m_PropertyAliases->GetAliases(iter->first, m_ClassName.toStdString()); if (aliases.empty() && !m_ClassName.isEmpty()) aliases = m_PropertyAliases->GetAliases(iter->first); } if (aliases.empty()) { QList data; data << QString::fromStdString(iter->first) << QVariant::fromValue((reinterpret_cast(iter->second.GetPointer()))); m_RootItem->AppendChild(new QmitkPropertyItem(data)); } else { std::vector::const_iterator end = aliases.end(); for (std::vector::const_iterator aliasIter = aliases.begin(); aliasIter != end; ++aliasIter) { QList data; data << QString::fromStdString(*aliasIter) << QVariant::fromValue((reinterpret_cast(iter->second.GetPointer()))); m_RootItem->AppendChild(new QmitkPropertyItem(data)); } } } } this->endResetModel(); } void QmitkPropertyItemModel::SetPropertyList(mitk::PropertyList* propertyList, const QString& className) { if (m_PropertyList.GetPointer() != propertyList) { m_ClassName = className; this->SetNewPropertyList(propertyList); } } void QmitkPropertyItemModel::Update() { this->SetNewPropertyList(m_PropertyList); } diff --git a/Plugins/org.mitk.gui.qt.properties/src/internal/org_mitk_gui_qt_properties_Activator.cpp b/Plugins/org.mitk.gui.qt.properties/src/internal/org_mitk_gui_qt_properties_Activator.cpp index 16112dd4f4..7c0a926d07 100644 --- a/Plugins/org.mitk.gui.qt.properties/src/internal/org_mitk_gui_qt_properties_Activator.cpp +++ b/Plugins/org.mitk.gui.qt.properties/src/internal/org_mitk_gui_qt_properties_Activator.cpp @@ -1,41 +1,43 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "org_mitk_gui_qt_properties_Activator.h" #include "QmitkPropertiesPreferencePage.h" #include "QmitkPropertyTreeView.h" #include ctkPluginContext* mitk::org_mitk_gui_qt_properties_Activator::m_Context = NULL; ctkPluginContext* mitk::org_mitk_gui_qt_properties_Activator::GetContext() { return m_Context; } void mitk::org_mitk_gui_qt_properties_Activator::start(ctkPluginContext* context) { BERRY_REGISTER_EXTENSION_CLASS(QmitkPropertiesPreferencePage, context); BERRY_REGISTER_EXTENSION_CLASS(QmitkPropertyTreeView, context); m_Context = context; } void mitk::org_mitk_gui_qt_properties_Activator::stop(ctkPluginContext*) { m_Context = NULL; } -Q_EXPORT_PLUGIN2(org_mitk_gui_qt_properties, mitk::org_mitk_gui_qt_properties_Activator) +#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) + Q_EXPORT_PLUGIN2(org_mitk_gui_qt_properties, mitk::org_mitk_gui_qt_properties_Activator) +#endif diff --git a/Plugins/org.mitk.gui.qt.properties/src/internal/org_mitk_gui_qt_properties_Activator.h b/Plugins/org.mitk.gui.qt.properties/src/internal/org_mitk_gui_qt_properties_Activator.h index 331a0bebd8..cf54d060c8 100644 --- a/Plugins/org.mitk.gui.qt.properties/src/internal/org_mitk_gui_qt_properties_Activator.h +++ b/Plugins/org.mitk.gui.qt.properties/src/internal/org_mitk_gui_qt_properties_Activator.h @@ -1,40 +1,43 @@ /*=================================================================== 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 org_mitk_gui_qt_properties_Activator_h #define org_mitk_gui_qt_properties_Activator_h #include namespace mitk { class org_mitk_gui_qt_properties_Activator : public QObject, public ctkPluginActivator { Q_OBJECT +#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) + Q_PLUGIN_METADATA(IID "org_mitk_gui_qt_properties") +#endif Q_INTERFACES(ctkPluginActivator) public: static ctkPluginContext* GetContext(); void start(ctkPluginContext* context); void stop(ctkPluginContext* context); private: static ctkPluginContext* m_Context; }; } #endif diff --git a/Plugins/org.mitk.gui.qt.python/src/internal/mitkPluginActivator.cpp b/Plugins/org.mitk.gui.qt.python/src/internal/mitkPluginActivator.cpp index e59a8e8108..eca9c442f4 100644 --- a/Plugins/org.mitk.gui.qt.python/src/internal/mitkPluginActivator.cpp +++ b/Plugins/org.mitk.gui.qt.python/src/internal/mitkPluginActivator.cpp @@ -1,38 +1,41 @@ /*=================================================================== 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 "mitkPluginActivator.h" #include #include "QmitkPythonView.h" namespace mitk { QString PluginActivator::m_XmlFilePath; void PluginActivator::start(ctkPluginContext* context) { m_XmlFilePath = context->getDataFile("PythonSnippets.xml").absoluteFilePath(); BERRY_REGISTER_EXTENSION_CLASS(QmitkPythonView, context) } void PluginActivator::stop(ctkPluginContext* context) { Q_UNUSED(context) } } -Q_EXPORT_PLUGIN2(org_mitk_gui_qt_python, mitk::PluginActivator) +#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) + Q_EXPORT_PLUGIN2(org_mitk_gui_qt_python, mitk::PluginActivator) +#endif + diff --git a/Plugins/org.mitk.gui.qt.python/src/internal/mitkPluginActivator.h b/Plugins/org.mitk.gui.qt.python/src/internal/mitkPluginActivator.h index 9a32e11e62..7c46ee5ea2 100644 --- a/Plugins/org.mitk.gui.qt.python/src/internal/mitkPluginActivator.h +++ b/Plugins/org.mitk.gui.qt.python/src/internal/mitkPluginActivator.h @@ -1,39 +1,42 @@ /*=================================================================== 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 MITKPLUGINACTIVATOR_H #define MITKPLUGINACTIVATOR_H #include #include namespace mitk { class MITK_LOCAL PluginActivator : public QObject, public ctkPluginActivator { Q_OBJECT +#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) + Q_PLUGIN_METADATA(IID "org_mitk_gui_qt_python") +#endif Q_INTERFACES(ctkPluginActivator) public: void start(ctkPluginContext* context); void stop(ctkPluginContext* context); static QString m_XmlFilePath; }; // PluginActivator } #endif // MITKPLUGINACTIVATOR_H diff --git a/Plugins/org.mitk.gui.qt.registration/src/internal/QmitkLoadPresetDialog.cpp b/Plugins/org.mitk.gui.qt.registration/src/internal/QmitkLoadPresetDialog.cpp index bbec4bf094..09e7863c4a 100644 --- a/Plugins/org.mitk.gui.qt.registration/src/internal/QmitkLoadPresetDialog.cpp +++ b/Plugins/org.mitk.gui.qt.registration/src/internal/QmitkLoadPresetDialog.cpp @@ -1,91 +1,91 @@ /*=================================================================== 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 "QmitkLoadPresetDialog.h" #include #include #include #include QmitkLoadPresetDialog::QmitkLoadPresetDialog(QWidget* parent, Qt::WindowFlags f, const char* name, std::list presets) :QDialog(parent, f) { QDialog::setMinimumSize(250, 300); this->setObjectName(name); QBoxLayout * verticalLayout = new QVBoxLayout( this ); verticalLayout->setMargin(5); verticalLayout->setSpacing(5); // list of all presets lblPrompt = new QLabel( "Which preset do you want to load?", this ); verticalLayout->addWidget( lblPrompt ); lstPresets = new QListWidget( this ); verticalLayout->addWidget( lstPresets ); std::list::iterator iter; for( iter = presets.begin(); iter != presets.end(); iter++ ) { std::string preset = *iter; new QListWidgetItem(preset.c_str(), lstPresets); } lstPresets->setCurrentItem(0); // select first Item by default (might turn out to be a stupid descision) connect( lstPresets, SIGNAL(itemDoubleClicked (QListWidgetItem *)), this, SLOT(onPresetImmediatelySelected(QListWidgetItem *)) ); // buttons for closing the dialog btnOk = new QPushButton( tr("Ok"), this); btnOk->setObjectName("btnOk" ); btnOk->setDefault(true); connect( btnOk, SIGNAL(clicked()), this, SLOT(accept()) ); QPushButton* btnCancel = new QPushButton( tr("Cancel"), this); btnCancel->setObjectName("btnCancel" ); connect( btnCancel, SIGNAL(clicked()), this, SLOT(reject()) ); QWidget* buttonWidget = new QWidget(this); QBoxLayout * horizontalLayout = new QHBoxLayout( buttonWidget ); horizontalLayout->setSpacing(5); horizontalLayout->addStretch(); horizontalLayout->addWidget( btnOk ); horizontalLayout->addWidget( btnCancel ); verticalLayout->addWidget(buttonWidget); } QmitkLoadPresetDialog::~QmitkLoadPresetDialog() { } std::string QmitkLoadPresetDialog::GetPresetName() { - std::string presetName = std::string(lstPresets->currentItem()->text().toAscii()); + std::string presetName = std::string(lstPresets->currentItem()->text().toLatin1()); return presetName; } void QmitkLoadPresetDialog::onPresetImmediatelySelected(QListWidgetItem * ) { if ( (signed)(lstPresets->row(lstPresets->currentItem())) != (signed)(lstPresets->count()-1) ) { accept(); // close } else { // dont close } } diff --git a/Plugins/org.mitk.gui.qt.registration/src/internal/mitkPluginActivator.cpp b/Plugins/org.mitk.gui.qt.registration/src/internal/mitkPluginActivator.cpp index 681063590a..4925593fb2 100644 --- a/Plugins/org.mitk.gui.qt.registration/src/internal/mitkPluginActivator.cpp +++ b/Plugins/org.mitk.gui.qt.registration/src/internal/mitkPluginActivator.cpp @@ -1,41 +1,43 @@ /*=================================================================== 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 "mitkPluginActivator.h" #include "src/internal/QmitkDeformableRegistrationView.h" #include "src/internal/QmitkPointBasedRegistrationView.h" #include "src/internal/QmitkRigidRegistrationView.h" #include namespace mitk { void PluginActivator::start(ctkPluginContext* context) { BERRY_REGISTER_EXTENSION_CLASS(QmitkDeformableRegistrationView, context) BERRY_REGISTER_EXTENSION_CLASS(QmitkPointBasedRegistrationView, context) BERRY_REGISTER_EXTENSION_CLASS(QmitkRigidRegistrationView, context) //Q_UNUSED(context) } void PluginActivator::stop(ctkPluginContext* context) { Q_UNUSED(context) } } -Q_EXPORT_PLUGIN2(org_mitk_gui_qt_registration, mitk::PluginActivator) +#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) + Q_EXPORT_PLUGIN2(org_mitk_gui_qt_registration, mitk::PluginActivator) +#endif diff --git a/Plugins/org.mitk.gui.qt.registration/src/internal/mitkPluginActivator.h b/Plugins/org.mitk.gui.qt.registration/src/internal/mitkPluginActivator.h index 12053e09e3..30da5fdaa1 100644 --- a/Plugins/org.mitk.gui.qt.registration/src/internal/mitkPluginActivator.h +++ b/Plugins/org.mitk.gui.qt.registration/src/internal/mitkPluginActivator.h @@ -1,39 +1,42 @@ /*=================================================================== 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 MITKPLUGINACTIVATOR_H #define MITKPLUGINACTIVATOR_H #include #include namespace mitk { class MITK_LOCAL PluginActivator : public QObject, public ctkPluginActivator { Q_OBJECT +#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) + Q_PLUGIN_METADATA(IID "org_mitk_gui_qt_registration") +#endif Q_INTERFACES(ctkPluginActivator) public: void start(ctkPluginContext* context); void stop(ctkPluginContext* context); }; // PluginActivator } #endif // MITKPLUGINACTIVATOR_H diff --git a/Plugins/org.mitk.gui.qt.remeshing/CMakeLists.txt b/Plugins/org.mitk.gui.qt.remeshing/CMakeLists.txt index 34efdc8fe3..fdc8add159 100644 --- a/Plugins/org.mitk.gui.qt.remeshing/CMakeLists.txt +++ b/Plugins/org.mitk.gui.qt.remeshing/CMakeLists.txt @@ -1,9 +1,10 @@ project(org_mitk_gui_qt_remeshing) include_directories(${CTK_INCLUDE_DIRS}) MACRO_CREATE_MITK_CTK_PLUGIN( EXPORT_DIRECTIVE REMESHING_EXPORT EXPORTED_INCLUDE_SUFFIXES src MODULE_DEPENDS MitkQtWidgets MitkRemeshing + PACKAGE_DEPENDS Qt4|QtCore Qt5|OpenGL+Xml ) diff --git a/Plugins/org.mitk.gui.qt.remeshing/src/internal/org_mitk_gui_qt_remeshing_Activator.cpp b/Plugins/org.mitk.gui.qt.remeshing/src/internal/org_mitk_gui_qt_remeshing_Activator.cpp index 2fe6042c78..1f552fe402 100644 --- a/Plugins/org.mitk.gui.qt.remeshing/src/internal/org_mitk_gui_qt_remeshing_Activator.cpp +++ b/Plugins/org.mitk.gui.qt.remeshing/src/internal/org_mitk_gui_qt_remeshing_Activator.cpp @@ -1,30 +1,32 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "org_mitk_gui_qt_remeshing_Activator.h" #include "QmitkRemeshingView.h" #include void mitk::org_mitk_gui_qt_remeshing_Activator::start(ctkPluginContext* context) { BERRY_REGISTER_EXTENSION_CLASS(QmitkRemeshingView, context); } void mitk::org_mitk_gui_qt_remeshing_Activator::stop(ctkPluginContext*) { } -Q_EXPORT_PLUGIN2(org_mitk_gui_qt_remeshing, mitk::org_mitk_gui_qt_remeshing_Activator) +#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) + Q_EXPORT_PLUGIN2(org_mitk_gui_qt_remeshing, mitk::org_mitk_gui_qt_remeshing_Activator) +#endif diff --git a/Plugins/org.mitk.gui.qt.remeshing/src/internal/org_mitk_gui_qt_remeshing_Activator.h b/Plugins/org.mitk.gui.qt.remeshing/src/internal/org_mitk_gui_qt_remeshing_Activator.h index 3ecd3b77b8..efce73c069 100644 --- a/Plugins/org.mitk.gui.qt.remeshing/src/internal/org_mitk_gui_qt_remeshing_Activator.h +++ b/Plugins/org.mitk.gui.qt.remeshing/src/internal/org_mitk_gui_qt_remeshing_Activator.h @@ -1,35 +1,38 @@ /*=================================================================== 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 org_mitk_gui_qt_remeshing_Activator_h #define org_mitk_gui_qt_remeshing_Activator_h #include namespace mitk { class org_mitk_gui_qt_remeshing_Activator : public QObject, public ctkPluginActivator { Q_OBJECT +#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) + Q_PLUGIN_METADATA(IID "org_mitk_gui_qt_remeshing") +#endif Q_INTERFACES(ctkPluginActivator) public: void start(ctkPluginContext* context); void stop(ctkPluginContext* context); }; } #endif diff --git a/Plugins/org.mitk.gui.qt.segmentation/CMakeLists.txt b/Plugins/org.mitk.gui.qt.segmentation/CMakeLists.txt index 93cb1256d8..5e6125d475 100644 --- a/Plugins/org.mitk.gui.qt.segmentation/CMakeLists.txt +++ b/Plugins/org.mitk.gui.qt.segmentation/CMakeLists.txt @@ -1,9 +1,10 @@ project(org_mitk_gui_qt_segmentation) include_directories(${CTK_INCLUDE_DIRS}) MACRO_CREATE_MITK_CTK_PLUGIN( EXPORT_DIRECTIVE MITK_QT_SEGMENTATION EXPORTED_INCLUDE_SUFFIXES src MODULE_DEPENDS MitkQtWidgetsExt MitkSegmentationUI + PACKAGE_DEPENDS Qt4|QtCore Qt5|OpenGL ) diff --git a/Plugins/org.mitk.gui.qt.segmentation/src/internal/mitkPluginActivator.cpp b/Plugins/org.mitk.gui.qt.segmentation/src/internal/mitkPluginActivator.cpp index 6500500440..d1609d5dd2 100644 --- a/Plugins/org.mitk.gui.qt.segmentation/src/internal/mitkPluginActivator.cpp +++ b/Plugins/org.mitk.gui.qt.segmentation/src/internal/mitkPluginActivator.cpp @@ -1,53 +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. ===================================================================*/ #include "mitkPluginActivator.h" #include "QmitkSegmentationView.h" #include "QmitkThresholdAction.h" #include "QmitkCreatePolygonModelAction.h" #include "QmitkAutocropAction.h" #include "QmitkSegmentationPreferencePage.h" #include "QmitkDeformableClippingPlaneView.h" #include "SegmentationUtilities/QmitkSegmentationUtilitiesView.h" using namespace mitk; ctkPluginContext* PluginActivator::m_context = NULL; void PluginActivator::start(ctkPluginContext *context) { BERRY_REGISTER_EXTENSION_CLASS(QmitkSegmentationView, context) BERRY_REGISTER_EXTENSION_CLASS(QmitkThresholdAction, context) BERRY_REGISTER_EXTENSION_CLASS(QmitkCreatePolygonModelAction, context) BERRY_REGISTER_EXTENSION_CLASS(QmitkAutocropAction, context) BERRY_REGISTER_EXTENSION_CLASS(QmitkSegmentationPreferencePage, context) BERRY_REGISTER_EXTENSION_CLASS(QmitkDeformableClippingPlaneView, context) BERRY_REGISTER_EXTENSION_CLASS(QmitkSegmentationUtilitiesView, context) this->m_context = context; } void PluginActivator::stop(ctkPluginContext *) { this->m_context = NULL; } ctkPluginContext*PluginActivator::getContext() { return m_context; } -Q_EXPORT_PLUGIN2(org_mitk_gui_qt_segmentation, mitk::PluginActivator) +#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) + Q_EXPORT_PLUGIN2(org_mitk_gui_qt_segmentation, mitk::PluginActivator) +#endif diff --git a/Plugins/org.mitk.gui.qt.segmentation/src/internal/mitkPluginActivator.h b/Plugins/org.mitk.gui.qt.segmentation/src/internal/mitkPluginActivator.h index d0c6e5f9e2..6f030a44c9 100644 --- a/Plugins/org.mitk.gui.qt.segmentation/src/internal/mitkPluginActivator.h +++ b/Plugins/org.mitk.gui.qt.segmentation/src/internal/mitkPluginActivator.h @@ -1,43 +1,46 @@ /*=================================================================== 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 MITKPLUGINACTIVATOR_H #define MITKPLUGINACTIVATOR_H // Parent classes #include #include #include namespace mitk { class MITK_LOCAL PluginActivator : public QObject, public ctkPluginActivator { Q_OBJECT +#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) + Q_PLUGIN_METADATA(IID "org_mitk_gui_qt_segmentation") +#endif Q_INTERFACES(ctkPluginActivator) public: void start(ctkPluginContext *context); void stop(ctkPluginContext *context); static ctkPluginContext* getContext(); private: static ctkPluginContext* m_context; }; } #endif diff --git a/Plugins/org.mitk.gui.qt.simulation/src/internal/QmitkBaseItemDelegate.h b/Plugins/org.mitk.gui.qt.simulation/src/internal/QmitkBaseItemDelegate.h index 01a009a16d..73500b789e 100644 --- a/Plugins/org.mitk.gui.qt.simulation/src/internal/QmitkBaseItemDelegate.h +++ b/Plugins/org.mitk.gui.qt.simulation/src/internal/QmitkBaseItemDelegate.h @@ -1,49 +1,39 @@ /*=================================================================== 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 QmitkBaseItemDelegate_h #define QmitkBaseItemDelegate_h #include - -namespace sofa -{ - namespace core - { - namespace objectmodel - { - class BaseData; - } - } -} +#include class QmitkBaseItemDelegate : public QStyledItemDelegate { Q_OBJECT public: explicit QmitkBaseItemDelegate(QObject* parent = NULL); ~QmitkBaseItemDelegate(); QWidget* createEditor(QWidget *parent, const QStyleOptionViewItem& option, const QModelIndex& index) const; void paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const; void setEditorData(QWidget* editor, const QModelIndex& index) const; void setModelData(QWidget* editor, QAbstractItemModel* model, const QModelIndex& index) const; }; Q_DECLARE_METATYPE(sofa::core::objectmodel::BaseData*) #endif diff --git a/Plugins/org.mitk.gui.qt.simulation/src/internal/org_mitk_gui_qt_simulation_Activator.cpp b/Plugins/org.mitk.gui.qt.simulation/src/internal/org_mitk_gui_qt_simulation_Activator.cpp index 90369e11b2..60f0d28cb2 100644 --- a/Plugins/org.mitk.gui.qt.simulation/src/internal/org_mitk_gui_qt_simulation_Activator.cpp +++ b/Plugins/org.mitk.gui.qt.simulation/src/internal/org_mitk_gui_qt_simulation_Activator.cpp @@ -1,41 +1,43 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "org_mitk_gui_qt_simulation_Activator.h" #include "QmitkSimulationPreferencePage.h" #include "QmitkSimulationView.h" #include ctkPluginContext* mitk::org_mitk_gui_qt_simulation_Activator::Context = NULL; ctkPluginContext* mitk::org_mitk_gui_qt_simulation_Activator::GetContext() { return Context; } void mitk::org_mitk_gui_qt_simulation_Activator::start(ctkPluginContext* context) { BERRY_REGISTER_EXTENSION_CLASS(QmitkSimulationPreferencePage, context); BERRY_REGISTER_EXTENSION_CLASS(QmitkSimulationView, context); Context = context; } void mitk::org_mitk_gui_qt_simulation_Activator::stop(ctkPluginContext*) { Context = NULL; } -Q_EXPORT_PLUGIN2(org_mitk_gui_qt_simulation, mitk::org_mitk_gui_qt_simulation_Activator); +#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) + Q_EXPORT_PLUGIN2(org_mitk_gui_qt_simulation, mitk::org_mitk_gui_qt_simulation_Activator) +#endif diff --git a/Plugins/org.mitk.gui.qt.simulation/src/internal/org_mitk_gui_qt_simulation_Activator.h b/Plugins/org.mitk.gui.qt.simulation/src/internal/org_mitk_gui_qt_simulation_Activator.h index 65e96a3771..c299e30a7b 100644 --- a/Plugins/org.mitk.gui.qt.simulation/src/internal/org_mitk_gui_qt_simulation_Activator.h +++ b/Plugins/org.mitk.gui.qt.simulation/src/internal/org_mitk_gui_qt_simulation_Activator.h @@ -1,40 +1,43 @@ /*=================================================================== 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 org_mitk_gui_qt_simulation_Activator_h #define org_mitk_gui_qt_simulation_Activator_h #include namespace mitk { class org_mitk_gui_qt_simulation_Activator : public QObject, public ctkPluginActivator { Q_OBJECT +#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) + Q_PLUGIN_METADATA(IID "org_mitk_gui_qt_simulation") +#endif Q_INTERFACES(ctkPluginActivator); public: static ctkPluginContext* GetContext(); void start(ctkPluginContext* context); void stop(ctkPluginContext*); private: static ctkPluginContext* Context; }; } #endif diff --git a/Plugins/org.mitk.gui.qt.stdmultiwidgeteditor/src/internal/org_mitk_gui_qt_stdmultiwidgeteditor_Activator.cpp b/Plugins/org.mitk.gui.qt.stdmultiwidgeteditor/src/internal/org_mitk_gui_qt_stdmultiwidgeteditor_Activator.cpp index 1d5eb961dc..3aaf7b6c86 100644 --- a/Plugins/org.mitk.gui.qt.stdmultiwidgeteditor/src/internal/org_mitk_gui_qt_stdmultiwidgeteditor_Activator.cpp +++ b/Plugins/org.mitk.gui.qt.stdmultiwidgeteditor/src/internal/org_mitk_gui_qt_stdmultiwidgeteditor_Activator.cpp @@ -1,38 +1,40 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "org_mitk_gui_qt_stdmultiwidgeteditor_Activator.h" #include "../QmitkStdMultiWidgetEditor.h" #include "QmitkStdMultiWidgetEditorPreferencePage.h" void org_mitk_gui_qt_stdmultiwidgeteditor_Activator::start(ctkPluginContext* context) { Q_UNUSED(context) BERRY_REGISTER_EXTENSION_CLASS(QmitkStdMultiWidgetEditor, context) BERRY_REGISTER_EXTENSION_CLASS(QmitkStdMultiWidgetEditorPreferencePage, context) } void org_mitk_gui_qt_stdmultiwidgeteditor_Activator::stop(ctkPluginContext* context) { Q_UNUSED(context) } -Q_EXPORT_PLUGIN2(org_mitk_gui_qt_stdmultiwidgeteditor, org_mitk_gui_qt_stdmultiwidgeteditor_Activator) +#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) + Q_EXPORT_PLUGIN2(org_mitk_gui_qt_stdmultiwidgeteditor, org_mitk_gui_qt_stdmultiwidgeteditor_Activator) +#endif diff --git a/Plugins/org.mitk.gui.qt.stdmultiwidgeteditor/src/internal/org_mitk_gui_qt_stdmultiwidgeteditor_Activator.h b/Plugins/org.mitk.gui.qt.stdmultiwidgeteditor/src/internal/org_mitk_gui_qt_stdmultiwidgeteditor_Activator.h index aa8c4f44f9..6ef85778a0 100644 --- a/Plugins/org.mitk.gui.qt.stdmultiwidgeteditor/src/internal/org_mitk_gui_qt_stdmultiwidgeteditor_Activator.h +++ b/Plugins/org.mitk.gui.qt.stdmultiwidgeteditor/src/internal/org_mitk_gui_qt_stdmultiwidgeteditor_Activator.h @@ -1,39 +1,42 @@ /*=================================================================== 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 org_mitk_gui_qt_stdmultiwidgeteditor_Activator_H_ #define org_mitk_gui_qt_stdmultiwidgeteditor_Activator_H_ #include /** * \ingroup org_mitk_gui_qt_stdmultiwidgeteditor */ class org_mitk_gui_qt_stdmultiwidgeteditor_Activator : public QObject, public ctkPluginActivator { Q_OBJECT +#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) + Q_PLUGIN_METADATA(IID "org_mitk_gui_qt_stdmultiwidgeteditor") +#endif Q_INTERFACES(ctkPluginActivator) public: void start(ctkPluginContext* context); void stop(ctkPluginContext* context); }; #endif /* org_mitk_gui_qt_stdmultiwidgeteditor_Activator_H_ */ diff --git a/Plugins/org.mitk.gui.qt.toftutorial/src/internal/mitkPluginActivator.cpp b/Plugins/org.mitk.gui.qt.toftutorial/src/internal/mitkPluginActivator.cpp index d6162b8a10..a0f199e44d 100644 --- a/Plugins/org.mitk.gui.qt.toftutorial/src/internal/mitkPluginActivator.cpp +++ b/Plugins/org.mitk.gui.qt.toftutorial/src/internal/mitkPluginActivator.cpp @@ -1,35 +1,37 @@ /*=================================================================== 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 "mitkPluginActivator.h" #include #include "QmitkToFTutorialView.h" namespace mitk { void PluginActivator::start(ctkPluginContext* context) { BERRY_REGISTER_EXTENSION_CLASS(QmitkToFTutorialView, context) } void PluginActivator::stop(ctkPluginContext* context) { Q_UNUSED(context) } } -Q_EXPORT_PLUGIN2(org_mitk_gui_qt_toftutorial, mitk::PluginActivator) +#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) + Q_EXPORT_PLUGIN2(org_mitk_gui_qt_toftutorial, mitk::PluginActivator) +#endif diff --git a/Plugins/org.mitk.gui.qt.toftutorial/src/internal/mitkPluginActivator.h b/Plugins/org.mitk.gui.qt.toftutorial/src/internal/mitkPluginActivator.h index 489bd853ca..03aa373134 100644 --- a/Plugins/org.mitk.gui.qt.toftutorial/src/internal/mitkPluginActivator.h +++ b/Plugins/org.mitk.gui.qt.toftutorial/src/internal/mitkPluginActivator.h @@ -1,40 +1,43 @@ /*=================================================================== 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 MITKPLUGINACTIVATOR_H #define MITKPLUGINACTIVATOR_H #include #include namespace mitk { class MITK_LOCAL PluginActivator : public QObject, public ctkPluginActivator { Q_OBJECT +#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) + Q_PLUGIN_METADATA(IID "org_mitk_gui_qt_toftutorial") +#endif Q_INTERFACES(ctkPluginActivator) public: void start(ctkPluginContext* context); void stop(ctkPluginContext* context); }; // PluginActivator } #endif // MITKPLUGINACTIVATOR_H diff --git a/Plugins/org.mitk.gui.qt.tofutil/src/internal/mitkPluginActivator.cpp b/Plugins/org.mitk.gui.qt.tofutil/src/internal/mitkPluginActivator.cpp index 5a4c6d5d7e..547829cbea 100644 --- a/Plugins/org.mitk.gui.qt.tofutil/src/internal/mitkPluginActivator.cpp +++ b/Plugins/org.mitk.gui.qt.tofutil/src/internal/mitkPluginActivator.cpp @@ -1,37 +1,39 @@ /*=================================================================== 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 "mitkPluginActivator.h" #include #include "QmitkToFUtilView.h" #include "QmitkToFDeviceGeneration.h" namespace mitk { void PluginActivator::start(ctkPluginContext* context) { BERRY_REGISTER_EXTENSION_CLASS(QmitkToFUtilView, context) BERRY_REGISTER_EXTENSION_CLASS(QmitkToFDeviceGeneration, context) } void PluginActivator::stop(ctkPluginContext* context) { Q_UNUSED(context) } } -Q_EXPORT_PLUGIN2(org_mitk_gui_qt_tofutil, mitk::PluginActivator) +#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) + Q_EXPORT_PLUGIN2(org_mitk_gui_qt_tofutil, mitk::PluginActivator) +#endif diff --git a/Plugins/org.mitk.gui.qt.tofutil/src/internal/mitkPluginActivator.h b/Plugins/org.mitk.gui.qt.tofutil/src/internal/mitkPluginActivator.h index 489bd853ca..c1daf6b9f3 100644 --- a/Plugins/org.mitk.gui.qt.tofutil/src/internal/mitkPluginActivator.h +++ b/Plugins/org.mitk.gui.qt.tofutil/src/internal/mitkPluginActivator.h @@ -1,40 +1,43 @@ /*=================================================================== 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 MITKPLUGINACTIVATOR_H #define MITKPLUGINACTIVATOR_H #include #include namespace mitk { class MITK_LOCAL PluginActivator : public QObject, public ctkPluginActivator { Q_OBJECT +#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) + Q_PLUGIN_METADATA(IID "org_mitk_gui_qt_tofutil") +#endif Q_INTERFACES(ctkPluginActivator) public: void start(ctkPluginContext* context); void stop(ctkPluginContext* context); }; // PluginActivator } #endif // MITKPLUGINACTIVATOR_H diff --git a/Plugins/org.mitk.gui.qt.ugvisualization/src/internal/mitkPluginActivator.cpp b/Plugins/org.mitk.gui.qt.ugvisualization/src/internal/mitkPluginActivator.cpp index 763d7135fc..a0ede4b27a 100644 --- a/Plugins/org.mitk.gui.qt.ugvisualization/src/internal/mitkPluginActivator.cpp +++ b/Plugins/org.mitk.gui.qt.ugvisualization/src/internal/mitkPluginActivator.cpp @@ -1,36 +1,38 @@ /*=================================================================== 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 "mitkPluginActivator.h" #include #include "QmitkUGVisualizationView.h" namespace mitk { void PluginActivator::start(ctkPluginContext* context) { BERRY_REGISTER_EXTENSION_CLASS(QmitkUGVisualizationView, context) } void PluginActivator::stop(ctkPluginContext* context) { Q_UNUSED(context) } } -Q_EXPORT_PLUGIN2(org_mitk_gui_qt_ugvisualization, mitk::PluginActivator) +#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) + Q_EXPORT_PLUGIN2(org_mitk_gui_qt_ugvisualization, mitk::PluginActivator) +#endif diff --git a/Plugins/org.mitk.gui.qt.ugvisualization/src/internal/mitkPluginActivator.h b/Plugins/org.mitk.gui.qt.ugvisualization/src/internal/mitkPluginActivator.h index 489bd853ca..4761cacfa1 100644 --- a/Plugins/org.mitk.gui.qt.ugvisualization/src/internal/mitkPluginActivator.h +++ b/Plugins/org.mitk.gui.qt.ugvisualization/src/internal/mitkPluginActivator.h @@ -1,40 +1,43 @@ /*=================================================================== 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 MITKPLUGINACTIVATOR_H #define MITKPLUGINACTIVATOR_H #include #include namespace mitk { class MITK_LOCAL PluginActivator : public QObject, public ctkPluginActivator { Q_OBJECT +#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) + Q_PLUGIN_METADATA(IID "org_mitk_gui_qt_ugvisualization") +#endif Q_INTERFACES(ctkPluginActivator) public: void start(ctkPluginContext* context); void stop(ctkPluginContext* context); }; // PluginActivator } #endif // MITKPLUGINACTIVATOR_H diff --git a/Plugins/org.mitk.gui.qt.ultrasound/src/internal/org_mitk_gui_qt_ultrasound_Activator.cpp b/Plugins/org.mitk.gui.qt.ultrasound/src/internal/org_mitk_gui_qt_ultrasound_Activator.cpp index ef25db43db..04b614a8aa 100644 --- a/Plugins/org.mitk.gui.qt.ultrasound/src/internal/org_mitk_gui_qt_ultrasound_Activator.cpp +++ b/Plugins/org.mitk.gui.qt.ultrasound/src/internal/org_mitk_gui_qt_ultrasound_Activator.cpp @@ -1,49 +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. ===================================================================*/ #include "org_mitk_gui_qt_ultrasound_Activator.h" #include #include "UltrasoundSupport.h" namespace mitk { ctkPluginContext* org_mitk_gui_qt_ultrasound_Activator::m_Context = 0; void org_mitk_gui_qt_ultrasound_Activator::start(ctkPluginContext* context) { m_Context = context; BERRY_REGISTER_EXTENSION_CLASS(UltrasoundSupport, context) } void org_mitk_gui_qt_ultrasound_Activator::stop(ctkPluginContext* context) { m_Context = 0; Q_UNUSED(context) } ctkPluginContext *org_mitk_gui_qt_ultrasound_Activator::GetContext() { return m_Context; } } -Q_EXPORT_PLUGIN2(org_mitk_gui_qt_ultrasound, mitk::org_mitk_gui_qt_ultrasound_Activator) +#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) + Q_EXPORT_PLUGIN2(org_mitk_gui_qt_ultrasound, mitk::org_mitk_gui_qt_ultrasound_Activator) +#endif diff --git a/Plugins/org.mitk.gui.qt.ultrasound/src/internal/org_mitk_gui_qt_ultrasound_Activator.h b/Plugins/org.mitk.gui.qt.ultrasound/src/internal/org_mitk_gui_qt_ultrasound_Activator.h index c34cbc0eda..54e46694f6 100644 --- a/Plugins/org.mitk.gui.qt.ultrasound/src/internal/org_mitk_gui_qt_ultrasound_Activator.h +++ b/Plugins/org.mitk.gui.qt.ultrasound/src/internal/org_mitk_gui_qt_ultrasound_Activator.h @@ -1,47 +1,50 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #ifndef org_mitk_gui_qt_ultrasound_Activator_h #define org_mitk_gui_qt_ultrasound_Activator_h #include namespace mitk { class org_mitk_gui_qt_ultrasound_Activator : public QObject, public ctkPluginActivator { Q_OBJECT +#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) + Q_PLUGIN_METADATA(IID "org_mitk_gui_qt_ultrasound") +#endif Q_INTERFACES(ctkPluginActivator) public: void start(ctkPluginContext* context); void stop(ctkPluginContext* context); static ctkPluginContext* GetContext(); private: static ctkPluginContext* m_Context; }; // org_mitk_gui_qt_ultrasound_Activator typedef org_mitk_gui_qt_ultrasound_Activator PluginActivator; } #endif // org_mitk_gui_qt_ultrasound_Activator_h diff --git a/Plugins/org.mitk.gui.qt.viewnavigator/src/internal/org_mitk_gui_qt_viewnavigator_Activator.cpp b/Plugins/org.mitk.gui.qt.viewnavigator/src/internal/org_mitk_gui_qt_viewnavigator_Activator.cpp index 50a638f6f0..d4dfcaa33e 100644 --- a/Plugins/org.mitk.gui.qt.viewnavigator/src/internal/org_mitk_gui_qt_viewnavigator_Activator.cpp +++ b/Plugins/org.mitk.gui.qt.viewnavigator/src/internal/org_mitk_gui_qt_viewnavigator_Activator.cpp @@ -1,38 +1,40 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "org_mitk_gui_qt_viewnavigator_Activator.h" #include #include "ViewNavigatorView.h" namespace mitk { void org_mitk_gui_qt_viewnavigator_Activator::start(ctkPluginContext* context) { BERRY_REGISTER_EXTENSION_CLASS(ViewNavigatorView, context) } void org_mitk_gui_qt_viewnavigator_Activator::stop(ctkPluginContext* context) { Q_UNUSED(context) } } -Q_EXPORT_PLUGIN2(org_mitk_gui_qt_viewnavigator, mitk::org_mitk_gui_qt_viewnavigator_Activator) +#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) + Q_EXPORT_PLUGIN2(org_mitk_gui_qt_viewnavigator, mitk::org_mitk_gui_qt_viewnavigator_Activator) +#endif diff --git a/Plugins/org.mitk.gui.qt.viewnavigator/src/internal/org_mitk_gui_qt_viewnavigator_Activator.h b/Plugins/org.mitk.gui.qt.viewnavigator/src/internal/org_mitk_gui_qt_viewnavigator_Activator.h index 67ebc8166a..8f0d1acc9a 100644 --- a/Plugins/org.mitk.gui.qt.viewnavigator/src/internal/org_mitk_gui_qt_viewnavigator_Activator.h +++ b/Plugins/org.mitk.gui.qt.viewnavigator/src/internal/org_mitk_gui_qt_viewnavigator_Activator.h @@ -1,40 +1,43 @@ /*=================================================================== 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 org_mitk_gui_qt_viewnavigator_Activator_h #define org_mitk_gui_qt_viewnavigator_Activator_h #include namespace mitk { class org_mitk_gui_qt_viewnavigator_Activator : public QObject, public ctkPluginActivator { Q_OBJECT +#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) + Q_PLUGIN_METADATA(IID "org_mitk_gui_qt_viewnavigator") +#endif Q_INTERFACES(ctkPluginActivator) public: void start(ctkPluginContext* context); void stop(ctkPluginContext* context); }; // org_mitk_gui_qt_viewnavigator_Activator } #endif // org_mitk_gui_qt_viewnavigator_Activator_h diff --git a/Plugins/org.mitk.gui.qt.volumevisualization/src/internal/QmitkVolumeVisualizationView.cpp b/Plugins/org.mitk.gui.qt.volumevisualization/src/internal/QmitkVolumeVisualizationView.cpp index 3fd2a7b691..e7ae864f41 100755 --- a/Plugins/org.mitk.gui.qt.volumevisualization/src/internal/QmitkVolumeVisualizationView.cpp +++ b/Plugins/org.mitk.gui.qt.volumevisualization/src/internal/QmitkVolumeVisualizationView.cpp @@ -1,351 +1,348 @@ /*=================================================================== 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 "QmitkVolumeVisualizationView.h" #include #include #include #include //#include #include #include #include #include #include #include #include "mitkHistogramGenerator.h" #include "QmitkPiecewiseFunctionCanvas.h" #include "QmitkColorTransferFunctionCanvas.h" #include "mitkBaseRenderer.h" #include "mitkVtkVolumeRenderingProperty.h" #include #include -#include const std::string QmitkVolumeVisualizationView::VIEW_ID = "org.mitk.views.volumevisualization"; enum RenderMode { RM_CPU_COMPOSITE_RAYCAST = 0, RM_CPU_MIP_RAYCAST = 1, RM_GPU_COMPOSITE_SLICING = 2, RM_GPU_COMPOSITE_RAYCAST = 3, RM_GPU_MIP_RAYCAST = 4 }; QmitkVolumeVisualizationView::QmitkVolumeVisualizationView() : QmitkAbstractView(), m_Controls(NULL) { } QmitkVolumeVisualizationView::~QmitkVolumeVisualizationView() { } void QmitkVolumeVisualizationView::CreateQtPartControl(QWidget* parent) { if (!m_Controls) { m_Controls = new Ui::QmitkVolumeVisualizationViewControls; m_Controls->setupUi(parent); - m_Controls->m_TransferFunctionWidget->SetIntegerMode(true); - // Fill the tf presets in the generator widget std::vector names; mitk::TransferFunctionInitializer::GetPresetNames(names); for (std::vector::const_iterator it = names.begin(); it != names.end(); ++it) { m_Controls->m_TransferFunctionGeneratorWidget->AddPreset(QString::fromStdString(*it)); } m_Controls->m_RenderMode->addItem("CPU raycast"); m_Controls->m_RenderMode->addItem("CPU MIP raycast"); m_Controls->m_RenderMode->addItem("GPU slicing"); // Only with VTK 5.6 or above #if ((VTK_MAJOR_VERSION > 5) || ((VTK_MAJOR_VERSION==5) && (VTK_MINOR_VERSION>=6) )) m_Controls->m_RenderMode->addItem("GPU raycast"); m_Controls->m_RenderMode->addItem("GPU MIP raycast"); #endif connect( m_Controls->m_EnableRenderingCB, SIGNAL( toggled(bool) ),this, SLOT( OnEnableRendering(bool) )); connect( m_Controls->m_EnableLOD, SIGNAL( toggled(bool) ),this, SLOT( OnEnableLOD(bool) )); connect( m_Controls->m_RenderMode, SIGNAL( activated(int) ),this, SLOT( OnRenderMode(int) )); connect( m_Controls->m_TransferFunctionGeneratorWidget, SIGNAL( SignalUpdateCanvas( ) ), m_Controls->m_TransferFunctionWidget, SLOT( OnUpdateCanvas( ) ) ); connect( m_Controls->m_TransferFunctionGeneratorWidget, SIGNAL(SignalTransferFunctionModeChanged(int)), SLOT(OnMitkInternalPreset(int))); m_Controls->m_EnableRenderingCB->setEnabled(false); m_Controls->m_EnableLOD->setEnabled(false); m_Controls->m_RenderMode->setEnabled(false); m_Controls->m_TransferFunctionWidget->setEnabled(false); m_Controls->m_TransferFunctionGeneratorWidget->setEnabled(false); m_Controls->m_SelectedImageLabel->hide(); m_Controls->m_ErrorImageLabel->hide(); } } void QmitkVolumeVisualizationView::OnMitkInternalPreset( int mode ) { if (m_SelectedNode.IsNull()) return; mitk::DataNode::Pointer node(m_SelectedNode.GetPointer()); mitk::TransferFunctionProperty::Pointer transferFuncProp; if (node->GetProperty(transferFuncProp, "TransferFunction")) { //first item is only information if( --mode == -1 ) return; // -- Creat new TransferFunction mitk::TransferFunctionInitializer::Pointer tfInit = mitk::TransferFunctionInitializer::New(transferFuncProp->GetValue()); tfInit->SetTransferFunctionMode(mode); this->GetRenderWindowPart()->GetRenderingManager()->RequestUpdateAll(); m_Controls->m_TransferFunctionWidget->OnUpdateCanvas(); } } void QmitkVolumeVisualizationView::OnSelectionChanged(berry::IWorkbenchPart::Pointer /*part*/, const QList& nodes) { bool weHadAnImageButItsNotThreeDeeOrFourDee = false; mitk::DataNode::Pointer node; foreach (mitk::DataNode::Pointer currentNode, nodes) { if( currentNode.IsNotNull() && dynamic_cast(currentNode->GetData()) ) { if( dynamic_cast(currentNode->GetData())->GetDimension()>=3 ) { if (node.IsNull()) { node = currentNode; } } else { weHadAnImageButItsNotThreeDeeOrFourDee = true; } } } if( node.IsNotNull() ) { m_Controls->m_NoSelectedImageLabel->hide(); m_Controls->m_ErrorImageLabel->hide(); m_Controls->m_SelectedImageLabel->show(); std::string infoText; if (node->GetName().empty()) infoText = std::string("Selected Image: [currently selected image has no name]"); else infoText = std::string("Selected Image: ") + node->GetName(); m_Controls->m_SelectedImageLabel->setText( QString( infoText.c_str() ) ); m_SelectedNode = node; } else { if(weHadAnImageButItsNotThreeDeeOrFourDee) { m_Controls->m_NoSelectedImageLabel->hide(); m_Controls->m_ErrorImageLabel->show(); std::string infoText; infoText = std::string("only 3D or 4D images are supported"); m_Controls->m_ErrorImageLabel->setText( QString( infoText.c_str() ) ); } else { m_Controls->m_SelectedImageLabel->hide(); m_Controls->m_ErrorImageLabel->hide(); m_Controls->m_NoSelectedImageLabel->show(); } m_SelectedNode = 0; } UpdateInterface(); } void QmitkVolumeVisualizationView::UpdateInterface() { if(m_SelectedNode.IsNull()) { // turnoff all m_Controls->m_EnableRenderingCB->setChecked(false); m_Controls->m_EnableRenderingCB->setEnabled(false); m_Controls->m_EnableLOD->setChecked(false); m_Controls->m_EnableLOD->setEnabled(false); m_Controls->m_RenderMode->setCurrentIndex(0); m_Controls->m_RenderMode->setEnabled(false); m_Controls->m_TransferFunctionWidget->SetDataNode(0); m_Controls->m_TransferFunctionWidget->setEnabled(false); m_Controls->m_TransferFunctionGeneratorWidget->SetDataNode(0); m_Controls->m_TransferFunctionGeneratorWidget->setEnabled(false); return; } bool enabled = false; m_SelectedNode->GetBoolProperty("volumerendering",enabled); m_Controls->m_EnableRenderingCB->setEnabled(true); m_Controls->m_EnableRenderingCB->setChecked(enabled); if(!enabled) { // turnoff all except volumerendering checkbox m_Controls->m_EnableLOD->setChecked(false); m_Controls->m_EnableLOD->setEnabled(false); m_Controls->m_RenderMode->setCurrentIndex(0); m_Controls->m_RenderMode->setEnabled(false); m_Controls->m_TransferFunctionWidget->SetDataNode(0); m_Controls->m_TransferFunctionWidget->setEnabled(false); m_Controls->m_TransferFunctionGeneratorWidget->SetDataNode(0); m_Controls->m_TransferFunctionGeneratorWidget->setEnabled(false); return; } // otherwise we can activate em all enabled = false; m_SelectedNode->GetBoolProperty("volumerendering.uselod",enabled); m_Controls->m_EnableLOD->setEnabled(true); m_Controls->m_EnableLOD->setChecked(enabled); m_Controls->m_RenderMode->setEnabled(true); // Determine Combo Box mode { bool usegpu=false; bool useray=false; bool usemip=false; m_SelectedNode->GetBoolProperty("volumerendering.usegpu",usegpu); // Only with VTK 5.6 or above #if ((VTK_MAJOR_VERSION > 5) || ((VTK_MAJOR_VERSION==5) && (VTK_MINOR_VERSION>=6) )) m_SelectedNode->GetBoolProperty("volumerendering.useray",useray); #endif m_SelectedNode->GetBoolProperty("volumerendering.usemip",usemip); int mode = 0; if(useray) { if(usemip) mode=RM_GPU_MIP_RAYCAST; else mode=RM_GPU_COMPOSITE_RAYCAST; } else if(usegpu) mode=RM_GPU_COMPOSITE_SLICING; else { if(usemip) mode=RM_CPU_MIP_RAYCAST; else mode=RM_CPU_COMPOSITE_RAYCAST; } m_Controls->m_RenderMode->setCurrentIndex(mode); } m_Controls->m_TransferFunctionWidget->SetDataNode(m_SelectedNode); m_Controls->m_TransferFunctionWidget->setEnabled(true); m_Controls->m_TransferFunctionGeneratorWidget->SetDataNode(m_SelectedNode); m_Controls->m_TransferFunctionGeneratorWidget->setEnabled(true); } void QmitkVolumeVisualizationView::OnEnableRendering(bool state) { if(m_SelectedNode.IsNull()) return; m_SelectedNode->SetProperty("volumerendering",mitk::BoolProperty::New(state)); UpdateInterface(); this->GetRenderWindowPart()->GetRenderingManager()->RequestUpdateAll(); } void QmitkVolumeVisualizationView::OnEnableLOD(bool state) { if(m_SelectedNode.IsNull()) return; m_SelectedNode->SetProperty("volumerendering.uselod",mitk::BoolProperty::New(state)); this->GetRenderWindowPart()->GetRenderingManager()->RequestUpdateAll(); } void QmitkVolumeVisualizationView::OnRenderMode(int mode) { if(m_SelectedNode.IsNull()) return; bool usegpu=mode==RM_GPU_COMPOSITE_SLICING; // Only with VTK 5.6 or above #if ((VTK_MAJOR_VERSION > 5) || ((VTK_MAJOR_VERSION==5) && (VTK_MINOR_VERSION>=6) )) bool useray=(mode==RM_GPU_COMPOSITE_RAYCAST)||(mode==RM_GPU_MIP_RAYCAST); #endif bool usemip=(mode==RM_GPU_MIP_RAYCAST)||(mode==RM_CPU_MIP_RAYCAST); m_SelectedNode->SetProperty("volumerendering.usegpu",mitk::BoolProperty::New(usegpu)); // Only with VTK 5.6 or above #if ((VTK_MAJOR_VERSION > 5) || ((VTK_MAJOR_VERSION==5) && (VTK_MINOR_VERSION>=6) )) m_SelectedNode->SetProperty("volumerendering.useray",mitk::BoolProperty::New(useray)); #endif m_SelectedNode->SetProperty("volumerendering.usemip",mitk::BoolProperty::New(usemip)); this->GetRenderWindowPart()->GetRenderingManager()->RequestUpdateAll(); } void QmitkVolumeVisualizationView::SetFocus() { } void QmitkVolumeVisualizationView::NodeRemoved(const mitk::DataNode* node) { if(m_SelectedNode == node) { m_SelectedNode=0; m_Controls->m_SelectedImageLabel->hide(); m_Controls->m_ErrorImageLabel->hide(); m_Controls->m_NoSelectedImageLabel->show(); UpdateInterface(); } } diff --git a/Plugins/org.mitk.gui.qt.volumevisualization/src/internal/mitkPluginActivator.cpp b/Plugins/org.mitk.gui.qt.volumevisualization/src/internal/mitkPluginActivator.cpp index 4849b6a992..e7f3775b4d 100644 --- a/Plugins/org.mitk.gui.qt.volumevisualization/src/internal/mitkPluginActivator.cpp +++ b/Plugins/org.mitk.gui.qt.volumevisualization/src/internal/mitkPluginActivator.cpp @@ -1,36 +1,38 @@ /*=================================================================== 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 "mitkPluginActivator.h" #include #include "QmitkVolumeVisualizationView.h" namespace mitk { void PluginActivator::start(ctkPluginContext* context) { BERRY_REGISTER_EXTENSION_CLASS(QmitkVolumeVisualizationView, context) } void PluginActivator::stop(ctkPluginContext* context) { Q_UNUSED(context) } } -Q_EXPORT_PLUGIN2(org_mitk_gui_qt_volumevisualization, mitk::PluginActivator) +#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) + Q_EXPORT_PLUGIN2(org_mitk_gui_qt_volumevisualization, mitk::PluginActivator) +#endif diff --git a/Plugins/org.mitk.gui.qt.volumevisualization/src/internal/mitkPluginActivator.h b/Plugins/org.mitk.gui.qt.volumevisualization/src/internal/mitkPluginActivator.h index 12053e09e3..624ff6e49e 100644 --- a/Plugins/org.mitk.gui.qt.volumevisualization/src/internal/mitkPluginActivator.h +++ b/Plugins/org.mitk.gui.qt.volumevisualization/src/internal/mitkPluginActivator.h @@ -1,39 +1,42 @@ /*=================================================================== 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 MITKPLUGINACTIVATOR_H #define MITKPLUGINACTIVATOR_H #include #include namespace mitk { class MITK_LOCAL PluginActivator : public QObject, public ctkPluginActivator { Q_OBJECT +#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) + Q_PLUGIN_METADATA(IID "org_mitk_gui_qt_volumevisualization") +#endif Q_INTERFACES(ctkPluginActivator) public: void start(ctkPluginContext* context); void stop(ctkPluginContext* context); }; // PluginActivator } #endif // MITKPLUGINACTIVATOR_H diff --git a/Plugins/org.mitk.gui.qt.xnat/src/internal/org_mitk_gui_qt_xnatinterface_Activator.cpp b/Plugins/org.mitk.gui.qt.xnat/src/internal/org_mitk_gui_qt_xnatinterface_Activator.cpp index 8996a9fa3e..989e9a3bf6 100644 --- a/Plugins/org.mitk.gui.qt.xnat/src/internal/org_mitk_gui_qt_xnatinterface_Activator.cpp +++ b/Plugins/org.mitk.gui.qt.xnat/src/internal/org_mitk_gui_qt_xnatinterface_Activator.cpp @@ -1,71 +1,73 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "org_mitk_gui_qt_xnatinterface_Activator.h" #include #include "QmitkXnatEditor.h" #include "QmitkXnatTreeBrowserView.h" #include "QmitkXnatConnectionPreferencePage.h" #include #include US_INITIALIZE_MODULE namespace mitk { ctkPluginContext* org_mitk_gui_qt_xnatinterface_Activator::m_Context = 0; us::ModuleContext* org_mitk_gui_qt_xnatinterface_Activator::m_ModuleContext = 0; QmitkXnatSessionManager* org_mitk_gui_qt_xnatinterface_Activator::GetXnatSessionManager() { static QmitkXnatSessionManager manager; return &manager; } ctkPluginContext* org_mitk_gui_qt_xnatinterface_Activator::GetContext() { return m_Context; } us::ModuleContext* org_mitk_gui_qt_xnatinterface_Activator::GetXnatModuleContext() { return m_ModuleContext; } void org_mitk_gui_qt_xnatinterface_Activator::start(ctkPluginContext* context) { this->m_Context = context; this->m_ModuleContext = us::GetModuleContext(); BERRY_REGISTER_EXTENSION_CLASS(QmitkXnatEditor, context) BERRY_REGISTER_EXTENSION_CLASS(QmitkXnatTreeBrowserView, context) BERRY_REGISTER_EXTENSION_CLASS(QmitkXnatConnectionPreferencePage, context) } void org_mitk_gui_qt_xnatinterface_Activator::stop(ctkPluginContext* context) { Q_UNUSED(context) Q_UNUSED(us::GetModuleContext()) this->m_Context = 0; this->m_ModuleContext = 0; } } -Q_EXPORT_PLUGIN2(org_mitk_gui_qt_xnatinterface, mitk::org_mitk_gui_qt_xnatinterface_Activator) +#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) + Q_EXPORT_PLUGIN2(org_mitk_gui_qt_xnatinterface, mitk::org_mitk_gui_qt_xnatinterface_Activator) +#endif diff --git a/Plugins/org.mitk.gui.qt.xnat/src/internal/org_mitk_gui_qt_xnatinterface_Activator.h b/Plugins/org.mitk.gui.qt.xnat/src/internal/org_mitk_gui_qt_xnatinterface_Activator.h index 29b284430c..3e8a712cbe 100644 --- a/Plugins/org.mitk.gui.qt.xnat/src/internal/org_mitk_gui_qt_xnatinterface_Activator.h +++ b/Plugins/org.mitk.gui.qt.xnat/src/internal/org_mitk_gui_qt_xnatinterface_Activator.h @@ -1,50 +1,53 @@ /*=================================================================== 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 org_mitk_gui_qt_xnatinterface_Activator_h #define org_mitk_gui_qt_xnatinterface_Activator_h #include #include "QmitkXnatSessionManager.h" namespace mitk { class org_mitk_gui_qt_xnatinterface_Activator : public QObject, public ctkPluginActivator { Q_OBJECT +#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) + Q_PLUGIN_METADATA(IID "org_mitk_gui_qt_xnatinterface") +#endif Q_INTERFACES(ctkPluginActivator) public: static QmitkXnatSessionManager* GetXnatSessionManager(); static ctkPluginContext* GetContext(); static us::ModuleContext* GetXnatModuleContext(); void start(ctkPluginContext* context); void stop(ctkPluginContext* context); private: static ctkPluginContext* m_Context; static us::ModuleContext* m_ModuleContext; }; // org_mitk_gui_qt_xnatinterface_Activator } #endif // org_mitk_gui_qt_xnatinterface_Activator_h diff --git a/Plugins/org.mitk.planarfigure/src/internal/mitkPlanarFigureActivator.cpp b/Plugins/org.mitk.planarfigure/src/internal/mitkPlanarFigureActivator.cpp index 5cb9e6022d..10486ec012 100644 --- a/Plugins/org.mitk.planarfigure/src/internal/mitkPlanarFigureActivator.cpp +++ b/Plugins/org.mitk.planarfigure/src/internal/mitkPlanarFigureActivator.cpp @@ -1,83 +1,85 @@ /*=================================================================== 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 "mitkPlanarFigureActivator.h" #include "mitkPlanarFigureObjectFactory.h" #include "QmitkNodeDescriptorManager.h" #include "mitkNodePredicateDataType.h" #include "mitkNodePredicateProperty.h" #include "mitkNodePredicateAnd.h" #include void mitk::PlanarFigureActivator::start(ctkPluginContext* /*context*/) { QmitkNodeDescriptorManager* descriptorManager = QmitkNodeDescriptorManager::GetInstance(); // Adding "PlanarLine" mitk::NodePredicateDataType::Pointer isPlanarLine = mitk::NodePredicateDataType::New("PlanarLine"); descriptorManager->AddDescriptor(new QmitkNodeDescriptor(QObject::tr("PlanarLine"), QString(":/QtWidgetsExt/PlanarLine_48.png"), isPlanarLine, descriptorManager)); // Adding "PlanarCircle" mitk::NodePredicateDataType::Pointer isPlanarCircle = mitk::NodePredicateDataType::New("PlanarCircle"); descriptorManager->AddDescriptor(new QmitkNodeDescriptor(QObject::tr("PlanarCircle"), QString(":/QtWidgetsExt/PlanarCircle_48.png"), isPlanarCircle, descriptorManager)); // Adding "PlanarEllipse" mitk::NodePredicateDataType::Pointer isPlanarEllipse = mitk::NodePredicateDataType::New("PlanarEllipse"); descriptorManager->AddDescriptor(new QmitkNodeDescriptor(QObject::tr("PlanarEllipse"), QString(":/QtWidgetsExt/PlanarEllipse_48.png"), isPlanarEllipse, descriptorManager)); // Adding "PlanarAngle" mitk::NodePredicateDataType::Pointer isPlanarAngle = mitk::NodePredicateDataType::New("PlanarAngle"); descriptorManager->AddDescriptor(new QmitkNodeDescriptor(QObject::tr("PlanarAngle"), QString(":/QtWidgetsExt/PlanarAngle_48.png"), isPlanarAngle, descriptorManager)); // Adding "PlanarFourPointAngle" mitk::NodePredicateDataType::Pointer isPlanarFourPointAngle = mitk::NodePredicateDataType::New("PlanarFourPointAngle"); descriptorManager->AddDescriptor(new QmitkNodeDescriptor(QObject::tr("PlanarFourPointAngle"), QString(":/QtWidgetsExt/PlanarFourPointAngle_48.png"), isPlanarFourPointAngle, descriptorManager)); // Adding "PlanarRectangle" mitk::NodePredicateDataType::Pointer isPlanarRectangle = mitk::NodePredicateDataType::New("PlanarRectangle"); descriptorManager->AddDescriptor(new QmitkNodeDescriptor(QObject::tr("PlanarRectangle"), QString(":/QtWidgetsExt/PlanarRectangle_48.png"), isPlanarRectangle, descriptorManager)); // Adding "PlanarPolygon" mitk::NodePredicateDataType::Pointer isPlanarPolygon = mitk::NodePredicateDataType::New("PlanarPolygon"); descriptorManager->AddDescriptor(new QmitkNodeDescriptor(QObject::tr("PlanarPolygon"), QString(":/QtWidgetsExt/PlanarPolygon_48.png"), isPlanarPolygon, descriptorManager)); // Adding "PlanarPath" mitk::NodePredicateProperty::Pointer isNotClosedPolygon = mitk::NodePredicateProperty::New("ClosedPlanarPolygon", mitk::BoolProperty::New(false)); mitk::NodePredicateAnd::Pointer isPlanarPath = mitk::NodePredicateAnd::New(isNotClosedPolygon, isPlanarPolygon); descriptorManager->AddDescriptor(new QmitkNodeDescriptor(QObject::tr("PlanarPath"), QString(":/QtWidgetsExt/PlanarPath_48.png"), isPlanarPath, descriptorManager)); // Adding "PlanarDoubleEllipse" mitk::NodePredicateDataType::Pointer isPlanarDoubleEllipse = mitk::NodePredicateDataType::New("PlanarDoubleEllipse"); descriptorManager->AddDescriptor(new QmitkNodeDescriptor("PlanarDoubleEllipse", ":/QtWidgetsExt/PlanarDoubleEllipse_48.png", isPlanarDoubleEllipse, descriptorManager)); // Adding "PlanarBezierCurve" mitk::NodePredicateDataType::Pointer isPlanarBezierCurve = mitk::NodePredicateDataType::New("PlanarBezierCurve"); descriptorManager->AddDescriptor(new QmitkNodeDescriptor("PlanarBezierCurve", ":/QtWidgetsExt/PlanarBezierCurve_48.png", isPlanarBezierCurve, descriptorManager)); // Adding "PlanarSubdivisionPolygon" mitk::NodePredicateDataType::Pointer isPlanarSubdivisionPolygon = mitk::NodePredicateDataType::New("PlanarSubdivisionPolygon"); descriptorManager->AddDescriptor(new QmitkNodeDescriptor("PlanarSubdivisionPolygon", ":/QtWidgetsExt/PlanarSubdivisionPolygon_48.png", isPlanarSubdivisionPolygon, descriptorManager)); } void mitk::PlanarFigureActivator::stop(ctkPluginContext* /*context*/) { } -Q_EXPORT_PLUGIN2(org_mitk_planarfigure, mitk::PlanarFigureActivator) +#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) + Q_EXPORT_PLUGIN2(org_mitk_planarfigure, mitk::PlanarFigureActivator) +#endif diff --git a/Plugins/org.mitk.planarfigure/src/internal/mitkPlanarFigureActivator.h b/Plugins/org.mitk.planarfigure/src/internal/mitkPlanarFigureActivator.h index c45556bf3c..49605698e8 100644 --- a/Plugins/org.mitk.planarfigure/src/internal/mitkPlanarFigureActivator.h +++ b/Plugins/org.mitk.planarfigure/src/internal/mitkPlanarFigureActivator.h @@ -1,52 +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 MITKPLANARFIGUREACTIVATOR_H_ #define MITKPLANARFIGUREACTIVATOR_H_ #include namespace mitk { /** * \ingroup org_mitk_planarfigure_internal * * \brief The plug-in activator for the planar figure module * * When the plug-in is started by the framework, it initialzes planar figure specific things. */ class PlanarFigureActivator : public QObject, public ctkPluginActivator { Q_OBJECT +#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) + Q_PLUGIN_METADATA(IID "org_mitk_planarfigure") +#endif Q_INTERFACES(ctkPluginActivator) public: /** * Registers sandbox core object factories. */ void start(ctkPluginContext* context); void stop(ctkPluginContext* context); }; } #endif /* MITKPLANARFIGUREACTIVATOR_H_ */ diff --git a/Plugins/org.mitk.simulation/src/internal/org_mitk_simulation_Activator.cpp b/Plugins/org.mitk.simulation/src/internal/org_mitk_simulation_Activator.cpp index 90895d08ff..1d74aa9eaa 100644 --- a/Plugins/org.mitk.simulation/src/internal/org_mitk_simulation_Activator.cpp +++ b/Plugins/org.mitk.simulation/src/internal/org_mitk_simulation_Activator.cpp @@ -1,107 +1,109 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "org_mitk_simulation_Activator.h" #include #include #include #include #include #include #include #include #include #include static void RegisterSofaClasses() { int MeshMitkLoaderClass = sofa::core::RegisterObject("").add(); } static void LoadSofaPlugins() { berry::IPreferences::Pointer preferences = mitk::GetSimulationPreferences(); if (preferences.IsNull()) return; QString plugins = preferences->GetByteArray("plugins", "").c_str(); if (plugins.isEmpty()) return; QStringList pluginList = plugins.split(';', QString::SkipEmptyParts); QStringListIterator it(pluginList); typedef sofa::helper::system::PluginManager PluginManager; PluginManager& pluginManager = PluginManager::getInstance(); while (it.hasNext()) { std::string plugin = it.next().toStdString(); std::ostringstream errlog; pluginManager.loadPlugin(plugin, &errlog); if (errlog.str().empty()) pluginManager.getPluginMap()[plugin].initExternalModule(); } } static void AddPropertyFilters() { mitk::IPropertyFilters* filters = mitk::org_mitk_simulation_Activator::GetService(); if (filters == NULL) return; mitk::PropertyFilter filter; filter.AddEntry("layer", mitk::PropertyFilter::Blacklist); filter.AddEntry("name", mitk::PropertyFilter::Blacklist); filter.AddEntry("path", mitk::PropertyFilter::Blacklist); filter.AddEntry("selected", mitk::PropertyFilter::Blacklist); filter.AddEntry("visible", mitk::PropertyFilter::Blacklist); filters->AddFilter(filter, "Simulation"); } ctkPluginContext* mitk::org_mitk_simulation_Activator::Context = NULL; void mitk::org_mitk_simulation_Activator::start(ctkPluginContext* context) { Context = context; RegisterSimulationObjectFactory(); RegisterSofaClasses(); LoadSofaPlugins(); AddPropertyFilters(); QmitkNodeDescriptorManager* nodeDescriptorManager = QmitkNodeDescriptorManager::GetInstance(); if (nodeDescriptorManager != NULL) { mitk::NodePredicateDataType::Pointer simulationPredicate = mitk::NodePredicateDataType::New("Simulation"); nodeDescriptorManager->AddDescriptor(new QmitkNodeDescriptor("Simulation", ":/Simulation/SOFAIcon.png", simulationPredicate, nodeDescriptorManager)); } } void mitk::org_mitk_simulation_Activator::stop(ctkPluginContext*) { Context = NULL; } -Q_EXPORT_PLUGIN2(org_mitk_simulation, mitk::org_mitk_simulation_Activator); +#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) + Q_EXPORT_PLUGIN2(org_mitk_simulation, mitk::org_mitk_simulation_Activator) +#endif diff --git a/Plugins/org.mitk.simulation/src/internal/org_mitk_simulation_Activator.h b/Plugins/org.mitk.simulation/src/internal/org_mitk_simulation_Activator.h index dd1d1ef36c..723654d737 100644 --- a/Plugins/org.mitk.simulation/src/internal/org_mitk_simulation_Activator.h +++ b/Plugins/org.mitk.simulation/src/internal/org_mitk_simulation_Activator.h @@ -1,51 +1,54 @@ /*=================================================================== 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 org_mitk_simulation_Activator_h #define org_mitk_simulation_Activator_h #include namespace mitk { class org_mitk_simulation_Activator : public QObject, public ctkPluginActivator { Q_OBJECT +#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) + Q_PLUGIN_METADATA(IID "org_mitk_simulation") +#endif Q_INTERFACES(ctkPluginActivator); public: template static T* GetService() { if (Context == NULL) return NULL; ctkServiceReference serviceReference = Context->getServiceReference(); return serviceReference ? Context->getService(serviceReference) : NULL; } void start(ctkPluginContext* context); void stop(ctkPluginContext*); private: static ctkPluginContext* Context; }; } #endif diff --git a/SuperBuild.cmake b/SuperBuild.cmake index 35829cba9e..ae6252490d 100644 --- a/SuperBuild.cmake +++ b/SuperBuild.cmake @@ -1,489 +1,487 @@ #----------------------------------------------------------------------------- # Convenient macro allowing to download a file #----------------------------------------------------------------------------- macro(downloadFile url dest) file(DOWNLOAD ${url} ${dest} STATUS status) list(GET status 0 error_code) list(GET status 1 error_msg) if(error_code) message(FATAL_ERROR "error: Failed to download ${url} - ${error_msg}") endif() endmacro() #----------------------------------------------------------------------------- # MITK Prerequisites #----------------------------------------------------------------------------- if(UNIX AND NOT APPLE) include(mitkFunctionCheckPackageHeader) # Check for libxt-dev mitkFunctionCheckPackageHeader(StringDefs.h libxt-dev /usr/include/X11/) # Check for libtiff4-dev mitkFunctionCheckPackageHeader(tiff.h libtiff4-dev) # Check for libwrap0-dev mitkFunctionCheckPackageHeader(tcpd.h libwrap0-dev) endif() #----------------------------------------------------------------------------- # Qt options for external projects and MITK #----------------------------------------------------------------------------- if(MITK_USE_QT) set(qt_project_args -DDESIRED_QT_VERSION:STRING=${DESIRED_QT_VERSION}) else() set(qt_project_args ) endif() if(MITK_USE_Qt4) list(APPEND qt_project_args -DQT_QMAKE_EXECUTABLE:FILEPATH=${QT_QMAKE_EXECUTABLE} ) endif() #----------------------------------------------------------------------------- # ExternalProjects #----------------------------------------------------------------------------- set(external_projects ZLIB Python Numpy tinyxml GLUT ANN CppUnit GLEW VTK ACVD GDCM OpenCV Poco ITK Boost DCMTK CTK SOFA MITKData Qwt PCRE Swig SimpleITK Eigen ) -# Qxt supports Qt5. We need to also support it in QxtCMakeLists.txt -#if(MITK_USE_Qt4) - list(APPEND external_projects Qxt) -#endif() - # These are "hard" dependencies and always set to ON set(MITK_USE_tinyxml 1) set(MITK_USE_ANN 1) set(MITK_USE_Eigen 1) set(MITK_USE_GLEW 1) set(MITK_USE_GDCM 1) set(MITK_USE_ITK 1) set(MITK_USE_VTK 1) # Semi-hard dependencies, enabled by user-controlled variables if(MITK_USE_QT) set(MITK_USE_Qwt 1) - #if(MITK_USE_Qt4) - set(MITK_USE_Qxt 1) #TODO: Check how Qxt builds with Qt 5 - #endif() endif() if(MITK_USE_SOFA) set(MITK_USE_GLUT 1) endif() if(NOT MITK_USE_SYSTEM_PYTHON) set(MITK_USE_ZLIB 1) endif() if(MITK_USE_SimpleITK OR MITK_USE_Python) set(MITK_USE_SWIG 1) if(UNIX) set(MITK_USE_PCRE 1) endif() endif() # A list of "nice" external projects, playing well together with CMake set(nice_external_projects ${external_projects}) list(REMOVE_ITEM nice_external_projects Boost) foreach(proj ${nice_external_projects}) if(MITK_USE_${proj}) set(EXTERNAL_${proj}_DIR "${${proj}_DIR}" CACHE PATH "Path to ${proj} build directory") mark_as_advanced(EXTERNAL_${proj}_DIR) if(EXTERNAL_${proj}_DIR) set(${proj}_DIR ${EXTERNAL_${proj}_DIR}) endif() endif() endforeach() if(MITK_USE_Boost) set(EXTERNAL_BOOST_ROOT "${BOOST_ROOT}" CACHE PATH "Path to Boost directory") mark_as_advanced(EXTERNAL_BOOST_ROOT) if(EXTERNAL_BOOST_ROOT) set(BOOST_ROOT ${EXTERNAL_BOOST_ROOT}) endif() endif() # Setup file for setting custom ctest vars configure_file( CMake/SuperbuildCTestCustom.cmake.in ${MITK_BINARY_DIR}/CTestCustom.cmake @ONLY ) if(BUILD_TESTING) set(EXTERNAL_MITK_DATA_DIR "${MITK_DATA_DIR}" CACHE PATH "Path to the MITK data directory") mark_as_advanced(EXTERNAL_MITK_DATA_DIR) if(EXTERNAL_MITK_DATA_DIR) set(MITK_DATA_DIR ${EXTERNAL_MITK_DATA_DIR}) endif() endif() # Look for git early on, if needed if((BUILD_TESTING AND NOT EXTERNAL_MITK_DATA_DIR) OR (MITK_USE_CTK AND NOT EXTERNAL_CTK_DIR)) find_package(Git REQUIRED) endif() #----------------------------------------------------------------------------- # External project settings #----------------------------------------------------------------------------- include(ExternalProject) set(ep_base "${CMAKE_BINARY_DIR}/CMakeExternals") set_property(DIRECTORY PROPERTY EP_BASE ${ep_base}) set(ep_install_dir ${ep_base}/Install) #set(ep_build_dir ${ep_base}/Build) set(ep_source_dir ${ep_base}/Source) #set(ep_parallelism_level) set(ep_build_shared_libs ON) set(ep_build_testing OFF) if(NOT MITK_THIRDPARTY_DOWNLOAD_PREFIX_URL) set(MITK_THIRDPARTY_DOWNLOAD_PREFIX_URL http://mitk.org/download/thirdparty) endif() # Compute -G arg for configuring external projects with the same CMake generator: if(CMAKE_EXTRA_GENERATOR) set(gen "${CMAKE_EXTRA_GENERATOR} - ${CMAKE_GENERATOR}") else() set(gen "${CMAKE_GENERATOR}") endif() # Use this value where semi-colons are needed in ep_add args: set(sep "^^") ## if(MSVC_VERSION) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /bigobj /MP") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /bigobj /MP") endif() set(ep_common_args -DBUILD_TESTING:BOOL=${ep_build_testing} -DCMAKE_INSTALL_PREFIX:PATH=${ep_install_dir} -DCMAKE_PREFIX_PATH:PATH=${CMAKE_PREFIX_PATH} -DBUILD_SHARED_LIBS:BOOL=ON -DCMAKE_BUILD_TYPE:STRING=${CMAKE_BUILD_TYPE} -DCMAKE_C_COMPILER:FILEPATH=${CMAKE_C_COMPILER} -DCMAKE_CXX_COMPILER:FILEPATH=${CMAKE_CXX_COMPILER} -DCMAKE_C_FLAGS:STRING=${CMAKE_C_FLAGS} -DCMAKE_CXX_FLAGS:STRING=${CMAKE_CXX_FLAGS} #debug flags -DCMAKE_CXX_FLAGS_DEBUG:STRING=${CMAKE_CXX_FLAGS_DEBUG} -DCMAKE_C_FLAGS_DEBUG:STRING=${CMAKE_C_FLAGS_DEBUG} #release flags -DCMAKE_CXX_FLAGS_RELEASE:STRING=${CMAKE_CXX_FLAGS_RELEASE} -DCMAKE_C_FLAGS_RELEASE:STRING=${CMAKE_C_FLAGS_RELEASE} #relwithdebinfo -DCMAKE_CXX_FLAGS_RELWITHDEBINFO:STRING=${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -DCMAKE_C_FLAGS_RELWITHDEBINFO:STRING=${CMAKE_C_FLAGS_RELWITHDEBINFO} #link flags -DCMAKE_EXE_LINKER_FLAGS:STRING=${CMAKE_EXE_LINKER_FLAGS} -DCMAKE_SHARED_LINKER_FLAGS:STRING=${CMAKE_SHARED_LINKER_FLAGS} -DCMAKE_MODULE_LINKER_FLAGS:STRING=${CMAKE_MODULE_LINKER_FLAGS} ) # Pass the CMAKE_OSX variables to external projects if(APPLE) set(MAC_OSX_ARCHITECTURE_ARGS -DCMAKE_OSX_ARCHITECTURES:PATH=${CMAKE_OSX_ARCHITECTURES} -DCMAKE_OSX_DEPLOYMENT_TARGET:PATH=${CMAKE_OSX_DEPLOYMENT_TARGET} -DCMAKE_OSX_SYSROOT:PATH=${CMAKE_OSX_SYSROOT} ) set(ep_common_args ${MAC_OSX_ARCHITECTURE_ARGS} ${ep_common_args} ) endif() # Include external projects foreach(p ${external_projects}) include(CMakeExternals/${p}.cmake) endforeach() #----------------------------------------------------------------------------- # Set superbuild boolean args #----------------------------------------------------------------------------- set(mitk_cmake_boolean_args BUILD_SHARED_LIBS WITH_COVERAGE BUILD_TESTING MITK_USE_QT MITK_BUILD_ALL_PLUGINS MITK_BUILD_ALL_APPS MITK_BUILD_TUTORIAL # Deprecated. Use MITK_BUILD_EXAMPLES instead MITK_BUILD_EXAMPLES MITK_USE_ACVD MITK_USE_CppUnit MITK_USE_GLEW MITK_USE_Boost MITK_USE_SYSTEM_Boost MITK_USE_BLUEBERRY MITK_USE_CTK MITK_USE_DCMTK MITK_USE_OpenCV MITK_USE_Poco MITK_USE_SOFA MITK_USE_Python MITK_USE_OpenCL MITK_ENABLE_PIC_READER ) #----------------------------------------------------------------------------- # Create the final variable containing superbuild boolean args #----------------------------------------------------------------------------- set(mitk_superbuild_boolean_args) foreach(mitk_cmake_arg ${mitk_cmake_boolean_args}) list(APPEND mitk_superbuild_boolean_args -D${mitk_cmake_arg}:BOOL=${${mitk_cmake_arg}}) endforeach() if(MITK_BUILD_ALL_PLUGINS) list(APPEND mitk_superbuild_boolean_args -DBLUEBERRY_BUILD_ALL_PLUGINS:BOOL=ON) endif() #----------------------------------------------------------------------------- # MITK Utilities #----------------------------------------------------------------------------- set(proj MITK-Utilities) ExternalProject_Add(${proj} DOWNLOAD_COMMAND "" CONFIGURE_COMMAND "" BUILD_COMMAND "" INSTALL_COMMAND "" DEPENDS # Mandatory dependencies ${tinyxml_DEPENDS} ${ANN_DEPENDS} ${VTK_DEPENDS} ${ITK_DEPENDS} # Optionnal dependencies ${ACVD_DEPENDS} ${CppUnit_DEPENDS} ${Eigen_DEPENDS} ${GLUT_DEPENDS} ${GLEW_DEPENDS} ${Boost_DEPENDS} ${CTK_DEPENDS} ${DCMTK_DEPENDS} ${OpenCV_DEPENDS} ${Poco_DEPENDS} ${SOFA_DEPENDS} ${MITK-Data_DEPENDS} ${Qwt_DEPENDS} - ${Qxt_DEPENDS} ${ZLIB_DEPENDS} ${SimpleITK_DEPENDS} ${Numpy_DEPENDS} ) #----------------------------------------------------------------------------- # Additional MITK CXX/C Flags #----------------------------------------------------------------------------- set(MITK_ADDITIONAL_C_FLAGS "" CACHE STRING "Additional C Flags for MITK") set(MITK_ADDITIONAL_C_FLAGS_RELEASE "" CACHE STRING "Additional Release C Flags for MITK") set(MITK_ADDITIONAL_C_FLAGS_DEBUG "" CACHE STRING "Additional Debug C Flags for MITK") mark_as_advanced(MITK_ADDITIONAL_C_FLAGS MITK_ADDITIONAL_C_FLAGS_DEBUG MITK_ADDITIONAL_C_FLAGS_RELEASE) set(MITK_ADDITIONAL_CXX_FLAGS "" CACHE STRING "Additional CXX Flags for MITK") set(MITK_ADDITIONAL_CXX_FLAGS_RELEASE "" CACHE STRING "Additional Release CXX Flags for MITK") set(MITK_ADDITIONAL_CXX_FLAGS_DEBUG "" CACHE STRING "Additional Debug CXX Flags for MITK") mark_as_advanced(MITK_ADDITIONAL_CXX_FLAGS MITK_ADDITIONAL_CXX_FLAGS_DEBUG MITK_ADDITIONAL_CXX_FLAGS_RELEASE) set(MITK_ADDITIONAL_EXE_LINKER_FLAGS "" CACHE STRING "Additional exe linker flags for MITK") set(MITK_ADDITIONAL_SHARED_LINKER_FLAGS "" CACHE STRING "Additional shared linker flags for MITK") set(MITK_ADDITIONAL_MODULE_LINKER_FLAGS "" CACHE STRING "Additional module linker flags for MITK") mark_as_advanced(MITK_ADDITIONAL_EXE_LINKER_FLAGS MITK_ADDITIONAL_SHARED_LINKER_FLAGS MITK_ADDITIONAL_MODULE_LINKER_FLAGS) #----------------------------------------------------------------------------- # MITK Configure #----------------------------------------------------------------------------- if(MITK_INITIAL_CACHE_FILE) set(mitk_initial_cache_arg -C "${MITK_INITIAL_CACHE_FILE}") endif() set(mitk_optional_cache_args ) foreach(type RUNTIME ARCHIVE LIBRARY) if(DEFINED CTK_PLUGIN_${type}_OUTPUT_DIRECTORY) list(APPEND mitk_optional_cache_args -DCTK_PLUGIN_${type}_OUTPUT_DIRECTORY:PATH=${CTK_PLUGIN_${type}_OUTPUT_DIRECTORY}) endif() endforeach() # Optional python variables if(MITK_USE_Python) list(APPEND mitk_optional_cache_args -DPYTHON_EXECUTABLE:FILEPATH=${PYTHON_EXECUTABLE} -DPYTHON_INCLUDE_DIR:PATH=${PYTHON_INCLUDE_DIR} -DPYTHON_LIBRARY:FILEPATH=${PYTHON_LIBRARY} -DPYTHON_INCLUDE_DIR2:PATH=${PYTHON_INCLUDE_DIR2} -DMITK_USE_SYSTEM_PYTHON:BOOL=${MITK_USE_SYSTEM_PYTHON} -DMITK_BUILD_org.mitk.gui.qt.python:BOOL=ON ) if( NOT MITK_USE_SYSTEM_PYTHON ) list(APPEND mitk_optional_cache_args # Folders are needed to create an installer -DPython_DIR:PATH=${Python_DIR} -DNumpy_DIR:PATH=${Numpy_DIR} ) endif() endif() +if(MITK_USE_QT) + if(DESIRED_QT_VERSION MATCHES "5") + list(APPEND mitk_optional_cache_args + -DQT5_INSTALL_PREFIX:PATH=${QT5_INSTALL_PREFIX} + ) + endif() +endif() + set(proj MITK-Configure) ExternalProject_Add(${proj} LIST_SEPARATOR ^^ DOWNLOAD_COMMAND "" CMAKE_GENERATOR ${gen} CMAKE_CACHE_ARGS # --------------- Build options ---------------- -DBUILD_TESTING:BOOL=${ep_build_testing} -DCMAKE_INSTALL_PREFIX:PATH=${CMAKE_BINARY_DIR}/MITK-build/install -DBUILD_SHARED_LIBS:BOOL=ON -DCMAKE_BUILD_TYPE:STRING=${CMAKE_BUILD_TYPE} # --------------- Compile options ---------------- -DCMAKE_C_COMPILER:FILEPATH=${CMAKE_C_COMPILER} -DCMAKE_CXX_COMPILER:FILEPATH=${CMAKE_CXX_COMPILER} "-DCMAKE_C_FLAGS:STRING=${CMAKE_C_FLAGS} ${MITK_ADDITIONAL_C_FLAGS}" "-DCMAKE_CXX_FLAGS:STRING=${CMAKE_CXX_FLAGS} ${MITK_ADDITIONAL_CXX_FLAGS}" # debug flags "-DCMAKE_CXX_FLAGS_DEBUG:STRING=${CMAKE_CXX_FLAGS_DEBUG} ${MITK_ADDITIONAL_CXX_FLAGS_DEBUG}" "-DCMAKE_C_FLAGS_DEBUG:STRING=${CMAKE_C_FLAGS_DEBUG} ${MITK_ADDITIONAL_C_FLAGS_DEBUG}" # release flags "-DCMAKE_CXX_FLAGS_RELEASE:STRING=${CMAKE_CXX_FLAGS_RELEASE} ${MITK_ADDITIONAL_CXX_FLAGS_RELEASE}" "-DCMAKE_C_FLAGS_RELEASE:STRING=${CMAKE_C_FLAGS_RELEASE} ${MITK_ADDITIONAL_C_FLAGS_RELEASE}" # relwithdebinfo -DCMAKE_CXX_FLAGS_RELWITHDEBINFO:STRING=${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -DCMAKE_C_FLAGS_RELWITHDEBINFO:STRING=${CMAKE_C_FLAGS_RELWITHDEBINFO} # link flags "-DCMAKE_EXE_LINKER_FLAGS:STRING=${CMAKE_EXE_LINKER_FLAGS} ${MITK_ADDITIONAL_EXE_LINKER_FLAGS}" "-DCMAKE_SHARED_LINKER_FLAGS:STRING=${CMAKE_SHARED_LINKER_FLAGS} ${MITK_ADDITIONAL_SHARED_LINKER_FLAGS}" "-DCMAKE_MODULE_LINKER_FLAGS:STRING=${CMAKE_MODULE_LINKER_FLAGS} ${MITK_ADDITIONAL_MODULE_LINKER_FLAGS}" # Output directories -DMITK_CMAKE_LIBRARY_OUTPUT_DIRECTORY:PATH=${MITK_CMAKE_LIBRARY_OUTPUT_DIRECTORY} -DMITK_CMAKE_RUNTIME_OUTPUT_DIRECTORY:PATH=${MITK_CMAKE_RUNTIME_OUTPUT_DIRECTORY} -DMITK_CMAKE_ARCHIVE_OUTPUT_DIRECTORY:PATH=${MITK_CMAKE_ARCHIVE_OUTPUT_DIRECTORY} # ------------- Boolean build options -------------- ${mitk_superbuild_boolean_args} ${mitk_optional_cache_args} -DMITK_USE_SUPERBUILD:BOOL=OFF -DMITK_BUILD_CONFIGURATION:STRING=${MITK_BUILD_CONFIGURATION} -DCTEST_USE_LAUNCHERS:BOOL=${CTEST_USE_LAUNCHERS} # ----------------- Miscellaneous --------------- -DMITK_CTEST_SCRIPT_MODE:STRING=${MITK_CTEST_SCRIPT_MODE} -DMITK_SUPERBUILD_BINARY_DIR:PATH=${MITK_BINARY_DIR} -DMITK_MODULES_TO_BUILD:INTERNAL=${MITK_MODULES_TO_BUILD} ${qt_project_args} -DMITK_ACCESSBYITK_INTEGRAL_PIXEL_TYPES:STRING=${MITK_ACCESSBYITK_INTEGRAL_PIXEL_TYPES} -DMITK_ACCESSBYITK_FLOATING_PIXEL_TYPES:STRING=${MITK_ACCESSBYITK_FLOATING_PIXEL_TYPES} -DMITK_ACCESSBYITK_COMPOSITE_PIXEL_TYPES:STRING=${MITK_ACCESSBYITK_COMPOSITE_PIXEL_TYPES} -DMITK_ACCESSBYITK_VECTOR_PIXEL_TYPES:STRING=${MITK_ACCESSBYITK_VECTOR_PIXEL_TYPES} -DMITK_ACCESSBYITK_DIMENSIONS:STRING=${MITK_ACCESSBYITK_DIMENSIONS} # --------------- External project dirs --------------- -DCppMicroServices_DIR:PATH=${CppMicroServices_DIR} -DMITK_KWSTYLE_EXECUTABLE:FILEPATH=${MITK_KWSTYLE_EXECUTABLE} -DCTK_DIR:PATH=${CTK_DIR} -DDCMTK_DIR:PATH=${DCMTK_DIR} -DEigen_DIR:PATH=${Eigen_DIR} -Dtinyxml_DIR:PATH=${tinyxml_DIR} -DGLUT_DIR:PATH=${GLUT_DIR} -DGLEW_DIR:PATH=${GLEW_DIR} -DANN_DIR:PATH=${ANN_DIR} -DCppUnit_DIR:PATH=${CppUnit_DIR} -DVTK_DIR:PATH=${VTK_DIR} # FindVTK expects VTK_DIR -DITK_DIR:PATH=${ITK_DIR} # FindITK expects ITK_DIR -DACVD_DIR:PATH=${ACVD_DIR} -DOpenCV_DIR:PATH=${OpenCV_DIR} -DPoco_DIR:PATH=${Poco_DIR} -DSOFA_DIR:PATH=${SOFA_DIR} -DGDCM_DIR:PATH=${GDCM_DIR} -DBOOST_ROOT:PATH=${BOOST_ROOT} -DMITK_USE_Boost_LIBRARIES:STRING=${MITK_USE_Boost_LIBRARIES} -DMITK_DATA_DIR:PATH=${MITK_DATA_DIR} -DQwt_DIR:PATH=${Qwt_DIR} - -DQxt_DIR:PATH=${Qxt_DIR} -DSimpleITK_DIR:PATH=${SimpleITK_DIR} -DNumpy_DIR:PATH=${Numpy_DIR} CMAKE_ARGS ${mitk_initial_cache_arg} ${MAC_OSX_ARCHITECTURE_ARGS} SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR} BINARY_DIR ${CMAKE_BINARY_DIR}/MITK-build BUILD_COMMAND "" INSTALL_COMMAND "" DEPENDS MITK-Utilities ) #----------------------------------------------------------------------------- # MITK #----------------------------------------------------------------------------- if(CMAKE_GENERATOR MATCHES ".*Makefiles.*") set(mitk_build_cmd "$(MAKE)") else() set(mitk_build_cmd ${CMAKE_COMMAND} --build ${CMAKE_CURRENT_BINARY_DIR}/MITK-build --config ${CMAKE_CFG_INTDIR}) endif() if(NOT DEFINED SUPERBUILD_EXCLUDE_MITKBUILD_TARGET OR NOT SUPERBUILD_EXCLUDE_MITKBUILD_TARGET) set(MITKBUILD_TARGET_ALL_OPTION "ALL") else() set(MITKBUILD_TARGET_ALL_OPTION "") endif() add_custom_target(MITK-build ${MITKBUILD_TARGET_ALL_OPTION} COMMAND ${mitk_build_cmd} WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/MITK-build DEPENDS MITK-Configure ) #----------------------------------------------------------------------------- # Custom target allowing to drive the build of the MITK project itself #----------------------------------------------------------------------------- add_custom_target(MITK COMMAND ${mitk_build_cmd} WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/MITK-build )