diff --git a/Modules/DICOMReader/files.cmake b/Modules/DICOMReader/files.cmake index 7218fa0662..05d6cd2f66 100644 --- a/Modules/DICOMReader/files.cmake +++ b/Modules/DICOMReader/files.cmake @@ -1,63 +1,64 @@ file(GLOB_RECURSE H_FILES RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" "${CMAKE_CURRENT_SOURCE_DIR}/include/*") set(CPP_FILES mitkBaseDICOMReaderService.cpp mitkDICOMFileReader.cpp mitkDICOMTagScanner.cpp mitkDICOMGDCMTagScanner.cpp mitkDICOMDCMTKTagScanner.cpp mitkDICOMImageBlockDescriptor.cpp mitkDICOMITKSeriesGDCMReader.cpp mitkDICOMDatasetSorter.cpp mitkDICOMTagBasedSorter.cpp mitkDICOMGDCMImageFrameInfo.cpp mitkDICOMImageFrameInfo.cpp mitkDICOMIOHelper.cpp mitkDICOMGenericImageFrameInfo.cpp mitkDICOMDatasetAccessingImageFrameInfo.cpp mitkDICOMSortCriterion.cpp mitkDICOMSortByTag.cpp mitkITKDICOMSeriesReaderHelper.cpp mitkEquiDistantBlocksSorter.cpp mitkNormalDirectionConsistencySorter.cpp mitkSortByImagePositionPatient.cpp mitkGantryTiltInformation.cpp mitkClassicDICOMSeriesReader.cpp mitkThreeDnTDICOMSeriesReader.cpp mitkDICOMTag.cpp mitkDICOMTagsOfInterestHelper.cpp mitkDICOMTagCache.cpp mitkDICOMGDCMTagCache.cpp mitkDICOMGenericTagCache.cpp mitkDICOMEnums.cpp mitkDICOMReaderConfigurator.cpp mitkDICOMFileReaderSelector.cpp mitkIDICOMTagsOfInterest.cpp + mitkDICOMTagsOfInterestAddHelper.cpp mitkDICOMTagPath.cpp mitkDICOMProperty.cpp mitkDICOMFilesHelper.cpp mitkDICOMIOMetaInformationPropertyConstants.cpp legacy/mitkDicomSeriesReader.cpp legacy/mitkDicomSR_GantryTiltInformation.cpp legacy/mitkDicomSR_ImageBlockDescriptor.cpp legacy/mitkDicomSR_LoadDICOMRGBPixel.cpp legacy/mitkDicomSR_LoadDICOMRGBPixel4D.cpp legacy/mitkDicomSR_LoadDICOMScalar.cpp legacy/mitkDicomSR_LoadDICOMScalar4D.cpp legacy/mitkDicomSR_SliceGroupingResult.cpp ) set(RESOURCE_FILES configurations/3D/classicreader.xml configurations/3D/imageposition.xml configurations/3D/imageposition_byacquisition.xml configurations/3D/instancenumber.xml configurations/3D/instancenumber_soft.xml configurations/3D/slicelocation.xml configurations/3D/simpleinstancenumber_soft.xml configurations/3DnT/classicreader.xml configurations/3DnT/imageposition.xml configurations/3DnT/imageposition_byacquisition.xml configurations/3DnT/imageposition_bytriggertime.xml ) diff --git a/Modules/DICOMReader/include/mitkDICOMTagsOfInterestAddHelper.h b/Modules/DICOMReader/include/mitkDICOMTagsOfInterestAddHelper.h new file mode 100644 index 0000000000..d5cb9cceb4 --- /dev/null +++ b/Modules/DICOMReader/include/mitkDICOMTagsOfInterestAddHelper.h @@ -0,0 +1,72 @@ +/*============================================================================ + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) German Cancer Research Center (DKFZ) +All rights reserved. + +Use of this source code is governed by a 3-clause BSD license that can be +found in the LICENSE file. + +============================================================================*/ + +#ifndef mitkDICOMTagsOfInterestAddHelper_h +#define mitkDICOMTagsOfInterestAddHelper_h + +#include + +#include + +#include + +#include +#include + +#include "MitkDICOMReaderExports.h" + +namespace us +{ + class ModuleContext; +} + +namespace mitk +{ + class IDICOMTagsOfInterest; + + /** Helper class that can be used to ensure that a given list + of DICOM tags will be registered at existing DICOMTagsOfInterest + services. If the services are available the tags will be directly + added. As long as the helper is active, it will add the given tags to + all new DICOMTagsOfInterest services as soon as they are registered. + This helper class is e.g. used in module activators where the + DICOMTagsOfInterest service might not be registered when a module + is loaded but the module wants to ensure that the tags are added + as soon as possible. + The helper must be deactivated before the module context used on activation + gets invalid (e.g. in the Unload function of the module activator that + uses the helper to ensure that the tags will be added). + */ + class MITKDICOMREADER_EXPORT DICOMTagsOfInterestAddHelper + { + public: + using TagsOfInterestVector = std::vector; + ~DICOMTagsOfInterestAddHelper(); + + void Activate(us::ModuleContext* context, TagsOfInterestVector tags); + void Deactivate(); + + private: + void RegisterTagsOfInterest(IDICOMTagsOfInterest* toiService) const; + void DICOMTagsOfInterestServiceChanged(const us::ServiceEvent event); + + TagsOfInterestVector m_TagsOfInterest; + + bool m_Active = false; + us::ModuleContext* m_Context = nullptr; + + /**mutex to guard the service listening */ + std::mutex m_Mutex; + }; +} + +#endif diff --git a/Modules/DICOMReader/src/mitkDICOMTagsOfInterestAddHelper.cpp b/Modules/DICOMReader/src/mitkDICOMTagsOfInterestAddHelper.cpp new file mode 100644 index 0000000000..592a21d2a7 --- /dev/null +++ b/Modules/DICOMReader/src/mitkDICOMTagsOfInterestAddHelper.cpp @@ -0,0 +1,102 @@ +/*============================================================================ + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) German Cancer Research Center (DKFZ) +All rights reserved. + +Use of this source code is governed by a 3-clause BSD license that can be +found in the LICENSE file. + +============================================================================*/ + +#include "mitkDICOMTagsOfInterestAddHelper.h" + +#include + +#include "usModuleContext.h" + +void mitk::DICOMTagsOfInterestAddHelper::Activate(us::ModuleContext* context, TagsOfInterestVector tags) +{ + if (!m_Active && nullptr != context) + { + std::lock_guard lock(m_Mutex); + m_Active = true; + m_Context = context; + + // Listen for events pertaining to dictionary services. + m_Context->AddServiceListener(this, &DICOMTagsOfInterestAddHelper::DICOMTagsOfInterestServiceChanged, + std::string("(&(") + us::ServiceConstants::OBJECTCLASS() + "=" + + us_service_interface_iid() + "))"); + // Query for any service references matching any language. + std::vector > refs = + m_Context->GetServiceReferences(); + if (!refs.empty()) + { + for (const auto& ref : refs) + { + this->RegisterTagsOfInterest(context->GetService(ref)); + context->UngetService(ref); + } + } + } +} + +void mitk::DICOMTagsOfInterestAddHelper::Deactivate() +{ + if (m_Active) + { + std::lock_guard lock(m_Mutex); + m_Active = false; + try + { + if (nullptr != m_Context) + { + m_Context->RemoveServiceListener(this, &DICOMTagsOfInterestAddHelper::DICOMTagsOfInterestServiceChanged); + } + } + catch (...) + { + MITK_WARN << "Was not able to remove service listener from module context."; + } + } +} + +mitk::DICOMTagsOfInterestAddHelper::~DICOMTagsOfInterestAddHelper() +{ + if (m_Active) + { + MITK_WARN << "DICOMTagsOfInterestAddHelper was not deactivated correctly befor its destructor was called."; + } +} + +void mitk::DICOMTagsOfInterestAddHelper::RegisterTagsOfInterest(IDICOMTagsOfInterest* toiService) const +{ + if (nullptr != toiService) + { + for (const auto& tag : m_TagsOfInterest) + { + toiService->AddTagOfInterest(tag); + } + } +} + +void mitk::DICOMTagsOfInterestAddHelper::DICOMTagsOfInterestServiceChanged(const us::ServiceEvent event) +{ + // If a DICOMTagsOfInterestService was registered, register all tags of interest. + if (event.GetType() == us::ServiceEvent::REGISTERED) + { + if (nullptr != m_Context) + { + std::lock_guard lock(m_Mutex); + // Get a reference to the service object. + us::ServiceReference ref = event.GetServiceReference(); + this->RegisterTagsOfInterest(m_Context->GetService(ref)); + m_Context->UngetService(ref); + } + else + { + MITK_ERROR << "New DICOMTagsOfInterestService was registered, but no module context exists. Thus, no DICOM tags of interest where added."; + } + } +}