diff --git a/Modules/Core/src/IO/mitkIOMimeTypes.cpp b/Modules/Core/src/IO/mitkIOMimeTypes.cpp index b4c9eb86e4..db8b8b4bee 100644 --- a/Modules/Core/src/IO/mitkIOMimeTypes.cpp +++ b/Modules/Core/src/IO/mitkIOMimeTypes.cpp @@ -1,330 +1,356 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "mitkIOMimeTypes.h" #include "mitkCustomMimeType.h" #include "mitkLogMacros.h" #include "itkGDCMImageIO.h" #include "itkMetaDataObject.h" +#include +#include + namespace mitk { IOMimeTypes::DicomMimeType::DicomMimeType() : CustomMimeType(DICOM_MIMETYPE_NAME()) { this->AddExtension("gdcm"); this->AddExtension("dcm"); this->AddExtension("DCM"); this->AddExtension("dc3"); this->AddExtension("DC3"); this->AddExtension("ima"); this->AddExtension("img"); this->SetCategory(CATEGORY_IMAGES()); this->SetComment("DICOM"); } bool IOMimeTypes::DicomMimeType::AppliesTo(const std::string &path) const { + // check whether directory or file + // if directory try to find first file within it instead + bool pathIsDirectory = itksys::SystemTools::FileIsDirectory(path); + + std::string filepath = path; + + if (pathIsDirectory) + { + itksys::Directory input; + input.Load(path.c_str()); + + std::vector files; + for (unsigned long idx = 0; idxSetFileName(path); + gdcmIO->SetFileName(filepath); try { gdcmIO->ReadImageInformation(); } catch (const itk::ExceptionObject & /*err*/) { return false; } //DICOMRT modalities have specific reader, don't read with normal DICOM readers std::string modality; itk::MetaDataDictionary& dict = gdcmIO->GetMetaDataDictionary(); itk::ExposeMetaData(dict, "0008|0060", modality); MITK_INFO << "DICOM Modality is " << modality; if (modality == "RTSTRUCT" || modality == "RTDOSE" || modality == "RTPLAN") { return false; } else { - return gdcmIO->CanReadFile(path.c_str()); + return gdcmIO->CanReadFile(filepath.c_str()); } } IOMimeTypes::DicomMimeType *IOMimeTypes::DicomMimeType::Clone() const { return new DicomMimeType(*this); } std::vector IOMimeTypes::Get() { std::vector mimeTypes; // order matters here (descending rank for mime types) mimeTypes.push_back(NRRD_MIMETYPE().Clone()); mimeTypes.push_back(NIFTI_MIMETYPE().Clone()); mimeTypes.push_back(VTK_IMAGE_MIMETYPE().Clone()); mimeTypes.push_back(VTK_PARALLEL_IMAGE_MIMETYPE().Clone()); mimeTypes.push_back(VTK_IMAGE_LEGACY_MIMETYPE().Clone()); mimeTypes.push_back(DICOM_MIMETYPE().Clone()); mimeTypes.push_back(VTK_POLYDATA_MIMETYPE().Clone()); mimeTypes.push_back(VTK_PARALLEL_POLYDATA_MIMETYPE().Clone()); mimeTypes.push_back(VTK_POLYDATA_LEGACY_MIMETYPE().Clone()); mimeTypes.push_back(STEREOLITHOGRAPHY_MIMETYPE().Clone()); mimeTypes.push_back(WAVEFRONT_OBJ_MIMETYPE().Clone()); mimeTypes.push_back(STANFORD_PLY_MIMETYPE().Clone()); mimeTypes.push_back(RAW_MIMETYPE().Clone()); mimeTypes.push_back(POINTSET_MIMETYPE().Clone()); return mimeTypes; } CustomMimeType IOMimeTypes::VTK_IMAGE_MIMETYPE() { CustomMimeType mimeType(VTK_IMAGE_NAME()); mimeType.AddExtension("vti"); mimeType.SetCategory(CATEGORY_IMAGES()); mimeType.SetComment("VTK Image"); return mimeType; } CustomMimeType IOMimeTypes::VTK_IMAGE_LEGACY_MIMETYPE() { CustomMimeType mimeType(VTK_IMAGE_LEGACY_NAME()); mimeType.AddExtension("vtk"); mimeType.SetCategory(CATEGORY_IMAGES()); mimeType.SetComment("VTK Legacy Image"); return mimeType; } CustomMimeType IOMimeTypes::VTK_PARALLEL_IMAGE_MIMETYPE() { CustomMimeType mimeType(VTK_PARALLEL_IMAGE_NAME()); mimeType.AddExtension("pvti"); mimeType.SetCategory(CATEGORY_IMAGES()); mimeType.SetComment("VTK Parallel Image"); return mimeType; } CustomMimeType IOMimeTypes::VTK_POLYDATA_MIMETYPE() { CustomMimeType mimeType(VTK_POLYDATA_NAME()); mimeType.AddExtension("vtp"); mimeType.SetCategory(CATEGORY_SURFACES()); mimeType.SetComment("VTK PolyData"); return mimeType; } CustomMimeType IOMimeTypes::VTK_POLYDATA_LEGACY_MIMETYPE() { CustomMimeType mimeType(VTK_POLYDATA_LEGACY_NAME()); mimeType.AddExtension("vtk"); mimeType.SetCategory(CATEGORY_SURFACES()); mimeType.SetComment("VTK Legacy PolyData"); return mimeType; } CustomMimeType IOMimeTypes::VTK_PARALLEL_POLYDATA_MIMETYPE() { CustomMimeType mimeType(VTK_PARALLEL_POLYDATA_NAME()); mimeType.AddExtension("pvtp"); mimeType.SetCategory(CATEGORY_SURFACES()); mimeType.SetComment("VTK Parallel PolyData"); return mimeType; } CustomMimeType IOMimeTypes::STEREOLITHOGRAPHY_MIMETYPE() { CustomMimeType mimeType(STEREOLITHOGRAPHY_NAME()); mimeType.AddExtension("stl"); mimeType.SetCategory(CATEGORY_SURFACES()); mimeType.SetComment("Stereolithography"); return mimeType; } CustomMimeType IOMimeTypes::WAVEFRONT_OBJ_MIMETYPE() { CustomMimeType mimeType(WAVEFRONT_OBJ_NAME()); mimeType.AddExtension("obj"); mimeType.SetCategory(CATEGORY_SURFACES()); mimeType.SetComment("Wavefront OBJ"); return mimeType; } CustomMimeType IOMimeTypes::STANFORD_PLY_MIMETYPE() { CustomMimeType mimeType(STANFORD_PLY_NAME()); mimeType.AddExtension("ply"); mimeType.SetCategory(CATEGORY_SURFACES()); mimeType.SetComment("Stanford PLY"); return mimeType; } std::string IOMimeTypes::STEREOLITHOGRAPHY_NAME() { static std::string name = DEFAULT_BASE_NAME() + ".stl"; return name; } std::string IOMimeTypes::WAVEFRONT_OBJ_NAME() { static std::string name = DEFAULT_BASE_NAME() + ".obj"; return name; } std::string IOMimeTypes::STANFORD_PLY_NAME() { static std::string name = DEFAULT_BASE_NAME() + ".ply"; return name; } std::string IOMimeTypes::DEFAULT_BASE_NAME() { static std::string name = "application/vnd.mitk"; return name; } std::string IOMimeTypes::CATEGORY_IMAGES() { static std::string cat = "Images"; return cat; } std::string IOMimeTypes::CATEGORY_SURFACES() { static std::string cat = "Surfaces"; return cat; } std::string IOMimeTypes::VTK_IMAGE_NAME() { static std::string name = DEFAULT_BASE_NAME() + ".vtk.image"; return name; } std::string IOMimeTypes::VTK_IMAGE_LEGACY_NAME() { static std::string name = DEFAULT_BASE_NAME() + ".vtk.image.legacy"; return name; } std::string IOMimeTypes::VTK_PARALLEL_IMAGE_NAME() { static std::string name = DEFAULT_BASE_NAME() + ".vtk.parallel.image"; return name; } std::string IOMimeTypes::VTK_POLYDATA_NAME() { static std::string name = DEFAULT_BASE_NAME() + ".vtk.polydata"; return name; } std::string IOMimeTypes::VTK_POLYDATA_LEGACY_NAME() { static std::string name = DEFAULT_BASE_NAME() + ".vtk.polydata.legacy"; return name; } std::string IOMimeTypes::VTK_PARALLEL_POLYDATA_NAME() { static std::string name = DEFAULT_BASE_NAME() + ".vtk.parallel.polydata"; return name; } CustomMimeType IOMimeTypes::NRRD_MIMETYPE() { CustomMimeType mimeType(NRRD_MIMETYPE_NAME()); mimeType.AddExtension("nrrd"); mimeType.AddExtension("nhdr"); mimeType.SetCategory("Images"); mimeType.SetComment("NRRD"); return mimeType; } CustomMimeType IOMimeTypes::NIFTI_MIMETYPE() { CustomMimeType mimeType(NIFTI_MIMETYPE_NAME()); mimeType.AddExtension("nii"); mimeType.AddExtension("nii.gz"); mimeType.AddExtension("hdr"); mimeType.AddExtension("hdr.gz"); mimeType.AddExtension("img"); mimeType.AddExtension("img.gz"); mimeType.AddExtension("nia"); mimeType.SetCategory("Images"); mimeType.SetComment("Nifti"); return mimeType; } CustomMimeType IOMimeTypes::RAW_MIMETYPE() { CustomMimeType mimeType(RAW_MIMETYPE_NAME()); mimeType.AddExtension("raw"); mimeType.SetCategory("Images"); mimeType.SetComment("Raw data"); return mimeType; } IOMimeTypes::DicomMimeType IOMimeTypes::DICOM_MIMETYPE() { return DicomMimeType(); } std::string IOMimeTypes::NRRD_MIMETYPE_NAME() { static std::string name = DEFAULT_BASE_NAME() + ".image.nrrd"; return name; } std::string IOMimeTypes::NIFTI_MIMETYPE_NAME() { static std::string name = DEFAULT_BASE_NAME() + ".image.nifti"; return name; } std::string IOMimeTypes::RAW_MIMETYPE_NAME() { static std::string name = DEFAULT_BASE_NAME() + ".image.raw"; return name; } std::string IOMimeTypes::DICOM_MIMETYPE_NAME() { static std::string name = DEFAULT_BASE_NAME() + ".image.dicom"; return name; } CustomMimeType IOMimeTypes::POINTSET_MIMETYPE() { CustomMimeType mimeType(POINTSET_MIMETYPE_NAME()); mimeType.AddExtension("mps"); mimeType.SetCategory("Point Sets"); mimeType.SetComment("MITK Point Set"); return mimeType; } std::string IOMimeTypes::POINTSET_MIMETYPE_NAME() { static std::string name = DEFAULT_BASE_NAME() + ".pointset"; return name; } CustomMimeType IOMimeTypes::GEOMETRY_DATA_MIMETYPE() { mitk::CustomMimeType mimeType(DEFAULT_BASE_NAME() + ".geometrydata"); mimeType.AddExtension("mitkgeometry"); mimeType.SetCategory("Geometries"); mimeType.SetComment("GeometryData object"); return mimeType; } } diff --git a/Modules/DICOMReader/include/mitkBaseDICOMReaderService.h b/Modules/DICOMReader/include/mitkBaseDICOMReaderService.h index 79c4b84734..914c858777 100644 --- a/Modules/DICOMReader/include/mitkBaseDICOMReaderService.h +++ b/Modules/DICOMReader/include/mitkBaseDICOMReaderService.h @@ -1,55 +1,57 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #ifndef MITKBASEDICOMREADERSERVICE_H #define MITKBASEDICOMREADERSERVICE_H #include #include #include "MitkDICOMReaderExports.h" namespace mitk { /** Base class for service wrappers that make DICOMFileReader from the DICOMReader module usable. */ class MITKDICOMREADER_EXPORT BaseDICOMReaderService : public AbstractFileReader { public: BaseDICOMReaderService(const std::string& description); BaseDICOMReaderService(const mitk::CustomMimeType& customType, const std::string& description); using AbstractFileReader::Read; /** Uses this->GetRelevantFile() and this->GetReader to load the image. * data and puts it into base data instances-*/ virtual std::vector > Read() override; + virtual IFileReader::ConfidenceLevel GetConfidenceLevel() const override; + protected: /** Returns the list of all DCM files that are in the same directory * like this->GetLocalFileName().*/ mitk::StringList GetRelevantFiles() const; /** Returns the reader instance that should be used. The descission may be based * one the passed relevant file list.*/ virtual mitk::DICOMFileReader::Pointer GetReader(const mitk::StringList& relevantFiles) const = 0; }; } #endif // MITKBASEDICOMREADERSERVICE_H diff --git a/Modules/DICOMReader/src/mitkBaseDICOMReaderService.cpp b/Modules/DICOMReader/src/mitkBaseDICOMReaderService.cpp index 810608f9df..6a11ea49ca 100644 --- a/Modules/DICOMReader/src/mitkBaseDICOMReaderService.cpp +++ b/Modules/DICOMReader/src/mitkBaseDICOMReaderService.cpp @@ -1,148 +1,192 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "mitkBaseDICOMReaderService.h" #include #include #include #include #include #include #include #include #include #include #include + +#include +#include + namespace mitk { BaseDICOMReaderService::BaseDICOMReaderService(const std::string& description) : AbstractFileReader(CustomMimeType(IOMimeTypes::DICOM_MIMETYPE()), description) { } BaseDICOMReaderService::BaseDICOMReaderService(const mitk::CustomMimeType& customType, const std::string& description) : AbstractFileReader(customType, description) { } std::vector > BaseDICOMReaderService::Read() { std::vector result; //special handling of Philips 3D US DICOM. //Copied from DICOMSeriesReaderService std::string fileName = this->GetLocalFileName(); if (DicomSeriesReader::IsPhilips3DDicom(fileName)) { MITK_INFO << "it is a Philips3D US Dicom file" << std::endl; mitk::LocaleSwitch localeSwitch("C"); std::locale previousCppLocale(std::cin.getloc()); std::locale l("C"); std::cin.imbue(l); DataNode::Pointer node = DataNode::New(); mitk::DicomSeriesReader::StringContainer stringvec; stringvec.push_back(fileName); if (DicomSeriesReader::LoadDicomSeries(stringvec, *node)) { BaseData::Pointer data = node->GetData(); StringProperty::Pointer nameProp = StringProperty::New(itksys::SystemTools::GetFilenameName(fileName)); data->GetPropertyList()->SetProperty("name", nameProp); result.push_back(data); } std::cin.imbue(previousCppLocale); return result; } //Normal DICOM handling (It wasn't a Philips 3D US) mitk::StringList relevantFiles = this->GetRelevantFiles(); + // check whether directory or file + // if directory try to find first file within it instead + // We only support this for a single directory at once + if (relevantFiles.empty()) + { + bool pathIsDirectory = itksys::SystemTools::FileIsDirectory(this->GetLocalFileName()); + if (pathIsDirectory) + { + itksys::Directory input; + input.Load(this->GetLocalFileName().c_str()); + + std::vector files; + for (unsigned long idx = 0; idxGetLocalFileName() + "/" + std::string(input.GetFile(idx)); + files.push_back(fullpath.c_str()); + } + } + relevantFiles = files; + } + } + if (relevantFiles.empty()) { MITK_INFO << "DICOMReader service found no relevant files in specified location. No data is loaded. Location: "<GetReader(relevantFiles); if(reader.IsNull()) { MITK_INFO << "DICOMReader service found no suitable reader configuration for relevant files."; } else { reader->SetAdditionalTagsOfInterest(mitk::GetCurrentDICOMTagsOfInterest()); reader->SetTagLookupTableToPropertyFunctor(mitk::GetDICOMPropertyForDICOMValuesFunctor); reader->SetInputFiles(relevantFiles); mitk::DICOMDCMTKTagScanner::Pointer scanner = mitk::DICOMDCMTKTagScanner::New(); scanner->AddTagPaths(reader->GetTagsOfInterest()); scanner->SetInputFiles(relevantFiles); scanner->Scan(); reader->SetTagCache(scanner->GetScanCache()); reader->AnalyzeInputFiles(); reader->LoadImages(); for (unsigned int i = 0; i < reader->GetNumberOfOutputs(); ++i) { const mitk::DICOMImageBlockDescriptor& desc = reader->GetOutput(i); mitk::BaseData::Pointer data = desc.GetMitkImage().GetPointer(); std::string nodeName = "Unnamed_DICOM"; std::string studyDescription = desc.GetPropertyAsString("studyDescription"); std::string seriesDescription = desc.GetPropertyAsString("seriesDescription"); if (!studyDescription.empty()) { nodeName = studyDescription; } if (!seriesDescription.empty()) { if (!studyDescription.empty()) { nodeName += "/"; } nodeName += seriesDescription; } StringProperty::Pointer nameProp = StringProperty::New(nodeName); data->SetProperty("name", nameProp); result.push_back(data); } } } return result; } StringList BaseDICOMReaderService::GetRelevantFiles() const { std::string fileName = this->GetLocalFileName(); mitk::StringList relevantFiles = mitk::GetDICOMFilesInSameDirectory(fileName); return relevantFiles; } +IFileReader::ConfidenceLevel BaseDICOMReaderService::GetConfidenceLevel() const +{ + IFileReader::ConfidenceLevel abstractConfidence = AbstractFileReader::GetConfidenceLevel(); + + if (Unsupported == abstractConfidence) + { + if (itksys::SystemTools::FileIsDirectory(this->GetInputLocation().c_str())) + { + // In principle we support dicom directories + return Supported; + } + } + + return abstractConfidence; +} + } diff --git a/Modules/DICOMReaderServices/src/mitkAutoSelectingDICOMReaderService.cpp b/Modules/DICOMReaderServices/src/mitkAutoSelectingDICOMReaderService.cpp index 7d432e1815..72b9169de7 100644 --- a/Modules/DICOMReaderServices/src/mitkAutoSelectingDICOMReaderService.cpp +++ b/Modules/DICOMReaderServices/src/mitkAutoSelectingDICOMReaderService.cpp @@ -1,53 +1,54 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "mitkAutoSelectingDICOMReaderService.h" #include namespace mitk { AutoSelectingDICOMReaderService::AutoSelectingDICOMReaderService() : BaseDICOMReaderService("MITK DICOM Reader v2 (autoselect)") { + this->SetRanking(5); this->RegisterService(); } DICOMFileReader::Pointer AutoSelectingDICOMReaderService::GetReader(const mitk::StringList& relevantFiles) const { mitk::DICOMFileReaderSelector::Pointer selector = mitk::DICOMFileReaderSelector::New(); selector->LoadBuiltIn3DConfigs(); selector->LoadBuiltIn3DnTConfigs(); selector->SetInputFiles(relevantFiles); mitk::DICOMFileReader::Pointer reader = selector->GetFirstReaderWithMinimumNumberOfOutputImages(); if(reader.IsNotNull()) { //reset tag cache to ensure that additional tags of interest //will be regarded by the reader if set later on. reader->SetTagCache(nullptr); } return reader; }; AutoSelectingDICOMReaderService* AutoSelectingDICOMReaderService::Clone() const { return new AutoSelectingDICOMReaderService(*this); } } diff --git a/Plugins/org.mitk.gui.qt.dicom/resources/dicom.svg b/Plugins/org.mitk.gui.qt.dicom/resources/dicom.svg index a0c135fe55..f5e031c0fd 100644 --- a/Plugins/org.mitk.gui.qt.dicom/resources/dicom.svg +++ b/Plugins/org.mitk.gui.qt.dicom/resources/dicom.svg @@ -1,55 +1,85 @@ + width="100" + inkscape:version="0.91 r13725" + sodipodi:docname="dicom.svg"> + image/svg+xml - + - DCM + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:915.96606445px;line-height:125%;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#ff00ff;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + id="text4152-8"> + + + + diff --git a/Plugins/org.mitk.gui.qt.dicom/src/internal/DicomEventHandler.cpp b/Plugins/org.mitk.gui.qt.dicom/src/internal/DicomEventHandler.cpp index 0c9ffb7c62..e488dee9ad 100644 --- a/Plugins/org.mitk.gui.qt.dicom/src/internal/DicomEventHandler.cpp +++ b/Plugins/org.mitk.gui.qt.dicom/src/internal/DicomEventHandler.cpp @@ -1,320 +1,265 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "mitkPluginActivator.h" #include "DicomEventHandler.h" #include #include #include #include #include #include #include #include #include #include "mitkImage.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 DicomEventHandler::DicomEventHandler() { } DicomEventHandler::~DicomEventHandler() { } void DicomEventHandler::OnSignalAddSeriesToDataManager(const ctkEvent& ctkEvent) { QStringList listOfFilesForSeries; listOfFilesForSeries = ctkEvent.getProperty("FilesForSeries").toStringList(); if (!listOfFilesForSeries.isEmpty()) { //for rt data, if the modality tag isn't defined or is "CT" the image is handled like before if(ctkEvent.containsProperty("Modality") && (ctkEvent.getProperty("Modality").toString().compare("RTDOSE",Qt::CaseInsensitive) == 0 || ctkEvent.getProperty("Modality").toString().compare("RTSTRUCT",Qt::CaseInsensitive) == 0 || ctkEvent.getProperty("Modality").toString().compare("RTPLAN", Qt::CaseInsensitive) == 0)) { QString modality = ctkEvent.getProperty("Modality").toString(); if(modality.compare("RTDOSE",Qt::CaseInsensitive) == 0) { auto doseReader = mitk::RTDoseReaderService(); doseReader.SetInput(listOfFilesForSeries.front().toStdString()); std::vector > readerOutput = doseReader.Read(); if (!readerOutput.empty()){ mitk::Image::Pointer doseImage = dynamic_cast(readerOutput.at(0).GetPointer()); mitk::DataNode::Pointer doseImageNode = mitk::DataNode::New(); doseImageNode->SetData(doseImage); doseImageNode->SetName("RTDose"); if (doseImage != nullptr) { auto sopUIDProperty = doseImage->GetProperty("dicomseriesreader.SOPClassUID"); if (sopUIDProperty.IsNotNull()){ auto sopUIDStringProperty = dynamic_cast(sopUIDProperty.GetPointer()); if (sopUIDStringProperty != nullptr){ std::string sopUID = sopUIDStringProperty->GetValue(); doseImageNode->SetName(sopUID); } } berry::IPreferencesService* prefService = berry::Platform::GetPreferencesService(); berry::IPreferences::Pointer prefNode = prefService->GetSystemPreferences()->Node(mitk::RTUIConstants::ROOT_DOSE_VIS_PREFERENCE_NODE_ID.c_str()); if (prefNode.IsNull()) { mitkThrow() << "Error in preference interface. Cannot find preset node under given name. Name: " << prefNode->ToString().toStdString(); } //set some specific colorwash and isoline properties bool showColorWashGlobal = prefNode->GetBool(mitk::RTUIConstants::GLOBAL_VISIBILITY_COLORWASH_ID.c_str(), true); bool showIsolinesGlobal = prefNode->GetBool(mitk::RTUIConstants::GLOBAL_VISIBILITY_ISOLINES_ID.c_str(), true); //Set reference dose property double referenceDose = prefNode->GetDouble(mitk::RTUIConstants::REFERENCE_DOSE_ID.c_str(), mitk::RTUIConstants::DEFAULT_REFERENCE_DOSE_VALUE); mitk::ConfigureNodeAsDoseNode(doseImageNode, mitk::GeneratIsoLevels_Virtuos(), referenceDose, showColorWashGlobal); ctkServiceReference serviceReference = mitk::PluginActivator::getContext()->getServiceReference(); mitk::IDataStorageService* storageService = mitk::PluginActivator::getContext()->getService(serviceReference); mitk::DataStorage* dataStorage = storageService->GetDefaultDataStorage().GetPointer()->GetDataStorage(); dataStorage->Add(doseImageNode); mitk::RenderingManager::GetInstance()->InitializeViewsByBoundingObjects(dataStorage); } }//END DOSE } else if(modality.compare("RTSTRUCT",Qt::CaseInsensitive) == 0) { auto structReader = mitk::RTStructureSetReaderService(); structReader.SetInput(listOfFilesForSeries.front().toStdString()); std::vector > readerOutput = structReader.Read(); if (readerOutput.empty()){ MITK_ERROR << "No structure sets were created" << endl; } else { std::vector modelVector; ctkServiceReference serviceReference = mitk::PluginActivator::getContext()->getServiceReference(); mitk::IDataStorageService* storageService = mitk::PluginActivator::getContext()->getService(serviceReference); mitk::DataStorage* dataStorage = storageService->GetDefaultDataStorage().GetPointer()->GetDataStorage(); for (const auto& aStruct : readerOutput){ mitk::ContourModelSet::Pointer countourModelSet = dynamic_cast(aStruct.GetPointer()); mitk::DataNode::Pointer structNode = mitk::DataNode::New(); structNode->SetData(countourModelSet); structNode->SetProperty("name", aStruct->GetProperty("name")); structNode->SetProperty("color", aStruct->GetProperty("contour.color")); structNode->SetProperty("contour.color", aStruct->GetProperty("contour.color")); structNode->SetProperty("includeInBoundingBox", mitk::BoolProperty::New(false)); structNode->SetVisibility(true, mitk::BaseRenderer::GetInstance( mitk::BaseRenderer::GetRenderWindowByName("stdmulti.widget1"))); structNode->SetVisibility(false, mitk::BaseRenderer::GetInstance( mitk::BaseRenderer::GetRenderWindowByName("stdmulti.widget2"))); structNode->SetVisibility(false, mitk::BaseRenderer::GetInstance( mitk::BaseRenderer::GetRenderWindowByName("stdmulti.widget3"))); structNode->SetVisibility(true, mitk::BaseRenderer::GetInstance( mitk::BaseRenderer::GetRenderWindowByName("stdmulti.widget4"))); dataStorage->Add(structNode); } mitk::RenderingManager::GetInstance()->InitializeViewsByBoundingObjects(dataStorage); } } else if (modality.compare("RTPLAN", Qt::CaseInsensitive) == 0) { auto planReader = mitk::RTPlanReaderService(); planReader.SetInput(listOfFilesForSeries.front().toStdString()); std::vector > readerOutput = planReader.Read(); if (!readerOutput.empty()){ //there is no image, only the properties are interesting mitk::Image::Pointer planDummyImage = dynamic_cast(readerOutput.at(0).GetPointer()); mitk::DataNode::Pointer planImageNode = mitk::DataNode::New(); planImageNode->SetData(planDummyImage); planImageNode->SetName("RTPlan"); ctkServiceReference serviceReference = mitk::PluginActivator::getContext()->getServiceReference(); mitk::IDataStorageService* storageService = mitk::PluginActivator::getContext()->getService(serviceReference); mitk::DataStorage* dataStorage = storageService->GetDefaultDataStorage().GetPointer()->GetDataStorage(); dataStorage->Add(planImageNode); } } } else { mitk::StringList seriesToLoad; QStringListIterator it(listOfFilesForSeries); while (it.hasNext()) { seriesToLoad.push_back(it.next().toStdString()); } //Get Reference for default data storage. ctkServiceReference serviceReference = mitk::PluginActivator::getContext()->getServiceReference(); mitk::IDataStorageService* storageService = mitk::PluginActivator::getContext()->getService(serviceReference); mitk::DataStorage* dataStorage = storageService->GetDefaultDataStorage().GetPointer()->GetDataStorage(); - //special handling of Philips 3D US DICOM. - //Copied from DICOMSeriesReaderService - if (!seriesToLoad.empty() && mitk::DicomSeriesReader::IsPhilips3DDicom(seriesToLoad.front())) + std::vector baseDatas = mitk::IOUtil::Load(seriesToLoad.front()); + for (const auto &data : baseDatas) { - MITK_INFO << "it is a Philips3D US Dicom file" << std::endl; - mitk::LocaleSwitch localeSwitch("C"); - std::locale previousCppLocale(std::cin.getloc()); - std::locale l("C"); - std::cin.imbue(l); - - mitk::DataNode::Pointer node = mitk::DataNode::New(); - mitk::DicomSeriesReader::StringContainer stringvec; - stringvec.push_back(seriesToLoad.front()); - if (mitk::DicomSeriesReader::LoadDicomSeries(stringvec, *node)) - { - mitk::BaseData::Pointer data = node->GetData(); - mitk::StringProperty::Pointer nameProp = mitk::StringProperty::New(itksys::SystemTools::GetFilenameName(seriesToLoad.front())); - data->GetPropertyList()->SetProperty("name", nameProp); - node->SetProperty("name", nameProp); - dataStorage->Add(node); - } - std::cin.imbue(previousCppLocale); - return; - } + mitk::DataNode::Pointer node = mitk::DataNode::New(); + node->SetData(data); - //Normal DICOM handling (It wasn't a Philips 3D US) - mitk::DICOMFileReaderSelector::Pointer selector = mitk::DICOMFileReaderSelector::New(); + std::string nodeName = "Unnamed Dicom"; - selector->LoadBuiltIn3DConfigs(); - selector->LoadBuiltIn3DnTConfigs(); - selector->SetInputFiles(seriesToLoad); + std::string studyUID = ""; + std::string seriesUID = ""; - mitk::DICOMFileReader::Pointer reader = selector->GetFirstReaderWithMinimumNumberOfOutputImages(); - reader->SetAdditionalTagsOfInterest(mitk::GetCurrentDICOMTagsOfInterest()); - reader->SetTagLookupTableToPropertyFunctor(mitk::GetDICOMPropertyForDICOMValuesFunctor); - reader->SetInputFiles(seriesToLoad); + data->GetPropertyList()->GetStringProperty("DICOM.0020.000D", studyUID); + data->GetPropertyList()->GetStringProperty("DICOM.0020.000E", seriesUID); - mitk::DICOMDCMTKTagScanner::Pointer scanner = mitk::DICOMDCMTKTagScanner::New(); - scanner->AddTagPaths(reader->GetTagsOfInterest()); - scanner->SetInputFiles(seriesToLoad); - scanner->Scan(); + if (!studyUID.empty()) + { + nodeName = studyUID; + } - reader->SetTagCache(scanner->GetScanCache()); - reader->AnalyzeInputFiles(); - reader->LoadImages(); - - for (unsigned int i = 0; i < reader->GetNumberOfOutputs(); ++i) - { - const mitk::DICOMImageBlockDescriptor& desc = reader->GetOutput(i); - mitk::BaseData::Pointer data = desc.GetMitkImage().GetPointer(); - - std::string nodeName = "Unnamed_DICOM"; - - std::string studyDescription = desc.GetPropertyAsString("studyDescription"); - std::string seriesDescription = desc.GetPropertyAsString("seriesDescription"); - - if (!studyDescription.empty()) + if (!seriesUID.empty()) + { + if (!studyUID.empty()) { - nodeName = studyDescription; + nodeName += "/"; } + nodeName += seriesUID; + } - if (!seriesDescription.empty()) - { - if (!studyDescription.empty()) - { - nodeName += "/"; - } - nodeName += seriesDescription; - } - - mitk::StringProperty::Pointer nameProp = mitk::StringProperty::New(nodeName); - data->SetProperty("name", nameProp); - - mitk::DataNode::Pointer node = mitk::DataNode::New(); - node->SetData(data); - nameProp = mitk::StringProperty::New(nodeName); - node->SetProperty("name", nameProp); - - dataStorage->Add(node); - } - - if (reader->GetNumberOfOutputs() < 1) - { - MITK_ERROR << "Error loading series: " << ctkEvent.getProperty("SeriesName").toString().toStdString() - << " id: " << ctkEvent.getProperty("SeriesUID").toString().toStdString(); + dataStorage->Add(node); } } } else { MITK_INFO << "There are no files for the current series"; } } void DicomEventHandler::OnSignalRemoveSeriesFromStorage(const ctkEvent& /*ctkEvent*/) { } void DicomEventHandler::SubscribeSlots() { ctkServiceReference ref = mitk::PluginActivator::getContext()->getServiceReference(); if (ref) { ctkEventAdmin* eventAdmin = mitk::PluginActivator::getContext()->getService(ref); ctkDictionary properties; properties[ctkEventConstants::EVENT_TOPIC] = "org/mitk/gui/qt/dicom/ADD"; eventAdmin->subscribeSlot(this, SLOT(OnSignalAddSeriesToDataManager(ctkEvent)), properties); properties[ctkEventConstants::EVENT_TOPIC] = "org/mitk/gui/qt/dicom/DELETED"; eventAdmin->subscribeSlot(this, SLOT(OnSignalRemoveSeriesFromStorage(ctkEvent)), properties); } } diff --git a/Plugins/org.mitk.gui.qt.ext/resources/dicom.svg b/Plugins/org.mitk.gui.qt.ext/resources/dicom.svg index a0c135fe55..f5e031c0fd 100644 --- a/Plugins/org.mitk.gui.qt.ext/resources/dicom.svg +++ b/Plugins/org.mitk.gui.qt.ext/resources/dicom.svg @@ -1,55 +1,85 @@ + width="100" + inkscape:version="0.91 r13725" + sodipodi:docname="dicom.svg"> + image/svg+xml - + - DCM + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:915.96606445px;line-height:125%;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#ff00ff;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + id="text4152-8"> + + + + diff --git a/Plugins/org.mitk.gui.qt.ext/resources/org_mitk_gui_qt_ext.qrc b/Plugins/org.mitk.gui.qt.ext/resources/org_mitk_gui_qt_ext.qrc index 05e95763f9..007377ac7e 100644 --- a/Plugins/org.mitk.gui.qt.ext/resources/org_mitk_gui_qt_ext.qrc +++ b/Plugins/org.mitk.gui.qt.ext/resources/org_mitk_gui_qt_ext.qrc @@ -1,9 +1,9 @@ dicom.svg image_navigator.svg index.html xnat-icon.png - view-manager_48.png + view-manager.svg diff --git a/Plugins/org.mitk.gui.qt.multilabelsegmentation/resources/multilabelsegmentation.svg b/Plugins/org.mitk.gui.qt.multilabelsegmentation/resources/multilabelsegmentation.svg index 72d0d52ea9..9f74c3ac99 100644 --- a/Plugins/org.mitk.gui.qt.multilabelsegmentation/resources/multilabelsegmentation.svg +++ b/Plugins/org.mitk.gui.qt.multilabelsegmentation/resources/multilabelsegmentation.svg @@ -1,10575 +1,10607 @@ + version="1.1" + inkscape:version="0.91 r13725" + sodipodi:docname="multilabelsegmentation.svg"> + image/svg+xml - + + transform="matrix(0.04170618,0,0,0.04170618,35.494577,90.91554)" + style="fill:#ff00ff;fill-opacity:1"> + transform="matrix(0.04170618,0,0,0.04170618,47.647104,90.91554)" + style="fill:#ff00ff;fill-opacity:1"> + transform="matrix(0.04170618,0,0,0.04170618,59.799628,90.91554)" + style="fill:#ff00ff;fill-opacity:1"> + transform="matrix(0.04170618,0,0,0.04170618,71.952155,90.91554)" + style="fill:#ff00ff;fill-opacity:1"> + transform="matrix(0.04170618,0,0,0.04170618,47.647104,78.81404)" + style="fill:#ff00ff;fill-opacity:1"> + transform="matrix(0.04170618,0,0,0.04170618,71.952155,78.81404)" + style="fill:#ff00ff;fill-opacity:1"> + transform="matrix(0.04170618,0,0,0.04170618,59.799627,66.70724)" + style="fill:#ff00ff;fill-opacity:1"> + transform="matrix(0.04170618,0,0,0.04170618,59.799628,78.81404)" + style="fill:#ff00ff;fill-opacity:1"> + style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:80.00000119%;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';text-align:start;writing-mode:lr-tb;text-anchor:start;clip-rule:nonzero;visibility:visible;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#ff00ff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto"> diff --git a/Plugins/org.mitk.gui.qt.multilabelsegmentation/resources/multilabelsegmentation_utilities.svg b/Plugins/org.mitk.gui.qt.multilabelsegmentation/resources/multilabelsegmentation_utilities.svg index b0072cccd2..ef34d33a6c 100644 --- a/Plugins/org.mitk.gui.qt.multilabelsegmentation/resources/multilabelsegmentation_utilities.svg +++ b/Plugins/org.mitk.gui.qt.multilabelsegmentation/resources/multilabelsegmentation_utilities.svg @@ -1,9123 +1,9155 @@ + version="1.1" + inkscape:version="0.91 r13725" + sodipodi:docname="multilabelsegmentation_utilities.svg"> + image/svg+xml - + + transform="matrix(0.04170618,0,0,0.04170618,35.494577,90.91554)" + style="fill:#ff00ff;fill-opacity:1"> + transform="matrix(0.04170618,0,0,0.04170618,47.647104,90.91554)" + style="fill:#ff00ff;fill-opacity:1"> + transform="matrix(0.04170618,0,0,0.04170618,59.799628,90.91554)" + style="fill:#ff00ff;fill-opacity:1"> + transform="matrix(0.04170618,0,0,0.04170618,71.952155,90.91554)" + style="fill:#ff00ff;fill-opacity:1"> + transform="matrix(0.04170618,0,0,0.04170618,47.647104,78.81404)" + style="fill:#ff00ff;fill-opacity:1"> + transform="matrix(0.04170618,0,0,0.04170618,71.952155,78.81404)" + style="fill:#ff00ff;fill-opacity:1"> + transform="matrix(0.04170618,0,0,0.04170618,59.799627,66.70724)" + style="fill:#ff00ff;fill-opacity:1"> + transform="matrix(0.04170618,0,0,0.04170618,59.799628,78.81404)" + style="fill:#ff00ff;fill-opacity:1"> + style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:80.00000119%;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';text-align:start;writing-mode:lr-tb;text-anchor:start;clip-rule:nonzero;visibility:visible;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#ff00ff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto"> diff --git a/Plugins/org.mitk.gui.qt.remeshing/documentation/UserManual/QmitkRemeshing.dox b/Plugins/org.mitk.gui.qt.remeshing/documentation/UserManual/QmitkRemeshing.dox index 810053213a..223aa31385 100644 --- a/Plugins/org.mitk.gui.qt.remeshing/documentation/UserManual/QmitkRemeshing.dox +++ b/Plugins/org.mitk.gui.qt.remeshing/documentation/UserManual/QmitkRemeshing.dox @@ -1,19 +1,19 @@ /** \page org_mitk_gui_qt_remeshing The Remeshing Plugin -\imageMacro{QmitkRemeshing_Icon.png,"Icon of the Remeshing Plugin.",2.00} +\imageMacro{RemeshingIcon.png,"Icon of the Remeshing Plugin.",2.00} \tableofcontents \section org_mitk_gui_qt_remeshingOverview Overview The Remeshing View allows you to remesh surfaces. If done right, remeshing can dramatically increase the quality of your surface mesh. However, you might lose precision if you reduce the vertex density of your surface mesh too strong. Even when you preserve the detail of your mesh, there might be a tiny distance between your original surface and the remeshed surface. Hence, be careful when using remeshed surfaces for evaluation purposes and always keep the original versions. \section org_mitk_gui_qt_remeshingUsage Usage The Remeshing View provides details on its parameters in its user interface. When in doubt, start with the default parameters and iterate to your desired result by reducing the density parameter. */ diff --git a/Plugins/org.mitk.gui.qt.remeshing/documentation/UserManual/QmitkRemeshing_Icon.png b/Plugins/org.mitk.gui.qt.remeshing/documentation/UserManual/QmitkRemeshing_Icon.png deleted file mode 100644 index edb50dccd5..0000000000 Binary files a/Plugins/org.mitk.gui.qt.remeshing/documentation/UserManual/QmitkRemeshing_Icon.png and /dev/null differ diff --git a/Plugins/org.mitk.gui.qt.remeshing/documentation/UserManual/RemeshingIcon.png b/Plugins/org.mitk.gui.qt.remeshing/documentation/UserManual/RemeshingIcon.png new file mode 100644 index 0000000000..6b2362c5b2 Binary files /dev/null and b/Plugins/org.mitk.gui.qt.remeshing/documentation/UserManual/RemeshingIcon.png differ diff --git a/Plugins/org.mitk.gui.qt.segmentation/plugin.xml b/Plugins/org.mitk.gui.qt.segmentation/plugin.xml index 56282d66a3..322e175fee 100644 --- a/Plugins/org.mitk.gui.qt.segmentation/plugin.xml +++ b/Plugins/org.mitk.gui.qt.segmentation/plugin.xml @@ -1,94 +1,94 @@ Allows the segmentation of images using different tools. - Allow the clipping of a volume using a deformable plane. - + --> Edit segmentations using standard operations. diff --git a/Plugins/org.mitk.gui.qt.segmentation/resources/segmentation.svg b/Plugins/org.mitk.gui.qt.segmentation/resources/segmentation.svg index adb76428c9..1ba1aa7f2d 100644 --- a/Plugins/org.mitk.gui.qt.segmentation/resources/segmentation.svg +++ b/Plugins/org.mitk.gui.qt.segmentation/resources/segmentation.svg @@ -1,1948 +1,1980 @@ + version="1.1" + inkscape:version="0.91 r13725" + sodipodi:docname="Segmentation.svg"> + image/svg+xml - + + transform="matrix(0.04170618,0,0,0.04170618,35.494577,90.91554)" + style="fill:#ff00ff;fill-opacity:1"> + transform="matrix(0.04170618,0,0,0.04170618,47.647104,90.91554)" + style="fill:#ff00ff;fill-opacity:1"> + transform="matrix(0.04170618,0,0,0.04170618,59.799628,90.91554)" + style="fill:#ff00ff;fill-opacity:1"> + transform="matrix(0.04170618,0,0,0.04170618,71.952155,90.91554)" + style="fill:#ff00ff;fill-opacity:1"> + transform="matrix(0.04170618,0,0,0.04170618,47.647104,78.81404)" + style="fill:#ff00ff;fill-opacity:1"> + transform="matrix(0.04170618,0,0,0.04170618,71.952155,78.81404)" + style="fill:#ff00ff;fill-opacity:1"> + transform="matrix(0.04170618,0,0,0.04170618,59.799627,66.70724)" + style="fill:#ff00ff;fill-opacity:1"> + transform="matrix(0.04170618,0,0,0.04170618,59.799628,78.81404)" + style="fill:#ff00ff;fill-opacity:1"> diff --git a/Plugins/org.mitk.gui.qt.segmentation/resources/segmentation_utilities.svg b/Plugins/org.mitk.gui.qt.segmentation/resources/segmentation_utilities.svg index 669b8f0f54..e469f9419d 100644 --- a/Plugins/org.mitk.gui.qt.segmentation/resources/segmentation_utilities.svg +++ b/Plugins/org.mitk.gui.qt.segmentation/resources/segmentation_utilities.svg @@ -1,3464 +1,3472 @@ + sodipodi:docname="segmentation_utilities.svg"> + inkscape:current-layer="g5371" /> image/svg+xml - + + id="g4857-6-3" + style="fill:#ff00ff;fill-opacity:1"> + id="g4857-14-3" + style="fill:#ff00ff;fill-opacity:1"> + id="g4857-4-0" + style="fill:#ff00ff;fill-opacity:1"> + id="g4857-63-2" + style="fill:#ff00ff;fill-opacity:1"> + id="g4857-14-8" + style="fill:#ff00ff;fill-opacity:1"> + id="g4857-63-0" + style="fill:#ff00ff;fill-opacity:1"> + id="g4857-4-6" + style="fill:#ff00ff;fill-opacity:1"> + id="g4857-63-0-0" + style="fill:#ff00ff;fill-opacity:1"> diff --git a/Plugins/org.mitk.gui.qt.viewnavigator/documentation/UserManual/QmitkViewNavigator.dox b/Plugins/org.mitk.gui.qt.viewnavigator/documentation/UserManual/QmitkViewNavigator.dox index d2a7748601..e44be368d5 100644 --- a/Plugins/org.mitk.gui.qt.viewnavigator/documentation/UserManual/QmitkViewNavigator.dox +++ b/Plugins/org.mitk.gui.qt.viewnavigator/documentation/UserManual/QmitkViewNavigator.dox @@ -1,43 +1,43 @@ /** \page org_mitk_gui_qt_viewnavigator The View Navigator -\imageMacro{view-manager_48.png,"Icon of the view navigator",2.00} +\imageMacro{view-manager.png,"Icon of the view navigator",2.00} \tableofcontents \section org_mitk_gui_qt_viewnavigatorOverview Overview This view allows for the easy navigation of the available views. You can select which view to open by double-clicking the name of the view in the view navigator. It provides a keyworded, grouped and searchable list of views. \section org_mitk_gui_qt_viewnavigatorUsage Usage You can toggle the View Navigator on and off by clicking on its icon in the menu bar. Alternatively it is also available via the Window->Show Views dialog. \imageMacro{QmitkViewNavigatorGUI.png,"The View Navigator GUI",6.00} Once the View Navigator has been opened you will see a list divided in workflows/perspectives and views. Via this list you can access any view or perspective provided by the application. They are further organized based on their associated category. An entry on the list is opened by a double left-click. \subsection org_mitk_gui_qt_viewnavigatorSearch Search You can search the lists for view/workflow names, keywords or categories. \imageMacro{QmitkViewNavigatorSearch.png,"Search the View Navigator",4.00} \subsection org_mitk_gui_qt_viewnavigatorCustomWorkflows Custom Workflows \imageMacro{QmitkViewNavigatorContextMenuWorkflows.png,"The workflow context menu",4.00} A right click on a workflow opens a context menu that allows you to copy that workflow to create your own custom one. \note The duplicated workflow will look like the basic state of the original workflow. Any changes to the original workflow will not be copied. \imageMacro{QmitkViewNavigatorNewWorkflow.png,"Custom workflow creation dialog",4.00} Your new workflow will appear in the list and you can modify it independently of the original workflow. Any changes will be stored for future sessions unless the workflow is deleted. \note Resetting a custom perspective will return it to the original state after duplicating. \imageMacro{QmitkViewNavigatorContextMenuCustomWorkflow.png,"Custom workflow context menu",4.00} */ diff --git a/Plugins/org.mitk.gui.qt.viewnavigator/documentation/UserManual/view-manager.png b/Plugins/org.mitk.gui.qt.viewnavigator/documentation/UserManual/view-manager.png new file mode 100644 index 0000000000..f74a5abbaf Binary files /dev/null and b/Plugins/org.mitk.gui.qt.viewnavigator/documentation/UserManual/view-manager.png differ diff --git a/Plugins/org.mitk.gui.qt.viewnavigator/documentation/UserManual/view-manager_48.png b/Plugins/org.mitk.gui.qt.viewnavigator/documentation/UserManual/view-manager_48.png deleted file mode 100644 index 78243f799e..0000000000 Binary files a/Plugins/org.mitk.gui.qt.viewnavigator/documentation/UserManual/view-manager_48.png and /dev/null differ