import * as dicomViewer from "./dicomViewer.js" window.dicomViewer = dicomViewer; window.marked_answers = { "correct": [], "half-correct": [], "incorrect": [], } window.control_pressed = false; $(document).ready(function () { $("table thead th input").click((e) => { let status = e.currentTarget.checked; $("table tbody input").prop("checked", status); }) //$(".answer-list li").each(function (index, element) { // $(element).append($("G")); //}); $(".answer-list span.answer").each(function (index, element) { console.log(element); $(element).click(function (e) { var classes = ['answer correct', 'answer half-correct', 'answer incorrect']; $(element).each(function () { let mark = classes[($.inArray(this.className, classes) + 1) % classes.length]; this.className = mark this.dataset.newmark = mark.split(" ")[1] }); prepAnswerData(); }); }); prepAnswerData(); if ($(".post-form").length > 0) { $(".post-form").get(0).addEventListener("submit", function (e) { //if ($(".not-marked").length > 0 && e.submitter.name != "skip") { // e.preventDefault(); // before the code // alert("Ensure all answers are marked first"); //} }); } let dicom_images = document.getElementsByClassName("dicom-image"); if (dicom_images.length) { for (let element of dicom_images) { setUpDicom(element) } } loadDicomViewer(); if ($("#question-mark-list").length) { $(".show-all-button").click(() => { $("#question-mark-list li").show(); }); $(".show-unmarked-button").click(() => { $("#question-mark-list li").each((n, el) => { // Can't seem to get django to output this as a int.... if (parseInt(el.dataset.markcount) < 1) { $(el).hide(); } }) }); } // $(document).keydown(keyDownHandler); // $(document).keyup(keyUpHandler); $("#button-select-add-exam").click(function (evt) { // Find selected objects var jqxhr = $.get(evt.target.dataset.exam_list_url, function (data) { console.log(data); $("#exam-options").empty(); data.forEach((obj, n) => { $("#exam-options").append($(document.createElement('button')).prop({ type: 'button', innerHTML: obj.name, class: '', }).data("exam-id", obj.id).click((evt) => { addToExam(evt) })) }) }) .done(function () { //alert( "second success" ); }) .fail(function () { //alert( "error" ); }) .always(function () { //alert( "finished" ); }); return; function addToExam(evt) { let ids = [] $("tbody input:checked").each((n, el) => { ids.push(el.value) }) // if no question selected if (ids.length < 1) { toastr.info('No question selected.'); return } let post_url = document.getElementById("button-select-add-exam").dataset.exam_json_edit_url; let type = document.getElementById("button-select-add-exam").dataset.type; let csrf = document.getElementById("button-select-add-exam").dataset.csrf; $.ajax({ url: post_url, data: { csrfmiddlewaretoken: csrf, add_exam_questions: JSON.stringify(ids), type: type, exam_id: $(evt.target).data("exam-id"), }, type: "POST", dataType: "json", }) // $.ajax().done(), $.ajax().fail(), $ajax().always() are upto you. Add/change accordingly .done(function (data) { console.log(data); if (data.status == "success") { toastr.info('Questions added to exams.') } }) .always(function () { console.log('[Done]'); $("#exam-options").empty(); }) } }); }); window.loadDicomViewerEvent = new Event('loadDicomViewer'); window.addEventListener('loadDicomViewer', function (e) { //console.log("listen", e.detail) let images = []; //console.log($("#image_form_set img")); $(e.detail).each((n, el) => { images.push($(el).attr("src")); }); //console.log("listen2", images) loadDicomViewer(images); }, false); window.loadDicomViewerEvent = new Event('loadDicomViewerUrls'); window.addEventListener('loadDicomViewerUrls', function (e) { loadDicomViewer(e.detail.images, e.detail.annotations); }, false); function loadDicomViewer(images_to_load, annotations_to_load) { console.log("loadDicomViewer", images_to_load); let single_dicom = document.getElementById("single-dicom-viewer"); if (single_dicom) { $(single_dicom).empty() let images = single_dicom.dataset.images; if (images_to_load != undefined) { images = images_to_load; //} else if (images.indexOf(",") > 0) { } else if (images == undefined || images == "") { // No images to load return } else { images = JSON.parse(images); } console.log(images); let annotations = single_dicom.dataset.annotations; if (annotations_to_load != undefined) { annotations = annotations_to_load; } else if (annotations && annotations.indexOf(",") > 0) { annotations = JSON.parse(annotations); } else { annotations = undefined; } let load_as_stack; if (images.length > 5) { load_as_stack = true; } else { load_as_stack = false; } if (images) { dicomViewer.loadCornerstone($(single_dicom), null, images, annotations, load_as_stack); } } } window.loadDicomViewer = loadDicomViewer function prepAnswerData() { //$("#id_correct").val($("li.correct").map(function() { // ans = $(this).text(); // window.marked_answers["correct"].push(ans); // return ans //}).get().join('--//--')); //$("#id_half_correct").val($("li.half-correct").map(function() { // ans = $(this).text(); // window.marked_answers["half-correct"].push(ans); // return ans; //}).get().join('--//--')); //$("#id_incorrect").val($("li.incorrect").map(function() { // ans = $(this).text(); // window.marked_answers["incorrect"].push(ans); // return ans; //}).get().join('--//--')); window.marked_answers["correct"] = []; window.marked_answers["half-correct"] = []; window.marked_answers["incorrect"] = []; $("li span.correct").map(function () { let ans = $(this).text(); window.marked_answers["correct"].push(ans); }) $("li span.half-correct").map(function () { let ans = $(this).text(); window.marked_answers["half-correct"].push(ans); }) $("li span.incorrect").map(function () { let ans = $(this).text(); window.marked_answers["incorrect"].push(ans); }) $("#id_marked_answers").val(JSON.stringify(window.marked_answers)); } function loadJsonToolStateOnCurrentImage(json) { let el = document.getElementById("dicom-image"); const toolStateManager = cornerstoneTools.globalImageIdSpecificToolStateManager; const c = cornerstone.getEnabledElement(el); let image_id = c.image.imageId; let tool_state_no_id = JSON.parse(json); let tool_state = {}; tool_state[image_id] = tool_state_no_id; toolStateManager.restoreToolState(tool_state); cornerstone.reset(el); return tool_state; } async function setUpDicom(element) { console.log("Dicom element found ", $(element)); $(element).bind('contextmenu', function (e) { return false; }); $(element).dblclick((evt) => { element.requestFullscreen(); }) cornerstoneBase64ImageLoader.external.cornerstone = cornerstone; cornerstoneWebImageLoader.external.cornerstone = cornerstone; cornerstoneWADOImageLoader.external.cornerstone = cornerstone; cornerstoneTools.init(); const PanTool = cornerstoneTools.PanTool; const ZoomTool = cornerstoneTools.ZoomTool; const ZoomMouseWheelTool = cornerstoneTools.ZoomMouseWheelTool; const WwwcTool = cornerstoneTools.WwwcTool; const WwwcRegionTool = cornerstoneTools.WwwcRegionTool; const RotateTool = cornerstoneTools.RotateTool; const StackScrollTool = cornerstoneTools.StackScrollTool; const MagnifyTool = cornerstoneTools.MagnifyTool; const ArrowAnnotateTool = cornerstoneTools.ArrowAnnotateTool; const images = element.dataset.url.split(","); //console.log("Dicom - load imageId: ", imageIds); //for (let index = 0; index < imageIds.length; index++) { // if (imageIds[index].endsWith("dcm")) { // imageIds[index] = "wadouri:" + imageIds[index]; // } //} let imageIds = []; for (let i = 0; i < images.length; i++) { let data_url = images[i]; // check stack type if (data_url.startsWith("data:image")) { let imageId = "base64://" + data_url.split(",")[1]; imageIds.push(imageId); } else if (data_url.startsWith("base64://") || data_url.startsWith("wadouri:")) { imageIds.push(data_url); // Treat application/octet-stream as if they are dicoms } else if (data_url.startsWith("data:application/dicom") || data_url.startsWith("data:application/octet-stream")) { //stack = stack.split(";")[1]; let dfile = await urltoFile(data_url, "dicom", "application/dicom"); const imageId = cornerstoneWADOImageLoader.wadouri.fileManager.add( dfile ); loadAnnotation(imageId, annotation); imageIds.push(imageId); //cornerstone.loadImage(imageId).then(function(image) { // tempFunction(image); //}); } else { let url; // This doesn't seem to have any benefit //if (data_url.startsWith("http")) { // url = data_url; //} else { // url = window.location.href.replace(/\/\#\/?$/, '') + "/" + data_url //} url = data_url; if (url.endsWith("dcm")) { url = "wadouri:" + url; } // if there is no extension treat it as a dicom if (/(?:\/|^)[^.\/]+$/.test(url)) { url = "wadouri:" + url; } imageIds.push(url); } } cornerstone.enable(element); cornerstone.loadAndCacheImage(imageIds[0]).then(function (image) { cornerstone.displayImage(element, image); cornerstoneTools.addToolForElement(element, PanTool); cornerstoneTools.addToolForElement(element, ZoomTool); cornerstoneTools.addToolForElement(element, ZoomMouseWheelTool); cornerstoneTools.addToolForElement(element, WwwcTool); cornerstoneTools.addToolForElement(element, WwwcRegionTool); cornerstoneTools.addToolForElement(element, RotateTool); cornerstoneTools.addToolForElement(element, StackScrollTool); cornerstoneTools.addToolForElement(element, MagnifyTool); cornerstoneTools.addToolForElement(element, ArrowAnnotateTool, { configuration: { getTextCallback: () => {}, changeTextCallback: () => {}, allowEmptyLabel: true, renderDashed: false, drawHandles: false, drawHandlesOnHover: true, }, }); // Enable our tools // Avoid incorrect aspect ratio cornerstoneTools.setToolActiveForElement(element, "Pan", { mouseButtonMask: 1 }); cornerstoneTools.setToolActiveForElement(element, "Wwwc", { mouseButtonMask: 2 }); cornerstoneTools.setToolActiveForElement(element, "ZoomMouseWheel", { mouseButtonMask: 3 }); cornerstoneTools.setToolActiveForElement(element, "Zoom", { mouseButtonMask: 4 }); if (element.dataset.edit_annotation == "true") { cornerstoneTools.setToolActiveForElement(element, "ArrowAnnotate", { mouseButtonMask: 2 }); } else { cornerstoneTools.setToolEnabledForElement(element, "ArrowAnnotate"); } if (element.dataset.annotations) { loadJsonToolStateOnCurrentImage(element.dataset.annotations) } cornerstone.resize(element); }).catch((err, err2) => { console.log(err); }); } //function keyUpHandler(e) { // if (e.key == "Control") { // dicomViewer.registerPrimaryDicomInterface(e); // window.control_pressed = false; // } //} // //function keyDownHandler(e) { // // Ignore our custom keybindings if we are currently in a field that // // accepts some kind of input // if ($("*:focus:not(disabled)").is("textarea, input")) { // // unless a modifier key is pressed (not shift) // if (e.altKey ? true : false || e.ctrlKey ? true : false) {} else { // return; // } // } // // if (e.key == "Control") { // if (window.control_pressed == false) { // window.control_pressed = true; // dicomViewer.registerAltDicomInterface(e); // } // } // // var charCode = typeof e.which == "number" ? e.which : e.keyCode; // console.log(e, charCode); // // function numberKeyPressed(e, x) { // if (e.altKey ? true : false) { // dicomViewer.selectThumb(x); // e.preventDefault(); // } else {} // } // // switch (charCode) { // case 13: // Return // if (e.shiftKey ? true : false) { // //$(".next-button:last").click(); // } else { // //$(".check-button:last").click(); // } // break; // case 32: // Space // if (e.shiftKey ? true : false) { // //$(".previous-button:last").click(); // } else { // //$(".next-button:last").click(); // } // e.preventDefault(); // Needed to stop the default action (scroll) // break; // case 46: // . // //toggleFlagged(); // break; // // // Numbers 1-9 select the corresponding answer (if it exists) // // TODO: fix for multi question questions // case 49: // 1 // numberKeyPressed(e, 0); // break; // case 50: // 2 // numberKeyPressed(e, 1); // break; // case 51: // 3 // numberKeyPressed(e, 2); // break; // case 52: // 4 // numberKeyPressed(e, 3); // break; // case 53: // 5 // numberKeyPressed(e, 4); // break; // case 54: // 6 // numberKeyPressed(e, 5); // break; // case 55: // 7 // numberKeyPressed(e, 6); // break; // case 56: // 8 // numberKeyPressed(e, 7); // break; // case 57: // 9 // numberKeyPressed(e, 8); // break; // case 72: // H // previousQuestion(); // break; // case 76: // L // //nextQuestion(); // break; // // case 102: // f // //$("#filter-toggle").click(); // break; // case 103: // g // //$("#options").slideDown("slow"); // //$("#goto-question-input").focus(); // //e.preventDefault(); // break; // // // Vim like scrolling (incredibly important) // case 106: // j // //window.scrollBy(0, 25); // break; // case 107: // k // //window.scrollBy(0, -25); // break; // } //} function create_popup_window(url, title) { newwindow = window.open(url, title, 'height=800,width=600'); if (window.focus) { newwindow.focus() } return false; } window.create_popup_window = create_popup_window function delete_multiple(url, csrf_token) { let answer_ids = []; $("tbody input:checked").each((n, el) => { answer_ids.push(el.value); }) if (confirm(`Delete ${answer_ids.length} answers?`)) { $.ajax({ url: url, data: { csrfmiddlewaretoken: csrf_token, answer_ids: JSON.stringify(answer_ids) // true if checked else false }, type: "POST", dataType: "json", }) // $.ajax().done(), $.ajax().fail(), $ajax().always() are upto you. Add/change accordingly .done(function (data) { console.log(data); if (data.status == "success") { toastr.info('Deleted.') } // show some message according to the response. // For eg. A message box showing that the status has been changed }) .always(function () { console.log('[Done]'); }) } } window.delete_multiple = delete_multiple