diff --git a/Packages/ohif-hanging-protocols/client/components/ruleEntryDialog/ruleEntryDialog.js b/Packages/ohif-hanging-protocols/client/components/ruleEntryDialog/ruleEntryDialog.js index 640afd0a5..ec3f2fc87 100644 --- a/Packages/ohif-hanging-protocols/client/components/ruleEntryDialog/ruleEntryDialog.js +++ b/Packages/ohif-hanging-protocols/client/components/ruleEntryDialog/ruleEntryDialog.js @@ -80,20 +80,21 @@ openRuleEntryDialog = function(attributes, level, rule) { // Set the current value input based on the rule constraint var currentValue = rule.constraint[validator][validatorOption]; currentValueInput.val(currentValue); + + // If a Comparator was found, set the default value of the Comparators select2 box + // to the comparatorId in the input rule + if (comparator) { + // Trigger('change') is used to update the Select2 choice in the UI + dialog.find('.comparators').val(comparator.id).trigger('change'); + } } - // If a Comparator was found, set the default value of the Comparators select2 box - // to the comparatorId in the input rule - if (comparator) { - // Trigger('change') is used to update the Select2 choice in the UI - dialog.find('.comparators').val(comparator.id).trigger('change'); - } // Update the dialog's CSS so that it is visible on the page dialog.css('display', 'block'); // Show the backdrop - UI.render(Template.removableBackdrop, document.body); + Blaze.render(Template.removableBackdrop, document.body); // Make sure the context menu is closed when the user clicks away $('.removableBackdrop').one('mousedown touchstart', function() { @@ -105,31 +106,12 @@ openRuleEntryDialog = function(attributes, level, rule) { * Retrieves the current active element's imageId using Cornerstone */ function getActiveViewportImageId() { - // Retrieve the active viewport index from the Session - var activeViewport = Session.get('activeViewport'); - if (activeViewport === undefined) { + const enabledElement = Viewerbase.viewportUtils.getEnabledElementForActiveElement(); + + if (!enabledElement) { return; } - // Obtain the list of all Viewports on the page - var viewports = $('.imageViewerViewport'); - - // Retrieve the active viewport element - var element = viewports.get(activeViewport); - if (!element) { - return; - } - - // Obtain the enabled element from Cornerstone - try { - var enabledElement = cornerstone.getEnabledElement(element); - if (!enabledElement) { - return; - } - } catch(error) { - OHIF.log.warn(error); - return; - } // Return the enabled element's imageId return enabledElement.image.imageId; } @@ -179,36 +161,50 @@ function getAbstractPriorValue(imageId) { } /** - * Retrieve the current value of an attribute - * @returns {*} + * Retrieve the current value of a metadata tag or property. It searches the value in different levels (study, series or instance) + * @param {String} tagOrProperty DICOM Tag or Property name (Ex: 'x00100020', 'patientId') + * @return {Any} The value of the DICOM tag or property name */ -function getCurrentAttributeValue(attribute, level) { +const getCurrentTagOrPropertyValue = tagOrProperty => { // Retrieve the active viewport's imageId. If none exists, stop here - var imageId = getActiveViewportImageId(); + const imageId = getActiveViewportImageId(); if (!imageId) { return; } - // If the dialog level is specified as 'protocol', change it to - // 'study' for metaData retrieval - if (level === 'protocol') { - level = 'study'; - } - - if (attribute === 'abstractPriorValue') { + if (tagOrProperty === 'abstractPriorValue') { return getAbstractPriorValue(imageId); } - // Retrieve the metadata values for the specified level from - // the Cornerstone Tools metaData provider - var metadata = cornerstoneTools.metaData.get(level, imageId); + // Create the object for the instance metadata + let instance; - if (metadata[attribute] === undefined) { - return HP.attributeDefaults[attribute]; + OHIF.viewer.StudyMetadataList.find(studyMetadata => { + // Search for the instance that has the current imageId + instance = studyMetadata.findInstance(instance => { + return instance.getImageId() === imageId; + }); + + // If instance if found stop the search + return !!instance; + }); + + // No instance found + if (!instance) { + return; } - return metadata[attribute]; -} + // Get the value for the given tag + // It searches the value in different levels (study, series or instance) + const tagOrPropertyValue = instance.getTagValue(tagOrProperty); + + // If not found, is a custom Hanging Protocol attribute + if (tagOrPropertyValue === void 0) { + return HP.attributeDefaults[tagOrProperty]; + } + + return tagOrPropertyValue; +}; Template.ruleEntryDialog.onCreated(function() { // Define the ReactiveVars that will be used to link aspects of the UI @@ -362,11 +358,11 @@ Template.ruleEntryDialog.events({ // Store this attribute in the template data context Template.ruleEntryDialog.selectedAttribute = attribute; - // Get the level of this dialog - var level = Template.ruleEntryDialog.level; + // // Get the level of this dialog + // var level = Template.ruleEntryDialog.level; // Retrieve the current value of the attribute for the active viewport model - var value = getCurrentAttributeValue(attribute, level); + var value = getCurrentTagOrPropertyValue(attribute); // Update the ReactiveVar with the user-specified value template.currentValue.set(value); diff --git a/Packages/ohif-metadata/client/OHIFStudyMetadata.js b/Packages/ohif-metadata/client/OHIFStudyMetadata.js index de440beee..4c0894633 100644 --- a/Packages/ohif-metadata/client/OHIFStudyMetadata.js +++ b/Packages/ohif-metadata/client/OHIFStudyMetadata.js @@ -14,7 +14,7 @@ export class OHIFStudyMetadata extends Viewerbase.metadata.StudyMetadata { init() { const study = this.getData(); - // define "_studyInstanceUID" protected property... + // define "_studyInstanceUID" protected property Object.defineProperty(this, '_studyInstanceUID', { configurable: false, enumerable: false, @@ -22,7 +22,7 @@ export class OHIFStudyMetadata extends Viewerbase.metadata.StudyMetadata { value: study.studyInstanceUid }); - // populate internal list of series... + // populate internal list of series study.seriesList.forEach(series => { this.addSeries(new OHIFSeriesMetadata(series, study)); }); diff --git a/Packages/ohif-viewerbase/client/lib/classes/metadata/SeriesMetadata.js b/Packages/ohif-viewerbase/client/lib/classes/metadata/SeriesMetadata.js index 9d574e89c..121bf8403 100644 --- a/Packages/ohif-viewerbase/client/lib/classes/metadata/SeriesMetadata.js +++ b/Packages/ohif-viewerbase/client/lib/classes/metadata/SeriesMetadata.js @@ -160,6 +160,22 @@ export class SeriesMetadata extends Metadata { return this._instances.indexOf(instance); } + /** + * Search the associated instances using the supplied callback as criteria. The callback is passed + * two arguments: instance (a InstanceMetadata instance) and index (the integer + * index of the instance within its series) + * @param {function} callback The callback function which will be invoked for each instance. + * @returns {InstanceMetadata|undefined} If an instance is found based on callback criteria it + * returns a InstanceMetadata. "undefined" is returned otherwise + */ + findInstance(callback) { + if (Metadata.isValidCallback(callback)) { + return this._instances.find((instance, index) => { + return callback.call(null, instance, index); + }); + } + } + /** * Compares the current series with another one. * @param {SeriesMetadata} series An instance of the SeriesMetadata class. diff --git a/Packages/ohif-viewerbase/client/lib/classes/metadata/StudyMetadata.js b/Packages/ohif-viewerbase/client/lib/classes/metadata/StudyMetadata.js index 0e55ca076..ea2d82c88 100644 --- a/Packages/ohif-viewerbase/client/lib/classes/metadata/StudyMetadata.js +++ b/Packages/ohif-viewerbase/client/lib/classes/metadata/StudyMetadata.js @@ -338,4 +338,65 @@ export class StudyMetadata extends Metadata { return instance; } + /** + * Search the associated series to find an specific instance using the supplied callback as criteria. + * The callback is passed two arguments: instance (a InstanceMetadata instance) and index (the integer + * index of the instance within the current series) + * @param {function} callback The callback function which will be invoked for each instance instance. + * @returns {Object} Result object containing series (SeriesMetadata) and instance (InstanceMetadata) + * objects or an empty object if not found. + */ + findSeriesAndInstanceByInstance(callback) { + let result; + + if (Metadata.isValidCallback(callback)) { + let instance; + + const series = this._series.find(series => { + instance = series.findInstance(callback); + return instance instanceof InstanceMetadata; + }); + + // No series found + if (series instanceof SeriesMetadata) { + result = { + series, + instance + }; + } + } + + return result || {}; + } + + /** + * Find series by instance using the supplied callback as criteria. The callback is passed + * two arguments: instance (a InstanceMetadata instance) and index (the integer index of + * the instance within its series) + * @param {function} callback The callback function which will be invoked for each instance. + * @returns {SeriesMetadata|undefined} If a series is found based on callback criteria it + * returns a SeriesMetadata. "undefined" is returned otherwise + */ + findSeriesByInstance(callback) { + const result = this.findSeriesAndInstanceByInstance(callback); + + return result.series; + } + + /** + * Find an instance using the supplied callback as criteria. The callback is passed + * two arguments: instance (a InstanceMetadata instance) and index (the integer index of + * the instance within its series) + * @param {function} callback The callback function which will be invoked for each instance. + * @returns {InstanceMetadata|undefined} If an instance is found based on callback criteria it + * returns a InstanceMetadata. "undefined" is returned otherwise + */ + findInstance(callback) { + const result = this.findSeriesAndInstanceByInstance(callback); + + return result.instance; + } + + + } diff --git a/Packages/ohif-viewerbase/client/lib/viewportUtils.js b/Packages/ohif-viewerbase/client/lib/viewportUtils.js index 9822d6072..d243c20cc 100644 --- a/Packages/ohif-viewerbase/client/lib/viewportUtils.js +++ b/Packages/ohif-viewerbase/client/lib/viewportUtils.js @@ -7,11 +7,46 @@ import { OHIF } from 'meteor/ohif:core'; import { updateOrientationMarkers } from './updateOrientationMarkers'; import { getInstanceClassDefaultViewport } from './instanceClassSpecificViewport'; +/** + * Get a cornerstone enabledElement for a DOM Element + * @param {DOMElement} element Element to get the enabledElement from Cornerstone + * @return {Object} Cornerstone's enabledElement object for the given + * element or undefined if the element is not enabled + */ +const getEnabledElement = element => { + let enabledElement; + + try { + enabledElement = cornerstone.getEnabledElement(element); + } catch(error) { + OHIF.log.warn(error); + } + + return enabledElement; +}; + +/** + * Get the active viewport element. It uses activeViewport Session Variable + * @return {DOMElement} DOMElement of the current active viewport + */ const getActiveViewportElement = () => { const viewportIndex = Session.get('activeViewport') || 0; return $('.imageViewerViewport').get(viewportIndex); }; +/** + * Get a cornerstone enabledElement for the Active Viewport Element + * @return {Object} Cornerstone's enabledElement object for the active + * viewport element or undefined if the element + * is not enabled + */ +const getEnabledElementForActiveElement = () => { + const activeViewportElement = getActiveViewportElement(); + const enabledElement = getEnabledElement(activeViewportElement); + + return enabledElement; +}; + const zoomIn = () => { const element = getActiveViewportElement(); if (!element) { @@ -99,8 +134,7 @@ const flipH = () => { }; const resetViewport = () => { - const element = getActiveViewportElement(); - const enabledElement = cornerstone.getEnabledElement(element); + const enabledElement = getEnabledElementForActiveElement(); if (enabledElement.fitToWindow === false) { const imageId = enabledElement.image.imageId; const instance = cornerstoneTools.metaData.get('instance', imageId); @@ -272,6 +306,8 @@ $(window).on('CornerstoneToolsClipStopped', () => Session.set('UpdateCINE', Rand */ const viewportUtils = { + getEnabledElementForActiveElement, + getEnabledElement, getActiveViewportElement, zoomIn, zoomOut,