diff --git a/Modules/Core/files.cmake b/Modules/Core/files.cmake
index e9b2cedff7..eb40ccde9d 100644
--- a/Modules/Core/files.cmake
+++ b/Modules/Core/files.cmake
@@ -1,329 +1,327 @@
file(GLOB_RECURSE H_FILES RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" "${CMAKE_CURRENT_SOURCE_DIR}/include/*")
set(CPP_FILES
mitkCoreActivator.cpp
mitkCoreObjectFactoryBase.cpp
mitkCoreObjectFactory.cpp
mitkCoreServices.cpp
mitkException.cpp
Algorithms/mitkBaseDataSource.cpp
Algorithms/mitkClippedSurfaceBoundsCalculator.cpp
Algorithms/mitkCompareImageDataFilter.cpp
Algorithms/mitkCompositePixelValueToString.cpp
Algorithms/mitkConvert2Dto3DImageFilter.cpp
Algorithms/mitkDataNodeSource.cpp
Algorithms/mitkExtractSliceFilter.cpp
Algorithms/mitkExtractSliceFilter2.cpp
Algorithms/mitkHistogramGenerator.cpp
Algorithms/mitkImageChannelSelector.cpp
Algorithms/mitkImageSliceSelector.cpp
Algorithms/mitkImageSource.cpp
Algorithms/mitkImageTimeSelector.cpp
Algorithms/mitkImageToImageFilter.cpp
Algorithms/mitkImageToSurfaceFilter.cpp
Algorithms/mitkMultiComponentImageDataComparisonFilter.cpp
Algorithms/mitkPlaneGeometryDataToSurfaceFilter.cpp
Algorithms/mitkPointSetSource.cpp
Algorithms/mitkPointSetToPointSetFilter.cpp
Algorithms/mitkRGBToRGBACastImageFilter.cpp
Algorithms/mitkSubImageSelector.cpp
Algorithms/mitkSurfaceSource.cpp
Algorithms/mitkSurfaceToImageFilter.cpp
Algorithms/mitkSurfaceToSurfaceFilter.cpp
Algorithms/mitkUIDGenerator.cpp
Algorithms/mitkVolumeCalculator.cpp
Algorithms/mitkTemporalJoinImagesFilter.cpp
Controllers/mitkBaseController.cpp
Controllers/mitkCallbackFromGUIThread.cpp
Controllers/mitkCameraController.cpp
Controllers/mitkCameraRotationController.cpp
Controllers/mitkCrosshairManager.cpp
Controllers/mitkLimitedLinearUndo.cpp
Controllers/mitkOperationEvent.cpp
Controllers/mitkPlanePositionManager.cpp
Controllers/mitkProgressBar.cpp
Controllers/mitkRenderingManager.cpp
Controllers/mitkSliceNavigationController.cpp
Controllers/mitkSliceNavigationHelper.cpp
Controllers/mitkStatusBar.cpp
Controllers/mitkStepper.cpp
Controllers/mitkTestManager.cpp
Controllers/mitkUndoController.cpp
Controllers/mitkVerboseLimitedLinearUndo.cpp
Controllers/mitkVtkLayerController.cpp
DataManagement/mitkAnatomicalStructureColorPresets.cpp
DataManagement/mitkArbitraryTimeGeometry.cpp
DataManagement/mitkAbstractTransformGeometry.cpp
DataManagement/mitkAnnotationProperty.cpp
DataManagement/mitkApplicationCursor.cpp
DataManagement/mitkApplyTransformMatrixOperation.cpp
DataManagement/mitkBaseData.cpp
DataManagement/mitkBaseGeometry.cpp
DataManagement/mitkBaseProperty.cpp
DataManagement/mitkChannelDescriptor.cpp
DataManagement/mitkClippingProperty.cpp
DataManagement/mitkColorProperty.cpp
DataManagement/mitkCrosshairData.cpp
DataManagement/mitkDataNode.cpp
DataManagement/mitkDataStorage.cpp
DataManagement/mitkEnumerationProperty.cpp
DataManagement/mitkFloatPropertyExtension.cpp
DataManagement/mitkGeometry3D.cpp
DataManagement/mitkGeometryData.cpp
DataManagement/mitkGeometryTransformHolder.cpp
DataManagement/mitkGroupTagProperty.cpp
DataManagement/mitkGenericIDRelationRule.cpp
DataManagement/mitkIdentifiable.cpp
DataManagement/mitkImageAccessorBase.cpp
DataManagement/mitkImageCaster.cpp
DataManagement/mitkImageCastPart1.cpp
DataManagement/mitkImageCastPart2.cpp
DataManagement/mitkImageCastPart3.cpp
DataManagement/mitkImageCastPart4.cpp
DataManagement/mitkImage.cpp
DataManagement/mitkImageDataItem.cpp
DataManagement/mitkImageDescriptor.cpp
DataManagement/mitkImageReadAccessor.cpp
DataManagement/mitkImageStatisticsHolder.cpp
DataManagement/mitkImageVtkAccessor.cpp
DataManagement/mitkImageVtkReadAccessor.cpp
DataManagement/mitkImageVtkWriteAccessor.cpp
DataManagement/mitkImageWriteAccessor.cpp
DataManagement/mitkIntPropertyExtension.cpp
DataManagement/mitkIPersistenceService.cpp
DataManagement/mitkIPropertyAliases.cpp
DataManagement/mitkIPropertyDescriptions.cpp
DataManagement/mitkIPropertyExtensions.cpp
DataManagement/mitkIPropertyFilters.cpp
DataManagement/mitkIPropertyOwner.cpp
DataManagement/mitkIPropertyPersistence.cpp
DataManagement/mitkIPropertyProvider.cpp
DataManagement/mitkLandmarkProjectorBasedCurvedGeometry.cpp
DataManagement/mitkLandmarkProjector.cpp
DataManagement/mitkLevelWindow.cpp
DataManagement/mitkLevelWindowManager.cpp
DataManagement/mitkLevelWindowPreset.cpp
DataManagement/mitkLevelWindowProperty.cpp
DataManagement/mitkLine.cpp
DataManagement/mitkLookupTable.cpp
DataManagement/mitkLookupTableProperty.cpp
DataManagement/mitkLookupTables.cpp # specializations of GenericLookupTable
DataManagement/mitkMaterial.cpp
DataManagement/mitkMemoryUtilities.cpp
DataManagement/mitkModalityProperty.cpp
DataManagement/mitkModifiedLock.cpp
DataManagement/mitkNodePredicateAnd.cpp
DataManagement/mitkNodePredicateBase.cpp
DataManagement/mitkNodePredicateCompositeBase.cpp
DataManagement/mitkNodePredicateData.cpp
DataManagement/mitkNodePredicateDataType.cpp
DataManagement/mitkNodePredicateDataUID.cpp
DataManagement/mitkNodePredicateDimension.cpp
- DataManagement/mitkNodePredicateFirstLevel.cpp
DataManagement/mitkNodePredicateFunction.cpp
DataManagement/mitkNodePredicateGeometry.cpp
DataManagement/mitkNodePredicateNot.cpp
DataManagement/mitkNodePredicateOr.cpp
DataManagement/mitkNodePredicateProperty.cpp
DataManagement/mitkNodePredicateDataProperty.cpp
- DataManagement/mitkNodePredicateSource.cpp
DataManagement/mitkNodePredicateSubGeometry.cpp
DataManagement/mitkNumericConstants.cpp
DataManagement/mitkPlaneGeometry.cpp
DataManagement/mitkPlaneGeometryData.cpp
DataManagement/mitkPlaneOperation.cpp
DataManagement/mitkPlaneOrientationProperty.cpp
DataManagement/mitkPointOperation.cpp
DataManagement/mitkPointSet.cpp
DataManagement/mitkPointSetShapeProperty.cpp
DataManagement/mitkProperties.cpp
DataManagement/mitkPropertyAliases.cpp
DataManagement/mitkPropertyDescriptions.cpp
DataManagement/mitkPropertyExtension.cpp
DataManagement/mitkPropertyExtensions.cpp
DataManagement/mitkPropertyFilter.cpp
DataManagement/mitkPropertyFilters.cpp
DataManagement/mitkPropertyKeyPath.cpp
DataManagement/mitkPropertyList.cpp
DataManagement/mitkPropertyListReplacedObserver.cpp
DataManagement/mitkPropertyNameHelper.cpp
DataManagement/mitkPropertyObserver.cpp
DataManagement/mitkPropertyPersistence.cpp
DataManagement/mitkPropertyPersistenceInfo.cpp
DataManagement/mitkPropertyRelationRuleBase.cpp
DataManagement/mitkProportionalTimeGeometry.cpp
DataManagement/mitkRenderingModeProperty.cpp
DataManagement/mitkResliceMethodProperty.cpp
DataManagement/mitkRestorePlanePositionOperation.cpp
DataManagement/mitkRotationOperation.cpp
DataManagement/mitkScaleOperation.cpp
DataManagement/mitkSlicedData.cpp
DataManagement/mitkSlicedGeometry3D.cpp
DataManagement/mitkSmartPointerProperty.cpp
DataManagement/mitkStandaloneDataStorage.cpp
DataManagement/mitkStringProperty.cpp
DataManagement/mitkSurface.cpp
DataManagement/mitkSurfaceOperation.cpp
DataManagement/mitkSourceImageRelationRule.cpp
DataManagement/mitkThinPlateSplineCurvedGeometry.cpp
DataManagement/mitkTimeGeometry.cpp
DataManagement/mitkTransferFunction.cpp
DataManagement/mitkTransferFunctionInitializer.cpp
DataManagement/mitkTransferFunctionProperty.cpp
DataManagement/mitkTemporoSpatialStringProperty.cpp
DataManagement/mitkUIDManipulator.cpp
DataManagement/mitkVector.cpp
DataManagement/mitkVectorProperty.cpp
DataManagement/mitkVtkInterpolationProperty.cpp
DataManagement/mitkVtkRepresentationProperty.cpp
DataManagement/mitkVtkResliceInterpolationProperty.cpp
DataManagement/mitkVtkScalarModeProperty.cpp
DataManagement/mitkWeakPointerProperty.cpp
DataManagement/mitkIPropertyRelations.cpp
DataManagement/mitkPropertyRelations.cpp
Interactions/mitkAction.cpp
Interactions/mitkBindDispatcherInteractor.cpp
Interactions/mitkDataInteractor.cpp
Interactions/mitkDispatcher.cpp
Interactions/mitkDisplayActionEventBroadcast.cpp
Interactions/mitkDisplayActionEventFunctions.cpp
Interactions/mitkDisplayActionEventHandler.cpp
Interactions/mitkDisplayActionEventHandlerDesynchronized.cpp
Interactions/mitkDisplayActionEventHandlerStd.cpp
Interactions/mitkDisplayActionEventHandlerSynchronized.cpp
Interactions/mitkDisplayCoordinateOperation.cpp
Interactions/mitkEventConfig.cpp
Interactions/mitkEventFactory.cpp
Interactions/mitkEventRecorder.cpp
Interactions/mitkEventStateMachine.cpp
Interactions/mitkInteractionEventConst.cpp
Interactions/mitkInteractionEvent.cpp
Interactions/mitkInteractionEventHandler.cpp
Interactions/mitkInteractionEventObserver.cpp
Interactions/mitkInteractionKeyEvent.cpp
Interactions/mitkInteractionPositionEvent.cpp
Interactions/mitkInteractionSchemeSwitcher.cpp
Interactions/mitkInternalEvent.cpp
Interactions/mitkMouseDoubleClickEvent.cpp
Interactions/mitkMouseMoveEvent.cpp
Interactions/mitkMousePressEvent.cpp
Interactions/mitkMouseReleaseEvent.cpp
Interactions/mitkMouseWheelEvent.cpp
Interactions/mitkPointSetDataInteractor.cpp
Interactions/mitkSinglePointDataInteractor.cpp
Interactions/mitkStateMachineAction.cpp
Interactions/mitkStateMachineCondition.cpp
Interactions/mitkStateMachineContainer.cpp
Interactions/mitkStateMachineState.cpp
Interactions/mitkStateMachineTransition.cpp
Interactions/mitkVtkEventAdapter.cpp
Interactions/mitkVtkInteractorStyle.cxx
Interactions/mitkXML2EventParser.cpp
IO/mitkAbstractFileIO.cpp
IO/mitkAbstractFileReader.cpp
IO/mitkAbstractFileWriter.cpp
IO/mitkCustomMimeType.cpp
IO/mitkFileReader.cpp
IO/mitkFileReaderRegistry.cpp
IO/mitkFileReaderSelector.cpp
IO/mitkFileReaderWriterBase.cpp
IO/mitkFileWriter.cpp
IO/mitkFileWriterRegistry.cpp
IO/mitkFileWriterSelector.cpp
IO/mitkGeometry3DToXML.cpp
IO/mitkIFileIO.cpp
IO/mitkIFileReader.cpp
IO/mitkIFileWriter.cpp
IO/mitkGeometryDataReaderService.cpp
IO/mitkGeometryDataWriterService.cpp
IO/mitkImageGenerator.cpp
IO/mitkImageVtkLegacyIO.cpp
IO/mitkImageVtkXmlIO.cpp
IO/mitkIMimeTypeProvider.cpp
IO/mitkIOConstants.cpp
IO/mitkIOMimeTypes.cpp
IO/mitkIOUtil.cpp
IO/mitkItkImageIO.cpp
IO/mitkItkLoggingAdapter.cpp
IO/mitkLegacyFileReaderService.cpp
IO/mitkLegacyFileWriterService.cpp
IO/mitkLocaleSwitch.cpp
IO/mitkLog.cpp
IO/mitkMimeType.cpp
IO/mitkMimeTypeProvider.cpp
IO/mitkOperation.cpp
IO/mitkPixelType.cpp
IO/mitkPointSetReaderService.cpp
IO/mitkPointSetWriterService.cpp
IO/mitkProportionalTimeGeometryToXML.cpp
IO/mitkRawImageFileReader.cpp
IO/mitkStandardFileLocations.cpp
IO/mitkSurfaceStlIO.cpp
IO/mitkSurfaceVtkIO.cpp
IO/mitkSurfaceVtkLegacyIO.cpp
IO/mitkSurfaceVtkXmlIO.cpp
IO/mitkUtf8Util.cpp
IO/mitkVtkLoggingAdapter.cpp
IO/mitkPreferenceListReaderOptionsFunctor.cpp
IO/mitkIOMetaInformationPropertyConstants.cpp
IO/mitkIPreferences.cpp
IO/mitkPreferences.cpp
IO/mitkIPreferencesService.cpp
IO/mitkPreferencesService.cpp
IO/mitkIPreferencesStorage.cpp
IO/mitkXMLPreferencesStorage.cpp
Rendering/mitkAbstractAnnotationRenderer.cpp
Rendering/mitkAnnotationUtils.cpp
Rendering/mitkBaseRenderer.cpp
Rendering/mitkBaseRendererHelper.cpp
Rendering/mitkCrosshairVtkMapper2D.cpp
Rendering/mitkGradientBackground.cpp
Rendering/mitkImageVtkMapper2D.cpp
Rendering/mitkMapper.cpp
Rendering/mitkAnnotation.cpp
Rendering/mitkPlaneGeometryDataMapper2D.cpp
Rendering/mitkPlaneGeometryDataVtkMapper3D.cpp
Rendering/mitkPointSetVtkMapper2D.cpp
Rendering/mitkPointSetVtkMapper3D.cpp
Rendering/mitkRenderWindowBase.cpp
Rendering/mitkRenderWindow.cpp
Rendering/mitkRenderWindowFrame.cpp
Rendering/mitkSurfaceVtkMapper2D.cpp
Rendering/mitkSurfaceVtkMapper3D.cpp
Rendering/mitkVtkEventProvider.cpp
Rendering/mitkVtkMapper.cpp
Rendering/mitkVtkPropRenderer.cpp
Rendering/mitkVtkWidgetRendering.cpp
Rendering/vtkMitkLevelWindowFilter.cpp
Rendering/vtkMitkRectangleProp.cpp
Rendering/vtkMitkRenderProp.cpp
Rendering/vtkMitkThickSlicesFilter.cpp
Rendering/vtkNeverTranslucentTexture.cpp
)
set(RESOURCE_FILES
Interactions/globalConfig.xml
Interactions/DisplayInteraction.xml
Interactions/DisplayConfigMITKBase.xml
Interactions/DisplayConfigPACSBase.xml
Interactions/DisplayConfigCrosshair.xml
Interactions/DisplayConfigRotation.xml
Interactions/DisplayConfigActivateCoupling.xml
Interactions/DisplayConfigSwivel.xml
Interactions/DisplayConfigPACSPan.xml
Interactions/DisplayConfigPACSScroll.xml
Interactions/DisplayConfigPACSZoom.xml
Interactions/DisplayConfigPACSLevelWindow.xml
Interactions/DisplayConfigBlockLMB.xml
Interactions/PointSet.xml
Interactions/PointSetConfig.xml
mitkLevelWindowPresets.xml
mitkAnatomicalStructureColorPresets.xml
)
diff --git a/Modules/Core/include/mitkNodePredicateFirstLevel.h b/Modules/Core/include/mitkNodePredicateFirstLevel.h
deleted file mode 100644
index 5519b100a0..0000000000
--- a/Modules/Core/include/mitkNodePredicateFirstLevel.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/*============================================================================
-
-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 mitkNodePredicateFirstLevel_h
-#define mitkNodePredicateFirstLevel_h
-
-#include "mitkDataNode.h"
-#include "mitkDataStorage.h"
-#include "mitkNodePredicateBase.h"
-#include "mitkWeakPointer.h"
-
-namespace mitk
-{
- //##Documentation
- //## @brief Predicate that evaluates if the given node is a direct or indirect source node of a specific node
- //##
- //## @warning This class seems to be obsolete since mitk::DataStorage::GetDerivations().
- //## Since there is no real use case up until now, NodePredicateSource is NOT WORKING YET.
- //## If you need it working, inform us.
- //##
- //## @ingroup DataStorage
- class MITKCORE_EXPORT NodePredicateFirstLevel : public NodePredicateBase
- {
- public:
- mitkClassMacro(NodePredicateFirstLevel, NodePredicateBase);
- mitkNewMacro1Param(NodePredicateFirstLevel, mitk::DataStorage *);
-
- //##Documentation
- //## @brief Standard Destructor
- ~NodePredicateFirstLevel() override;
-
- //##Documentation
- //## @brief Checks, if the node is a source node of m_BaseNode (e.g. if m_BaseNode "was created from" node)
- bool CheckNode(const mitk::DataNode *node) const override;
-
- protected:
- //##Documentation
- //## @brief Constructor - This class can either search only for direct source objects or for all source objects
- NodePredicateFirstLevel(mitk::DataStorage *ds);
-
- mitk::WeakPointer m_DataStorage;
- };
-
-} // namespace mitk
-
-#endif
diff --git a/Modules/Core/include/mitkNodePredicateOr.h b/Modules/Core/include/mitkNodePredicateOr.h
index 297bd0476f..59fb999c52 100644
--- a/Modules/Core/include/mitkNodePredicateOr.h
+++ b/Modules/Core/include/mitkNodePredicateOr.h
@@ -1,53 +1,57 @@
/*============================================================================
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 mitkNodePredicateOr_h
#define mitkNodePredicateOr_h
#include "mitkNodePredicateCompositeBase.h"
namespace mitk
{
//##Documentation
//## @brief Composite predicate that forms a logical OR relation from its child predicates
//##
//##
//##
//##
//## @ingroup DataStorage
class MITKCORE_EXPORT NodePredicateOr : public NodePredicateCompositeBase
{
public:
mitkClassMacro(NodePredicateOr, NodePredicateCompositeBase);
itkFactorylessNewMacro(NodePredicateOr);
mitkNewMacro2Param(NodePredicateOr, const NodePredicateBase *, const NodePredicateBase *);
+ mitkNewMacro3Param(NodePredicateOr, const NodePredicateBase *, const NodePredicateBase *, const NodePredicateBase *);
//##Documentation
//## @brief Standard Destructor
~NodePredicateOr() override;
//##Documentation
//## @brief Checks, if the node fulfills any of the subpredicates conditions
bool CheckNode(const DataNode *node) const override;
protected:
//##Documentation
//## @brief Constructor
NodePredicateOr();
//##Documentation
//## @brief Convenience constructor that adds p1 and p2 to list of child predicates
NodePredicateOr(const NodePredicateBase *p1, const NodePredicateBase *p2);
+ //##Documentation
+ //## @brief Convenience constructor that adds p1, p2 and p3 to list of child predicates
+ NodePredicateOr(const NodePredicateBase *p1, const NodePredicateBase *p2, const NodePredicateBase *p3);
};
} // namespace mitk
#endif
diff --git a/Modules/Core/include/mitkNodePredicateSource.h b/Modules/Core/include/mitkNodePredicateSource.h
deleted file mode 100644
index 35596d8845..0000000000
--- a/Modules/Core/include/mitkNodePredicateSource.h
+++ /dev/null
@@ -1,56 +0,0 @@
-/*============================================================================
-
-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 mitkNodePredicateSource_h
-#define mitkNodePredicateSource_h
-
-#include "mitkDataNode.h"
-#include "mitkDataStorage.h"
-#include "mitkNodePredicateBase.h"
-#include "mitkWeakPointer.h"
-
-namespace mitk
-{
- //##Documentation
- //## @brief Predicate that evaluates if the given node is a direct or indirect source node of a specific node
- //##
- //## @warning Calling CheckNode() can be computationally quite expensive for a large DataStorage.
- //## Alternatively mitk::StandaloneDataStorage::GetSources() can be used
- //##
- //## @ingroup DataStorage
- class MITKCORE_EXPORT NodePredicateSource : public NodePredicateBase
- {
- public:
- mitkClassMacro(NodePredicateSource, NodePredicateBase);
- mitkNewMacro3Param(NodePredicateSource, mitk::DataNode *, bool, mitk::DataStorage *);
-
- //##Documentation
- //## @brief Standard Destructor
- ~NodePredicateSource() override;
-
- //##Documentation
- //## @brief Checks, if m_BaseNode is a source node of childNode (e.g. if childNode "was created from" m_BaseNode)
- bool CheckNode(const mitk::DataNode *childNode) const override;
-
- protected:
- //##Documentation
- //## @brief Constructor - This class can either search only for direct source objects or for all source objects
- NodePredicateSource(mitk::DataNode *n, bool allsources, mitk::DataStorage *ds);
-
- mitk::WeakPointer m_BaseNode;
- bool m_SearchAllSources;
- mitk::WeakPointer m_DataStorage;
- };
-
-} // namespace mitk
-
-#endif
diff --git a/Modules/Core/src/DataManagement/mitkNodePredicateFirstLevel.cpp b/Modules/Core/src/DataManagement/mitkNodePredicateFirstLevel.cpp
deleted file mode 100644
index 996bfac5b5..0000000000
--- a/Modules/Core/src/DataManagement/mitkNodePredicateFirstLevel.cpp
+++ /dev/null
@@ -1,35 +0,0 @@
-/*============================================================================
-
-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 "mitkNodePredicateFirstLevel.h"
-
-mitk::NodePredicateFirstLevel::NodePredicateFirstLevel(mitk::DataStorage *ds) : NodePredicateBase(), m_DataStorage(ds)
-{
-}
-
-mitk::NodePredicateFirstLevel::~NodePredicateFirstLevel()
-{
-}
-
-bool mitk::NodePredicateFirstLevel::CheckNode(const mitk::DataNode *node) const
-{
- if (node == nullptr)
- throw std::invalid_argument("NodePredicateFirstLevel: invalid node");
-
- auto dataStorage = m_DataStorage.Lock();
-
- if (dataStorage.IsNull())
- throw std::invalid_argument("NodePredicateFirstLevel: DataStorage is invalid");
-
- mitk::DataStorage::SetOfObjects::ConstPointer list = dataStorage->GetSources(node, nullptr, true);
- return (list->Size() == 0);
-}
diff --git a/Modules/Core/src/DataManagement/mitkNodePredicateOr.cpp b/Modules/Core/src/DataManagement/mitkNodePredicateOr.cpp
index 36d744e7bc..8212943fa8 100644
--- a/Modules/Core/src/DataManagement/mitkNodePredicateOr.cpp
+++ b/Modules/Core/src/DataManagement/mitkNodePredicateOr.cpp
@@ -1,44 +1,52 @@
/*============================================================================
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 "mitkNodePredicateOr.h"
mitk::NodePredicateOr::NodePredicateOr() : NodePredicateCompositeBase()
{
}
mitk::NodePredicateOr::NodePredicateOr(const NodePredicateBase *p1, const NodePredicateBase *p2)
: NodePredicateCompositeBase()
{
this->AddPredicate(p1);
this->AddPredicate(p2);
}
+mitk::NodePredicateOr::NodePredicateOr(const NodePredicateBase *p1, const NodePredicateBase *p2, const NodePredicateBase *p3)
+ : NodePredicateCompositeBase()
+{
+ this->AddPredicate(p1);
+ this->AddPredicate(p2);
+ this->AddPredicate(p3);
+}
+
mitk::NodePredicateOr::~NodePredicateOr()
{
}
bool mitk::NodePredicateOr::CheckNode(const DataNode *node) const
{
if (m_ChildPredicates.empty())
throw std::invalid_argument("NodePredicateOr: no child predicates available");
if (node == nullptr)
throw std::invalid_argument("NodePredicateOr: invalid node");
/* return the disjunction of the child predicate. If any predicate returns true, we return true too. Return false only
* if all child predicates return false */
for (auto it = m_ChildPredicates.cbegin(); it != m_ChildPredicates.cend(); ++it)
if ((*it)->CheckNode(node) == true)
return true;
return false; // none of the childs was true, so return false
}
diff --git a/Modules/Core/src/DataManagement/mitkNodePredicateSource.cpp b/Modules/Core/src/DataManagement/mitkNodePredicateSource.cpp
deleted file mode 100644
index 240c725023..0000000000
--- a/Modules/Core/src/DataManagement/mitkNodePredicateSource.cpp
+++ /dev/null
@@ -1,35 +0,0 @@
-/*============================================================================
-
-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 "mitkNodePredicateSource.h"
-
-mitk::NodePredicateSource::NodePredicateSource(mitk::DataNode *n, bool allsources, mitk::DataStorage *ds)
- : NodePredicateBase(), m_BaseNode(n), m_SearchAllSources(allsources), m_DataStorage(ds)
-{
-}
-
-mitk::NodePredicateSource::~NodePredicateSource()
-{
-}
-
-bool mitk::NodePredicateSource::CheckNode(const mitk::DataNode *childNode) const
-{
- if (m_DataStorage && m_BaseNode)
- {
- const mitk::DataStorage::SetOfObjects::STLContainerType sources =
- m_DataStorage.Lock()->GetSources(childNode, nullptr, !m_SearchAllSources)->CastToSTLConstContainer();
-
- return std::find(sources.cbegin(), sources.cend(), m_BaseNode.Lock()) != sources.cend();
- }
-
- return false;
-}
diff --git a/Modules/Core/test/files.cmake b/Modules/Core/test/files.cmake
index e75b1a306d..5e7a4c8a5f 100644
--- a/Modules/Core/test/files.cmake
+++ b/Modules/Core/test/files.cmake
@@ -1,199 +1,198 @@
# tests with no extra command line parameter
set(MODULE_TESTS
# IMPORTANT: If you plan to deactivate / comment out a test please write a bug number to the commented out line of code.
#
# Example: #mitkMyTest #this test is commented out because of bug 12345
#
# It is important that the bug is open and that the test will be activated again before the bug is closed. This assures that
# no test is forgotten after it was commented out. If there is no bug for your current problem, please add a new one and
# mark it as critical.
################## DISABLED TESTS #################################################
#mitkAbstractTransformGeometryTest.cpp #seems as tested class mitkExternAbstractTransformGeometry doesn't exist any more
#mitkStateMachineContainerTest.cpp #rewrite test, indirect since no longer exported Bug 14529
#mitkRegistrationBaseTest.cpp #tested class mitkRegistrationBase doesn't exist any more
#mitkSegmentationInterpolationTest.cpp #file doesn't exist!
#mitkPipelineSmartPointerCorrectnessTest.cpp #file doesn't exist!
#mitkITKThreadingTest.cpp #test outdated because itk::Semaphore was removed from ITK
#mitkAbstractTransformPlaneGeometryTest.cpp #mitkVtkAbstractTransformPlaneGeometry doesn't exist any more
#mitkTestUtilSharedLibrary.cpp #Linker problem with this test...
#mitkTextOverlay2DSymbolsRenderingTest.cpp #Implementation of the tested feature is not finished yet. Ask Christoph or see bug 15104 for details.
################# RUNNING TESTS ###################################################
mitkAccessByItkTest.cpp
mitkCoreObjectFactoryTest.cpp
mitkDataNodeTest.cpp
mitkMaterialTest.cpp
mitkActionTest.cpp
mitkDispatcherTest.cpp
mitkEnumerationPropertyTest.cpp
mitkFileReaderRegistryTest.cpp
#mitkFileWriterRegistryTest.cpp
mitkFloatToStringTest.cpp
mitkGenericPropertyTest.cpp
mitkGeometry3DTest.cpp
mitkGeometry3DEqualTest.cpp
mitkGeometryDataIOTest.cpp
mitkGeometryDataToSurfaceFilterTest.cpp
mitkImageCastTest.cpp
mitkImageDataItemTest.cpp
mitkImageGeneratorTest.cpp
mitkIOUtilTest.cpp
mitkBaseDataTest.cpp
mitkImportItkImageTest.cpp
mitkGrabItkImageMemoryTest.cpp
mitkInstantiateAccessFunctionTest.cpp
mitkLevelWindowTest.cpp
mitkMessageTest.cpp
mitkPixelTypeTest.cpp
mitkPlaneGeometryTest.cpp
mitkPointSetTest.cpp
mitkPointSetEqualTest.cpp
mitkPointSetFileIOTest.cpp
mitkPointSetOnEmptyTest.cpp
mitkPointSetLocaleTest.cpp
mitkPointSetWriterTest.cpp
mitkPointSetPointOperationsTest.cpp
mitkProgressBarTest.cpp
mitkPropertyTest.cpp
mitkPropertyListTest.cpp
mitkPropertyPersistenceTest.cpp
mitkPropertyPersistenceInfoTest.cpp
mitkPropertyRelationRuleBaseTest.cpp
mitkPropertyRelationsTest.cpp
mitkSlicedGeometry3DTest.cpp
mitkSliceNavigationControllerTest.cpp
mitkSurfaceTest.cpp
mitkSurfaceEqualTest.cpp
mitkSurfaceToSurfaceFilterTest.cpp
mitkTimeGeometryTest.cpp
mitkProportionalTimeGeometryTest.cpp
mitkUndoControllerTest.cpp
mitkVtkWidgetRenderingTest.cpp
mitkVerboseLimitedLinearUndoTest.cpp
mitkWeakPointerTest.cpp
mitkTransferFunctionTest.cpp
mitkStepperTest.cpp
mitkRenderingManagerTest.cpp
mitkCompositePixelValueToStringTest.cpp
vtkMitkThickSlicesFilterTest.cpp
- mitkNodePredicateSourceTest.cpp
mitkNodePredicateDataPropertyTest.cpp
mitkNodePredicateFunctionTest.cpp
mitkVectorTest.cpp
mitkClippedSurfaceBoundsCalculatorTest.cpp
mitkExceptionTest.cpp
mitkExtractSliceFilterTest.cpp
mitkLogTest.cpp
mitkImageDimensionConverterTest.cpp
mitkLoggingAdapterTest.cpp
mitkUIDGeneratorTest.cpp
mitkPlanePositionManagerTest.cpp
mitkAffineTransformBaseTest.cpp
mitkPropertyAliasesTest.cpp
mitkPropertyDescriptionsTest.cpp
mitkPropertyExtensionsTest.cpp
mitkPropertyFiltersTest.cpp
mitkPropertyKeyPathTest.cpp
mitkTinyXMLTest.cpp
mitkRawImageFileReaderTest.cpp
mitkInteractionEventTest.cpp
mitkLookupTableTest.cpp
mitkSTLFileReaderTest.cpp
mitkPointTypeConversionTest.cpp
mitkVectorTypeConversionTest.cpp
mitkMatrixTypeConversionTest.cpp
mitkArrayTypeConversionTest.cpp
mitkSurfaceToImageFilterTest.cpp
mitkBaseGeometryTest.cpp
mitkImageToSurfaceFilterTest.cpp
mitkEqualTest.cpp
mitkLineTest.cpp
mitkArbitraryTimeGeometryTest.cpp
mitkItkImageIOTest.cpp
mitkLevelWindowManagerTest.cpp
mitkVectorPropertyTest.cpp
mitkTemporoSpatialStringPropertyTest.cpp
mitkPropertyNameHelperTest.cpp
mitkNodePredicateGeometryTest.cpp
mitkNodePredicateSubGeometryTest.cpp
mitkPreferenceListReaderOptionsFunctorTest.cpp
mitkGenericIDRelationRuleTest.cpp
mitkSourceImageRelationRuleTest.cpp
mitkTemporalJoinImagesFilterTest.cpp
mitkPreferencesTest.cpp
)
set(MODULE_RENDERING_TESTS
mitkPointSetDataInteractorTest.cpp
mitkSurfaceVtkMapper2DTest.cpp
mitkSurfaceVtkMapper2D3DTest.cpp
)
# test with image filename as an extra command line parameter
set(MODULE_IMAGE_TESTS
mitkImageTimeSelectorTest.cpp #only runs on images
mitkImageAccessorTest.cpp #only runs on images
)
set(MODULE_SURFACE_TESTS
mitkSurfaceVtkWriterTest.cpp #only runs on surfaces
)
# list of images for which the tests are run
set(MODULE_TESTIMAGE
US4DCyl.nrrd
Pic3D.nrrd
Pic2DplusT.nrrd
BallBinary30x30x30.nrrd
Png2D-bw.png
)
set(MODULE_TESTSURFACE
binary.stl
ball.stl
)
set(MODULE_CUSTOM_TESTS
mitkDataStorageTest.cpp
mitkDataNodeTest.cpp
mitkEventConfigTest.cpp
mitkPointSetLocaleTest.cpp
mitkImageTest.cpp
mitkImageVtkMapper2DTest.cpp
mitkImageVtkMapper2DLevelWindowTest.cpp
mitkImageVtkMapper2DOpacityTest.cpp
mitkImageVtkMapper2DResliceInterpolationPropertyTest.cpp
mitkImageVtkMapper2DColorTest.cpp
mitkImageVtkMapper2DSwivelTest.cpp
mitkImageVtkMapper2DTransferFunctionTest.cpp
mitkImageVtkMapper2DOpacityTransferFunctionTest.cpp
mitkImageVtkMapper2DLookupTableTest.cpp
mitkSurfaceVtkMapper3DTest.cpp
mitkVolumeCalculatorTest.cpp
mitkLevelWindowManagerTest.cpp
mitkPointSetVtkMapper2DTest.cpp
mitkPointSetVtkMapper2DImageTest.cpp
mitkPointSetVtkMapper2DGlyphTypeTest.cpp
mitkPointSetVtkMapper2DTransformedPointsTest.cpp
mitkVTKRenderWindowSizeTest.cpp
mitkMultiComponentImageDataComparisonFilterTest.cpp
mitkImageToItkTest.cpp
mitkImageSliceSelectorTest.cpp
mitkPointSetReaderTest.cpp
mitkImageEqualTest.cpp
mitkRotatedSlice4DTest.cpp
mitkPlaneGeometryDataMapper2DTest.cpp
)
# Currently not working on windows because of a rendering timing issue
# see bug 18083 for details
if(NOT WIN32)
set(MODULE_CUSTOM_TESTS ${MODULE_CUSTOM_TESTS} mitkSurfaceDepthSortingTest.cpp)
endif()
set(RESOURCE_FILES
Interactions/AddAndRemovePoints.xml
Interactions/globalConfig.xml
Interactions/StatemachineTest.xml
Interactions/StatemachineConfigTest.xml
)
diff --git a/Modules/Core/test/mitkDataStorageTest.cpp b/Modules/Core/test/mitkDataStorageTest.cpp
index 428fd93240..81a5e0588e 100644
--- a/Modules/Core/test/mitkDataStorageTest.cpp
+++ b/Modules/Core/test/mitkDataStorageTest.cpp
@@ -1,874 +1,873 @@
/*============================================================================
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
#include
#include "mitkColorProperty.h"
#include "mitkDataNode.h"
#include "mitkGroupTagProperty.h"
#include "mitkImage.h"
#include "mitkReferenceCountWatcher.h"
#include "mitkStringProperty.h"
#include "mitkSurface.h"
#include "mitkDataStorage.h"
#include "mitkIOUtil.h"
#include "mitkMessage.h"
#include "mitkNodePredicateAnd.h"
#include "mitkNodePredicateData.h"
#include "mitkNodePredicateDataType.h"
#include "mitkNodePredicateDimension.h"
#include "mitkNodePredicateNot.h"
#include "mitkNodePredicateOr.h"
#include "mitkNodePredicateProperty.h"
-#include "mitkNodePredicateSource.h"
#include "mitkStandaloneDataStorage.h"
//#include "mitkPicFileReader.h"
#include "mitkTestingMacros.h"
void TestDataStorage(mitk::DataStorage *ds, std::string filename);
namespace mitk
{
class TestStandaloneDataStorage : public StandaloneDataStorage
{
public:
mitkClassMacro(TestStandaloneDataStorage, mitk::DataStorage);
itkFactorylessNewMacro(Self)
itkCloneMacro(Self) std::map GetModifiedObserverTags() const
{
return m_NodeModifiedObserverTags;
}
std::map GetDeletedObserverTags() const { return m_NodeDeleteObserverTags; }
protected:
TestStandaloneDataStorage() {}
};
}
class DSEventReceiver // Helper class for event testing
{
public:
const mitk::DataNode *m_NodeAdded;
const mitk::DataNode *m_NodeRemoved;
DSEventReceiver() : m_NodeAdded(nullptr), m_NodeRemoved(nullptr) {}
void OnAdd(const mitk::DataNode *node) { m_NodeAdded = node; }
void OnRemove(const mitk::DataNode *node) { m_NodeRemoved = node; }
};
///
/// \brief a class for checking if the datastorage is really thread safe
///
/// Therefore it listens to a node contained in the datastorage. when this node
/// gets removed and deleted, this class gets informed by calling OnObjectDelete().
/// in OnObjectDelete() an empty node gets added. this must not cause a deadlock
///
struct ItkDeleteEventListener
{
ItkDeleteEventListener(mitk::DataStorage *ds) : m_Node(nullptr), m_DataStorage(ds), m_DeleteObserverTag(0) {}
void SetNode(mitk::DataNode *_Node)
{
if (m_Node)
return;
m_Node = _Node;
itk::MemberCommand::Pointer onObjectDelete =
itk::MemberCommand::New();
onObjectDelete->SetCallbackFunction(this, &ItkDeleteEventListener::OnObjectDelete);
m_DeleteObserverTag = m_Node->AddObserver(itk::DeleteEvent(), onObjectDelete);
}
void OnObjectDelete(const itk::Object * /*caller*/, const itk::EventObject &)
{
mitk::DataNode::Pointer node = mitk::DataNode::New();
m_DataStorage->Add(node); // SHOULD NOT CAUSE A DEADLOCK!
m_DataStorage->Remove(node); // tidy up: remove the empty node again
m_Node = nullptr;
}
protected:
mitk::DataNode *m_Node;
mitk::DataStorage::Pointer m_DataStorage;
unsigned int m_DeleteObserverTag;
};
//## Documentation
//## main testing method
//## NOTE: the current Singleton implementation of DataTreeStorage will lead to crashes if a testcase fails
//## and therefore mitk::DataStorage::ShutdownSingleton() is not called.
int mitkDataStorageTest(int argc, char *argv[])
{
MITK_TEST_BEGIN("DataStorageTest");
// muellerm: test observer tag remove
mitk::TestStandaloneDataStorage::Pointer testDS = mitk::TestStandaloneDataStorage::New();
mitk::DataNode::Pointer n1 = mitk::DataNode::New();
testDS->Add(n1);
MITK_TEST_CONDITION_REQUIRED(testDS->GetModifiedObserverTags().size() == 1,
"Testing if modified"
" observer was added.");
MITK_TEST_CONDITION_REQUIRED(testDS->GetDeletedObserverTags().size() == 1,
"Testing if delete"
" observer was added.");
testDS->Remove(n1);
MITK_TEST_CONDITION_REQUIRED(testDS->GetModifiedObserverTags().size() == 0,
"Testing if modified"
" observer was removed.");
MITK_TEST_CONDITION_REQUIRED(testDS->GetDeletedObserverTags().size() == 0,
"Testing if delete"
" observer was removed.");
/* Create StandaloneDataStorage */
MITK_TEST_OUTPUT(<< "Create StandaloneDataStorage : ");
mitk::StandaloneDataStorage::Pointer sds;
try
{
sds = mitk::StandaloneDataStorage::New();
MITK_TEST_CONDITION_REQUIRED(sds.IsNotNull(), "Testing Instatiation");
}
catch (...)
{
MITK_TEST_FAILED_MSG(<< "Exception during creation of StandaloneDataStorage");
}
MITK_TEST_OUTPUT(<< "Testing StandaloneDataStorage: ");
MITK_TEST_CONDITION_REQUIRED(argc > 1, "Testing correct test invocation");
TestDataStorage(sds, argv[1]);
// TODO: Add specific StandaloneDataStorage Tests here
sds = nullptr;
MITK_TEST_END();
}
//##Documentation
//## @brief Test for the DataStorage class and its associated classes (e.g. the predicate classes)
//## This method will be called once for each subclass of DataStorage
void TestDataStorage(mitk::DataStorage *ds, std::string filename)
{
/* DataStorage valid? */
MITK_TEST_CONDITION_REQUIRED(ds != nullptr, "DataStorage valid?");
// Take the ItkImageFile Reader for the .nrrd data format.
// (was previously pic which is now deprecated format)
mitk::Image::Pointer image = mitk::IOUtil::Load(filename);
// create some DataNodes to fill the ds
mitk::DataNode::Pointer n1 = mitk::DataNode::New(); // node with image and name property
// mitk::Image::Pointer image = mitk::Image::New();
// unsigned int imageDimensions[] = { 10, 10, 10, 10 };
// mitk::PixelType pt(typeid(int));
// image->Initialize( pt, 4, imageDimensions );
n1->SetData(image);
n1->SetProperty("name", mitk::StringProperty::New("Node 1 - Image Node"));
mitk::DataStorage::SetOfObjects::Pointer parents1 = mitk::DataStorage::SetOfObjects::New();
mitk::DataNode::Pointer n2 = mitk::DataNode::New(); // node with surface and name and color properties
mitk::Surface::Pointer surface = mitk::Surface::New();
n2->SetData(surface);
n2->SetProperty("name", mitk::StringProperty::New("Node 2 - Surface Node"));
mitk::Color color;
color.Set(1.0f, 1.0f, 0.0f);
n2->SetColor(color);
n2->SetProperty("Resection Proposal 1", mitk::GroupTagProperty::New());
mitk::DataStorage::SetOfObjects::Pointer parents2 = mitk::DataStorage::SetOfObjects::New();
parents2->InsertElement(0, n1); // n1 (image node) is source of n2 (surface node)
mitk::DataNode::Pointer n3 = mitk::DataNode::New(); // node without data but with name property
n3->SetProperty("name", mitk::StringProperty::New("Node 3 - Empty Node"));
n3->SetProperty("Resection Proposal 1", mitk::GroupTagProperty::New());
n3->SetProperty("Resection Proposal 2", mitk::GroupTagProperty::New());
mitk::DataStorage::SetOfObjects::Pointer parents3 = mitk::DataStorage::SetOfObjects::New();
parents3->InsertElement(0, n2); // n2 is source of n3
mitk::DataNode::Pointer n4 = mitk::DataNode::New(); // node without data but with color property
n4->SetColor(color);
n4->SetProperty("Resection Proposal 2", mitk::GroupTagProperty::New());
mitk::DataStorage::SetOfObjects::Pointer parents4 = mitk::DataStorage::SetOfObjects::New();
parents4->InsertElement(0, n2);
parents4->InsertElement(1, n3); // n2 and n3 are sources of n4
mitk::DataNode::Pointer n5 = mitk::DataNode::New(); // extra node
n5->SetProperty("name", mitk::StringProperty::New("Node 5"));
try /* adding objects */
{
/* Add an object */
ds->Add(n1, parents1);
MITK_TEST_CONDITION_REQUIRED((ds->GetAll()->Size() == 1) && (ds->GetAll()->GetElement(0) == n1),
"Testing Adding a new object");
/* Check exception on adding the same object again */
MITK_TEST_OUTPUT(<< "Check exception on adding the same object again: ");
MITK_TEST_FOR_EXCEPTION(std::exception, ds->Add(n1, parents1));
MITK_TEST_CONDITION(ds->GetAll()->Size() == 1, "Test if object count is correct after exception");
/* Add an object that has a source object */
ds->Add(n2, parents2);
MITK_TEST_CONDITION_REQUIRED(ds->GetAll()->Size() == 2, "Testing Adding an object that has a source object");
/* Add some more objects needed for further tests */
ds->Add(n3, parents3); // n3 object that has name property and one parent
ds->Add(n4, parents4); // n4 object that has color property
ds->Add(n5); // n5 has no parents
MITK_TEST_CONDITION_REQUIRED(ds->GetAll()->Size() == 5, "Adding some more objects needed for further tests");
}
catch (...)
{
MITK_TEST_FAILED_MSG(<< "Exception during object creation");
}
try /* object retrieval methods */
{
/* Requesting all Objects */
{
const mitk::DataStorage::SetOfObjects::ConstPointer all = ds->GetAll();
std::vector stlAll = all->CastToSTLConstContainer();
MITK_TEST_CONDITION((stlAll.size() == 5) // check if all tree nodes are in resultset
&&
(std::find(stlAll.begin(), stlAll.end(), n1) != stlAll.end()) &&
(std::find(stlAll.begin(), stlAll.end(), n2) != stlAll.end()) &&
(std::find(stlAll.begin(), stlAll.end(), n3) != stlAll.end()) &&
(std::find(stlAll.begin(), stlAll.end(), n4) != stlAll.end()) &&
(std::find(stlAll.begin(), stlAll.end(), n5) != stlAll.end()),
"Testing GetAll()");
}
/* Requesting a named object */
{
mitk::NodePredicateProperty::Pointer predicate(
mitk::NodePredicateProperty::New("name", mitk::StringProperty::New("Node 2 - Surface Node")));
mitk::DataStorage::SetOfObjects::ConstPointer all = ds->GetSubset(predicate);
MITK_TEST_CONDITION((all->Size() == 1) && (all->GetElement(0) == n2), "Requesting a named object");
}
/* Requesting objects of specific data type */
{
mitk::NodePredicateDataType::Pointer predicate(mitk::NodePredicateDataType::New("Image"));
mitk::DataStorage::SetOfObjects::ConstPointer all = ds->GetSubset(predicate);
MITK_TEST_CONDITION((all->Size() == 1) && (all->GetElement(0) == n1), "Requesting objects of specific data type")
}
/* Requesting objects of specific dimension */
{
mitk::NodePredicateDimension::Pointer predicate(mitk::NodePredicateDimension::New(4));
mitk::DataStorage::SetOfObjects::ConstPointer all = ds->GetSubset(predicate);
MITK_TEST_CONDITION((all->Size() == 1) && (all->GetElement(0) == n1), "Requesting objects of specific dimension")
}
/* Requesting objects with specific data object */
{
mitk::NodePredicateData::Pointer predicate(mitk::NodePredicateData::New(image));
mitk::DataStorage::SetOfObjects::ConstPointer all = ds->GetSubset(predicate);
MITK_TEST_CONDITION((all->Size() == 1) && (all->GetElement(0) == n1),
"Requesting objects with specific data object")
}
/* Requesting objects with nullptr data */
{
mitk::NodePredicateData::Pointer predicate(mitk::NodePredicateData::New(nullptr));
mitk::DataStorage::SetOfObjects::ConstPointer all = ds->GetSubset(predicate);
MITK_TEST_CONDITION((all->Size() == 3) && (std::find(all->begin(), all->end(), n3) != all->end()) &&
(std::find(all->begin(), all->end(), n4) != all->end()) &&
(std::find(all->begin(), all->end(), n5) != all->end()),
"Requesting objects with nullptr data");
}
/* Requesting objects that meet a conjunction criteria */
{
mitk::NodePredicateDataType::Pointer p1 = mitk::NodePredicateDataType::New("Surface");
mitk::NodePredicateProperty::Pointer p2 =
mitk::NodePredicateProperty::New("color", mitk::ColorProperty::New(color));
mitk::NodePredicateAnd::Pointer predicate = mitk::NodePredicateAnd::New();
predicate->AddPredicate(p1);
predicate->AddPredicate(p2); // objects must be of datatype "Surface" and have red color (= n2)
const mitk::DataStorage::SetOfObjects::ConstPointer all = ds->GetSubset(predicate);
MITK_TEST_CONDITION((all->Size() == 1) && (all->GetElement(0) == n2),
"Requesting objects that meet a conjunction criteria");
}
/* Requesting objects that meet a disjunction criteria */
{
mitk::NodePredicateDataType::Pointer p1(mitk::NodePredicateDataType::New("Image"));
mitk::NodePredicateProperty::Pointer p2(
mitk::NodePredicateProperty::New("color", mitk::ColorProperty::New(color)));
mitk::NodePredicateOr::Pointer predicate = mitk::NodePredicateOr::New();
predicate->AddPredicate(p1);
predicate->AddPredicate(p2); // objects must be of datatype "Surface" or have red color (= n1, n2, n4)
const mitk::DataStorage::SetOfObjects::ConstPointer all = ds->GetSubset(predicate);
MITK_TEST_CONDITION((all->Size() == 3) && (std::find(all->begin(), all->end(), n1) != all->end()) &&
(std::find(all->begin(), all->end(), n2) != all->end()) &&
(std::find(all->begin(), all->end(), n4) != all->end()),
"Requesting objects that meet a disjunction criteria");
}
/* Requesting objects that do not meet a criteria */
{
mitk::ColorProperty::Pointer cp = mitk::ColorProperty::New(color);
mitk::NodePredicateProperty::Pointer proppred(mitk::NodePredicateProperty::New("color", cp));
mitk::NodePredicateNot::Pointer predicate(mitk::NodePredicateNot::New(proppred));
const mitk::DataStorage::SetOfObjects::ConstPointer all = ds->GetSubset(predicate);
std::vector stlAll = all->CastToSTLConstContainer();
MITK_TEST_CONDITION((all->Size() == 3) // check if correct objects are in resultset
&&
(std::find(stlAll.begin(), stlAll.end(), n1) != stlAll.end()) &&
(std::find(stlAll.begin(), stlAll.end(), n3) != stlAll.end()) &&
(std::find(stlAll.begin(), stlAll.end(), n5) != stlAll.end()),
"Requesting objects that do not meet a criteria");
}
/* Requesting *direct* source objects */
{
const mitk::DataStorage::SetOfObjects::ConstPointer all =
ds->GetSources(n3, nullptr, true); // Get direct parents of n3 (=n2)
std::vector stlAll = all->CastToSTLConstContainer();
MITK_TEST_CONDITION((all->Size() == 1) && (std::find(stlAll.begin(), stlAll.end(), n2) != stlAll.end()),
"Requesting *direct* source objects");
}
/* Requesting *all* source objects */
{
const mitk::DataStorage::SetOfObjects::ConstPointer all =
ds->GetSources(n3, nullptr, false); // Get all parents of n3 (= n1 + n2)
std::vector stlAll = all->CastToSTLConstContainer();
MITK_TEST_CONDITION((all->Size() == 2) && (std::find(stlAll.begin(), stlAll.end(), n1) != stlAll.end()) &&
(std::find(stlAll.begin(), stlAll.end(), n2) != stlAll.end()),
"Requesting *all* source objects"); // check if n1 and n2 are the resultset
}
/* Requesting *all* sources of object with multiple parents */
{
const mitk::DataStorage::SetOfObjects::ConstPointer all =
ds->GetSources(n4, nullptr, false); // Get all parents of n4 (= n1 + n2 + n3)
std::vector stlAll = all->CastToSTLConstContainer();
MITK_TEST_CONDITION(
(all->Size() == 3) && (std::find(stlAll.begin(), stlAll.end(), n1) != stlAll.end()) &&
(std::find(stlAll.begin(), stlAll.end(), n2) != stlAll.end()) &&
(std::find(stlAll.begin(), stlAll.end(), n3) != stlAll.end()) // check if n1 and n2 and n3 are the resultset
,
"Requesting *all* sources of object with multiple parents");
}
/* Requesting *direct* derived objects */
{
const mitk::DataStorage::SetOfObjects::ConstPointer all =
ds->GetDerivations(n1, nullptr, true); // Get direct childs of n1 (=n2)
std::vector stlAll = all->CastToSTLConstContainer();
MITK_TEST_CONDITION((all->Size() == 1) && (std::find(stlAll.begin(), stlAll.end(), n2) !=
stlAll.end()) // check if n1 is the resultset
,
"Requesting *direct* derived objects");
}
///* Requesting *direct* derived objects with multiple parents/derivations */
{
const mitk::DataStorage::SetOfObjects::ConstPointer all =
ds->GetDerivations(n2, nullptr, true); // Get direct childs of n2 (=n3 + n4)
std::vector stlAll = all->CastToSTLConstContainer();
MITK_TEST_CONDITION(
(all->Size() == 2) &&
(std::find(stlAll.begin(), stlAll.end(), n3) != stlAll.end()) // check if n3 is the resultset
&&
(std::find(stlAll.begin(), stlAll.end(), n4) != stlAll.end()) // check if n4 is the resultset
,
"Requesting *direct* derived objects with multiple parents/derivations");
}
//* Requesting *all* derived objects */
{
const mitk::DataStorage::SetOfObjects::ConstPointer all =
ds->GetDerivations(n1, nullptr, false); // Get all childs of n1 (=n2, n3, n4)
std::vector stlAll = all->CastToSTLConstContainer();
MITK_TEST_CONDITION((all->Size() == 3) && (std::find(stlAll.begin(), stlAll.end(), n2) != stlAll.end()) &&
(std::find(stlAll.begin(), stlAll.end(), n3) != stlAll.end()) &&
(std::find(stlAll.begin(), stlAll.end(), n4) != stlAll.end()),
"Requesting *all* derived objects");
}
/* Checking for circular source relationships */
{
parents1->InsertElement(0, n4); // make n1 derived from n4 (which is derived from n2, which is derived from n1)
const mitk::DataStorage::SetOfObjects::ConstPointer all = ds->GetSources(
n4,
nullptr,
false); // Get all parents of n4 (= n1 + n2 + n3, not n4 itself and not multiple versions of the nodes!)
std::vector stlAll = all->CastToSTLConstContainer();
MITK_TEST_CONDITION(
(all->Size() == 3) && (std::find(stlAll.begin(), stlAll.end(), n1) != stlAll.end()) &&
(std::find(stlAll.begin(), stlAll.end(), n2) != stlAll.end()) &&
(std::find(stlAll.begin(), stlAll.end(), n3) != stlAll.end()) // check if n1 and n2 and n3 are the resultset
,
"Checking for circular source relationships");
}
///* Checking for circular derivation relationships can not be performed, because the internal derivations
/// datastructure
// can not be accessed from the outside. (Therefore it should not be possible to create these circular relations
// */
//* Checking GroupTagProperty */
{
mitk::GroupTagProperty::Pointer tp = mitk::GroupTagProperty::New();
mitk::NodePredicateProperty::Pointer pred(mitk::NodePredicateProperty::New("Resection Proposal 1", tp));
const mitk::DataStorage::SetOfObjects::ConstPointer all = ds->GetSubset(pred);
std::vector stlAll = all->CastToSTLConstContainer();
MITK_TEST_CONDITION((all->Size() == 2) // check if n2 and n3 are in resultset
&&
(std::find(stlAll.begin(), stlAll.end(), n2) != stlAll.end()) &&
(std::find(stlAll.begin(), stlAll.end(), n3) != stlAll.end()),
"Checking GroupTagProperty");
}
/* Checking GroupTagProperty 2 */
{
mitk::GroupTagProperty::Pointer tp = mitk::GroupTagProperty::New();
mitk::NodePredicateProperty::Pointer pred(mitk::NodePredicateProperty::New("Resection Proposal 2", tp));
const mitk::DataStorage::SetOfObjects::ConstPointer all = ds->GetSubset(pred);
std::vector stlAll = all->CastToSTLConstContainer();
MITK_TEST_CONDITION((all->Size() == 2) // check if n3 and n4 are in resultset
&&
(std::find(stlAll.begin(), stlAll.end(), n3) != stlAll.end()) &&
(std::find(stlAll.begin(), stlAll.end(), n4) != stlAll.end()),
"Checking GroupTagProperty 2");
}
/* Checking direct sources with condition */
{
mitk::NodePredicateDataType::Pointer pred = mitk::NodePredicateDataType::New("Surface");
const mitk::DataStorage::SetOfObjects::ConstPointer all = ds->GetSources(n4, pred, true);
std::vector stlAll = all->CastToSTLConstContainer();
MITK_TEST_CONDITION((all->Size() == 1) // check if n2 is in resultset
&&
(std::find(stlAll.begin(), stlAll.end(), n2) != stlAll.end()),
"checking direct sources with condition");
}
/* Checking all sources with condition */
{
mitk::NodePredicateDataType::Pointer pred = mitk::NodePredicateDataType::New("Image");
const mitk::DataStorage::SetOfObjects::ConstPointer all = ds->GetSources(n4, pred, false);
std::vector stlAll = all->CastToSTLConstContainer();
MITK_TEST_CONDITION((all->Size() == 1) // check if n1 is in resultset
&&
(std::find(stlAll.begin(), stlAll.end(), n1) != stlAll.end()),
"Checking all sources with condition");
}
/* Checking all sources with condition with empty resultset */
{
mitk::NodePredicateDataType::Pointer pred = mitk::NodePredicateDataType::New("VesselTree");
const mitk::DataStorage::SetOfObjects::ConstPointer all = ds->GetSources(n4, pred, false);
MITK_TEST_CONDITION(all->Size() == 0,
"Checking all sources with condition with empty resultset"); // check if resultset is empty
}
/* Checking direct derivations with condition */
{
mitk::NodePredicateProperty::Pointer pred = mitk::NodePredicateProperty::New("color");
const mitk::DataStorage::SetOfObjects::ConstPointer all = ds->GetDerivations(n1, pred, true);
std::vector stlAll = all->CastToSTLConstContainer();
MITK_TEST_CONDITION((all->Size() == 1) // check if n2 is in resultset
&&
(std::find(stlAll.begin(), stlAll.end(), n2) != stlAll.end()),
"Checking direct derivations with condition");
}
/* Checking all derivations with condition */
{
mitk::NodePredicateProperty::Pointer pred = mitk::NodePredicateProperty::New("color");
const mitk::DataStorage::SetOfObjects::ConstPointer all = ds->GetDerivations(n1, pred, false);
std::vector stlAll = all->CastToSTLConstContainer();
MITK_TEST_CONDITION((all->Size() == 2) // check if n2 and n4 are in resultset
&&
(std::find(stlAll.begin(), stlAll.end(), n2) != stlAll.end()) &&
(std::find(stlAll.begin(), stlAll.end(), n4) != stlAll.end()),
"Checking direct derivations with condition");
}
/* Checking named node method */
MITK_TEST_CONDITION(ds->GetNamedNode("Node 2 - Surface Node") == n2, "Checking named node method");
MITK_TEST_CONDITION(ds->GetNamedNode(std::string("Node 2 - Surface Node")) == n2,
"Checking named node(std::string) method");
/* Checking named node method with wrong name */
MITK_TEST_CONDITION(ds->GetNamedNode("This name does not exist") == nullptr,
"Checking named node method with wrong name");
/* Checking named object method */
MITK_TEST_CONDITION(ds->GetNamedObject("Node 1 - Image Node") == image,
"Checking named object method");
MITK_TEST_CONDITION(ds->GetNamedObject(std::string("Node 1 - Image Node")) == image,
"Checking named object(std::string) method");
/* Checking named object method with wrong DataType */
MITK_TEST_CONDITION(ds->GetNamedObject("Node 1 - Image Node") == nullptr,
"Checking named object method with wrong DataType");
/* Checking named object method with wrong name */
MITK_TEST_CONDITION(ds->GetNamedObject("This name does not exist") == nullptr,
"Checking named object method with wrong name");
/* Checking GetNamedDerivedNode with valid name and direct derivation only */
MITK_TEST_CONDITION(ds->GetNamedDerivedNode("Node 2 - Surface Node", n1, true) == n2,
"Checking GetNamedDerivedNode with valid name & direct derivation only");
/* Checking GetNamedDerivedNode with invalid Name and direct derivation only */
MITK_TEST_CONDITION(ds->GetNamedDerivedNode("wrong name", n1, true) == nullptr,
"Checking GetNamedDerivedNode with invalid name & direct derivation only");
/* Checking GetNamedDerivedNode with invalid Name and direct derivation only */
MITK_TEST_CONDITION(ds->GetNamedDerivedNode("Node 3 - Empty Node", n1, false) == n3,
"Checking GetNamedDerivedNode with invalid name & direct derivation only");
/* Checking GetNamedDerivedNode with valid Name but direct derivation only */
MITK_TEST_CONDITION(ds->GetNamedDerivedNode("Node 3 - Empty Node", n1, true) == nullptr,
"Checking GetNamedDerivedNode with valid Name but direct derivation only");
/* Checking GetNode with valid predicate */
{
mitk::NodePredicateDataType::Pointer p(mitk::NodePredicateDataType::New("Image"));
MITK_TEST_CONDITION(ds->GetNode(p) == n1, "Checking GetNode with valid predicate");
}
/* Checking GetNode with invalid predicate */
{
mitk::NodePredicateDataType::Pointer p(mitk::NodePredicateDataType::New("PointSet"));
MITK_TEST_CONDITION(ds->GetNode(p) == nullptr, "Checking GetNode with invalid predicate");
}
} // object retrieval methods
catch (...)
{
MITK_TEST_FAILED_MSG(<< "Exception during object retrieval (GetXXX() Methods)");
}
try /* object removal methods */
{
/* Checking removal of a node without relations */
{
mitk::DataNode::Pointer extra = mitk::DataNode::New();
extra->SetProperty("name", mitk::StringProperty::New("extra"));
mitk::ReferenceCountWatcher::Pointer watcher = new mitk::ReferenceCountWatcher(extra);
int refCountbeforeDS = watcher->GetReferenceCount();
ds->Add(extra);
MITK_TEST_CONDITION(ds->GetNamedNode("extra") == extra, "Adding extra node");
ds->Remove(extra);
MITK_TEST_CONDITION((ds->GetNamedNode("extra") == nullptr) && (refCountbeforeDS == watcher->GetReferenceCount()),
"Checking removal of a node without relations");
extra = nullptr;
}
/* Checking removal of a node with a parent */
{
mitk::DataNode::Pointer extra = mitk::DataNode::New();
extra->SetProperty("name", mitk::StringProperty::New("extra"));
mitk::ReferenceCountWatcher::Pointer watcher = new mitk::ReferenceCountWatcher(extra);
int refCountbeforeDS = watcher->GetReferenceCount();
ds->Add(extra, n1); // n1 is parent of extra
MITK_TEST_CONDITION((ds->GetNamedNode("extra") == extra) &&
(ds->GetDerivations(n1)->Size() == 2) // n2 and extra should be derived from n1
,
"Adding extra node");
ds->Remove(extra);
MITK_TEST_CONDITION((ds->GetNamedNode("extra") == nullptr) && (refCountbeforeDS == watcher->GetReferenceCount()) &&
(ds->GetDerivations(n1)->Size() == 1),
"Checking removal of a node with a parent");
extra = nullptr;
}
/* Checking removal of a node with two parents */
{
mitk::DataNode::Pointer extra = mitk::DataNode::New();
extra->SetProperty("name", mitk::StringProperty::New("extra"));
mitk::ReferenceCountWatcher::Pointer watcher = new mitk::ReferenceCountWatcher(extra);
int refCountbeforeDS = watcher->GetReferenceCount();
mitk::DataStorage::SetOfObjects::Pointer p = mitk::DataStorage::SetOfObjects::New();
p->push_back(n1);
p->push_back(n2);
ds->Add(extra, p); // n1 and n2 are parents of extra
MITK_TEST_CONDITION((ds->GetNamedNode("extra") == extra) &&
(ds->GetDerivations(n1)->Size() == 2) // n2 and extra should be derived from n1
&&
(ds->GetDerivations(n2)->Size() == 3),
"add extra node");
ds->Remove(extra);
MITK_TEST_CONDITION(
(ds->GetNamedNode("extra") == nullptr) && (refCountbeforeDS == watcher->GetReferenceCount()) &&
(ds->GetDerivations(n1)->Size() == 1) // after remove, only n2 should be derived from n1
&&
(ds->GetDerivations(n2)->Size() == 2) // after remove, only n3 and n4 should be derived from n2
,
"Checking removal of a node with two parents");
extra = nullptr;
}
/* Checking removal of a node with two derived nodes */
{
mitk::DataNode::Pointer extra = mitk::DataNode::New();
extra->SetProperty("name", mitk::StringProperty::New("extra"));
mitk::ReferenceCountWatcher::Pointer watcher = new mitk::ReferenceCountWatcher(extra);
int refCountbeforeDS = watcher->GetReferenceCount();
ds->Add(extra);
mitk::DataNode::Pointer d1 = mitk::DataNode::New();
d1->SetProperty("name", mitk::StringProperty::New("d1"));
ds->Add(d1, extra);
mitk::DataNode::Pointer d2 = mitk::DataNode::New();
d2->SetProperty("name", mitk::StringProperty::New("d2"));
ds->Add(d2, extra);
MITK_TEST_CONDITION((ds->GetNamedNode("extra") == extra) && (ds->GetNamedNode("d1") == d1) &&
(ds->GetNamedNode("d2") == d2) &&
(ds->GetSources(d1)->Size() == 1) // extra should be source of d1
&&
(ds->GetSources(d2)->Size() == 1) // extra should be source of d2
&&
(ds->GetDerivations(extra)->Size() == 2) // d1 and d2 should be derived from extra
,
"add extra node");
ds->Remove(extra);
MITK_TEST_CONDITION((ds->GetNamedNode("extra") == nullptr) && (ds->GetNamedNode("d1") == d1) &&
(ds->GetNamedNode("d2") == d2) && (refCountbeforeDS == watcher->GetReferenceCount()) &&
(ds->GetSources(d1)->Size() == 0) // after remove, d1 should not have a source anymore
&&
(ds->GetSources(d2)->Size() == 0) // after remove, d2 should not have a source anymore
,
"Checking removal of a node with two derived nodes");
extra = nullptr;
}
/* Checking removal of a node with two parents and two derived nodes */
{
mitk::DataNode::Pointer extra = mitk::DataNode::New();
extra->SetProperty("name", mitk::StringProperty::New("extra"));
mitk::ReferenceCountWatcher::Pointer watcher = new mitk::ReferenceCountWatcher(extra);
mitk::ReferenceCountWatcher::Pointer n1watcher = new mitk::ReferenceCountWatcher(n1);
int refCountbeforeDS = watcher->GetReferenceCount();
mitk::DataStorage::SetOfObjects::Pointer p = mitk::DataStorage::SetOfObjects::New();
p->push_back(n1);
p->push_back(n2);
ds->Add(extra, p); // n1 and n2 are parents of extra
mitk::DataNode::Pointer d1 = mitk::DataNode::New();
d1->SetProperty("name", mitk::StringProperty::New("d1x"));
ds->Add(d1, extra);
mitk::DataNode::Pointer d2 = mitk::DataNode::New();
d2->SetProperty("name", mitk::StringProperty::New("d2x"));
ds->Add(d2, extra);
MITK_TEST_CONDITION((ds->GetNamedNode("extra") == extra) && (ds->GetNamedNode("d1x") == d1) &&
(ds->GetNamedNode("d2x") == d2) &&
(ds->GetSources(d1)->Size() == 1) // extra should be source of d1
&&
(ds->GetSources(d2)->Size() == 1) // extra should be source of d2
&&
(ds->GetDerivations(n1)->Size() == 2) // n2 and extra should be derived from n1
&&
(ds->GetDerivations(n2)->Size() == 3) // n3, n4 and extra should be derived from n2
&&
(ds->GetDerivations(extra)->Size() == 2) // d1 and d2 should be derived from extra
,
"add extra node");
ds->Remove(extra);
MITK_TEST_CONDITION(
(ds->GetNamedNode("extra") == nullptr) && (ds->GetNamedNode("d1x") == d1) && (ds->GetNamedNode("d2x") == d2) &&
(refCountbeforeDS == watcher->GetReferenceCount()) &&
(ds->GetDerivations(n1)->Size() == 1) // after remove, only n2 should be derived from n1
&&
(ds->GetDerivations(n2)->Size() == 2) // after remove, only n3 and n4 should be derived from n2
&&
(ds->GetSources(d1)->Size() == 0) // after remove, d1 should not have a source anymore
&&
(ds->GetSources(d2)->Size() == 0) // after remove, d2 should not have a source anymore
,
"Checking removal of a node with two parents and two derived nodes");
extra = nullptr;
}
}
catch (...)
{
MITK_TEST_FAILED_MSG(<< "Exception during object removal methods");
}
/* Checking for node is it's own parent exception */
{
MITK_TEST_FOR_EXCEPTION_BEGIN(std::exception);
mitk::DataNode::Pointer extra = mitk::DataNode::New();
extra->SetProperty("name", mitk::StringProperty::New("extra"));
mitk::DataStorage::SetOfObjects::Pointer p = mitk::DataStorage::SetOfObjects::New();
p->push_back(n1);
p->push_back(extra); // extra is parent of extra!!!
ds->Add(extra, p);
MITK_TEST_FOR_EXCEPTION_END(std::exception);
}
/* Checking reference count of node after add and remove */
{
mitk::DataNode::Pointer extra = mitk::DataNode::New();
mitk::ReferenceCountWatcher::Pointer watcher = new mitk::ReferenceCountWatcher(extra);
extra->SetProperty("name", mitk::StringProperty::New("extra"));
mitk::DataStorage::SetOfObjects::Pointer p = mitk::DataStorage::SetOfObjects::New();
p->push_back(n1);
p->push_back(n3);
ds->Add(extra, p);
extra = nullptr;
ds->Remove(ds->GetNamedNode("extra"));
MITK_TEST_CONDITION(watcher->GetReferenceCount() == 0, "Checking reference count of node after add and remove");
}
/* Checking removal of a node with two derived nodes [ dataStorage->GetDerivations( rootNode )] see bug #3426 */
{
mitk::DataNode::Pointer extra = mitk::DataNode::New();
extra->SetProperty("name", mitk::StringProperty::New("extra"));
ds->Add(extra);
mitk::DataNode::Pointer d1y = mitk::DataNode::New();
d1y->SetProperty("name", mitk::StringProperty::New("d1y"));
mitk::ReferenceCountWatcher::Pointer watcherD1y = new mitk::ReferenceCountWatcher(d1y);
int refCountbeforeDS = watcherD1y->GetReferenceCount();
ds->Add(d1y, extra);
mitk::DataNode::Pointer d2y = mitk::DataNode::New();
d2y->SetProperty("name", mitk::StringProperty::New("d2y"));
ds->Add(d2y, extra);
MITK_TEST_CONDITION((ds->GetNamedNode("extra") == extra) && (ds->GetNamedNode("d1y") == d1y) &&
(ds->GetNamedNode("d2y") == d2y) &&
(ds->GetSources(d1y)->Size() == 1) // extra should be source of d1y
&&
(ds->GetSources(d2y)->Size() == 1) // extra should be source of d2y
&&
(ds->GetDerivations(extra)->Size() == 2) // d1y and d2y should be derived from extra
,
"add extra node");
ds->Remove(ds->GetDerivations(extra));
MITK_TEST_CONDITION((ds->GetNamedNode("extra") == extra) &&
(ds->GetNamedNode("d1y") == nullptr) // d1y should be nullptr now
&&
(ds->GetNamedNode("d2y") == nullptr) // d2y should be nullptr now
&&
(refCountbeforeDS == watcherD1y->GetReferenceCount()),
"Checking removal of subset of two derived nodes from one parent node");
ds->Remove(extra);
MITK_TEST_CONDITION((ds->GetNamedNode("extra") == nullptr), "Checking removal of a parent node");
extra = nullptr;
}
/* Checking GetGrouptags() */
{
const std::set groupTags = ds->GetGroupTags();
MITK_TEST_CONDITION((groupTags.size() == 2) &&
(std::find(groupTags.begin(), groupTags.end(), "Resection Proposal 1") != groupTags.end()) &&
(std::find(groupTags.begin(), groupTags.end(), "Resection Proposal 2") != groupTags.end()),
"Checking GetGrouptags()");
}
/* Checking Event handling */
DSEventReceiver listener;
try
{
ds->AddNodeEvent +=
mitk::MessageDelegate1(&listener, &DSEventReceiver::OnAdd);
ds->RemoveNodeEvent +=
mitk::MessageDelegate1(&listener, &DSEventReceiver::OnRemove);
mitk::DataNode::Pointer extra = mitk::DataNode::New();
mitk::ReferenceCountWatcher::Pointer watcher = new mitk::ReferenceCountWatcher(extra);
ds->Add(extra);
MITK_TEST_CONDITION(listener.m_NodeAdded == extra.GetPointer(), "Checking AddEvent");
ds->Remove(extra);
MITK_TEST_CONDITION(listener.m_NodeRemoved == extra.GetPointer(), "Checking RemoveEvent");
/* RemoveListener */
ds->AddNodeEvent -=
mitk::MessageDelegate1(&listener, &DSEventReceiver::OnAdd);
ds->RemoveNodeEvent -=
mitk::MessageDelegate1(&listener, &DSEventReceiver::OnRemove);
listener.m_NodeAdded = nullptr;
listener.m_NodeRemoved = nullptr;
ds->Add(extra);
ds->Remove(extra);
MITK_TEST_CONDITION((listener.m_NodeRemoved == nullptr) && (listener.m_NodeAdded == nullptr), "Checking RemoveListener");
std::cout << "Pointer handling after event handling: " << std::flush;
extra = nullptr; // delete reference to the node. its memory should be freed now
MITK_TEST_CONDITION(watcher->GetReferenceCount() == 0, "Pointer handling after event handling");
}
catch (...)
{
/* cleanup */
ds->AddNodeEvent -=
mitk::MessageDelegate1(&listener, &DSEventReceiver::OnAdd);
ds->RemoveNodeEvent -=
mitk::MessageDelegate1(&listener, &DSEventReceiver::OnRemove);
MITK_TEST_FAILED_MSG(<< "Exception during object removal methods");
}
// Checking ComputeBoundingGeometry3D method*/
const mitk::DataStorage::SetOfObjects::ConstPointer all = ds->GetAll();
auto geometry = ds->ComputeBoundingGeometry3D();
MITK_TEST_CONDITION(geometry->CountTimeSteps() == 4, "Test for number or time steps with ComputeBoundingGeometry()");
mitk::TimeBounds timebounds = geometry->GetTimeBounds();
MITK_TEST_CONDITION((timebounds[0] == 0) && (timebounds[1] == 4),
"Test for timebounds with ComputeBoundingGeometry()");
for (unsigned int i = 0; i < geometry->CountTimeSteps(); i++)
{
mitk::BaseGeometry::Pointer subGeometry = geometry->GetGeometryForTimeStep(i);
mitk::TimeBounds bounds = geometry->GetTimeBounds(i);
MITK_TEST_CONDITION((bounds[0] == i) && (bounds[1] == i + 1),
"Test for timebounds of geometry at different time steps with ComputeBoundingGeometry()");
}
geometry = ds->ComputeBoundingGeometry3D(all);
MITK_TEST_CONDITION(geometry->CountTimeSteps() == 4,
"Test for number or time steps with ComputeBoundingGeometry(allNodes)");
timebounds = geometry->GetTimeBounds();
MITK_TEST_CONDITION((timebounds[0] == 0) && (timebounds[1] == 4),
"Test for timebounds with ComputeBoundingGeometry(allNodes)");
for (unsigned int i = 0; i < geometry->CountTimeSteps(); i++)
{
mitk::BaseGeometry::Pointer subGeometry = geometry->GetGeometryForTimeStep(i);
mitk::TimeBounds bounds = geometry->GetTimeBounds(i);
MITK_TEST_CONDITION((bounds[0] == i) && (bounds[1] == i + 1),
"Test for timebounds of geometry at different time steps with ComputeBoundingGeometry()");
}
// test for thread safety of DataStorage
try
{
mitk::StandaloneDataStorage::Pointer standaloneDataStorage = mitk::StandaloneDataStorage::New();
ItkDeleteEventListener listener(standaloneDataStorage);
{
mitk::DataNode::Pointer emptyNode = mitk::DataNode::New();
mitk::DataNode *pEmptyNode = emptyNode;
listener.SetNode(emptyNode);
standaloneDataStorage->Add(emptyNode);
emptyNode = nullptr; // emptyNode is still alive because standaloneDataStorage
// owns it
standaloneDataStorage->Remove(pEmptyNode); // this should not freeze the whole thing
}
}
catch (...)
{
MITK_TEST_FAILED_MSG(<< "Exception during testing DataStorage thread safe");
}
/* Clear DataStorage */
ds->Remove(ds->GetAll());
MITK_TEST_CONDITION(ds->GetAll()->Size() == 0, "Checking Clear DataStorage");
}
diff --git a/Modules/Core/test/mitkNodePredicateSourceTest.cpp b/Modules/Core/test/mitkNodePredicateSourceTest.cpp
deleted file mode 100644
index 22a769e09c..0000000000
--- a/Modules/Core/test/mitkNodePredicateSourceTest.cpp
+++ /dev/null
@@ -1,48 +0,0 @@
-/*============================================================================
-
-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 "mitkNodePredicateSource.h"
-#include "mitkStandaloneDataStorage.h"
-#include "mitkTestingMacros.h"
-
-int mitkNodePredicateSourceTest(int /* argc */, char * /*argv*/ [])
-{
- MITK_TEST_BEGIN("Testing nodePredicateSource")
-
- // Create a DataStorage
- mitk::DataStorage::Pointer myDataStorage(mitk::StandaloneDataStorage::New().GetPointer());
- mitk::DataNode::Pointer godfather, grandMother, mother, daughter;
- godfather = mitk::DataNode::New();
- grandMother = mitk::DataNode::New();
- mother = mitk::DataNode::New();
- daughter = mitk::DataNode::New();
-
- myDataStorage->Add(godfather);
- myDataStorage->Add(grandMother);
- myDataStorage->Add(mother, grandMother);
- myDataStorage->Add(daughter, mother);
- mitk::NodePredicateSource::Pointer testPredicate = mitk::NodePredicateSource::New(grandMother, false, myDataStorage);
- ;
-
- MITK_TEST_CONDITION_REQUIRED(true, "Testing instantiation");
- MITK_TEST_CONDITION_REQUIRED(testPredicate->CheckNode(mother), "Node is derivative");
- MITK_TEST_CONDITION_REQUIRED(!testPredicate->CheckNode(godfather), "Node is not derivative");
- MITK_TEST_CONDITION_REQUIRED(!testPredicate->CheckNode(daughter),
- "Node is derivative but only direct derivatives are wanted");
-
- testPredicate = mitk::NodePredicateSource::New(grandMother, true, myDataStorage);
- MITK_TEST_CONDITION_REQUIRED(testPredicate->CheckNode(daughter),
- "Node is not direct derivative and all derivatives are wanted ");
- MITK_TEST_CONDITION_REQUIRED(!testPredicate->CheckNode(grandMother), "Self is not a derivative!");
-
- MITK_TEST_END();
-}
diff --git a/Modules/Multilabel/mitkSegmentationTaskList.cpp b/Modules/Multilabel/mitkSegmentationTaskList.cpp
index 07a102f943..1755207f6a 100644
--- a/Modules/Multilabel/mitkSegmentationTaskList.cpp
+++ b/Modules/Multilabel/mitkSegmentationTaskList.cpp
@@ -1,196 +1,196 @@
/*============================================================================
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 "mitkSegmentationTaskList.h"
#include
#include
mitk::SegmentationTaskList::Task::Task()
: m_Defaults(nullptr)
{
}
mitk::SegmentationTaskList::Task::~Task()
{
}
void mitk::SegmentationTaskList::Task::SetDefaults(const Task* defaults)
{
m_Defaults = defaults;
}
mitk::SegmentationTaskList::SegmentationTaskList()
{
// A base data cannot be serialized if empty. To be not considered empty its
// geometry must consist of at least one time step. However, a segmentation
// task would then appear as invisible spacial object in a scene. This can
// be prevented by excluding it from the scene's bounding box calculations.
this->GetTimeGeometry()->Expand(1);
this->SetProperty("includeInBoundingBox", BoolProperty::New(false));
}
mitk::SegmentationTaskList::SegmentationTaskList(const Self& other)
: BaseData(other)
{
}
mitk::SegmentationTaskList::~SegmentationTaskList()
{
}
size_t mitk::SegmentationTaskList::GetNumberOfTasks() const
{
return m_Tasks.size();
}
size_t mitk::SegmentationTaskList::AddTask(const Task& subtask)
{
m_Tasks.push_back(subtask);
m_Tasks.back().SetDefaults(&m_Defaults);
return m_Tasks.size() - 1;
}
const mitk::SegmentationTaskList::Task* mitk::SegmentationTaskList::GetTask(size_t index) const
{
return &m_Tasks.at(index);
}
mitk::SegmentationTaskList::Task* mitk::SegmentationTaskList::GetTask(size_t index)
{
return &m_Tasks.at(index);
}
const mitk::SegmentationTaskList::Task& mitk::SegmentationTaskList::GetDefaults() const
{
return m_Defaults;
}
void mitk::SegmentationTaskList::SetDefaults(const Task& defaults)
{
m_Defaults = defaults;
for (auto& subtask : m_Tasks)
subtask.SetDefaults(&m_Defaults);
}
bool mitk::SegmentationTaskList::IsDone() const
{
for (size_t i = 0; i < m_Tasks.size(); ++i)
{
if (!this->IsDone(i))
return false;
}
return true;
}
bool mitk::SegmentationTaskList::IsDone(size_t index) const
{
return std::filesystem::exists(this->GetAbsolutePath(m_Tasks.at(index).GetResult()));
}
std::filesystem::path mitk::SegmentationTaskList::GetInputLocation() const
{
std::string inputLocation;
this->GetPropertyList()->GetStringProperty("MITK.IO.reader.inputlocation", inputLocation);
return !inputLocation.empty()
? std::filesystem::path(inputLocation).lexically_normal()
: std::filesystem::path();
}
std::filesystem::path mitk::SegmentationTaskList::GetBasePath() const
{
return this->GetInputLocation().remove_filename();
}
std::filesystem::path mitk::SegmentationTaskList::GetAbsolutePath(const std::filesystem::path& path) const
{
if (path.empty())
return path;
auto normalizedPath = path.lexically_normal();
return !normalizedPath.is_absolute()
? this->GetBasePath() / normalizedPath
: normalizedPath;
}
std::filesystem::path mitk::SegmentationTaskList::GetInterimPath(const std::filesystem::path& path) const
{
if (path.empty() || !path.has_filename())
return path;
auto interimPath = path;
return interimPath.replace_extension(".interim" + path.extension().string());
}
-void mitk::SegmentationTaskList::SaveTask(size_t index, const BaseData* segmentation, bool saveAsIntermediateResult)
+void mitk::SegmentationTaskList::SaveTask(size_t index, const BaseData* segmentation, bool saveAsInterimResult)
{
if (segmentation == nullptr)
return;
auto path = this->GetAbsolutePath(this->GetResult(index));
auto interimPath = this->GetInterimPath(path);
if (std::filesystem::exists(path))
- saveAsIntermediateResult = false;
+ saveAsInterimResult = false;
- IOUtil::Save(segmentation, saveAsIntermediateResult
+ IOUtil::Save(segmentation, saveAsInterimResult
? interimPath.string()
: path.string());
- if (!saveAsIntermediateResult && std::filesystem::exists(interimPath))
+ if (!saveAsInterimResult && std::filesystem::exists(interimPath))
{
std::error_code ec;
std::filesystem::remove(interimPath, ec);
}
}
std::vector::const_iterator mitk::SegmentationTaskList::begin() const
{
return m_Tasks.begin();
}
std::vector::const_iterator mitk::SegmentationTaskList::end() const
{
return m_Tasks.end();
}
std::vector::iterator mitk::SegmentationTaskList::begin()
{
return m_Tasks.begin();
}
std::vector::iterator mitk::SegmentationTaskList::end()
{
return m_Tasks.end();
}
void mitk::SegmentationTaskList::SetRequestedRegionToLargestPossibleRegion()
{
}
bool mitk::SegmentationTaskList::RequestedRegionIsOutsideOfTheBufferedRegion()
{
return false;
}
bool mitk::SegmentationTaskList::VerifyRequestedRegion()
{
return true;
}
void mitk::SegmentationTaskList::SetRequestedRegion(const itk::DataObject*)
{
}
diff --git a/Modules/Multilabel/mitkSegmentationTaskList.h b/Modules/Multilabel/mitkSegmentationTaskList.h
index f1f739d9f5..d57dfd555e 100644
--- a/Modules/Multilabel/mitkSegmentationTaskList.h
+++ b/Modules/Multilabel/mitkSegmentationTaskList.h
@@ -1,111 +1,111 @@
/*============================================================================
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 mitkSegmentationTaskList_h
#define mitkSegmentationTaskList_h
#include
#include
#include
#include
#include
namespace mitk
{
/** \brief A list of segmentation tasks.
*
* See \ref MITKSegmentationTaskListsPage for more information.
*/
class MITKMULTILABEL_EXPORT SegmentationTaskList : public BaseData
{
public:
class MITKMULTILABEL_EXPORT Task
{
public:
Task();
~Task();
void SetDefaults(const Task* defaults);
mitkSegmentationTaskValueMacro(std::string, Name)
mitkSegmentationTaskValueMacro(std::string, Description)
mitkSegmentationTaskValueMacro(std::filesystem::path, Image)
mitkSegmentationTaskValueMacro(std::filesystem::path, Segmentation)
mitkSegmentationTaskValueMacro(std::string, LabelName)
mitkSegmentationTaskValueMacro(std::filesystem::path, LabelNameSuggestions)
mitkSegmentationTaskValueMacro(std::filesystem::path, Preset)
mitkSegmentationTaskValueMacro(std::filesystem::path, Result)
mitkSegmentationTaskValueMacro(bool, Dynamic)
private:
const Task* m_Defaults;
};
mitkClassMacro(SegmentationTaskList, BaseData)
itkFactorylessNewMacro(Self)
itkCloneMacro(Self)
mitkSegmentationTaskListValueMacro(std::string, Name)
mitkSegmentationTaskListValueMacro(std::string, Description)
mitkSegmentationTaskListValueMacro(std::filesystem::path, Image)
mitkSegmentationTaskListValueMacro(std::filesystem::path, Segmentation)
mitkSegmentationTaskListValueMacro(std::string, LabelName)
mitkSegmentationTaskListValueMacro(std::filesystem::path, LabelNameSuggestions)
mitkSegmentationTaskListValueMacro(std::filesystem::path, Preset)
mitkSegmentationTaskListValueMacro(std::filesystem::path, Result)
mitkSegmentationTaskListValueMacro(bool, Dynamic)
size_t GetNumberOfTasks() const;
size_t AddTask(const Task& subtask);
const Task* GetTask(size_t index) const;
Task* GetTask(size_t index);
const Task& GetDefaults() const;
void SetDefaults(const Task& defaults);
bool IsDone() const;
bool IsDone(size_t index) const;
std::filesystem::path GetInputLocation() const;
std::filesystem::path GetBasePath() const;
std::filesystem::path GetAbsolutePath(const std::filesystem::path& path) const;
std::filesystem::path GetInterimPath(const std::filesystem::path& path) const;
- void SaveTask(size_t index, const BaseData* segmentation, bool saveAsIntermediateResult = false);
+ void SaveTask(size_t index, const BaseData* segmentation, bool saveAsInterimResult = false);
std::vector::const_iterator begin() const;
std::vector::const_iterator end() const;
std::vector::iterator begin();
std::vector::iterator end();
void SetRequestedRegionToLargestPossibleRegion() override;
bool RequestedRegionIsOutsideOfTheBufferedRegion() override;
bool VerifyRequestedRegion() override;
void SetRequestedRegion(const itk::DataObject*) override;
protected:
mitkCloneMacro(Self)
SegmentationTaskList();
SegmentationTaskList(const Self& other);
~SegmentationTaskList() override;
private:
Task m_Defaults;
std::vector m_Tasks;
};
}
#endif
diff --git a/Modules/QtWidgets/resource/Qmitk.qrc b/Modules/QtWidgets/resource/Qmitk.qrc
index 773e1502be..377d75c396 100644
--- a/Modules/QtWidgets/resource/Qmitk.qrc
+++ b/Modules/QtWidgets/resource/Qmitk.qrc
@@ -1,33 +1,34 @@
Binaerbilder_48.png
Images_48.png
PointSet_48.png
Segmentation_48.png
Surface_48.png
mm_pointer.png
mm_scroll.png
mm_zoom.png
mm_contrast.png
mm_pan.png
LabelSetImage_48.png
mwLayout.png
mwSynchronized.png
mwDesynchronized.png
mwMITK.png
mwPACS.png
star-solid.svg
history-solid.svg
tree_inspector.svg
list-solid.svg
favorite_add.svg
favorite_remove.svg
hourglass-half-solid.svg
times.svg
reset.svg
lock.svg
unlock.svg
invisible.svg
visible.svg
+ SegmentationTaskListIcon.svg
diff --git a/Plugins/org.mitk.gui.qt.flow.segmentation/resources/SegmentationTaskListIcon.svg b/Modules/QtWidgets/resource/SegmentationTaskListIcon.svg
similarity index 100%
copy from Plugins/org.mitk.gui.qt.flow.segmentation/resources/SegmentationTaskListIcon.svg
copy to Modules/QtWidgets/resource/SegmentationTaskListIcon.svg
diff --git a/Modules/QtWidgets/src/QmitkDataStorageFilterProxyModel.cpp b/Modules/QtWidgets/src/QmitkDataStorageFilterProxyModel.cpp
index 6113f8c1d1..8f71e7da03 100644
--- a/Modules/QtWidgets/src/QmitkDataStorageFilterProxyModel.cpp
+++ b/Modules/QtWidgets/src/QmitkDataStorageFilterProxyModel.cpp
@@ -1,80 +1,79 @@
/*============================================================================
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
#include
-#include
#include
#include
#include
#include
#include
#include
#include
#include "QmitkDataStorageFilterProxyModel.h"
#include "QmitkDataStorageTreeModel.h"
#include "QmitkNodeDescriptorManager.h"
#include
#include
#include
#include
#include
#include
").arg(isDone
? ColorString("Done", Qt::white, QColor(Qt::green).darker())
: ColorString("Not done", Qt::white, QColor(Qt::red).darker()));
}
if (m_TaskList->HasDescription(current))
details += QString("Description: %1
").arg(QString::fromStdString(m_TaskList->GetDescription(current)));
QStringList stringList;
if (m_TaskList->HasImage(current))
stringList << QString::fromStdString("Image: " + m_TaskList->GetImage(current).string());
if (m_TaskList->HasSegmentation(current))
stringList << QString::fromStdString("Segmentation: " + m_TaskList->GetSegmentation(current).string());
if (m_TaskList->HasLabelName(current))
stringList << QString::fromStdString("Label name: " + m_TaskList->GetLabelName(current));
if (m_TaskList->HasLabelNameSuggestions(current))
stringList << QString::fromStdString("Label name suggestions: " + m_TaskList->GetLabelNameSuggestions(current).string());
if (m_TaskList->HasPreset(current))
stringList << QString::fromStdString("Label set preset: " + m_TaskList->GetPreset(current).string());
if (m_TaskList->HasDynamic(current))
stringList << QString("Segmentation type: %1").arg(m_TaskList->GetDynamic(current) ? "Dynamic" : "Static");
if (!stringList.empty())
details += QString("%1
").arg(stringList.join(QStringLiteral("
")));
m_Ui->detailsLabel->setText(details);
}
+void QmitkSegmentationTaskListWidget::UpdateStoreAndAcceptButtons()
+{
+ auto activeTaskIsShown = this->ActiveTaskIsShown();
+
+ m_Ui->storeButton->setVisible(activeTaskIsShown);
+ m_Ui->acceptButton->setEnabled(activeTaskIsShown);
+}
+
/* Load/activate the currently displayed task. Unload all data nodes from
* previously active tasks first, but spare and reuse the image if possible.
*/
void QmitkSegmentationTaskListWidget::OnLoadButtonClicked()
{
if (!this->HandleUnsavedChanges() || m_UnsavedChanges)
return;
m_Ui->loadButton->setEnabled(false);
QApplication::setOverrideCursor(Qt::BusyCursor);
this->LoadTask(this->GetImageDataNode(m_CurrentTaskIndex.value()));
QApplication::restoreOverrideCursor();
}
/* If present, return the image data node for the task with the specified
* index. Otherwise, return nullptr.
*/
mitk::DataNode* QmitkSegmentationTaskListWidget::GetImageDataNode(size_t index) const
{
const auto imagePath = m_TaskList->GetAbsolutePath(m_TaskList->GetImage(index));
auto imageNodes = m_DataStorage->GetDerivations(m_TaskListNode, mitk::NodePredicateFunction::New([imagePath](const mitk::DataNode* node) {
return imagePath == GetInputLocation(node->GetData());
}));
return !imageNodes->empty()
? imageNodes->front()
: nullptr;
}
/* If present, return the segmentation data node for the task with the
* specified index. Otherwise, return nullptr.
*/
mitk::DataNode* QmitkSegmentationTaskListWidget::GetSegmentationDataNode(size_t index) const
{
const auto* imageNode = this->GetImageDataNode(index);
if (imageNode != nullptr)
{
auto segmentations = m_DataStorage->GetDerivations(imageNode, mitk::TNodePredicateDataType::New());
if (!segmentations->empty())
return segmentations->front();
}
return nullptr;
}
/* Unload all task data nodes but spare the passed image data node.
*/
void QmitkSegmentationTaskListWidget::UnloadTasks(const mitk::DataNode* skip)
{
this->UnsubscribeFromActiveSegmentation();
if (m_TaskListNode.IsNotNull())
{
auto imageNodes = m_DataStorage->GetDerivations(m_TaskListNode, mitk::TNodePredicateDataType::New());
for (auto imageNode : *imageNodes)
{
m_DataStorage->Remove(m_DataStorage->GetDerivations(imageNode, nullptr, false));
if (imageNode != skip)
m_DataStorage->Remove(imageNode);
}
}
this->SetActiveTaskIndex(std::nullopt);
}
void QmitkSegmentationTaskListWidget::LoadNextUnfinishedTask()
{
const auto current = m_CurrentTaskIndex.value();
const auto numTasks = m_TaskList->GetNumberOfTasks();
for (size_t unboundNext = current; unboundNext < current + numTasks; ++unboundNext)
{
auto next = unboundNext % numTasks;
if (!m_TaskList->IsDone(next))
{
this->SetCurrentTaskIndex(next);
this->OnLoadButtonClicked();
break;
}
}
}
/* Load/activate the currently displayed task. The task must specify
* an image. The segmentation is either created from scratch with an optional
* name for the first label, possibly based on a label set preset specified by
* the task, or loaded as specified by the task. If a result file does
* exist, it is chosen as segmentation instead.
*/
void QmitkSegmentationTaskListWidget::LoadTask(mitk::DataNode::Pointer imageNode)
{
this->UnloadTasks(imageNode);
const auto current = m_CurrentTaskIndex.value();
mitk::Image::Pointer image;
mitk::LabelSetImage::Pointer segmentation;
try
{
if (imageNode.IsNull())
{
const auto path = m_TaskList->GetAbsolutePath(m_TaskList->GetImage(current));
image = mitk::IOUtil::Load(path.string());
}
const auto path = m_TaskList->GetAbsolutePath(m_TaskList->GetResult(current));
const auto interimPath = m_TaskList->GetInterimPath(path);
if (std::filesystem::exists(path))
{
segmentation = mitk::IOUtil::Load(path.string());
}
else if (std::filesystem::exists(interimPath))
{
segmentation = mitk::IOUtil::Load(interimPath.string());
}
else if (m_TaskList->HasSegmentation(current))
{
const auto path = m_TaskList->GetAbsolutePath(m_TaskList->GetSegmentation(current));
segmentation = mitk::IOUtil::Load(path.string());
}
}
catch (const mitk::Exception&)
{
return;
}
if (imageNode.IsNull())
{
imageNode = mitk::DataNode::New();
imageNode->SetData(image);
m_DataStorage->Add(imageNode, m_TaskListNode);
mitk::RenderingManager::GetInstance()->InitializeViews(image->GetTimeGeometry());
}
else
{
image = static_cast(imageNode->GetData());
}
auto name = "Task " + std::to_string(current + 1);
imageNode->SetName(name);
if (segmentation.IsNull())
{
mitk::Image::ConstPointer templateImage = image;
if (templateImage->GetDimension() > 3)
{
if (m_TaskList->HasDynamic(current))
{
if (!m_TaskList->GetDynamic(current))
templateImage = mitk::SegmentationHelper::GetStaticSegmentationTemplate(image);
}
else
{
QmitkStaticDynamicSegmentationDialog dialog(this);
dialog.SetReferenceImage(templateImage);
dialog.exec();
templateImage = dialog.GetSegmentationTemplate();
}
}
auto segmentationNode = mitk::LabelSetImageHelper::CreateNewSegmentationNode(imageNode, templateImage, name);
segmentation = static_cast(segmentationNode->GetData());
if (m_TaskList->HasPreset(current))
{
const auto path = m_TaskList->GetAbsolutePath(m_TaskList->GetPreset(current));
mitk::LabelSetIOHelper::LoadLabelSetImagePreset(path.string(), segmentation);
}
else
{
auto label = mitk::LabelSetImageHelper::CreateNewLabel(segmentation);
if (m_TaskList->HasLabelName(current))
label->SetName(m_TaskList->GetLabelName(current));
segmentation->GetActiveLabelSet()->AddLabel(label);
}
m_DataStorage->Add(segmentationNode, imageNode);
}
else
{
auto segmentationNode = mitk::DataNode::New();
segmentationNode->SetName(name);
segmentationNode->SetData(segmentation);
m_DataStorage->Add(segmentationNode, imageNode);
}
// Workaround for T29431. Remove when T26953 is fixed.
mitk::DICOMQIPropertyHelper::DeriveDICOMSourceProperties(image, segmentation);
auto prefs = GetSegmentationPreferences();
if (prefs != nullptr)
{
if (m_TaskList->HasLabelNameSuggestions(current))
{
auto path = m_TaskList->GetAbsolutePath(m_TaskList->GetLabelNameSuggestions(current));
prefs->PutBool("default label naming", false);
prefs->Put("label suggestions", path.string());
prefs->PutBool("replace standard suggestions", true);
prefs->PutBool("suggest once", true);
}
else
{
prefs->PutBool("default label naming", true);
prefs->Put("label suggestions", "");
}
}
m_UnsavedChanges = false;
this->SetActiveTaskIndex(current);
this->SubscribeToActiveSegmentation();
this->OnCurrentTaskChanged();
}
void QmitkSegmentationTaskListWidget::SubscribeToActiveSegmentation()
{
if (m_ActiveTaskIndex.has_value())
{
auto segmentationNode = this->GetSegmentationDataNode(m_ActiveTaskIndex.value());
if (segmentationNode != nullptr)
{
auto segmentation = static_cast(segmentationNode->GetData());
auto command = itk::SimpleMemberCommand::New();
command->SetCallbackFunction(this, &QmitkSegmentationTaskListWidget::OnSegmentationModified);
m_SegmentationModifiedObserverTag = segmentation->AddObserver(itk::ModifiedEvent(), command);
}
}
}
void QmitkSegmentationTaskListWidget::UnsubscribeFromActiveSegmentation()
{
if (m_ActiveTaskIndex.has_value() && m_SegmentationModifiedObserverTag.has_value())
{
auto segmentationNode = this->GetSegmentationDataNode(m_ActiveTaskIndex.value());
if (segmentationNode != nullptr)
{
auto segmentation = static_cast(segmentationNode->GetData());
segmentation->RemoveObserver(m_SegmentationModifiedObserverTag.value());
}
m_SegmentationModifiedObserverTag.reset();
}
}
void QmitkSegmentationTaskListWidget::OnSegmentationModified()
{
if (!m_UnsavedChanges)
{
m_UnsavedChanges = true;
if (m_ActiveTaskIndex.value() == m_CurrentTaskIndex)
this->UpdateDetailsLabel();
}
}
void QmitkSegmentationTaskListWidget::SetActiveTaskIndex(const std::optional& index)
{
if (m_ActiveTaskIndex != index)
{
m_ActiveTaskIndex = index;
- emit ActiveTaskChanged(m_ActiveTaskIndex);
+ this->UpdateStoreAndAcceptButtons();
}
}
void QmitkSegmentationTaskListWidget::SetCurrentTaskIndex(const std::optional& index)
{
if (m_CurrentTaskIndex != index)
{
m_CurrentTaskIndex = index;
this->OnCurrentTaskChanged();
- emit CurrentTaskChanged(m_CurrentTaskIndex);
+
}
}
bool QmitkSegmentationTaskListWidget::ActiveTaskIsShown() const
{
return m_ActiveTaskIndex.has_value() && m_CurrentTaskIndex.has_value() && m_ActiveTaskIndex == m_CurrentTaskIndex;
}
bool QmitkSegmentationTaskListWidget::HandleUnsavedChanges(const QString& alternativeTitle)
{
if (m_UnsavedChanges)
{
const auto active = m_ActiveTaskIndex.value();
const auto current = m_CurrentTaskIndex.value();
QString title;
if (alternativeTitle.isEmpty())
{
title = QString("Load task %1").arg(current + 1);
if (m_TaskList->HasName(current))
title += ": " + QString::fromStdString(m_TaskList->GetName(current));
}
else
{
title = alternativeTitle;
}
auto text = QString("The currently active task %1 ").arg(active + 1);
if (m_TaskList->HasName(active))
text += "(" + QString::fromStdString(m_TaskList->GetName(active)) + ") ";
text += "has unsaved changes.";
auto reply = QMessageBox::question(this, title, text, QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel, QMessageBox::Cancel);
switch (reply)
{
case QMessageBox::Save:
this->SaveActiveTask(!std::filesystem::exists(m_TaskList->GetResult(active)));
break;
case QMessageBox::Discard:
m_UnsavedChanges = false;
break;
default:
return false;
}
}
return true;
}
void QmitkSegmentationTaskListWidget::SaveActiveTask(bool saveAsIntermediateResult)
{
if (!m_ActiveTaskIndex.has_value())
return;
QApplication::setOverrideCursor(Qt::BusyCursor);
try
{
const auto active = m_ActiveTaskIndex.value();
m_TaskList->SaveTask(active, this->GetSegmentationDataNode(active)->GetData(), saveAsIntermediateResult);
this->OnUnsavedChangesSaved();
}
catch (const mitk::Exception& e)
{
MITK_ERROR << e;
}
QApplication::restoreOverrideCursor();
}
bool QmitkSegmentationTaskListWidget::OnPreShutdown()
{
return this->HandleUnsavedChanges(QStringLiteral("Application shutdown"));
}
void QmitkSegmentationTaskListWidget::OnPreviousTaskShortcutActivated()
{
m_Ui->previousButton->click();
}
void QmitkSegmentationTaskListWidget::OnNextTaskShortcutActivated()
{
m_Ui->nextButton->click();
}
void QmitkSegmentationTaskListWidget::OnLoadTaskShortcutActivated()
{
m_Ui->loadButton->click();
}
+
+void QmitkSegmentationTaskListWidget::OnStoreInterimResultShortcutActivated()
+{
+ m_Ui->storeButton->click();
+}
+
+void QmitkSegmentationTaskListWidget::OnAcceptSegmentationShortcutActivated()
+{
+ m_Ui->acceptButton->click();
+}
+
+void QmitkSegmentationTaskListWidget::OnStoreButtonClicked()
+{
+ this->SaveActiveTask(true);
+}
+
+void QmitkSegmentationTaskListWidget::OnAcceptButtonClicked()
+{
+ auto* toolManager = mitk::ToolManagerProvider::GetInstance()->GetToolManager();
+ int activeToolId = -1;
+
+ if (toolManager != nullptr)
+ activeToolId = toolManager->GetActiveToolID();
+
+ this->SaveActiveTask();
+ this->LoadNextUnfinishedTask();
+
+ if (toolManager != nullptr)
+ toolManager->ActivateTool(activeToolId);
+}
diff --git a/Modules/SegmentationUI/Qmitk/QmitkSegmentationTaskListWidget.h b/Modules/SegmentationUI/Qmitk/QmitkSegmentationTaskListWidget.h
index d8aebca780..33813a7722 100644
--- a/Modules/SegmentationUI/Qmitk/QmitkSegmentationTaskListWidget.h
+++ b/Modules/SegmentationUI/Qmitk/QmitkSegmentationTaskListWidget.h
@@ -1,93 +1,99 @@
/*============================================================================
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 QmitkSegmentationTaskListWidget_h
#define QmitkSegmentationTaskListWidget_h
#include
#include
#include
#include
#include
class QFileSystemWatcher;
namespace Ui
{
class QmitkSegmentationTaskListWidget;
}
class MITKSEGMENTATIONUI_EXPORT QmitkSegmentationTaskListWidget : public QWidget
{
Q_OBJECT
public:
explicit QmitkSegmentationTaskListWidget(QWidget* parent = nullptr);
~QmitkSegmentationTaskListWidget() override;
void SetDataStorage(mitk::DataStorage* dataStorage);
+ void CheckDataStorage(const mitk::DataNode* removedNode = nullptr);
bool ActiveTaskIsShown() const;
void LoadNextUnfinishedTask();
void SaveActiveTask(bool saveAsIntermediateResult = false);
bool OnPreShutdown();
signals:
void ActiveTaskChanged(const std::optional& index);
void CurrentTaskChanged(const std::optional& index);
private:
void OnSelectionChanged(const QmitkSingleNodeSelectionWidget::NodeList& nodes);
void ResetControls();
void SetTaskList(mitk::SegmentationTaskList* task);
void ResetFileSystemWatcher();
void OnResultDirectoryChanged(const QString&);
void UpdateProgressBar();
void OnTaskListChanged(mitk::SegmentationTaskList* task);
void OnPreviousButtonClicked();
void OnNextButtonClicked();
void OnCurrentTaskChanged();
void UpdateLoadButton();
void UpdateNavigationButtons();
void UpdateDetailsLabel();
+ void UpdateStoreAndAcceptButtons();
void OnLoadButtonClicked();
mitk::DataNode* GetImageDataNode(size_t index) const;
void UnloadTasks(const mitk::DataNode* skip = nullptr);
void LoadTask(mitk::DataNode::Pointer imageNode = nullptr);
void SubscribeToActiveSegmentation();
void UnsubscribeFromActiveSegmentation();
void OnSegmentationModified();
void SetActiveTaskIndex(const std::optional& index);
void SetCurrentTaskIndex(const std::optional& index);
bool HandleUnsavedChanges(const QString& alternativeTitle = QString());
mitk::DataNode* GetSegmentationDataNode(size_t index) const;
void OnUnsavedChangesSaved();
void OnPreviousTaskShortcutActivated();
void OnNextTaskShortcutActivated();
void OnLoadTaskShortcutActivated();
+ void OnStoreInterimResultShortcutActivated();
+ void OnAcceptSegmentationShortcutActivated();
+ void OnStoreButtonClicked();
+ void OnAcceptButtonClicked();
Ui::QmitkSegmentationTaskListWidget* m_Ui;
QFileSystemWatcher* m_FileSystemWatcher;
mitk::DataStorage* m_DataStorage;
mitk::SegmentationTaskList::Pointer m_TaskList;
mitk::DataNode::Pointer m_TaskListNode;
std::optional m_CurrentTaskIndex;
std::optional m_ActiveTaskIndex;
std::optional m_SegmentationModifiedObserverTag;
bool m_UnsavedChanges;
};
#endif
diff --git a/Modules/SegmentationUI/Qmitk/QmitkSegmentationTaskListWidget.ui b/Modules/SegmentationUI/Qmitk/QmitkSegmentationTaskListWidget.ui
index db3f206306..9fa63f8100 100644
--- a/Modules/SegmentationUI/Qmitk/QmitkSegmentationTaskListWidget.ui
+++ b/Modules/SegmentationUI/Qmitk/QmitkSegmentationTaskListWidget.ui
@@ -1,150 +1,240 @@
QmitkSegmentationTaskListWidget
0
0
- 299
- 329
+ 288
+ 478
Segmentation Task List
-
- 0
-
-
- 0
-
-
- 0
-
-
- 0
-
-
-
-
- Segmentation Task List
+
+
+
+
+ Qt::RichText
+
+
+ true
+
+
+
+ -
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
-
0
40
-
0
40
0
Qt::AlignCenter
-
-
40
40
Previous subtask
Qt::LeftArrow
-
0
40
Load subtask
-
40
40
Next subtask
Qt::RightArrow
-
+
+
+
-
+
0
0
-
-
-
Qt::RichText
Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop
true
+
+ true
+
+ -
+
+
-
+
+
+
+ 50
+ 50
+
+
+
+
+ 50
+ 50
+
+
+
+ Save interim segmentation
+
+
+
+ 32
+ 32
+
+
+
+
+ -
+
+
+
+ 0
+ 50
+
+
+
+ Save and accept segmentation
+
+
+ Accept segmentation
+
+
+
+ 32
+ 32
+
+
+
+
+
+
+ -
+
+
+ Qt::Vertical
+
+
+
+ 20
+ 40
+
+
+
+
+ -
+
+
+ Qt::Vertical
+
+
+
+ 20
+ 40
+
+
+
+
QmitkSingleNodeSelectionWidget
QWidget
QmitkSingleNodeSelectionWidget.h
1
diff --git a/Plugins/org.mitk.gui.qt.application/src/QmitkDataNodeContextMenu.cpp b/Plugins/org.mitk.gui.qt.application/src/QmitkDataNodeContextMenu.cpp
index 4afd52578c..b7e0afe75d 100644
--- a/Plugins/org.mitk.gui.qt.application/src/QmitkDataNodeContextMenu.cpp
+++ b/Plugins/org.mitk.gui.qt.application/src/QmitkDataNodeContextMenu.cpp
@@ -1,488 +1,488 @@
/*============================================================================
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
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
QmitkDataNodeContextMenu::QmitkDataNodeContextMenu(berry::IWorkbenchPartSite::Pointer workbenchPartSite, QWidget* parent)
: QMenu(parent),
m_Parent(parent),
m_WorkbenchPartSite(workbenchPartSite)
{
this->InitNodeDescriptors();
this->InitDefaultActions();
this->InitExtensionPointActions();
}
QmitkDataNodeContextMenu::~QmitkDataNodeContextMenu()
{
for (auto& descriptorActionPair : m_DescriptorActionList)
descriptorActionPair.first->RemoveAction(descriptorActionPair.second);
}
void QmitkDataNodeContextMenu::SetDataStorage(mitk::DataStorage* dataStorage)
{
m_DataStorage = dataStorage;
for (auto& descriptorActionPair : m_DescriptorActionList)
{
auto dataNodeAction = dynamic_cast(descriptorActionPair.second);
if (nullptr != dataNodeAction)
dataNodeAction->SetDataStorage(dataStorage);
}
}
void QmitkDataNodeContextMenu::SetBaseRenderer(mitk::BaseRenderer* baseRenderer)
{
m_BaseRenderer = baseRenderer;
for (auto& descriptorActionPair : m_DescriptorActionList)
{
auto dataNodeAction = dynamic_cast(descriptorActionPair.second);
if (nullptr != dataNodeAction)
dataNodeAction->SetBaseRenderer(baseRenderer);
}
}
void QmitkDataNodeContextMenu::SetSurfaceDecimation(bool surfaceDecimation)
{
m_SurfaceDecimation = surfaceDecimation;
}
void QmitkDataNodeContextMenu::SetSelectedNodes(const QList& selectedNodes)
{
m_SelectedNodes = selectedNodes;
}
void QmitkDataNodeContextMenu::InitNodeDescriptors()
{
auto nodeDescriptorManager = QmitkNodeDescriptorManager::GetInstance();
m_UnknownDataNodeDescriptor = nodeDescriptorManager->GetUnknownDataNodeDescriptor();
m_ImageDataNodeDescriptor = nodeDescriptorManager->GetDescriptor("Image");
m_MultiComponentImageDataNodeDescriptor = nodeDescriptorManager->GetDescriptor("MultiComponentImage");
m_DiffusionImageDataNodeDescriptor = nodeDescriptorManager->GetDescriptor("DiffusionImage");
m_FiberBundleDataNodeDescriptor = nodeDescriptorManager->GetDescriptor("FiberBundle");
m_PeakImageDataNodeDescriptor = nodeDescriptorManager->GetDescriptor("PeakImage");
m_SegmentDataNodeDescriptor = nodeDescriptorManager->GetDescriptor("Segment");
m_SurfaceDataNodeDescriptor = nodeDescriptorManager->GetDescriptor("Surface");
m_PointSetNodeDescriptor = nodeDescriptorManager->GetDescriptor("PointSet");
m_PlanarLineNodeDescriptor = nodeDescriptorManager->GetDescriptor("PlanarLine");
m_PlanarCircleNodeDescriptor = nodeDescriptorManager->GetDescriptor("PlanarCircle");
m_PlanarEllipseNodeDescriptor = nodeDescriptorManager->GetDescriptor("PlanarEllipse");
m_PlanarAngleNodeDescriptor = nodeDescriptorManager->GetDescriptor("PlanarAngle");
m_PlanarFourPointAngleNodeDescriptor = nodeDescriptorManager->GetDescriptor("PlanarFourPointAngle");
m_PlanarRectangleNodeDescriptor = nodeDescriptorManager->GetDescriptor("PlanarRectangle");
m_PlanarPolygonNodeDescriptor = nodeDescriptorManager->GetDescriptor("PlanarPolygon");
m_PlanarPathNodeDescriptor = nodeDescriptorManager->GetDescriptor("PlanarPath");
m_PlanarDoubleEllipseNodeDescriptor = nodeDescriptorManager->GetDescriptor("PlanarDoubleEllipse");
m_PlanarBezierCurveNodeDescriptor = nodeDescriptorManager->GetDescriptor("PlanarBezierCurve");
m_PlanarSubdivisionPolygonNodeDescriptor = nodeDescriptorManager->GetDescriptor("PlanarSubdivisionPolygon");
}
void QmitkDataNodeContextMenu::InitDefaultActions()
{
auto workbenchPartSite = m_WorkbenchPartSite.Lock();
m_GlobalReinitAction = new QmitkDataNodeGlobalReinitAction(m_Parent, workbenchPartSite);
m_GlobalReinitAction->setIcon(QIcon(":/org.mitk.gui.qt.datamanager/Refresh_48.png"));
m_UnknownDataNodeDescriptor->AddAction(m_GlobalReinitAction, true);
m_DescriptorActionList.push_back(std::make_pair(m_UnknownDataNodeDescriptor, m_GlobalReinitAction));
m_ReinitAction = new QmitkDataNodeReinitAction(m_Parent, workbenchPartSite);
m_ReinitAction->setIcon(QIcon(":/org.mitk.gui.qt.datamanager/Refresh_48.png"));
m_UnknownDataNodeDescriptor->AddAction(m_ReinitAction, true);
m_DescriptorActionList.push_back(std::make_pair(m_UnknownDataNodeDescriptor, m_ReinitAction));
m_ResetGeometryAction = new QmitkDataNodeResetGeometryAction(m_Parent, workbenchPartSite);
m_ResetGeometryAction->setIcon(QIcon(":/org.mitk.gui.qt.datamanager/Refresh_48.png"));
m_UnknownDataNodeDescriptor->AddAction(m_ResetGeometryAction, true);
m_DescriptorActionList.push_back(std::make_pair(m_UnknownDataNodeDescriptor, m_ResetGeometryAction));
QAction* saveAction = new QmitkFileSaveAction(QIcon(":/org.mitk.gui.qt.datamanager/Save_48.png"), workbenchPartSite->GetWorkbenchWindow());
m_UnknownDataNodeDescriptor->AddAction(saveAction, true);
m_DescriptorActionList.push_back(std::make_pair(m_UnknownDataNodeDescriptor, saveAction));
m_RemoveAction = new QmitkDataNodeRemoveAction(m_Parent, workbenchPartSite);
m_RemoveAction->setIcon(QIcon(":/org.mitk.gui.qt.datamanager/Remove_48.png"));
m_UnknownDataNodeDescriptor->AddAction(m_RemoveAction, true);
m_DescriptorActionList.push_back(std::make_pair(m_UnknownDataNodeDescriptor, m_RemoveAction));
m_ShowSelectedNodesAction = new QmitkDataNodeShowSelectedNodesAction(m_Parent, workbenchPartSite);
- m_RemoveAction->setIcon(QIcon(":/org.mitk.gui.qt.datamanager/ShowSelectedNode_48.png"));
+ m_ShowSelectedNodesAction->setIcon(QIcon(":/org.mitk.gui.qt.datamanager/ShowSelectedNode_48.png"));
m_UnknownDataNodeDescriptor->AddAction(m_ShowSelectedNodesAction, true);
m_DescriptorActionList.push_back(std::make_pair(m_UnknownDataNodeDescriptor, m_ShowSelectedNodesAction));
m_ToggleVisibilityAction = new QmitkDataNodeToggleVisibilityAction(m_Parent, workbenchPartSite);
m_ToggleVisibilityAction->setIcon(QIcon(":/org.mitk.gui.qt.datamanager/InvertShowSelectedNode_48.png"));
m_UnknownDataNodeDescriptor->AddAction(m_ToggleVisibilityAction, true);
m_DescriptorActionList.push_back(std::make_pair(m_UnknownDataNodeDescriptor, m_ToggleVisibilityAction));
m_ShowDetailsAction = new QmitkDataNodeShowDetailsAction(m_Parent, workbenchPartSite);
m_ShowDetailsAction->setIcon(QIcon(":/org.mitk.gui.qt.datamanager/ShowDataInfo_48.png"));
m_UnknownDataNodeDescriptor->AddAction(m_ShowDetailsAction, true);
m_DescriptorActionList.push_back(std::make_pair(m_UnknownDataNodeDescriptor, m_ShowDetailsAction));
m_OpacityAction = new QmitkDataNodeOpacityAction(m_Parent, workbenchPartSite);
m_UnknownDataNodeDescriptor->AddAction(m_OpacityAction, false);
m_DescriptorActionList.push_back(std::make_pair(m_UnknownDataNodeDescriptor, m_OpacityAction));
m_ColorAction = new QmitkDataNodeColorAction(m_Parent, workbenchPartSite);
this->AddColorAction(m_ColorAction);
m_ColormapAction = new QmitkDataNodeColorMapAction(m_Parent, workbenchPartSite);
m_ImageDataNodeDescriptor->AddAction(m_ColormapAction);
m_DescriptorActionList.push_back(std::make_pair(m_ImageDataNodeDescriptor, m_ColormapAction));
if (nullptr != m_DiffusionImageDataNodeDescriptor)
{
m_DiffusionImageDataNodeDescriptor->AddAction(m_ColormapAction, false);
m_DescriptorActionList.push_back(std::make_pair(m_DiffusionImageDataNodeDescriptor, m_ColormapAction));
}
m_ComponentAction = new QmitkDataNodeComponentAction(m_Parent, workbenchPartSite);
m_MultiComponentImageDataNodeDescriptor->AddAction(m_ComponentAction, false);
m_DescriptorActionList.push_back(std::make_pair(m_MultiComponentImageDataNodeDescriptor, m_ComponentAction));
if (nullptr != m_DiffusionImageDataNodeDescriptor)
{
m_DiffusionImageDataNodeDescriptor->AddAction(m_ComponentAction, false);
m_DescriptorActionList.push_back(std::make_pair(m_DiffusionImageDataNodeDescriptor, m_ComponentAction));
}
m_TextureInterpolationAction = new QmitkDataNodeTextureInterpolationAction(m_Parent, workbenchPartSite);
m_ImageDataNodeDescriptor->AddAction(m_TextureInterpolationAction, false);
m_DescriptorActionList.push_back(std::make_pair(m_ImageDataNodeDescriptor, m_TextureInterpolationAction));
if (nullptr != m_DiffusionImageDataNodeDescriptor)
{
m_DiffusionImageDataNodeDescriptor->AddAction(m_TextureInterpolationAction, false);
m_DescriptorActionList.push_back(std::make_pair(m_DiffusionImageDataNodeDescriptor, m_TextureInterpolationAction));
}
if (nullptr != m_SegmentDataNodeDescriptor)
{
m_SegmentDataNodeDescriptor->AddAction(m_TextureInterpolationAction, false);
m_DescriptorActionList.push_back(std::make_pair(m_SegmentDataNodeDescriptor, m_TextureInterpolationAction));
}
m_SurfaceRepresentationAction = new QmitkDataNodeSurfaceRepresentationAction(m_Parent, workbenchPartSite);
m_SurfaceDataNodeDescriptor->AddAction(m_SurfaceRepresentationAction, false);
m_DescriptorActionList.push_back(std::make_pair(m_SurfaceDataNodeDescriptor, m_SurfaceRepresentationAction));
}
void QmitkDataNodeContextMenu::InitExtensionPointActions()
{
auto extensionPointService = berry::Platform::GetExtensionRegistry();
auto customMenuConfigs = extensionPointService->GetConfigurationElementsFor("org.mitk.gui.qt.datamanager.contextMenuActions");
DescriptorActionListType descriptorActionList;
m_ConfigElements.clear();
for (const auto& customMenuConfig : qAsConst(customMenuConfigs))
{
auto descriptorName = customMenuConfig->GetAttribute("nodeDescriptorName");
auto actionLabel = customMenuConfig->GetAttribute("label");
auto actionClass = customMenuConfig->GetAttribute("class");
if (descriptorName.isEmpty() || actionLabel.isEmpty() || actionClass.isEmpty())
continue;
auto descriptor = QmitkNodeDescriptorManager::GetInstance()->GetDescriptor(descriptorName);
if (nullptr == descriptor)
{
MITK_WARN << "Cannot add action \"" << actionLabel << "\" to non-existent descriptor \"" << descriptorName << "\".";
continue;
}
QAction* action = nullptr;
auto actionIcon = customMenuConfig->GetAttribute("icon");
if (!actionIcon.isEmpty())
{
QIcon icon = !QFile::exists(actionIcon)
? berry::AbstractUICTKPlugin::ImageDescriptorFromPlugin(customMenuConfig->GetContributor()->GetName(), actionIcon)
: QIcon(actionIcon);
action = new QAction(icon, actionLabel, m_Parent);
}
else
{
action = new QAction(actionLabel, m_Parent);
}
if (nullptr != action)
{
// See T26938. We do not know why but without the lambda function indirection, the
// connection is lost after the content menu was shown for the first time.
connect(action, &QAction::triggered, [action, this]()
{
this->OnExtensionPointActionTriggered(action);
});
m_ConfigElements[action] = customMenuConfig;
descriptorActionList.push_back(std::make_pair(descriptor, action));
}
}
this->AddDescriptorActionList(descriptorActionList);
}
void QmitkDataNodeContextMenu::InitServiceActions()
{
}
void QmitkDataNodeContextMenu::OnContextMenuRequested(const QPoint& /*pos*/)
{
auto workbenchPartSite = m_WorkbenchPartSite.Lock();
if (workbenchPartSite.IsNull())
return;
auto selection = workbenchPartSite->GetWorkbenchWindow()->GetSelectionService()->GetSelection()
.Cast();
if (selection.IsNull() || selection->IsEmpty())
return;
m_SelectedNodes = QList::fromStdList(selection->GetSelectedDataNodes());
if (!m_SelectedNodes.isEmpty())
{
this->clear();
auto actions = m_SelectedNodes.size() == 1
? this->GetActions(m_SelectedNodes.front())
: this->GetActions(m_SelectedNodes);
for (auto& action : actions)
{
auto dataNodeAction = dynamic_cast(action);
if (nullptr != dataNodeAction)
dataNodeAction->SetSelectedNodes(m_SelectedNodes);
}
this->addActions(actions);
this->popup(QCursor::pos());
}
}
void QmitkDataNodeContextMenu::OnExtensionPointActionTriggered(QAction* action)
{
auto configElementIter = m_ConfigElements.find(action);
if (m_ConfigElements.end() == configElementIter)
{
MITK_WARN << "Associated configuration element for action \"" << action->text() << "\" not found.";
return;
}
auto configElement = configElementIter->second;
auto contextMenuAction = configElement->CreateExecutableExtension("class");
auto dataStorage = m_DataStorage.Lock();
if (dataStorage.IsNotNull())
contextMenuAction->SetDataStorage(dataStorage);
if ("QmitkCreatePolygonModelAction" == configElement->GetAttribute("class"))
{
contextMenuAction->SetSmoothed("true" == configElement->GetAttribute("smoothed"));
contextMenuAction->SetDecimated(m_SurfaceDecimation);
}
contextMenuAction->Run(m_SelectedNodes);
}
void QmitkDataNodeContextMenu::AddColorAction(QWidgetAction* colorAction)
{
if (nullptr != m_ImageDataNodeDescriptor)
{
m_ImageDataNodeDescriptor->AddAction(colorAction, true);
m_DescriptorActionList.push_back(std::make_pair(m_ImageDataNodeDescriptor, colorAction));
}
if (nullptr != m_MultiComponentImageDataNodeDescriptor)
{
m_MultiComponentImageDataNodeDescriptor->AddAction(colorAction, true);
m_DescriptorActionList.push_back(std::make_pair(m_MultiComponentImageDataNodeDescriptor, colorAction));
}
if (nullptr != m_DiffusionImageDataNodeDescriptor)
{
m_DiffusionImageDataNodeDescriptor->AddAction(colorAction, true);
m_DescriptorActionList.push_back(std::make_pair(m_DiffusionImageDataNodeDescriptor, colorAction));
}
if (nullptr != m_FiberBundleDataNodeDescriptor)
{
m_FiberBundleDataNodeDescriptor->AddAction(colorAction, false);
m_DescriptorActionList.push_back(std::make_pair(m_FiberBundleDataNodeDescriptor, colorAction));
}
if (nullptr != m_PeakImageDataNodeDescriptor)
{
m_PeakImageDataNodeDescriptor->AddAction(colorAction, false);
m_DescriptorActionList.push_back(std::make_pair(m_PeakImageDataNodeDescriptor, colorAction));
}
if (nullptr != m_SegmentDataNodeDescriptor)
{
m_SegmentDataNodeDescriptor->AddAction(colorAction, false);
m_DescriptorActionList.push_back(std::make_pair(m_SegmentDataNodeDescriptor, colorAction));
}
if (nullptr != m_SurfaceDataNodeDescriptor)
{
m_SurfaceDataNodeDescriptor->AddAction(colorAction, true);
m_DescriptorActionList.push_back(std::make_pair(m_SurfaceDataNodeDescriptor, colorAction));
}
if (nullptr != m_PointSetNodeDescriptor)
{
m_PointSetNodeDescriptor->AddAction(colorAction, true);
m_DescriptorActionList.push_back(std::make_pair(m_PointSetNodeDescriptor, colorAction));
}
if (nullptr != m_PlanarLineNodeDescriptor)
{
m_PlanarLineNodeDescriptor->AddAction(colorAction, true);
m_DescriptorActionList.push_back(std::make_pair(m_PlanarLineNodeDescriptor, colorAction));
}
if (nullptr != m_PlanarCircleNodeDescriptor)
{
m_PlanarCircleNodeDescriptor->AddAction(colorAction, true);
m_DescriptorActionList.push_back(std::make_pair(m_PlanarCircleNodeDescriptor, colorAction));
}
if (nullptr != m_PlanarEllipseNodeDescriptor)
{
m_PlanarEllipseNodeDescriptor->AddAction(colorAction, true);
m_DescriptorActionList.push_back(std::make_pair(m_PlanarEllipseNodeDescriptor, colorAction));
}
if (nullptr != m_PlanarAngleNodeDescriptor)
{
m_PlanarAngleNodeDescriptor->AddAction(colorAction, true);
m_DescriptorActionList.push_back(std::make_pair(m_PlanarAngleNodeDescriptor, colorAction));
}
if (nullptr != m_PlanarFourPointAngleNodeDescriptor)
{
m_PlanarFourPointAngleNodeDescriptor->AddAction(colorAction, true);
m_DescriptorActionList.push_back(std::make_pair(m_PlanarFourPointAngleNodeDescriptor, colorAction));
}
if (nullptr != m_PlanarRectangleNodeDescriptor)
{
m_PlanarRectangleNodeDescriptor->AddAction(colorAction, true);
m_DescriptorActionList.push_back(std::make_pair(m_PlanarRectangleNodeDescriptor, colorAction));
}
if (nullptr != m_PlanarPolygonNodeDescriptor)
{
m_PlanarPolygonNodeDescriptor->AddAction(colorAction, true);
m_DescriptorActionList.push_back(std::make_pair(m_PlanarPolygonNodeDescriptor, colorAction));
}
if (nullptr != m_PlanarPathNodeDescriptor)
{
m_PlanarPathNodeDescriptor->AddAction(colorAction, true);
m_DescriptorActionList.push_back(std::make_pair(m_PlanarPathNodeDescriptor, colorAction));
}
if (nullptr != m_PlanarDoubleEllipseNodeDescriptor)
{
m_PlanarDoubleEllipseNodeDescriptor->AddAction(colorAction, true);
m_DescriptorActionList.push_back(std::make_pair(m_PlanarDoubleEllipseNodeDescriptor, colorAction));
}
if (nullptr != m_PlanarBezierCurveNodeDescriptor)
{
m_PlanarBezierCurveNodeDescriptor->AddAction(colorAction, true);
m_DescriptorActionList.push_back(std::make_pair(m_PlanarBezierCurveNodeDescriptor, colorAction));
}
if (nullptr != m_PlanarSubdivisionPolygonNodeDescriptor)
{
m_PlanarSubdivisionPolygonNodeDescriptor->AddAction(colorAction, true);
m_DescriptorActionList.push_back(std::make_pair(m_PlanarSubdivisionPolygonNodeDescriptor, colorAction));
}
}
void QmitkDataNodeContextMenu::AddDescriptorActionList(DescriptorActionListType& descriptorActionList)
{
using ListItem = std::pair;
std::sort(descriptorActionList.begin(), descriptorActionList.end(), [](const ListItem& left, const ListItem& right) -> bool
{
return left.second->text() < right.second->text();
});
for (auto& descriptorActionPair : descriptorActionList)
{
descriptorActionPair.first->AddAction(descriptorActionPair.second);
m_DescriptorActionList.push_back(descriptorActionPair);
}
}
QList QmitkDataNodeContextMenu::GetActions(const mitk::DataNode* node)
{
QList actions;
for(const auto& descriptorActionPair : m_DescriptorActionList)
{
if (descriptorActionPair.first->CheckNode(node) || "Unknown" == descriptorActionPair.first->GetNameOfClass())
actions.append(descriptorActionPair.second);
}
return actions;
}
QList QmitkDataNodeContextMenu::GetActions(const QList& nodes)
{
QList actions;
for (const auto& descriptorActionPair : m_DescriptorActionList)
{
for (const auto& node : nodes)
{
if (descriptorActionPair.first->CheckNode(node) || "Unknown" == descriptorActionPair.first->GetNameOfClass())
{
auto batchActions = descriptorActionPair.first->GetBatchActions();
if (std::find(batchActions.begin(), batchActions.end(), descriptorActionPair.second) != batchActions.end())
actions.append(descriptorActionPair.second);
break;
}
}
}
return actions;
}
diff --git a/Plugins/org.mitk.gui.qt.application/src/QmitkDataNodeShowSelectedNodesAction.cpp b/Plugins/org.mitk.gui.qt.application/src/QmitkDataNodeShowSelectedNodesAction.cpp
index f9a998d19c..e42ec1aa42 100644
--- a/Plugins/org.mitk.gui.qt.application/src/QmitkDataNodeShowSelectedNodesAction.cpp
+++ b/Plugins/org.mitk.gui.qt.application/src/QmitkDataNodeShowSelectedNodesAction.cpp
@@ -1,71 +1,70 @@
/*============================================================================
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
-#include
// mitk core
#include
QmitkDataNodeShowSelectedNodesAction::QmitkDataNodeShowSelectedNodesAction(QWidget* parent, berry::IWorkbenchPartSite::Pointer workbenchpartSite)
: QAction(parent)
, QmitkAbstractDataNodeAction(workbenchpartSite)
{
setText(tr("Show only selected nodes"));
InitializeAction();
}
QmitkDataNodeShowSelectedNodesAction::QmitkDataNodeShowSelectedNodesAction(QWidget* parent, berry::IWorkbenchPartSite* workbenchpartSite)
: QAction(parent)
, QmitkAbstractDataNodeAction(berry::IWorkbenchPartSite::Pointer(workbenchpartSite))
{
setText(tr("Show only selected nodes"));
InitializeAction();
}
void QmitkDataNodeShowSelectedNodesAction::InitializeAction()
{
connect(this, &QmitkDataNodeShowSelectedNodesAction::triggered, this, &QmitkDataNodeShowSelectedNodesAction::OnActionTriggered);
}
void QmitkDataNodeShowSelectedNodesAction::OnActionTriggered(bool /*checked*/)
{
auto dataStorage = m_DataStorage.Lock();
if (dataStorage.IsNull())
{
return;
}
mitk::BaseRenderer::Pointer baseRenderer = GetBaseRenderer();
auto selectedNodes = GetSelectedNodes();
auto allNodes = dataStorage->GetAll();
for (auto& node : *allNodes)
{
if (node.IsNotNull() && node->GetData() != nullptr && strcmp(node->GetData()->GetNameOfClass(), "PlaneGeometryData"))
{
node->SetVisibility(selectedNodes.contains(node), baseRenderer);
}
}
if (nullptr == baseRenderer)
{
mitk::RenderingManager::GetInstance()->RequestUpdateAll();
}
else
{
mitk::RenderingManager::GetInstance()->RequestUpdate(baseRenderer->GetRenderWindow());
}
}
diff --git a/Plugins/org.mitk.gui.qt.flow.segmentation/files.cmake b/Plugins/org.mitk.gui.qt.flow.segmentation/files.cmake
index 45e6d49d05..07628bc3d2 100644
--- a/Plugins/org.mitk.gui.qt.flow.segmentation/files.cmake
+++ b/Plugins/org.mitk.gui.qt.flow.segmentation/files.cmake
@@ -1,46 +1,45 @@
set(SRC_CPP_FILES
)
set(INTERNAL_CPP_FILES
org_mitk_gui_qt_flow_segmentation_Activator.cpp
QmitkSegmentationFlowControlView.cpp
perspectives/QmitkFlowSegmentationPerspective.cpp
)
set(UI_FILES
src/internal/QmitkSegmentationFlowControlView.ui
)
set(MOC_H_FILES
src/internal/org_mitk_gui_qt_flow_segmentation_Activator.h
src/internal/QmitkSegmentationFlowControlView.h
src/internal/perspectives/QmitkFlowSegmentationPerspective.h
)
# list of resource files which can be used by the plug-in
# system without loading the plug-ins shared library,
# for example the icon used in the menu and tabs for the
# plug-in views in the workbench
set(CACHED_RESOURCE_FILES
resources/icon.svg
plugin.xml
resources/perspectives/segmentation_icon.svg
)
# list of Qt .qrc files which contain additional resources
# specific to this plugin
set(QRC_FILES
- resources/SegmentationTaskList.qrc
)
set(CPP_FILES )
foreach(file ${SRC_CPP_FILES})
set(CPP_FILES ${CPP_FILES} src/${file})
endforeach(file ${SRC_CPP_FILES})
foreach(file ${INTERNAL_CPP_FILES})
set(CPP_FILES ${CPP_FILES} src/internal/${file})
endforeach(file ${INTERNAL_CPP_FILES})
diff --git a/Plugins/org.mitk.gui.qt.flow.segmentation/src/internal/QmitkSegmentationFlowControlView.cpp b/Plugins/org.mitk.gui.qt.flow.segmentation/src/internal/QmitkSegmentationFlowControlView.cpp
index 71e81f6602..998501ab37 100644
--- a/Plugins/org.mitk.gui.qt.flow.segmentation/src/internal/QmitkSegmentationFlowControlView.cpp
+++ b/Plugins/org.mitk.gui.qt.flow.segmentation/src/internal/QmitkSegmentationFlowControlView.cpp
@@ -1,209 +1,150 @@
/*============================================================================
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 "org_mitk_gui_qt_flow_segmentation_Activator.h"
-// Blueberry
-#include
-#include
-#include
-#include
-
#include
+#include
+
//MITK
#include
#include
#include
#include
#include
#include
#include
-#include
// Qmitk
#include "QmitkSegmentationFlowControlView.h"
#include
// Qt
-#include
#include
-#include
const std::string QmitkSegmentationFlowControlView::VIEW_ID = "org.mitk.views.flow.control";
QmitkSegmentationFlowControlView::QmitkSegmentationFlowControlView()
- : m_Controls(new Ui::SegmentationFlowControlView),
- m_Parent(nullptr)
+ : m_Controls(new Ui::SegmentationFlowControlView)
{
+ berry::PlatformUI::GetWorkbench()->AddWorkbenchListener(this);
+
auto notHelperObject = mitk::NodePredicateNot::New(
mitk::NodePredicateProperty::New("helper object"));
m_SegmentationPredicate = mitk::NodePredicateAnd::New(
mitk::TNodePredicateDataType::New(),
notHelperObject);
m_SegmentationTaskListPredicate = mitk::NodePredicateAnd::New(
mitk::TNodePredicateDataType::New(),
notHelperObject);
-
- berry::PlatformUI::GetWorkbench()->AddWorkbenchListener(this);
}
QmitkSegmentationFlowControlView::~QmitkSegmentationFlowControlView()
{
berry::PlatformUI::GetWorkbench()->RemoveWorkbenchListener(this);
}
-bool QmitkSegmentationFlowControlView::PreShutdown(berry::IWorkbench*, bool)
-{
- return m_Controls->segmentationTaskListWidget != nullptr
- ? m_Controls->segmentationTaskListWidget->OnPreShutdown()
- : true;
-}
-
void QmitkSegmentationFlowControlView::SetFocus()
{
- m_Controls->btnStoreAndAccept->setFocus();
+ m_Controls->btnStoreAndAccept->setFocus();
}
void QmitkSegmentationFlowControlView::CreateQtPartControl(QWidget* parent)
{
m_Controls->setupUi(parent);
- m_Parent = parent;
-
- using Self = QmitkSegmentationFlowControlView;
-
- connect(m_Controls->btnStore, &QPushButton::clicked, this, &Self::OnStoreButtonClicked);
- connect(m_Controls->btnStoreAndAccept, &QPushButton::clicked, this, &Self::OnAcceptButtonClicked);
- connect(m_Controls->segmentationTaskListWidget, &QmitkSegmentationTaskListWidget::ActiveTaskChanged, this, &Self::OnActiveTaskChanged);
- connect(m_Controls->segmentationTaskListWidget, &QmitkSegmentationTaskListWidget::CurrentTaskChanged, this, &Self::OnCurrentTaskChanged);
-
- auto* prevShortcut = new QShortcut(QKeySequence(Qt::CTRL | Qt::ALT | Qt::Key::Key_S), parent);
- connect(prevShortcut, &QShortcut::activated, this, &Self::OnStoreInterimResultShortcutActivated);
-
- auto* nextShortcut = new QShortcut(QKeySequence(Qt::CTRL | Qt::ALT | Qt::Key::Key_A), parent);
- connect(nextShortcut, &QShortcut::activated, this, &Self::OnAcceptSegmentationShortcutActivated);
-
- m_Controls->btnStore->setIcon(berry::QtStyleManager::ThemeIcon(QStringLiteral(":/org_mitk_icons/icons/awesome/scalable/actions/document-save.svg")));
- m_Controls->btnStore->setVisible(false);
m_Controls->segmentationTaskListWidget->SetDataStorage(this->GetDataStorage());
m_Controls->segmentationTaskListWidget->setVisible(false);
m_Controls->labelStored->setVisible(false);
+ using Self = QmitkSegmentationFlowControlView;
+
+ connect(m_Controls->btnStoreAndAccept, &QPushButton::clicked, this, &Self::OnAcceptButtonClicked);
+
this->UpdateControls();
m_OutputDir = QString::fromStdString(mitk::BaseApplication::instance().config().getString("flow.outputdir", itksys::SystemTools::GetCurrentWorkingDirectory()));
m_OutputDir = QDir::fromNativeSeparators(m_OutputDir);
m_FileExtension = QString::fromStdString(mitk::BaseApplication::instance().config().getString("flow.outputextension", "nrrd"));
}
-void QmitkSegmentationFlowControlView::OnStoreButtonClicked()
-{
- m_Controls->segmentationTaskListWidget->SaveActiveTask(true);
-}
-
void QmitkSegmentationFlowControlView::OnAcceptButtonClicked()
{
- if (m_Controls->segmentationTaskListWidget->isVisible())
- {
- auto* toolManager = mitk::ToolManagerProvider::GetInstance()->GetToolManager();
- int activeToolId = -1;
-
- if (toolManager != nullptr)
- activeToolId = toolManager->GetActiveToolID();
-
- m_Controls->segmentationTaskListWidget->SaveActiveTask();
- m_Controls->segmentationTaskListWidget->LoadNextUnfinishedTask();
+ auto nodes = this->GetDataStorage()->GetSubset(m_SegmentationPredicate);
- if (toolManager != nullptr)
- toolManager->ActivateTool(activeToolId);
- }
- else
+ for (auto node : *nodes)
{
- auto nodes = this->GetDataStorage()->GetSubset(m_SegmentationPredicate);
-
- for (auto node : *nodes)
- {
- QString outputpath = m_OutputDir + "/" + QString::fromStdString(node->GetName()) + "." + m_FileExtension;
- outputpath = QDir::toNativeSeparators(QDir::cleanPath(outputpath));
- mitk::IOUtil::Save(node->GetData(), outputpath.toStdString());
- }
-
- m_Controls->labelStored->setVisible(true);
+ QString outputpath = m_OutputDir + "/" + QString::fromStdString(node->GetName()) + "." + m_FileExtension;
+ outputpath = QDir::toNativeSeparators(QDir::cleanPath(outputpath));
+ mitk::IOUtil::Save(node->GetData(), outputpath.toStdString());
}
-}
-
-void QmitkSegmentationFlowControlView::OnActiveTaskChanged(const std::optional&)
-{
- this->UpdateControls();
-}
-void QmitkSegmentationFlowControlView::OnCurrentTaskChanged(const std::optional&)
-{
- this->UpdateControls();
+ m_Controls->labelStored->setVisible(true);
}
void QmitkSegmentationFlowControlView::UpdateControls()
{
auto dataStorage = this->GetDataStorage();
- auto hasTaskList = !dataStorage->GetSubset(m_SegmentationTaskListPredicate)->empty();
+ auto hasSegmentationTaskList = !dataStorage->GetSubset(m_SegmentationTaskListPredicate)->empty();
- m_Controls->segmentationTaskListWidget->setVisible(hasTaskList);
+ m_Controls->segmentationTaskListWidget->setVisible(hasSegmentationTaskList);
- if (hasTaskList)
+ if (hasSegmentationTaskList) // Give precedence to segmentation task list
{
- auto activeTaskIsShown = m_Controls->segmentationTaskListWidget->ActiveTaskIsShown();
-
- m_Controls->btnStore->setVisible(activeTaskIsShown);
- m_Controls->btnStoreAndAccept->setEnabled(activeTaskIsShown);
+ m_Controls->btnStoreAndAccept->setVisible(false);
+ m_Controls->labelStored->setVisible(false);
+ return;
}
- else
- {
- auto hasSegmentation = !dataStorage->GetSubset(m_SegmentationPredicate)->empty();
- m_Controls->btnStore->setVisible(false);
- m_Controls->btnStoreAndAccept->setEnabled(hasSegmentation);
- }
+ auto hasSegmentation = !dataStorage->GetSubset(m_SegmentationPredicate)->empty();
+
+ m_Controls->btnStoreAndAccept->setEnabled(hasSegmentation);
+ m_Controls->btnStoreAndAccept->setVisible(true);
}
void QmitkSegmentationFlowControlView::NodeAdded(const mitk::DataNode* node)
{
if (dynamic_cast(node->GetData()) != nullptr)
this->UpdateControls();
+
+ if (m_Controls->segmentationTaskListWidget->isVisible())
+ m_Controls->segmentationTaskListWidget->CheckDataStorage();
}
void QmitkSegmentationFlowControlView::NodeChanged(const mitk::DataNode* node)
{
if (dynamic_cast(node->GetData()) != nullptr)
this->UpdateControls();
}
void QmitkSegmentationFlowControlView::NodeRemoved(const mitk::DataNode* node)
{
if (dynamic_cast(node->GetData()) != nullptr)
this->UpdateControls();
-}
-void QmitkSegmentationFlowControlView::OnStoreInterimResultShortcutActivated()
-{
- m_Controls->btnStore->click();
+ if (m_Controls->segmentationTaskListWidget->isVisible())
+ m_Controls->segmentationTaskListWidget->CheckDataStorage(node);
}
-void QmitkSegmentationFlowControlView::OnAcceptSegmentationShortcutActivated()
+bool QmitkSegmentationFlowControlView::PreShutdown(berry::IWorkbench*, bool)
{
- m_Controls->btnStoreAndAccept->click();
+ if (m_Controls->segmentationTaskListWidget->isVisible())
+ return m_Controls->segmentationTaskListWidget->OnPreShutdown();
+
+ return true; // No veto against shutdown
}
diff --git a/Plugins/org.mitk.gui.qt.flow.segmentation/src/internal/QmitkSegmentationFlowControlView.h b/Plugins/org.mitk.gui.qt.flow.segmentation/src/internal/QmitkSegmentationFlowControlView.h
index 26e4316e21..2ac6e8e0a4 100644
--- a/Plugins/org.mitk.gui.qt.flow.segmentation/src/internal/QmitkSegmentationFlowControlView.h
+++ b/Plugins/org.mitk.gui.qt.flow.segmentation/src/internal/QmitkSegmentationFlowControlView.h
@@ -1,88 +1,81 @@
/*============================================================================
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 QmitkSegmentationFlowControlView_h
#define QmitkSegmentationFlowControlView_h
#include
#include
#include
#include "mitkNodePredicateBase.h"
-#include
-
namespace Ui
{
class SegmentationFlowControlView;
}
/*!
\brief QmitkSegmentationFlowControlView
Class that "controls" the segmentation view. It offers the possibility to accept a segmentation.
Accepting the segmentation stores the segmentation to the given working directory.
The working directory is specified by command line arguments. If no commandline flag is set the current working directory will be used.
*/
class QmitkSegmentationFlowControlView : public QmitkAbstractView, public berry::IWorkbenchListener
{
// this is needed for all Qt objects that should have a Qt meta-object
// (everything that derives from QObject and wants to have signal/slots)
Q_OBJECT
public:
static const std::string VIEW_ID;
/**
* Creates smartpointer typedefs
*/
berryObjectMacro(QmitkSegmentationFlowControlView)
QmitkSegmentationFlowControlView();
~QmitkSegmentationFlowControlView() override;
void CreateQtPartControl(QWidget *parent) override;
protected slots:
- void OnStoreButtonClicked();
void OnAcceptButtonClicked();
- void OnActiveTaskChanged(const std::optional& index);
- void OnCurrentTaskChanged(const std::optional& index);
- void OnStoreInterimResultShortcutActivated();
- void OnAcceptSegmentationShortcutActivated();
+
protected:
void SetFocus() override;
void NodeAdded(const mitk::DataNode* node) override;
void NodeChanged(const mitk::DataNode* node) override;
void NodeRemoved(const mitk::DataNode* node) override;
bool PreShutdown(berry::IWorkbench*, bool) override;
void UpdateControls();
Ui::SegmentationFlowControlView* m_Controls;
private:
- QWidget *m_Parent;
mitk::NodePredicateBase::Pointer m_SegmentationPredicate;
mitk::NodePredicateBase::Pointer m_SegmentationTaskListPredicate;
QString m_OutputDir;
QString m_FileExtension;
};
#endif
diff --git a/Plugins/org.mitk.gui.qt.flow.segmentation/src/internal/QmitkSegmentationFlowControlView.ui b/Plugins/org.mitk.gui.qt.flow.segmentation/src/internal/QmitkSegmentationFlowControlView.ui
index e2a96650c9..0d9da019c7 100644
--- a/Plugins/org.mitk.gui.qt.flow.segmentation/src/internal/QmitkSegmentationFlowControlView.ui
+++ b/Plugins/org.mitk.gui.qt.flow.segmentation/src/internal/QmitkSegmentationFlowControlView.ui
@@ -1,133 +1,108 @@
SegmentationFlowControlView
0
0
268
324
-
Qt::Vertical
20
40
-
-
-
-
-
-
-
- 50
- 50
-
-
-
-
- 50
- 50
-
-
-
- Save interim segmentation
-
-
-
- 32
- 32
-
-
-
-
-
0
50
Save and accept segmentation
Accept segmentation
32
32
-
<html><head/><body><p><span style=" font-size:12pt;">Segmentation accepted! Flow on...</span></p></body></html>
Qt::AlignCenter
-
Qt::Vertical
20
40
QmitkSegmentationTaskListWidget
QWidget
QmitkSegmentationTaskListWidget.h
1
5
5
true
true
true
diff --git a/Plugins/org.mitk.gui.qt.flow.segmentation/src/internal/org_mitk_gui_qt_flow_segmentation_Activator.cpp b/Plugins/org.mitk.gui.qt.flow.segmentation/src/internal/org_mitk_gui_qt_flow_segmentation_Activator.cpp
index d1aa34e0e6..721bad692e 100644
--- a/Plugins/org.mitk.gui.qt.flow.segmentation/src/internal/org_mitk_gui_qt_flow_segmentation_Activator.cpp
+++ b/Plugins/org.mitk.gui.qt.flow.segmentation/src/internal/org_mitk_gui_qt_flow_segmentation_Activator.cpp
@@ -1,59 +1,45 @@
/*============================================================================
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 "org_mitk_gui_qt_flow_segmentation_Activator.h"
#include "QmitkSegmentationFlowControlView.h"
#include "perspectives/QmitkFlowSegmentationPerspective.h"
#include
#include
-#include
-#include
-
#include
US_INITIALIZE_MODULE
ctkPluginContext* org_mitk_gui_qt_flow_segmentation_Activator::m_Context = nullptr;
void org_mitk_gui_qt_flow_segmentation_Activator::start(ctkPluginContext* context)
{
BERRY_REGISTER_EXTENSION_CLASS(QmitkSegmentationFlowControlView, context)
BERRY_REGISTER_EXTENSION_CLASS(QmitkFlowSegmentationPerspective, context);
- auto* descriptorManager = QmitkNodeDescriptorManager::GetInstance();
-
- if (descriptorManager != nullptr)
- {
- auto icon = QmitkStyleManager::ThemeIcon(QStringLiteral(":/SegmentationTaskList/Icon.svg"));
- auto predicate = mitk::TNodePredicateDataType::New();
- auto* descriptor = new QmitkNodeDescriptor("SegmentationTaskList", icon, predicate, descriptorManager);
-
- descriptorManager->AddDescriptor(descriptor);
- }
-
m_Context = context;
}
void org_mitk_gui_qt_flow_segmentation_Activator::stop(ctkPluginContext* context)
{
Q_UNUSED(context)
m_Context = nullptr;
}
ctkPluginContext* org_mitk_gui_qt_flow_segmentation_Activator::GetContext()
{
return m_Context;
}
diff --git a/Plugins/org.mitk.gui.qt.flow.segmentation/src/internal/perspectives/QmitkFlowSegmentationPerspective.cpp b/Plugins/org.mitk.gui.qt.flow.segmentation/src/internal/perspectives/QmitkFlowSegmentationPerspective.cpp
index d5650449a4..54d2424a30 100644
--- a/Plugins/org.mitk.gui.qt.flow.segmentation/src/internal/perspectives/QmitkFlowSegmentationPerspective.cpp
+++ b/Plugins/org.mitk.gui.qt.flow.segmentation/src/internal/perspectives/QmitkFlowSegmentationPerspective.cpp
@@ -1,43 +1,43 @@
/*============================================================================
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 "QmitkFlowSegmentationPerspective.h"
-#include "berryIViewLayout.h"
+#include
QmitkFlowSegmentationPerspective::QmitkFlowSegmentationPerspective()
{
}
void QmitkFlowSegmentationPerspective::CreateInitialLayout(berry::IPageLayout::Pointer layout)
{
QString editorArea = layout->GetEditorArea();
layout->AddView("org.mitk.views.segmentation", berry::IPageLayout::LEFT, 0.24f, editorArea);
berry::IViewLayout::Pointer lo = layout->GetViewLayout("org.mitk.views.segmentation");
lo->SetCloseable(false);
layout->AddStandaloneView("org.mitk.views.flow.control",false, berry::IPageLayout::RIGHT, 0.72f, editorArea);
lo = layout->GetViewLayout("org.mitk.views.flow.control");
lo->SetCloseable(false);
layout->AddView("org.mitk.views.imagenavigator",
berry::IPageLayout::TOP, 0.1f, "org.mitk.views.flow.control");
berry::IPlaceholderFolderLayout::Pointer bottomFolder = layout->CreatePlaceholderFolder("bottom", berry::IPageLayout::BOTTOM, 0.7f, editorArea);
bottomFolder->AddPlaceholder("org.blueberry.views.logview");
berry::IPlaceholderFolderLayout::Pointer rightFolder = layout->CreatePlaceholderFolder("right", berry::IPageLayout::RIGHT, 0.3f, editorArea);
rightFolder->AddPlaceholder("org.mitk.views.datamanager");
layout->AddPerspectiveShortcut("org.mitk.qt.flowapplication.defaultperspective");
}
diff --git a/Plugins/org.mitk.gui.qt.flowapplication/src/internal/QmitkFlowApplicationWorkbenchWindowAdvisor.cpp b/Plugins/org.mitk.gui.qt.flowapplication/src/internal/QmitkFlowApplicationWorkbenchWindowAdvisor.cpp
index 3ecc52eac8..fb76fb6949 100644
--- a/Plugins/org.mitk.gui.qt.flowapplication/src/internal/QmitkFlowApplicationWorkbenchWindowAdvisor.cpp
+++ b/Plugins/org.mitk.gui.qt.flowapplication/src/internal/QmitkFlowApplicationWorkbenchWindowAdvisor.cpp
@@ -1,1152 +1,1153 @@
/*============================================================================
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 "QmitkFlowApplicationWorkbenchWindowAdvisor.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
#include
#include "QmitkExtFileSaveProjectAction.h"
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
// UGLYYY
#include "QmitkFlowApplicationWorkbenchWindowAdvisorHack.h"
#include "QmitkFlowApplicationPlugin.h"
#include "mitkUndoController.h"
#include "mitkVerboseLimitedLinearUndo.h"
#include
#include
#include
#include
#include
#include
QmitkFlowApplicationWorkbenchWindowAdvisorHack* QmitkFlowApplicationWorkbenchWindowAdvisorHack::undohack =
new QmitkFlowApplicationWorkbenchWindowAdvisorHack();
QString QmitkFlowApplicationWorkbenchWindowAdvisor::QT_SETTINGS_FILENAME = "QtSettings.ini";
class PartListenerForTitle: public berry::IPartListener
{
public:
PartListenerForTitle(QmitkFlowApplicationWorkbenchWindowAdvisor* wa)
: windowAdvisor(wa)
{
}
Events::Types GetPartEventTypes() const override
{
return Events::ACTIVATED | Events::BROUGHT_TO_TOP | Events::CLOSED
| Events::HIDDEN | Events::VISIBLE;
}
void PartActivated(const berry::IWorkbenchPartReference::Pointer& ref) override
{
if (ref.Cast ())
{
windowAdvisor->UpdateTitle(false);
}
}
void PartBroughtToTop(const berry::IWorkbenchPartReference::Pointer& ref) override
{
if (ref.Cast ())
{
windowAdvisor->UpdateTitle(false);
}
}
void PartClosed(const berry::IWorkbenchPartReference::Pointer& /*ref*/) override
{
windowAdvisor->UpdateTitle(false);
}
void PartHidden(const berry::IWorkbenchPartReference::Pointer& ref) override
{
auto lockedLastActiveEditor = windowAdvisor->lastActiveEditor.Lock();
if (lockedLastActiveEditor.IsNotNull() && ref->GetPart(false) == lockedLastActiveEditor)
{
windowAdvisor->UpdateTitle(true);
}
}
void PartVisible(const berry::IWorkbenchPartReference::Pointer& ref) override
{
auto lockedLastActiveEditor = windowAdvisor->lastActiveEditor.Lock();
if (lockedLastActiveEditor.IsNotNull() && ref->GetPart(false) == lockedLastActiveEditor)
{
windowAdvisor->UpdateTitle(false);
}
}
private:
QmitkFlowApplicationWorkbenchWindowAdvisor* windowAdvisor;
};
class PartListenerForImageNavigator: public berry::IPartListener
{
public:
PartListenerForImageNavigator(QAction* act)
: imageNavigatorAction(act)
{
}
Events::Types GetPartEventTypes() const override
{
return Events::OPENED | Events::CLOSED | Events::HIDDEN |
Events::VISIBLE;
}
void PartOpened(const berry::IWorkbenchPartReference::Pointer& ref) override
{
if (ref->GetId()=="org.mitk.views.imagenavigator")
{
imageNavigatorAction->setChecked(true);
}
}
void PartClosed(const berry::IWorkbenchPartReference::Pointer& ref) override
{
if (ref->GetId()=="org.mitk.views.imagenavigator")
{
imageNavigatorAction->setChecked(false);
}
}
void PartVisible(const berry::IWorkbenchPartReference::Pointer& ref) override
{
if (ref->GetId()=="org.mitk.views.imagenavigator")
{
imageNavigatorAction->setChecked(true);
}
}
void PartHidden(const berry::IWorkbenchPartReference::Pointer& ref) override
{
if (ref->GetId()=="org.mitk.views.imagenavigator")
{
imageNavigatorAction->setChecked(false);
}
}
private:
QAction* imageNavigatorAction;
};
class PerspectiveListenerForTitle: public berry::IPerspectiveListener
{
public:
PerspectiveListenerForTitle(QmitkFlowApplicationWorkbenchWindowAdvisor* wa)
: windowAdvisor(wa)
, perspectivesClosed(false)
{
}
Events::Types GetPerspectiveEventTypes() const override
{
return Events::ACTIVATED | Events::SAVED_AS | Events::DEACTIVATED
| Events::CLOSED | Events::OPENED;
}
void PerspectiveActivated(const berry::IWorkbenchPage::Pointer& /*page*/,
const berry::IPerspectiveDescriptor::Pointer& /*perspective*/) override
{
windowAdvisor->UpdateTitle(false);
}
void PerspectiveSavedAs(const berry::IWorkbenchPage::Pointer& /*page*/,
const berry::IPerspectiveDescriptor::Pointer& /*oldPerspective*/,
const berry::IPerspectiveDescriptor::Pointer& /*newPerspective*/) override
{
windowAdvisor->UpdateTitle(false);
}
void PerspectiveDeactivated(const berry::IWorkbenchPage::Pointer& /*page*/,
const berry::IPerspectiveDescriptor::Pointer& /*perspective*/) override
{
windowAdvisor->UpdateTitle(false);
}
void PerspectiveOpened(const berry::IWorkbenchPage::Pointer& /*page*/,
const berry::IPerspectiveDescriptor::Pointer& /*perspective*/) override
{
if (perspectivesClosed)
{
QListIterator i(windowAdvisor->viewActions);
while (i.hasNext())
{
i.next()->setEnabled(true);
}
windowAdvisor->fileSaveProjectAction->setEnabled(true);
windowAdvisor->undoAction->setEnabled(true);
windowAdvisor->redoAction->setEnabled(true);
windowAdvisor->imageNavigatorAction->setEnabled(true);
windowAdvisor->resetPerspAction->setEnabled(true);
}
perspectivesClosed = false;
}
void PerspectiveClosed(const berry::IWorkbenchPage::Pointer& /*page*/,
const berry::IPerspectiveDescriptor::Pointer& /*perspective*/) override
{
berry::IWorkbenchWindow::Pointer wnd = windowAdvisor->GetWindowConfigurer()->GetWindow();
bool allClosed = true;
if (wnd->GetActivePage())
{
QList perspectives(wnd->GetActivePage()->GetOpenPerspectives());
allClosed = perspectives.empty();
}
if (allClosed)
{
perspectivesClosed = true;
QListIterator i(windowAdvisor->viewActions);
while (i.hasNext())
{
i.next()->setEnabled(false);
}
windowAdvisor->fileSaveProjectAction->setEnabled(false);
windowAdvisor->undoAction->setEnabled(false);
windowAdvisor->redoAction->setEnabled(false);
windowAdvisor->imageNavigatorAction->setEnabled(false);
windowAdvisor->resetPerspAction->setEnabled(false);
}
}
private:
QmitkFlowApplicationWorkbenchWindowAdvisor* windowAdvisor;
bool perspectivesClosed;
};
class PerspectiveListenerForMenu: public berry::IPerspectiveListener
{
public:
PerspectiveListenerForMenu(QmitkFlowApplicationWorkbenchWindowAdvisor* wa)
: windowAdvisor(wa)
{
}
Events::Types GetPerspectiveEventTypes() const override
{
return Events::ACTIVATED | Events::DEACTIVATED;
}
void PerspectiveActivated(const berry::IWorkbenchPage::Pointer& /*page*/,
const berry::IPerspectiveDescriptor::Pointer& perspective) override
{
QAction* action = windowAdvisor->mapPerspIdToAction[perspective->GetId()];
if (action)
{
action->setChecked(true);
}
}
void PerspectiveDeactivated(const berry::IWorkbenchPage::Pointer& /*page*/,
const berry::IPerspectiveDescriptor::Pointer& perspective) override
{
QAction* action = windowAdvisor->mapPerspIdToAction[perspective->GetId()];
if (action)
{
action->setChecked(false);
}
}
private:
QmitkFlowApplicationWorkbenchWindowAdvisor* windowAdvisor;
};
QmitkFlowApplicationWorkbenchWindowAdvisor::QmitkFlowApplicationWorkbenchWindowAdvisor(berry::WorkbenchAdvisor* wbAdvisor,
berry::IWorkbenchWindowConfigurer::Pointer configurer)
: berry::WorkbenchWindowAdvisor(configurer)
, lastInput(nullptr)
, wbAdvisor(wbAdvisor)
, showViewToolbar(true)
, showVersionInfo(true)
, showMitkVersionInfo(true)
, showMemoryIndicator(true)
, dropTargetListener(new QmitkDefaultDropTargetListener)
{
productName = QCoreApplication::applicationName();
viewExcludeList.push_back("org.mitk.views.viewnavigator");
}
QmitkFlowApplicationWorkbenchWindowAdvisor::~QmitkFlowApplicationWorkbenchWindowAdvisor()
{
}
QWidget* QmitkFlowApplicationWorkbenchWindowAdvisor::CreateEmptyWindowContents(QWidget* parent)
{
QWidget* parentWidget = static_cast(parent);
auto label = new QLabel(parentWidget);
label->setText("No perspectives are open. Open a perspective in the Window->Open Perspective menu.");
label->setContentsMargins(10,10,10,10);
label->setAlignment(Qt::AlignTop);
label->setEnabled(false);
parentWidget->layout()->addWidget(label);
return label;
}
void QmitkFlowApplicationWorkbenchWindowAdvisor::ShowMemoryIndicator(bool show)
{
showMemoryIndicator = show;
}
bool QmitkFlowApplicationWorkbenchWindowAdvisor::GetShowMemoryIndicator()
{
return showMemoryIndicator;
}
void QmitkFlowApplicationWorkbenchWindowAdvisor::ShowViewToolbar(bool show)
{
showViewToolbar = show;
}
void QmitkFlowApplicationWorkbenchWindowAdvisor::ShowVersionInfo(bool show)
{
showVersionInfo = show;
}
void QmitkFlowApplicationWorkbenchWindowAdvisor::ShowMitkVersionInfo(bool show)
{
showMitkVersionInfo = show;
}
void QmitkFlowApplicationWorkbenchWindowAdvisor::SetProductName(const QString& product)
{
productName = product;
}
void QmitkFlowApplicationWorkbenchWindowAdvisor::SetWindowIcon(const QString& wndIcon)
{
windowIcon = wndIcon;
}
void QmitkFlowApplicationWorkbenchWindowAdvisor::PostWindowCreate()
{
// very bad hack...
berry::IWorkbenchWindow::Pointer window = this->GetWindowConfigurer()->GetWindow();
QMainWindow* mainWindow = qobject_cast (window->GetShell()->GetControl());
if (!windowIcon.isEmpty())
{
mainWindow->setWindowIcon(QIcon(windowIcon));
}
mainWindow->setContextMenuPolicy(Qt::PreventContextMenu);
// Load icon theme
QIcon::setThemeSearchPaths(QStringList() << QStringLiteral(":/org_mitk_icons/icons/"));
QIcon::setThemeName(QStringLiteral("awesome"));
// ==== Application menu ============================
QMenuBar* menuBar = mainWindow->menuBar();
menuBar->setContextMenuPolicy(Qt::PreventContextMenu);
#ifdef __APPLE__
menuBar->setNativeMenuBar(true);
#else
menuBar->setNativeMenuBar(false);
#endif
auto basePath = QStringLiteral(":/org_mitk_icons/icons/awesome/scalable/actions/");
fileSaveProjectAction = new QmitkExtFileSaveProjectAction(window);
fileSaveProjectAction->setIcon(berry::QtStyleManager::ThemeIcon(basePath + "document-save.svg"));
auto perspGroup = new QActionGroup(menuBar);
std::map VDMap;
// sort elements (converting vector to map...)
QList::const_iterator iter;
berry::IViewRegistry* viewRegistry =
berry::PlatformUI::GetWorkbench()->GetViewRegistry();
const QList viewDescriptors = viewRegistry->GetViews();
bool skip = false;
for (iter = viewDescriptors.begin(); iter != viewDescriptors.end(); ++iter)
{
// if viewExcludeList is set, it contains the id-strings of view, which
// should not appear as an menu-entry in the menu
if (viewExcludeList.size() > 0)
{
for (int i=0; iGetId())
{
skip = true;
break;
}
}
if (skip)
{
skip = false;
continue;
}
}
if ((*iter)->GetId() == "org.blueberry.ui.internal.introview")
continue;
if ((*iter)->GetId() == "org.mitk.views.imagenavigator")
continue;
if ((*iter)->GetId() == "org.mitk.views.viewnavigator")
continue;
std::pair p((*iter)->GetLabel(), (*iter));
VDMap.insert(p);
}
std::map::const_iterator MapIter;
for (MapIter = VDMap.begin(); MapIter != VDMap.end(); ++MapIter)
{
berry::QtShowViewAction* viewAction = new berry::QtShowViewAction(window, (*MapIter).second);
viewActions.push_back(viewAction);
}
QMenu* fileMenu = menuBar->addMenu("&File");
fileMenu->setObjectName("FileMenu");
fileMenu->addAction(fileSaveProjectAction);
fileMenu->addSeparator();
QAction* fileExitAction = new QmitkFileExitAction(window);
fileExitAction->setIcon(berry::QtStyleManager::ThemeIcon(basePath + "system-log-out.svg"));
fileExitAction->setShortcut(QKeySequence::Quit);
fileExitAction->setObjectName("QmitkFileExitAction");
fileMenu->addAction(fileExitAction);
// another bad hack to get an edit/undo menu...
QMenu* editMenu = menuBar->addMenu("&Edit");
undoAction = editMenu->addAction(berry::QtStyleManager::ThemeIcon(basePath + "edit-undo.svg"),
"&Undo",
QmitkFlowApplicationWorkbenchWindowAdvisorHack::undohack, SLOT(onUndo()),
QKeySequence("CTRL+Z"));
undoAction->setToolTip("Undo the last action (not supported by all modules)");
redoAction = editMenu->addAction(berry::QtStyleManager::ThemeIcon(basePath + "edit-redo.svg"),
"&Redo",
QmitkFlowApplicationWorkbenchWindowAdvisorHack::undohack, SLOT(onRedo()),
QKeySequence("CTRL+Y"));
redoAction->setToolTip("execute the last action that was undone again (not supported by all modules)");
// ==== Window Menu ==========================
QMenu* windowMenu = menuBar->addMenu("Window");
QMenu* perspMenu = windowMenu->addMenu("&Open Perspective");
windowMenu->addSeparator();
resetPerspAction = windowMenu->addAction("&Reset Perspective",
QmitkFlowApplicationWorkbenchWindowAdvisorHack::undohack, SLOT(onResetPerspective()));
windowMenu->addSeparator();
windowMenu->addAction("&Preferences...",
QmitkFlowApplicationWorkbenchWindowAdvisorHack::undohack, SLOT(onEditPreferences()),
QKeySequence("CTRL+P"));
// fill perspective menu
berry::IPerspectiveRegistry* perspRegistry =
window->GetWorkbench()->GetPerspectiveRegistry();
QList perspectives(
perspRegistry->GetPerspectives());
skip = false;
for (QList::iterator perspIt =
perspectives.begin(); perspIt != perspectives.end(); ++perspIt)
{
// if perspectiveExcludeList is set, it contains the id-strings of perspectives, which
// should not appear as an menu-entry in the perspective menu
if (perspectiveExcludeList.size() > 0)
{
for (int i=0; iGetId())
{
skip = true;
break;
}
}
if (skip)
{
skip = false;
continue;
}
}
QAction* perspAction = new berry::QtOpenPerspectiveAction(window, *perspIt, perspGroup);
mapPerspIdToAction.insert((*perspIt)->GetId(), perspAction);
}
perspMenu->addActions(perspGroup->actions());
// ===== Help menu ====================================
QMenu* helpMenu = menuBar->addMenu("&Help");
helpMenu->addAction("&Welcome",this, SLOT(onIntro()));
helpMenu->addAction("&Open Help Perspective", this, SLOT(onHelpOpenHelpPerspective()));
helpMenu->addAction("&Context Help",this, SLOT(onHelp()), QKeySequence("F1"));
helpMenu->addAction("&About",this, SLOT(onAbout()));
// =====================================================
// toolbar for showing file open, undo, redo and other main actions
auto mainActionsToolBar = new QToolBar;
mainActionsToolBar->setObjectName("mainActionsToolBar");
mainActionsToolBar->setContextMenuPolicy(Qt::PreventContextMenu);
#ifdef __APPLE__
mainActionsToolBar->setToolButtonStyle ( Qt::ToolButtonTextUnderIcon );
#else
mainActionsToolBar->setToolButtonStyle ( Qt::ToolButtonTextBesideIcon );
#endif
basePath = QStringLiteral(":/org.mitk.gui.qt.ext/");
imageNavigatorAction = new QAction(berry::QtStyleManager::ThemeIcon(basePath + "image_navigator.svg"), "&Image Navigator", nullptr);
bool imageNavigatorViewFound = window->GetWorkbench()->GetViewRegistry()->Find("org.mitk.views.imagenavigator");
if (imageNavigatorViewFound)
{
QObject::connect(imageNavigatorAction, SIGNAL(triggered(bool)), QmitkFlowApplicationWorkbenchWindowAdvisorHack::undohack, SLOT(onImageNavigator()));
imageNavigatorAction->setCheckable(true);
// add part listener for image navigator
imageNavigatorPartListener.reset(new PartListenerForImageNavigator(imageNavigatorAction));
window->GetPartService()->AddPartListener(imageNavigatorPartListener.data());
berry::IViewPart::Pointer imageNavigatorView = window->GetActivePage()->FindView("org.mitk.views.imagenavigator");
imageNavigatorAction->setChecked(false);
if (imageNavigatorView)
{
bool isImageNavigatorVisible = window->GetActivePage()->IsPartVisible(imageNavigatorView);
if (isImageNavigatorVisible)
imageNavigatorAction->setChecked(true);
}
imageNavigatorAction->setToolTip("Toggle image navigator for navigating through image");
}
mainActionsToolBar->addAction(undoAction);
mainActionsToolBar->addAction(redoAction);
if (imageNavigatorViewFound)
{
mainActionsToolBar->addAction(imageNavigatorAction);
}
mainWindow->addToolBar(mainActionsToolBar);
// ==== View Toolbar ==================================
if (showViewToolbar)
{
auto* prefService = mitk::CoreServices::GetPreferencesService();
auto* stylePrefs = prefService->GetSystemPreferences()->Node(berry::QtPreferences::QT_STYLES_NODE);
bool showCategoryNames = stylePrefs->GetBool(berry::QtPreferences::QT_SHOW_TOOLBAR_CATEGORY_NAMES, true);
// Order view descriptors by category
QMultiMap categoryViewDescriptorMap;
for (auto labelViewDescriptorPair : VDMap)
{
auto viewDescriptor = labelViewDescriptorPair.second;
auto category = !viewDescriptor->GetCategoryPath().isEmpty()
? viewDescriptor->GetCategoryPath().back()
: QString();
categoryViewDescriptorMap.insert(category, viewDescriptor);
}
// Create a separate toolbar for each category
for (auto category : categoryViewDescriptorMap.uniqueKeys())
{
auto viewDescriptorsInCurrentCategory = categoryViewDescriptorMap.values(category);
QList > relevantViewDescriptors;
for (auto viewDescriptor : viewDescriptorsInCurrentCategory)
{
- if (viewDescriptor->GetId() != "org.mitk.views.flow.control")
+ if (viewDescriptor->GetId() != "org.mitk.views.flow.control" &&
+ viewDescriptor->GetId() != "org.mitk.views.segmentationtasklist")
{
relevantViewDescriptors.push_back(viewDescriptor);
}
}
if (!relevantViewDescriptors.isEmpty())
{
auto toolbar = new QToolBar;
toolbar->setObjectName(category + " View Toolbar");
mainWindow->addToolBar(toolbar);
if (showCategoryNames && !category.isEmpty())
{
auto categoryButton = new QToolButton;
categoryButton->setToolButtonStyle(Qt::ToolButtonTextOnly);
categoryButton->setText(category);
categoryButton->setStyleSheet("background: transparent; margin: 0; padding: 0;");
toolbar->addWidget(categoryButton);
connect(categoryButton, &QToolButton::clicked, [toolbar]()
{
for (QWidget* widget : toolbar->findChildren())
{
if (QStringLiteral("qt_toolbar_ext_button") == widget->objectName() && widget->isVisible())
{
QMouseEvent pressEvent(QEvent::MouseButtonPress, QPointF(0.0f, 0.0f), Qt::LeftButton, Qt::LeftButton, Qt::NoModifier);
QMouseEvent releaseEvent(QEvent::MouseButtonRelease, QPointF(0.0f, 0.0f), Qt::LeftButton, Qt::LeftButton, Qt::NoModifier);
QApplication::sendEvent(widget, &pressEvent);
QApplication::sendEvent(widget, &releaseEvent);
}
}
});
}
for (auto viewDescriptor : relevantViewDescriptors)
{
auto viewAction = new berry::QtShowViewAction(window, viewDescriptor);
toolbar->addAction(viewAction);
}
}
}
}
QSettings settings(GetQSettingsFile(), QSettings::IniFormat);
mainWindow->restoreState(settings.value("ToolbarPosition").toByteArray());
auto qStatusBar = new QStatusBar();
//creating a QmitkStatusBar for Output on the QStatusBar and connecting it with the MainStatusBar
auto statusBar = new QmitkStatusBar(qStatusBar);
//disabling the SizeGrip in the lower right corner
statusBar->SetSizeGripEnabled(false);
auto progBar = new QmitkProgressBar();
qStatusBar->addPermanentWidget(progBar, 0);
progBar->hide();
mainWindow->setStatusBar(qStatusBar);
if (showMemoryIndicator)
{
auto memoryIndicator = new QmitkMemoryUsageIndicatorView();
qStatusBar->addPermanentWidget(memoryIndicator, 0);
}
}
void QmitkFlowApplicationWorkbenchWindowAdvisor::PreWindowOpen()
{
berry::IWorkbenchWindowConfigurer::Pointer configurer = GetWindowConfigurer();
this->HookTitleUpdateListeners(configurer);
menuPerspectiveListener.reset(new PerspectiveListenerForMenu(this));
configurer->GetWindow()->AddPerspectiveListener(menuPerspectiveListener.data());
configurer->AddEditorAreaTransfer(QStringList("text/uri-list"));
configurer->ConfigureEditorAreaDropListener(dropTargetListener.data());
}
void QmitkFlowApplicationWorkbenchWindowAdvisor::PostWindowOpen()
{
berry::WorkbenchWindowAdvisor::PostWindowOpen();
// Force Rendering Window Creation on startup.
berry::IWorkbenchWindowConfigurer::Pointer configurer = GetWindowConfigurer();
ctkPluginContext* context = QmitkFlowApplicationPlugin::GetDefault()->GetPluginContext();
ctkServiceReference serviceRef = context->getServiceReference();
if (serviceRef)
{
mitk::IDataStorageService *dsService = context->getService(serviceRef);
if (dsService)
{
mitk::IDataStorageReference::Pointer dsRef = dsService->GetDataStorage();
mitk::DataStorageEditorInput::Pointer dsInput(new mitk::DataStorageEditorInput(dsRef));
mitk::WorkbenchUtil::OpenEditor(configurer->GetWindow()->GetActivePage(),dsInput);
}
}
}
void QmitkFlowApplicationWorkbenchWindowAdvisor::onIntro()
{
QmitkFlowApplicationWorkbenchWindowAdvisorHack::undohack->onIntro();
}
void QmitkFlowApplicationWorkbenchWindowAdvisor::onHelp()
{
QmitkFlowApplicationWorkbenchWindowAdvisorHack::undohack->onHelp();
}
void QmitkFlowApplicationWorkbenchWindowAdvisor::onHelpOpenHelpPerspective()
{
QmitkFlowApplicationWorkbenchWindowAdvisorHack::undohack->onHelpOpenHelpPerspective();
}
void QmitkFlowApplicationWorkbenchWindowAdvisor::onAbout()
{
QmitkFlowApplicationWorkbenchWindowAdvisorHack::undohack->onAbout();
}
void QmitkFlowApplicationWorkbenchWindowAdvisor::HookTitleUpdateListeners(berry::IWorkbenchWindowConfigurer::Pointer configurer)
{
// hook up the listeners to update the window title
titlePartListener.reset(new PartListenerForTitle(this));
titlePerspectiveListener.reset(new PerspectiveListenerForTitle(this));
editorPropertyListener.reset(new berry::PropertyChangeIntAdapter<
QmitkFlowApplicationWorkbenchWindowAdvisor>(this,
&QmitkFlowApplicationWorkbenchWindowAdvisor::PropertyChange));
configurer->GetWindow()->AddPerspectiveListener(titlePerspectiveListener.data());
configurer->GetWindow()->GetPartService()->AddPartListener(titlePartListener.data());
}
QString QmitkFlowApplicationWorkbenchWindowAdvisor::ComputeTitle()
{
berry::IWorkbenchWindowConfigurer::Pointer configurer = GetWindowConfigurer();
berry::IWorkbenchPage::Pointer currentPage = configurer->GetWindow()->GetActivePage();
berry::IEditorPart::Pointer activeEditor;
if (currentPage)
{
activeEditor = lastActiveEditor.Lock();
}
QString title;
berry::IProduct::Pointer product = berry::Platform::GetProduct();
if (product.IsNotNull())
{
title = product->GetName();
}
if (title.isEmpty())
{
// instead of the product name, we use a custom variable for now
title = productName;
}
if(showMitkVersionInfo)
{
QString mitkVersionInfo = MITK_REVISION_DESC;
if(mitkVersionInfo.isEmpty())
mitkVersionInfo = MITK_VERSION_STRING;
title += " " + mitkVersionInfo;
}
if (showVersionInfo)
{
// add version informatioin
QString versions = QString(" (ITK %1.%2.%3 | VTK %4.%5.%6 | Qt %7)")
.arg(ITK_VERSION_MAJOR).arg(ITK_VERSION_MINOR).arg(ITK_VERSION_PATCH)
.arg(VTK_MAJOR_VERSION).arg(VTK_MINOR_VERSION).arg(VTK_BUILD_VERSION)
.arg(QT_VERSION_STR);
title += versions;
}
if (currentPage)
{
if (activeEditor)
{
lastEditorTitle = activeEditor->GetTitleToolTip();
if (!lastEditorTitle.isEmpty())
title = lastEditorTitle + " - " + title;
}
berry::IPerspectiveDescriptor::Pointer persp = currentPage->GetPerspective();
QString label = "";
if (persp)
{
label = persp->GetLabel();
}
berry::IAdaptable* input = currentPage->GetInput();
if (input && input != wbAdvisor->GetDefaultPageInput())
{
label = currentPage->GetLabel();
}
if (!label.isEmpty())
{
title = label + " - " + title;
}
}
title += " (Not for use in diagnosis or treatment of patients)";
return title;
}
void QmitkFlowApplicationWorkbenchWindowAdvisor::RecomputeTitle()
{
berry::IWorkbenchWindowConfigurer::Pointer configurer = GetWindowConfigurer();
QString oldTitle = configurer->GetTitle();
QString newTitle = ComputeTitle();
if (newTitle != oldTitle)
{
configurer->SetTitle(newTitle);
}
}
void QmitkFlowApplicationWorkbenchWindowAdvisor::UpdateTitle(bool editorHidden)
{
berry::IWorkbenchWindowConfigurer::Pointer configurer = GetWindowConfigurer();
berry::IWorkbenchWindow::Pointer window = configurer->GetWindow();
berry::IEditorPart::Pointer activeEditor;
berry::IWorkbenchPage::Pointer currentPage = window->GetActivePage();
berry::IPerspectiveDescriptor::Pointer persp;
berry::IAdaptable* input = nullptr;
if (currentPage)
{
activeEditor = currentPage->GetActiveEditor();
persp = currentPage->GetPerspective();
input = currentPage->GetInput();
}
if (editorHidden)
{
activeEditor = nullptr;
}
// Nothing to do if the editor hasn't changed
if (activeEditor == lastActiveEditor.Lock() && currentPage == lastActivePage.Lock()
&& persp == lastPerspective.Lock() && input == lastInput)
{
return;
}
auto lockedLastActiveEditor = lastActiveEditor.Lock();
if (lockedLastActiveEditor.IsNotNull())
{
lockedLastActiveEditor->RemovePropertyListener(editorPropertyListener.data());
}
lastActiveEditor = activeEditor;
lastActivePage = currentPage;
lastPerspective = persp;
lastInput = input;
if (activeEditor)
{
activeEditor->AddPropertyListener(editorPropertyListener.data());
}
RecomputeTitle();
}
void QmitkFlowApplicationWorkbenchWindowAdvisor::PropertyChange(const berry::Object::Pointer& /*source*/, int propId)
{
if (propId == berry::IWorkbenchPartConstants::PROP_TITLE)
{
auto lockedLastActiveEditor = lastActiveEditor.Lock();
if (lockedLastActiveEditor.IsNotNull())
{
QString newTitle = lockedLastActiveEditor->GetPartName();
if (lastEditorTitle != newTitle)
{
RecomputeTitle();
}
}
}
}
void QmitkFlowApplicationWorkbenchWindowAdvisor::SetPerspectiveExcludeList(const QList& v)
{
this->perspectiveExcludeList = v;
}
QList QmitkFlowApplicationWorkbenchWindowAdvisor::GetPerspectiveExcludeList()
{
return this->perspectiveExcludeList;
}
void QmitkFlowApplicationWorkbenchWindowAdvisor::SetViewExcludeList(const QList& v)
{
this->viewExcludeList = v;
}
QList QmitkFlowApplicationWorkbenchWindowAdvisor::GetViewExcludeList()
{
return this->viewExcludeList;
}
void QmitkFlowApplicationWorkbenchWindowAdvisor::PostWindowClose()
{
berry::IWorkbenchWindow::Pointer window = this->GetWindowConfigurer()->GetWindow();
QMainWindow* mainWindow = static_cast (window->GetShell()->GetControl());
QSettings settings(GetQSettingsFile(), QSettings::IniFormat);
settings.setValue("ToolbarPosition", mainWindow->saveState());
}
QString QmitkFlowApplicationWorkbenchWindowAdvisor::GetQSettingsFile() const
{
QFileInfo settingsInfo = QmitkFlowApplicationPlugin::GetDefault()->GetPluginContext()->getDataFile(QT_SETTINGS_FILENAME);
return settingsInfo.canonicalFilePath();
}
//--------------------------------------------------------------------------------
// Ugly hack from here on. Feel free to delete when command framework
// and undo buttons are done.
//--------------------------------------------------------------------------------
QmitkFlowApplicationWorkbenchWindowAdvisorHack::QmitkFlowApplicationWorkbenchWindowAdvisorHack()
: QObject()
{
}
QmitkFlowApplicationWorkbenchWindowAdvisorHack::~QmitkFlowApplicationWorkbenchWindowAdvisorHack()
{
}
void QmitkFlowApplicationWorkbenchWindowAdvisorHack::onUndo()
{
mitk::UndoModel* model = mitk::UndoController::GetCurrentUndoModel();
if (model)
{
if (mitk::VerboseLimitedLinearUndo* verboseundo = dynamic_cast(model))
{
mitk::VerboseLimitedLinearUndo::StackDescription descriptions = verboseundo->GetUndoDescriptions();
if (descriptions.size() >= 1)
{
MITK_INFO << "Undo " << descriptions.front().second;
}
}
model->Undo();
}
else
{
MITK_ERROR << "No undo model instantiated";
}
}
void QmitkFlowApplicationWorkbenchWindowAdvisorHack::onRedo()
{
mitk::UndoModel* model = mitk::UndoController::GetCurrentUndoModel();
if (model)
{
if (mitk::VerboseLimitedLinearUndo* verboseundo = dynamic_cast(model))
{
mitk::VerboseLimitedLinearUndo::StackDescription descriptions = verboseundo->GetRedoDescriptions();
if (descriptions.size() >= 1)
{
MITK_INFO << "Redo " << descriptions.front().second;
}
}
model->Redo();
}
else
{
MITK_ERROR << "No undo model instantiated";
}
}
// safe calls to the complete chain
// berry::PlatformUI::GetWorkbench()->GetActiveWorkbenchWindow()->GetActivePage()->FindView("org.mitk.views.imagenavigator");
// to cover for all possible cases of closed pages etc.
static void SafeHandleNavigatorView(QString view_query_name)
{
berry::IWorkbench* wbench = berry::PlatformUI::GetWorkbench();
if (wbench == nullptr)
return;
berry::IWorkbenchWindow::Pointer wbench_window = wbench->GetActiveWorkbenchWindow();
if (wbench_window.IsNull())
return;
berry::IWorkbenchPage::Pointer wbench_page = wbench_window->GetActivePage();
if (wbench_page.IsNull())
return;
auto wbench_view = wbench_page->FindView(view_query_name);
if (wbench_view.IsNotNull())
{
bool isViewVisible = wbench_page->IsPartVisible(wbench_view);
if (isViewVisible)
{
wbench_page->HideView(wbench_view);
return;
}
}
wbench_page->ShowView(view_query_name);
}
void QmitkFlowApplicationWorkbenchWindowAdvisorHack::onImageNavigator()
{
// show/hide ImageNavigatorView
SafeHandleNavigatorView("org.mitk.views.imagenavigator");
}
void QmitkFlowApplicationWorkbenchWindowAdvisorHack::onEditPreferences()
{
QmitkPreferencesDialog _PreferencesDialog(QApplication::activeWindow());
_PreferencesDialog.exec();
}
void QmitkFlowApplicationWorkbenchWindowAdvisorHack::onQuit()
{
berry::PlatformUI::GetWorkbench()->Close();
}
void QmitkFlowApplicationWorkbenchWindowAdvisorHack::onResetPerspective()
{
berry::PlatformUI::GetWorkbench()->GetActiveWorkbenchWindow()->GetActivePage()->ResetPerspective();
}
void QmitkFlowApplicationWorkbenchWindowAdvisorHack::onClosePerspective()
{
berry::IWorkbenchPage::Pointer page =
berry::PlatformUI::GetWorkbench()->GetActiveWorkbenchWindow()->GetActivePage();
page->ClosePerspective(page->GetPerspective(), true, true);
}
void QmitkFlowApplicationWorkbenchWindowAdvisorHack::onIntro()
{
bool hasIntro =
berry::PlatformUI::GetWorkbench()->GetIntroManager()->HasIntro();
if (!hasIntro)
{
QRegExp reg("(.*)(\\n)*");
QRegExp reg2("(\\n)*(.*)");
QFile file(":/org.mitk.gui.qt.ext/index.html");
file.open(QIODevice::ReadOnly | QIODevice::Text); //text file only for reading
QString text = QString(file.readAll());
file.close();
QString title = text;
title.replace(reg, "");
title.replace(reg2, "");
std::cout << title.toStdString() << std::endl;
QMessageBox::information(nullptr, title,
text, "Close");
}
else
{
berry::PlatformUI::GetWorkbench()->GetIntroManager()->ShowIntro(
berry::PlatformUI::GetWorkbench()->GetActiveWorkbenchWindow(), false);
}
}
void QmitkFlowApplicationWorkbenchWindowAdvisorHack::onHelp()
{
ctkPluginContext* context = QmitkFlowApplicationPlugin::GetDefault()->GetPluginContext();
if (context == nullptr)
{
MITK_WARN << "Plugin context not set, unable to open context help";
return;
}
// Check if the org.blueberry.ui.qt.help plug-in is installed and started
QList > plugins = context->getPlugins();
foreach(QSharedPointer p, plugins)
{
if (p->getSymbolicName() == "org.blueberry.ui.qt.help")
{
if (p->getState() != ctkPlugin::ACTIVE)
{
// try to activate the plug-in explicitly
try
{
p->start(ctkPlugin::START_TRANSIENT);
}
catch (const ctkPluginException& pe)
{
MITK_ERROR << "Activating org.blueberry.ui.qt.help failed: " << pe.what();
return;
}
}
}
}
ctkServiceReference eventAdminRef = context->getServiceReference();
ctkEventAdmin* eventAdmin = nullptr;
if (eventAdminRef)
{
eventAdmin = context->getService(eventAdminRef);
}
if (eventAdmin == nullptr)
{
MITK_WARN << "ctkEventAdmin service not found. Unable to open context help";
}
else
{
ctkEvent ev("org/blueberry/ui/help/CONTEXTHELP_REQUESTED");
eventAdmin->postEvent(ev);
}
}
void QmitkFlowApplicationWorkbenchWindowAdvisorHack::onHelpOpenHelpPerspective()
{
berry::PlatformUI::GetWorkbench()->ShowPerspective("org.blueberry.perspectives.help",
berry::PlatformUI::GetWorkbench()->GetActiveWorkbenchWindow());
}
void QmitkFlowApplicationWorkbenchWindowAdvisorHack::onAbout()
{
auto aboutDialog = new QmitkAboutDialog(QApplication::activeWindow(), nullptr);
aboutDialog->open();
}
diff --git a/Plugins/org.mitk.gui.qt.igt.app.ultrasoundtrackingnavigation/src/internal/QmitkUSZonesDataModel.cpp b/Plugins/org.mitk.gui.qt.igt.app.ultrasoundtrackingnavigation/src/internal/QmitkUSZonesDataModel.cpp
index 9325927588..9b75e10e90 100644
--- a/Plugins/org.mitk.gui.qt.igt.app.ultrasoundtrackingnavigation/src/internal/QmitkUSZonesDataModel.cpp
+++ b/Plugins/org.mitk.gui.qt.igt.app.ultrasoundtrackingnavigation/src/internal/QmitkUSZonesDataModel.cpp
@@ -1,328 +1,327 @@
/*============================================================================
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 "QmitkUSZonesDataModel.h"
#include
#include "mitkMessage.h"
#include "mitkProperties.h"
#include "mitkRenderingManager.h"
-#include "mitkNodePredicateSource.h"
#include "Interactors/mitkUSZonesInteractor.h"
QmitkUSZonesDataModel::QmitkUSZonesDataModel(QObject *parent) :
QAbstractTableModel(parent),
m_ListenerAddNode(this, &QmitkUSZonesDataModel::AddNode),
m_ListenerChangeNode(this, &QmitkUSZonesDataModel::ChangeNode),
m_ListenerRemoveNode(this, &QmitkUSZonesDataModel::RemoveNode)
{
}
QmitkUSZonesDataModel::~QmitkUSZonesDataModel()
{
if ( m_DataStorage.IsNotNull() )
{
m_DataStorage->AddNodeEvent.RemoveListener(m_ListenerAddNode);
m_DataStorage->ChangedNodeEvent.RemoveListener(m_ListenerChangeNode);
m_DataStorage->InteractorChangedNodeEvent.RemoveListener(m_ListenerChangeNode);
m_DataStorage->RemoveNodeEvent.RemoveListener(m_ListenerRemoveNode);
}
}
void QmitkUSZonesDataModel::SetDataStorage(mitk::DataStorage::Pointer dataStorage, mitk::DataNode::Pointer baseNode)
{
m_DataStorage = dataStorage;
m_BaseNode = baseNode;
if ( m_DataStorage.IsNotNull() )
{
m_DataStorage->AddNodeEvent.AddListener(m_ListenerAddNode);
m_DataStorage->RemoveNodeEvent.AddListener(m_ListenerRemoveNode);
m_DataStorage->ChangedNodeEvent.AddListener(m_ListenerChangeNode);
m_DataStorage->InteractorChangedNodeEvent.AddListener(m_ListenerChangeNode);
}
}
void QmitkUSZonesDataModel::AddNode(const mitk::DataNode* node)
{
if ( m_DataStorage.IsNull() )
{
MITK_ERROR << "DataStorage has to be set before adding the first zone node.";
mitkThrow() << "DataStorage has to be set before adding the first zone node.";
}
// do not add nodes, which aren't fully created yet
bool boolValue;
if ( ! (node->GetBoolProperty(mitk::USZonesInteractor::DATANODE_PROPERTY_CREATED, boolValue) && boolValue) )
{
return;
}
// get source node of given node and test if m_BaseNode is a source node
mitk::DataStorage::SetOfObjects::ConstPointer sourceNodes = m_DataStorage->GetSources(node);
mitk::DataStorage::SetOfObjects::ConstIterator baseNodeIt = sourceNodes->Begin();
while ( baseNodeIt != sourceNodes->End() && baseNodeIt->Value() != m_BaseNode ) { ++baseNodeIt; }
// only nodes below m_BaseNode should be added to the model
if ( baseNodeIt == sourceNodes->End() ) { return; }
int newRowIndex = this->rowCount();
this->insertRow(newRowIndex);
m_ZoneNodes.at(newRowIndex) = const_cast(node);
// get row of the changed node and emit signal that the data of this row changed
emit dataChanged(this->index(newRowIndex, 0), this->index(newRowIndex, this->columnCount()));
}
void QmitkUSZonesDataModel::RemoveNode(const mitk::DataNode* node)
{
// find index of the given node in the nodes vector
unsigned int index = 0;
DataNodeVector::iterator current = m_ZoneNodes.begin();
while (current != m_ZoneNodes.end())
{
if ( *current == node ) { break; }
++index;
++current;
}
// remove node from model if it was found
if ( current != m_ZoneNodes.end() )
{
// remove node from the model and make sure that there will be no
// recursive removing calls (as removing node from data storage inside
// removeRows function will lead into another call of RemoveNode).
this->removeRows(index, 1, QModelIndex(), false);
}
}
void QmitkUSZonesDataModel::ChangeNode(const mitk::DataNode* node)
{
if ( static_cast >(node).IsNull() ) { return; }
DataNodeVector::iterator oldNodeIt = find (m_ZoneNodes.begin(), m_ZoneNodes.end(), node);
if (oldNodeIt == m_ZoneNodes.end())
{
// if node was not added yet, but it's creation is finished -> add it now
bool boolValue;
if ( node->GetBoolProperty(mitk::USZonesInteractor::DATANODE_PROPERTY_CREATED, boolValue) && boolValue )
{
this->AddNode(node);
}
return;
}
// get row of the changed node and emit signal that the data of this row changed
unsigned int row = oldNodeIt - m_ZoneNodes.begin();
emit dataChanged(this->index(row, 0), this->index(row, this->columnCount()));
}
int QmitkUSZonesDataModel::rowCount ( const QModelIndex& /*parent*/ ) const
{
return m_ZoneNodes.size();
}
int QmitkUSZonesDataModel::columnCount ( const QModelIndex& /*parent*/ ) const
{
return 3;
}
QVariant QmitkUSZonesDataModel::headerData ( int section, Qt::Orientation orientation, int role ) const
{
if ( role != Qt::DisplayRole ) { return QVariant(QVariant::Invalid); }
if ( orientation == Qt::Horizontal )
{
switch ( section )
{
case 0: return QVariant("Name");
case 1: return QVariant("Size");
case 2: return QVariant("Color");
}
}
else
{
return QVariant(section+1);
}
return QVariant(QVariant::Invalid);
}
Qt::ItemFlags QmitkUSZonesDataModel::flags ( const QModelIndex& index ) const
{
if (index.column() == 1 || index.column() == 2) { return Qt::ItemIsSelectable | Qt::ItemIsEnabled; }
return Qt::ItemIsSelectable | Qt::ItemIsEditable | Qt::ItemIsEnabled;
}
QVariant QmitkUSZonesDataModel::data ( const QModelIndex& index, int role ) const
{
// make sure that row and column index fit data borders
if (static_cast(index.row()) >= m_ZoneNodes.size()
|| index.column() >= this->columnCount())
{
return QVariant(QVariant::Invalid);
}
mitk::DataNode::Pointer curNode = m_ZoneNodes.at(index.row());
switch (role)
{
case Qt::BackgroundColorRole:
{
float color[3];
if ( curNode->GetColor(color) )
{
QColor qColor(color[0] * 255, color[1] * 255, color[2] * 255);
if (qColor.isValid()) { return QVariant(QBrush(qColor)); }
}
break;
}
case Qt::EditRole:
case Qt::DisplayRole:
{
switch ( index.column() )
{
case 0:
{
return QString::fromStdString(curNode->GetName());
}
case 1:
{
float floatValue;
if ( curNode->GetFloatProperty(mitk::USZonesInteractor::DATANODE_PROPERTY_SIZE, floatValue) )
{
return static_cast(floatValue);
}
else
{
return QVariant(QVariant::Invalid);
}
}
case 2:
{
float color[3];
if ( curNode->GetColor(color) )
{
QColor qColor(color[0] * 255, color[1] * 255, color[2] * 255);
if (qColor == Qt::darkGreen) { return QVariant("Green"); }
else if (qColor == Qt::red) { return QVariant("Red"); }
else if (qColor == Qt::blue) { return QVariant("Blue"); }
else if (qColor == Qt::yellow) { return QVariant("Yellow"); }
else { return QVariant(qColor.name()); }
}
else { return QVariant(QVariant::Invalid); }
}
}
break;
}
}
return QVariant(QVariant::Invalid);
}
bool QmitkUSZonesDataModel::setData ( const QModelIndex & index, const QVariant & value, int role )
{
if (role == Qt::EditRole)
{
if (static_cast(index.row()) >= m_ZoneNodes.size()
|| index.column() >= this->columnCount())
{
return false;
}
mitk::DataNode::Pointer curNode = m_ZoneNodes.at(index.row());
switch ( index.column() )
{
case 0:
{
curNode->SetName(value.toString().toStdString());
break;
}
case 1:
{
curNode->SetFloatProperty(mitk::USZonesInteractor::DATANODE_PROPERTY_SIZE, value.toFloat());
if (curNode->GetData() != nullptr)
{
curNode->SetFloatProperty(mitk::USZonesInteractor::DATANODE_PROPERTY_SIZE, value.toFloat());
mitk::USZonesInteractor::UpdateSurface(curNode);
}
break;
}
case 2:
{
QColor color(value.toString());
curNode->SetColor(color.redF(), color.greenF(), color.blueF());
break;
}
default:
return false;
}
emit dataChanged(index, index);
}
// update the RenderWindow to show new points
mitk::RenderingManager::GetInstance()->RequestUpdateAll();
return true;
}
bool QmitkUSZonesDataModel::insertRows ( int row, int count, const QModelIndex & parent )
{
this->beginInsertRows(parent, row, row+count-1);
for ( int n = 0; n < count; ++n )
{
m_ZoneNodes.insert(m_ZoneNodes.begin()+row, mitk::DataNode::New());
}
this->endInsertRows();
return true;
}
bool QmitkUSZonesDataModel::removeRows ( int row, int count, const QModelIndex & parent )
{
return this->removeRows(row, count, parent, true);
}
bool QmitkUSZonesDataModel::removeRows ( int row, int count, const QModelIndex & parent, bool removeFromDataStorage )
{
if ( static_cast(row+count) > m_ZoneNodes.size() ) { return false; }
this->beginRemoveRows(parent, row, row+count-1);
for ( int n = count-1; n >= 0; --n )
{
DataNodeVector::iterator it = m_ZoneNodes.begin()+row+n;
mitk::DataNode::Pointer curNode = *it;
m_ZoneNodes.erase(it);
if ( removeFromDataStorage && m_DataStorage.IsNotNull() )
{
m_DataStorage->Remove(curNode);
}
}
this->endRemoveRows();
return true;
}
diff --git a/Plugins/org.mitk.gui.qt.segmentation/files.cmake b/Plugins/org.mitk.gui.qt.segmentation/files.cmake
index 49b6f35827..c92f6fd02d 100644
--- a/Plugins/org.mitk.gui.qt.segmentation/files.cmake
+++ b/Plugins/org.mitk.gui.qt.segmentation/files.cmake
@@ -1,73 +1,78 @@
set(SRC_CPP_FILES
QmitkSegmentationPreferencePage.cpp
QmitkNewSegmentationDialog.cpp
QmitkLabelSetWidget.cpp
)
set(INTERNAL_CPP_FILES
mitkPluginActivator.cpp
QmitkSegmentationView.cpp
QmitkSegmentationUtilitiesView.cpp
+ QmitkSegmentationTaskListView.cpp
QmitkAutocropAction.cpp
QmitkAutocropLabelSetImageAction.cpp
QmitkCreatePolygonModelAction.cpp
QmitkLoadMultiLabelPresetAction.cpp
QmitkSaveMultiLabelPresetAction.cpp
QmitkConvertSurfaceToLabelAction.cpp
QmitkConvertMaskToLabelAction.cpp
QmitkConvertToMultiLabelSegmentationAction.cpp
QmitkCreateMultiLabelSegmentationAction.cpp
Common/QmitkLabelsWidget.cpp
Common/QmitkLayersWidget.cpp
)
set(UI_FILES
src/QmitkSegmentationPreferencePageControls.ui
src/QmitkNewSegmentationDialog.ui
src/QmitkLabelSetWidgetControls.ui
src/internal/QmitkSegmentationViewControls.ui
src/internal/QmitkSegmentationUtilitiesViewControls.ui
+ src/internal/QmitkSegmentationTaskListView.ui
src/internal/Common/QmitkLabelsWidgetControls.ui
src/internal/Common/QmitkLayersWidgetControls.ui
)
set(MOC_H_FILES
src/QmitkSegmentationPreferencePage.h
src/QmitkNewSegmentationDialog.h
src/QmitkLabelSetWidget.h
src/internal/mitkPluginActivator.h
src/internal/QmitkSegmentationView.h
src/internal/QmitkSegmentationUtilitiesView.h
+ src/internal/QmitkSegmentationTaskListView.h
src/internal/QmitkAutocropAction.h
src/internal/QmitkAutocropLabelSetImageAction.h
src/internal/QmitkCreatePolygonModelAction.h
src/internal/QmitkLoadMultiLabelPresetAction.h
src/internal/QmitkSaveMultiLabelPresetAction.h
src/internal/QmitkConvertSurfaceToLabelAction.h
src/internal/QmitkConvertMaskToLabelAction.h
src/internal/QmitkConvertToMultiLabelSegmentationAction.h
src/internal/QmitkCreateMultiLabelSegmentationAction.h
src/internal/Common/QmitkLabelsWidget.h
src/internal/Common/QmitkLayersWidget.h
)
set(CACHED_RESOURCE_FILES
resources/segmentation.svg
resources/segmentation_utilities.svg
+ resources/SegmentationTaskListIcon.svg
plugin.xml
)
set(QRC_FILES
resources/segmentation.qrc
resources/SegmentationUtilities.qrc
+ resources/SegmentationTaskList.qrc
)
set(CPP_FILES)
foreach(file ${SRC_CPP_FILES})
set(CPP_FILES ${CPP_FILES} src/${file})
endforeach(file ${SRC_CPP_FILES})
foreach(file ${INTERNAL_CPP_FILES})
set(CPP_FILES ${CPP_FILES} src/internal/${file})
endforeach(file ${INTERNAL_CPP_FILES})
diff --git a/Plugins/org.mitk.gui.qt.segmentation/plugin.xml b/Plugins/org.mitk.gui.qt.segmentation/plugin.xml
index d761442833..70faf41d0e 100644
--- a/Plugins/org.mitk.gui.qt.segmentation/plugin.xml
+++ b/Plugins/org.mitk.gui.qt.segmentation/plugin.xml
@@ -1,84 +1,102 @@
Allows the segmentation of images using different tools.
Edit segmentations using standard operations.
+
+ Create or edit a batch of segmentations according to a task list in a streamlined workflow.
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Plugins/org.mitk.gui.qt.flow.segmentation/resources/SegmentationTaskList.qrc b/Plugins/org.mitk.gui.qt.segmentation/resources/SegmentationTaskList.qrc
similarity index 53%
rename from Plugins/org.mitk.gui.qt.flow.segmentation/resources/SegmentationTaskList.qrc
rename to Plugins/org.mitk.gui.qt.segmentation/resources/SegmentationTaskList.qrc
index 327fbe97d1..9a581864a6 100644
--- a/Plugins/org.mitk.gui.qt.flow.segmentation/resources/SegmentationTaskList.qrc
+++ b/Plugins/org.mitk.gui.qt.segmentation/resources/SegmentationTaskList.qrc
@@ -1,5 +1,5 @@
- SegmentationTaskListIcon.svg
+ SegmentationTaskListIcon.svg
diff --git a/Plugins/org.mitk.gui.qt.flow.segmentation/resources/SegmentationTaskListIcon.svg b/Plugins/org.mitk.gui.qt.segmentation/resources/SegmentationTaskListIcon.svg
similarity index 100%
rename from Plugins/org.mitk.gui.qt.flow.segmentation/resources/SegmentationTaskListIcon.svg
rename to Plugins/org.mitk.gui.qt.segmentation/resources/SegmentationTaskListIcon.svg
diff --git a/Plugins/org.mitk.gui.qt.segmentation/src/internal/QmitkSegmentationTaskListView.cpp b/Plugins/org.mitk.gui.qt.segmentation/src/internal/QmitkSegmentationTaskListView.cpp
new file mode 100644
index 0000000000..d0207cd11a
--- /dev/null
+++ b/Plugins/org.mitk.gui.qt.segmentation/src/internal/QmitkSegmentationTaskListView.cpp
@@ -0,0 +1,54 @@
+/*============================================================================
+
+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 "QmitkSegmentationTaskListView.h"
+#include
+
+#include
+
+const std::string QmitkSegmentationTaskListView::VIEW_ID = "org.mitk.views.segmentationtasklist";
+
+QmitkSegmentationTaskListView::QmitkSegmentationTaskListView()
+ : m_Ui(new Ui::QmitkSegmentationTaskListView)
+{
+ berry::PlatformUI::GetWorkbench()->AddWorkbenchListener(this);
+}
+
+QmitkSegmentationTaskListView::~QmitkSegmentationTaskListView()
+{
+ berry::PlatformUI::GetWorkbench()->RemoveWorkbenchListener(this);
+}
+
+void QmitkSegmentationTaskListView::CreateQtPartControl(QWidget* parent)
+{
+ m_Ui->setupUi(parent);
+ m_Ui->segmentationTaskListWidget->SetDataStorage(this->GetDataStorage());
+}
+
+void QmitkSegmentationTaskListView::SetFocus()
+{
+}
+
+void QmitkSegmentationTaskListView::NodeAdded(const mitk::DataNode*)
+{
+ m_Ui->segmentationTaskListWidget->CheckDataStorage();
+}
+
+void QmitkSegmentationTaskListView::NodeRemoved(const mitk::DataNode* removedNode)
+{
+ m_Ui->segmentationTaskListWidget->CheckDataStorage(removedNode);
+}
+
+bool QmitkSegmentationTaskListView::PreShutdown(berry::IWorkbench*, bool)
+{
+ return m_Ui->segmentationTaskListWidget->OnPreShutdown();
+}
diff --git a/Plugins/org.mitk.gui.qt.segmentation/src/internal/QmitkSegmentationTaskListView.h b/Plugins/org.mitk.gui.qt.segmentation/src/internal/QmitkSegmentationTaskListView.h
new file mode 100644
index 0000000000..0a04ce203b
--- /dev/null
+++ b/Plugins/org.mitk.gui.qt.segmentation/src/internal/QmitkSegmentationTaskListView.h
@@ -0,0 +1,45 @@
+/*============================================================================
+
+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 QmitkSegmentationTaskListView_h
+#define QmitkSegmentationTaskListView_h
+
+#include
+#include
+
+namespace Ui
+{
+ class QmitkSegmentationTaskListView;
+}
+
+class QmitkSegmentationTaskListView : public QmitkAbstractView, public berry::IWorkbenchListener
+{
+ Q_OBJECT
+
+public:
+ static const std::string VIEW_ID;
+
+ QmitkSegmentationTaskListView();
+ ~QmitkSegmentationTaskListView() override;
+
+private:
+ void CreateQtPartControl(QWidget* parent) override;
+ void SetFocus() override;
+ void NodeAdded(const mitk::DataNode*) override;
+ void NodeRemoved(const mitk::DataNode* removedNode) override;
+
+ bool PreShutdown(berry::IWorkbench*, bool) override;
+
+ Ui::QmitkSegmentationTaskListView* m_Ui;
+};
+
+#endif
diff --git a/Plugins/org.mitk.gui.qt.segmentation/src/internal/QmitkSegmentationTaskListView.ui b/Plugins/org.mitk.gui.qt.segmentation/src/internal/QmitkSegmentationTaskListView.ui
new file mode 100644
index 0000000000..76821f3e6b
--- /dev/null
+++ b/Plugins/org.mitk.gui.qt.segmentation/src/internal/QmitkSegmentationTaskListView.ui
@@ -0,0 +1,32 @@
+
+
+ QmitkSegmentationTaskListView
+
+
+
+ 0
+ 0
+ 400
+ 300
+
+
+
+ Form
+
+
+ -
+
+
+
+
+
+
+ QmitkSegmentationTaskListWidget
+ QWidget
+ QmitkSegmentationTaskListWidget.h
+ 1
+
+
+
+
+
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 ea361b7226..70ab9cfbb3 100644
--- a/Plugins/org.mitk.gui.qt.segmentation/src/internal/mitkPluginActivator.cpp
+++ b/Plugins/org.mitk.gui.qt.segmentation/src/internal/mitkPluginActivator.cpp
@@ -1,78 +1,80 @@
/*============================================================================
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 "mitkPluginActivator.h"
#include "QmitkSegmentationView.h"
#include "QmitkSegmentationPreferencePage.h"
#include "QmitkSegmentationUtilitiesView.h"
+#include "QmitkSegmentationTaskListView.h"
#include "QmitkAutocropAction.h"
#include "QmitkAutocropLabelSetImageAction.h"
#include "QmitkCreatePolygonModelAction.h"
#include "QmitkLoadMultiLabelPresetAction.h"
#include "QmitkSaveMultiLabelPresetAction.h"
#include "QmitkConvertSurfaceToLabelAction.h"
#include "QmitkConvertMaskToLabelAction.h"
#include "QmitkConvertToMultiLabelSegmentationAction.h"
#include "QmitkCreateMultiLabelSegmentationAction.h"
#include
US_INITIALIZE_MODULE
using namespace mitk;
ctkPluginContext* PluginActivator::m_context = nullptr;
PluginActivator* PluginActivator::m_Instance = nullptr;
PluginActivator::PluginActivator()
{
m_Instance = this;
}
PluginActivator::~PluginActivator()
{
m_Instance = nullptr;
}
void PluginActivator::start(ctkPluginContext *context)
{
BERRY_REGISTER_EXTENSION_CLASS(QmitkSegmentationView, context)
BERRY_REGISTER_EXTENSION_CLASS(QmitkSegmentationPreferencePage, context)
BERRY_REGISTER_EXTENSION_CLASS(QmitkSegmentationUtilitiesView, context)
+ BERRY_REGISTER_EXTENSION_CLASS(QmitkSegmentationTaskListView, context)
BERRY_REGISTER_EXTENSION_CLASS(QmitkAutocropAction, context)
BERRY_REGISTER_EXTENSION_CLASS(QmitkAutocropLabelSetImageAction, context)
BERRY_REGISTER_EXTENSION_CLASS(QmitkCreatePolygonModelAction, context)
BERRY_REGISTER_EXTENSION_CLASS(QmitkLoadMultiLabelPresetAction, context)
BERRY_REGISTER_EXTENSION_CLASS(QmitkSaveMultiLabelPresetAction, context)
BERRY_REGISTER_EXTENSION_CLASS(QmitkConvertSurfaceToLabelAction, context)
BERRY_REGISTER_EXTENSION_CLASS(QmitkConvertMaskToLabelAction, context)
BERRY_REGISTER_EXTENSION_CLASS(QmitkConvertToMultiLabelSegmentationAction, context)
BERRY_REGISTER_EXTENSION_CLASS(QmitkCreateMultiLabelSegmentationAction, context)
this->m_context = context;
}
void PluginActivator::stop(ctkPluginContext *)
{
this->m_context = nullptr;
}
PluginActivator* PluginActivator::getDefault()
{
return m_Instance;
}
ctkPluginContext*PluginActivator::getContext()
{
return m_context;
}