extensions/net.sf.basedb.reggie/trunk/resources/sampleproc/histology_score.js

Code
Comments
Other
Rev Date Author Line
2832 20 Oct 14 nicklas 1 var Histology = function()
2832 20 Oct 14 nicklas 2 {
2832 20 Oct 14 nicklas 3   var histology = {};
2853 23 Oct 14 nicklas 4   var debug = 0;
2832 20 Oct 14 nicklas 5
2832 20 Oct 14 nicklas 6   var SCORES = ['ScoreInvasiveCancer', 'ScoreInsituCancer', 'ScoreLymphocytes', 'ScoreNormal', 'ScoreStroma', 'ScoreFat'];
2832 20 Oct 14 nicklas 7   var FIELDS = ['score_invasive_cancer', 'score_insitu_cancer', 'score_lymphocytes', 'score_normal', 'score_stroma', 'score_fat'];
2832 20 Oct 14 nicklas 8
2832 20 Oct 14 nicklas 9   var heGlass;
2832 20 Oct 14 nicklas 10   var samples;
2832 20 Oct 14 nicklas 11   var selectedSample;
2832 20 Oct 14 nicklas 12   var disableModificationCheck = false;
2832 20 Oct 14 nicklas 13   
2832 20 Oct 14 nicklas 14   // Page initialization
2832 20 Oct 14 nicklas 15   histology.initPage = function()
2832 20 Oct 14 nicklas 16   {
2832 20 Oct 14 nicklas 17     Events.addEventHandler('btnFindHeGlass', 'click', histology.searchHeGlass);
2832 20 Oct 14 nicklas 18     Events.doOnEnter('findHeGlassName', histology.searchHeGlass);
2832 20 Oct 14 nicklas 19     Buttons.addClickHandler('btnUncompletedHeGlass', histology.showUncompletedHeGlassMenu);
2832 20 Oct 14 nicklas 20     Events.addEventHandler('select-uncompleted-heglass', 'click', histology.uncompletedGlassSelected);
2832 20 Oct 14 nicklas 21     Events.addEventHandler('wizard', 'click', histology.hideUncompletedHeGlassMenu);
2832 20 Oct 14 nicklas 22     Buttons.addClickHandler('btnSelectHeGlass', histology.selectHeGlass);
2832 20 Oct 14 nicklas 23     Events.addEventHandler('btnSelectHeGlass', 'base-selected', histology.heGlassSelected);
2832 20 Oct 14 nicklas 24     
2832 20 Oct 14 nicklas 25     for (var i = 0; i < FIELDS.length; i++)
2832 20 Oct 14 nicklas 26     {
2832 20 Oct 14 nicklas 27       var f = FIELDS[i];
2832 20 Oct 14 nicklas 28       Events.addEventHandler(f, 'keypress', Events.integerOnly);
2832 20 Oct 14 nicklas 29       Events.addEventHandler(f, 'change', histology.checkScores);
2832 20 Oct 14 nicklas 30     }
2832 20 Oct 14 nicklas 31     
2832 20 Oct 14 nicklas 32     Events.addEventHandler('good_stain', 'click', histology.goodStainOnClick);
2832 20 Oct 14 nicklas 33     Events.addEventHandler('score_complete', 'click', histology.scoreCompleteOnClick);
2832 20 Oct 14 nicklas 34     Events.addEventHandler('comments', 'change', histology.commentsOnChange);
2832 20 Oct 14 nicklas 35     
3169 06 Mar 15 nicklas 36     Events.addEventHandler('ihc_quality', 'change', histology.ihcQualityOnChange);
3169 06 Mar 15 nicklas 37     
3369 08 Jun 15 nicklas 38     // Image selection - drag/drop
3367 05 Jun 15 nicklas 39     Events.addEventHandler('he-file-drop', 'drop', histology.onDropFile);
3367 05 Jun 15 nicklas 40     Events.addEventHandler('he-file-drop', 'dragenter', histology.onDragEnter);
3367 05 Jun 15 nicklas 41     Events.addEventHandler('he-file-drop', 'dragleave', histology.onDragLeave);
3367 05 Jun 15 nicklas 42     Events.addEventHandler('he-file-drop', 'dragover', histology.onDragOver);
3369 08 Jun 15 nicklas 43
3369 08 Jun 15 nicklas 44     // Image selection - regular selection via dialog
3369 08 Jun 15 nicklas 45     Events.addEventHandler('no-he-image', 'click', histology.selectFile);
3369 08 Jun 15 nicklas 46     Events.addEventHandler('selectFile', 'change', histology.fileSelected);
3367 05 Jun 15 nicklas 47     
6016 09 Oct 20 nicklas 48     // Image selection - copy/paste
6016 09 Oct 20 nicklas 49     Events.addEventHandler(document, 'paste', histology.pasteImage);
6016 09 Oct 20 nicklas 50     
3369 08 Jun 15 nicklas 51     // Delete image
3369 08 Jun 15 nicklas 52     Events.addEventHandler('he-image-delete', 'click', histology.deleteImage);
3369 08 Jun 15 nicklas 53
3369 08 Jun 15 nicklas 54     // Zoom in popup window
3369 08 Jun 15 nicklas 55     Events.addEventHandler('he-image', 'click', histology.imageOnClick);
3369 08 Jun 15 nicklas 56     
2832 20 Oct 14 nicklas 57     // Navigation
2832 20 Oct 14 nicklas 58     Buttons.addClickHandler('gonext', histology.goNext);
2832 20 Oct 14 nicklas 59     Buttons.addClickHandler('goregister', Wizard.goRegister);
2832 20 Oct 14 nicklas 60
2832 20 Oct 14 nicklas 61     // Final registration
2832 20 Oct 14 nicklas 62     Events.addEventHandler('wizard', 'wizard-submit', histology.submit);
2832 20 Oct 14 nicklas 63
2832 20 Oct 14 nicklas 64     var url = '../Histology.servlet?ID='+App.getSessionId();
2832 20 Oct 14 nicklas 65     url += '&cmd=GetHeGlassToScore';
2832 20 Oct 14 nicklas 66     var glassName = Data.get('page-data', 'he-glass');
2832 20 Oct 14 nicklas 67     if (glassName) url += '&name='+encodeURIComponent(glassName);
2832 20 Oct 14 nicklas 68
2832 20 Oct 14 nicklas 69     Wizard.showLoadingAnimation(glassName ? 'Finding HE glass: '+Strings.encodeTags(glassName) : 'Loading next HE glass for scoring...');
2832 20 Oct 14 nicklas 70     Wizard.asyncJsonRequest(url, histology.heGlassLoaded);
2832 20 Oct 14 nicklas 71   }
2832 20 Oct 14 nicklas 72   
2832 20 Oct 14 nicklas 73   histology.heGlassLoaded = function(response)
2832 20 Oct 14 nicklas 74   {
2832 20 Oct 14 nicklas 75     var glassName = response.name;
2832 20 Oct 14 nicklas 76     heGlass = response.heGlasses;
2832 20 Oct 14 nicklas 77
2832 20 Oct 14 nicklas 78     Doc.show('step-1');
2832 20 Oct 14 nicklas 79
2832 20 Oct 14 nicklas 80     if (heGlass.length > 0)
2832 20 Oct 14 nicklas 81     {
2832 20 Oct 14 nicklas 82       // Generate HE glass HTML
2832 20 Oct 14 nicklas 83       var html = '';
2832 20 Oct 14 nicklas 84       for (var glassNo = 0; glassNo < heGlass.length; glassNo++)
2832 20 Oct 14 nicklas 85       {
2832 20 Oct 14 nicklas 86         var glass = heGlass[glassNo];
2832 20 Oct 14 nicklas 87         html += histology.createHeGlassSection(glass);
2832 20 Oct 14 nicklas 88       }
2832 20 Oct 14 nicklas 89       Doc.element('he-glass-container').innerHTML = html;
2832 20 Oct 14 nicklas 90       Doc.show('he-glass-container');
2832 20 Oct 14 nicklas 91       
6017 09 Oct 20 nicklas 92       // Add handlers for viewing NDPI images
6017 09 Oct 20 nicklas 93       var images = document.getElementsByClassName('ndpi-image');
6017 09 Oct 20 nicklas 94       for (var i = 0; i < images.length; i++)
6017 09 Oct 20 nicklas 95       {
6055 13 Nov 20 nicklas 96         Events.addEventHandler(images[i], 'click', histology.previewNdpi);
6055 13 Nov 20 nicklas 97       }
6055 13 Nov 20 nicklas 98       var images = document.getElementsByClassName('open-ndpi');
6055 13 Nov 20 nicklas 99       for (var i = 0; i < images.length; i++)
6055 13 Nov 20 nicklas 100       {
6017 09 Oct 20 nicklas 101         Events.addEventHandler(images[i], 'click', Files.viewFileOnClick);
6017 09 Oct 20 nicklas 102       }
6017 09 Oct 20 nicklas 103       
2832 20 Oct 14 nicklas 104       // Fill form with know information
2832 20 Oct 14 nicklas 105       var firstGoodSample;
2832 20 Oct 14 nicklas 106       for (var glassNo = 0; glassNo < heGlass.length; glassNo++)
2832 20 Oct 14 nicklas 107       {
2832 20 Oct 14 nicklas 108         var glass = heGlass[glassNo];
2832 20 Oct 14 nicklas 109         for (var sampleNo = 0; sampleNo < glass.samples.length; sampleNo++)
2832 20 Oct 14 nicklas 110         {
2832 20 Oct 14 nicklas 111           var sample = glass.samples[sampleNo];
2832 20 Oct 14 nicklas 112           
2832 20 Oct 14 nicklas 113           histology.saveOriginalProperties(sample);
2832 20 Oct 14 nicklas 114           histology.restoreFromLocalStorage(sample);
2832 20 Oct 14 nicklas 115           
2832 20 Oct 14 nicklas 116           // Save ID of HE glass since we need that later
2832 20 Oct 14 nicklas 117           sample.heGlassId = glass.id;
3125 09 Feb 15 nicklas 118           sample.IHC = glass.IHC;
2832 20 Oct 14 nicklas 119           
2832 20 Oct 14 nicklas 120           // Save the first GoodStain sample so we can select it later
2832 20 Oct 14 nicklas 121           if (sample.GoodStain)
2832 20 Oct 14 nicklas 122           {
2832 20 Oct 14 nicklas 123             if (firstGoodSample == null) firstGoodSample = sample;
2832 20 Oct 14 nicklas 124           }
2832 20 Oct 14 nicklas 125           
2832 20 Oct 14 nicklas 126           
2832 20 Oct 14 nicklas 127           // Generate text inside table cell
3367 05 Jun 15 nicklas 128           var html = '<div>';
3367 05 Jun 15 nicklas 129           html += '<div class="sample-name">'+Strings.encodeTags(sample.name.replace(/\.he\d+$/, ''))+'</div>';
3125 09 Feb 15 nicklas 130           if (sample.IHC == null || sample.GoodStain)
3125 09 Feb 15 nicklas 131           {
3125 09 Feb 15 nicklas 132             // Calculate sum of scores
3125 09 Feb 15 nicklas 133             var total = histology.calculateTotalScore(sample);
3125 09 Feb 15 nicklas 134             html += '<div class="progress" id="'+sample.id+'.progress">' + total + '%</div>';
3125 09 Feb 15 nicklas 135           }
3125 09 Feb 15 nicklas 136           else
3125 09 Feb 15 nicklas 137           {
3169 06 Mar 15 nicklas 138             html += '<div class="progress" id="'+sample.id+'.progress">' + Strings.encodeTags(sample.IHC + ': ' + (sample.IHCQuality || '?')) + '</div>';
3125 09 Feb 15 nicklas 139           }
3367 05 Jun 15 nicklas 140           html += '<div class="thumbnail"></div>';
3367 05 Jun 15 nicklas 141           html += '</div>';
2832 20 Oct 14 nicklas 142           
2832 20 Oct 14 nicklas 143           var td = Doc.element(sample.heGlassId+'-'+sample.well.location);
2832 20 Oct 14 nicklas 144           td.innerHTML = html;
2832 20 Oct 14 nicklas 145           td.sample = sample;
3125 09 Feb 15 nicklas 146           
2832 20 Oct 14 nicklas 147           histology.setSampleClassName(sample);
3125 09 Feb 15 nicklas 148           if (sample.IHC == null || sample.GoodStain)
3125 09 Feb 15 nicklas 149           {
3125 09 Feb 15 nicklas 150             Events.addEventHandler(td, 'click', histology.sampleOnClick);
3125 09 Feb 15 nicklas 151           }
3169 06 Mar 15 nicklas 152           else
3169 06 Mar 15 nicklas 153           {
3169 06 Mar 15 nicklas 154             Events.addEventHandler(td, 'click', histology.ihcOnClick);
3169 06 Mar 15 nicklas 155           }
2832 20 Oct 14 nicklas 156         }
2832 20 Oct 14 nicklas 157       }
2832 20 Oct 14 nicklas 158       
2832 20 Oct 14 nicklas 159       if (firstGoodSample != null)
2832 20 Oct 14 nicklas 160       {
2832 20 Oct 14 nicklas 161         Doc.show('score-container');
2832 20 Oct 14 nicklas 162         histology.selectSample(firstGoodSample);
2832 20 Oct 14 nicklas 163       }
2832 20 Oct 14 nicklas 164       
3368 08 Jun 15 nicklas 165       if (heGlass.length > 3)
3368 08 Jun 15 nicklas 166       {
3368 08 Jun 15 nicklas 167         // To make sure the image does not scroll out of view
3368 08 Jun 15 nicklas 168         Doc.addClass('he-layout', 'many-he-glass');
3368 08 Jun 15 nicklas 169       }
3368 08 Jun 15 nicklas 170       
2832 20 Oct 14 nicklas 171       Wizard.keepSessionAlive();
2832 20 Oct 14 nicklas 172       Doc.show('goregister');
2832 20 Oct 14 nicklas 173       window.addEventListener('beforeunload', histology.confirmLeaveWizard);
2832 20 Oct 14 nicklas 174     }
2832 20 Oct 14 nicklas 175     else
2832 20 Oct 14 nicklas 176     {
2832 20 Oct 14 nicklas 177       var msg;
2832 20 Oct 14 nicklas 178       if (glassName)
2832 20 Oct 14 nicklas 179       {
2832 20 Oct 14 nicklas 180         msg = 'Could not find HE glass with name: ' + Strings.encodeTags(glassName);
2832 20 Oct 14 nicklas 181       }
2832 20 Oct 14 nicklas 182       else
2832 20 Oct 14 nicklas 183       {
2832 20 Oct 14 nicklas 184         msg = 'No HE glass available for scoring.';
2832 20 Oct 14 nicklas 185         msg += ' Specify HE glass name above to re-score.';
2832 20 Oct 14 nicklas 186       }
2832 20 Oct 14 nicklas 187       Doc.element('he-glass-container').innerHTML = '<div class="messagecontainer note">'+msg+'</div>';
2832 20 Oct 14 nicklas 188       Doc.show('he-glass-container');
2832 20 Oct 14 nicklas 189       Doc.show('gonext');
2832 20 Oct 14 nicklas 190     }
2832 20 Oct 14 nicklas 191     
2832 20 Oct 14 nicklas 192     
2832 20 Oct 14 nicklas 193     var url = '../Histology.servlet?ID='+App.getSessionId();
2832 20 Oct 14 nicklas 194     url += '&cmd=GetUncompletedHeGlass';
2832 20 Oct 14 nicklas 195     Wizard.asyncJsonRequest(url, histology.uncompletedHeGlassLoaded);
2832 20 Oct 14 nicklas 196   }
2832 20 Oct 14 nicklas 197   
6055 13 Nov 20 nicklas 198   /**
6055 13 Nov 20 nicklas 199     Show a preview of either the label or the scanned area.
6055 13 Nov 20 nicklas 200   */
6055 13 Nov 20 nicklas 201   histology.previewNdpi = function(event)
6055 13 Nov 20 nicklas 202   {
6055 13 Nov 20 nicklas 203     var img = event.currentTarget;
6055 13 Nov 20 nicklas 204     // Find out the 'x' coordinage of the mouse click
6055 13 Nov 20 nicklas 205     var bounds = img.getBoundingClientRect();
6055 13 Nov 20 nicklas 206       var left = bounds.left;
6055 13 Nov 20 nicklas 207       var height = img.clientHeight;
6055 13 Nov 20 nicklas 208       var x = event.pageX - left;
6055 13 Nov 20 nicklas 209
6055 13 Nov 20 nicklas 210       var fileId = Data.get(img, 'file-id');
6055 13 Nov 20 nicklas 211     var url = '../../thumbnails.jar/Thumbnails.servlet?ID='+App.getSessionId()+'&file='+fileId+'&size=XXLARGE';
6055 13 Nov 20 nicklas 212       if (x < height)
6055 13 Nov 20 nicklas 213       {
6055 13 Nov 20 nicklas 214         // The click was to the left, display the label (we know that it is at image index 7)
6055 13 Nov 20 nicklas 215       url += '&index=7&crop=LABEL';
6055 13 Nov 20 nicklas 216       }
6055 13 Nov 20 nicklas 217       else
6055 13 Nov 20 nicklas 218       {
6055 13 Nov 20 nicklas 219         // The click was to the right, display the scanned area (the smallest image is at image index 6)
6055 13 Nov 20 nicklas 220         url += '&index=6';
6055 13 Nov 20 nicklas 221       }
6055 13 Nov 20 nicklas 222     Doc.element('he-image-name').innerHTML = Data.get(img, 'glass-name');
6055 13 Nov 20 nicklas 223     Doc.hide('file-error');
6055 13 Nov 20 nicklas 224     Doc.addClass('he-image-container', 'has-image');
6055 13 Nov 20 nicklas 225     Doc.removeClass('he-image-container', 'can-delete');
6055 13 Nov 20 nicklas 226       Data.set('he-image', 'file-id', fileId);
6055 13 Nov 20 nicklas 227       Doc.element('he-image').src = '../images/loading.gif';
6055 13 Nov 20 nicklas 228       Doc.element('he-image').src = url;
6055 13 Nov 20 nicklas 229   }
6055 13 Nov 20 nicklas 230   
2832 20 Oct 14 nicklas 231   histology.uncompletedHeGlassLoaded = function(response)
2832 20 Oct 14 nicklas 232   {
2832 20 Oct 14 nicklas 233     var uncompleted = response.heGlasses;
2832 20 Oct 14 nicklas 234     
2832 20 Oct 14 nicklas 235     if (uncompleted.length > 0)
2832 20 Oct 14 nicklas 236     {
2832 20 Oct 14 nicklas 237       // Populate menu item
2832 20 Oct 14 nicklas 238       Doc.element('btnUncompletedHeGlass.text').innerHTML = uncompleted.length + ' uncompleted';
2832 20 Oct 14 nicklas 239       var html = '';  
2832 20 Oct 14 nicklas 240       for (var glassNo = 0; glassNo < uncompleted.length; glassNo++)
2832 20 Oct 14 nicklas 241       {
2832 20 Oct 14 nicklas 242         var glass = uncompleted[glassNo];
2832 20 Oct 14 nicklas 243       
3125 09 Feb 15 nicklas 244         html += '<div class="menuitem enabled interactable" id="glass-'+glass.id+'" data-name="'+Strings.encodeTags(glass.name)+'">';
2832 20 Oct 14 nicklas 245         html += Strings.encodeTags(glass.name)+' ('+glass.numUncompleteSamples +')</div>';
2832 20 Oct 14 nicklas 246       }
2832 20 Oct 14 nicklas 247       Doc.element('select-uncompleted-heglass-menu').innerHTML = html;
2832 20 Oct 14 nicklas 248       Doc.show('btnNncompletedHeGlass');
2832 20 Oct 14 nicklas 249     }
2832 20 Oct 14 nicklas 250     else
2832 20 Oct 14 nicklas 251     {
2832 20 Oct 14 nicklas 252       Doc.hide('btnUncompletedHeGlass');
2832 20 Oct 14 nicklas 253     }
2832 20 Oct 14 nicklas 254   }
2832 20 Oct 14 nicklas 255
2832 20 Oct 14 nicklas 256   histology.showUncompletedHeGlassMenu = function(event)
2832 20 Oct 14 nicklas 257   {
2832 20 Oct 14 nicklas 258     var pos = Doc.getElementPosition('btnUncompletedHeGlass');
2832 20 Oct 14 nicklas 259     var x = pos.left;
2832 20 Oct 14 nicklas 260     var y = pos.top+pos.height;
2832 20 Oct 14 nicklas 261
2832 20 Oct 14 nicklas 262     var menu = Doc.element('select-uncompleted-heglass');
2832 20 Oct 14 nicklas 263     menu.style.left = (x)+'px';
2832 20 Oct 14 nicklas 264     menu.style.top = (y)+'px';
2832 20 Oct 14 nicklas 265     menu.style.display = 'block';
2832 20 Oct 14 nicklas 266     event.stopPropagation();
2832 20 Oct 14 nicklas 267   }
2832 20 Oct 14 nicklas 268   
6824 30 Aug 22 nicklas 269   histology.hideUncompletedHeGlassMenu = function()
2832 20 Oct 14 nicklas 270   {
2832 20 Oct 14 nicklas 271     Doc.hide('select-uncompleted-heglass');
2832 20 Oct 14 nicklas 272   }
2832 20 Oct 14 nicklas 273
2832 20 Oct 14 nicklas 274   histology.uncompletedGlassSelected = function(event)
2832 20 Oct 14 nicklas 275   {
2832 20 Oct 14 nicklas 276     histology.findHeGlass(Data.get(event.target, 'name'));
2832 20 Oct 14 nicklas 277   }
2832 20 Oct 14 nicklas 278
2832 20 Oct 14 nicklas 279   
2832 20 Oct 14 nicklas 280   histology.selectHeGlass = function(event)
2832 20 Oct 14 nicklas 281   {
2832 20 Oct 14 nicklas 282     if (!histology.confirmLeaveWizard()) return;
2832 20 Oct 14 nicklas 283     
2832 20 Oct 14 nicklas 284     var url = '&resetTemporary=1';
2832 20 Oct 14 nicklas 285     url += '&tmpfilter:STRING:name='+encodeURIComponent('HE%');
2832 20 Oct 14 nicklas 286     Dialogs.selectItem('BIOPLATE', event.currentTarget.id, 0, url);
2832 20 Oct 14 nicklas 287   }
2832 20 Oct 14 nicklas 288   
2832 20 Oct 14 nicklas 289   histology.heGlassSelected = function(event)
2832 20 Oct 14 nicklas 290   {
2832 20 Oct 14 nicklas 291     disableModificationCheck = true;
2832 20 Oct 14 nicklas 292     histology.findHeGlass(event.detail.name);
2832 20 Oct 14 nicklas 293   }
2832 20 Oct 14 nicklas 294   
6824 30 Aug 22 nicklas 295   histology.searchHeGlass = function()
2832 20 Oct 14 nicklas 296   {
2832 20 Oct 14 nicklas 297     var frm = document.forms['reggie'];
2832 20 Oct 14 nicklas 298     if (frm.findGlassName.value) histology.findHeGlass();
2832 20 Oct 14 nicklas 299   }
2832 20 Oct 14 nicklas 300   
2832 20 Oct 14 nicklas 301   histology.findHeGlass = function(glassName, autoFind)
2832 20 Oct 14 nicklas 302   {
2832 20 Oct 14 nicklas 303     var frm = document.forms['reggie'];
2832 20 Oct 14 nicklas 304     if (!glassName && autoFind != true)
2832 20 Oct 14 nicklas 305     {
2832 20 Oct 14 nicklas 306       glassName = frm.findGlassName.value;
2832 20 Oct 14 nicklas 307       if (!glassName) return;
2832 20 Oct 14 nicklas 308       
2832 20 Oct 14 nicklas 309       if (glassName.match(/^\d+$/))
2832 20 Oct 14 nicklas 310       {
2832 20 Oct 14 nicklas 311         while (glassName.length < 5)
2832 20 Oct 14 nicklas 312         {
2832 20 Oct 14 nicklas 313           glassName = '0'+glassName;
2832 20 Oct 14 nicklas 314         }
2832 20 Oct 14 nicklas 315         glassName = 'HE'+glassName;
2832 20 Oct 14 nicklas 316       }
2832 20 Oct 14 nicklas 317     }
2832 20 Oct 14 nicklas 318     var url =  'histology_score.jsp?ID='+App.getSessionId();
2832 20 Oct 14 nicklas 319     if (glassName)
2832 20 Oct 14 nicklas 320     {
2832 20 Oct 14 nicklas 321       url += '&name='+encodeURIComponent(glassName);
2832 20 Oct 14 nicklas 322     }
2832 20 Oct 14 nicklas 323     
2832 20 Oct 14 nicklas 324     location.replace(url);
2832 20 Oct 14 nicklas 325   }
2832 20 Oct 14 nicklas 326
2832 20 Oct 14 nicklas 327   histology.goNext = function()
2832 20 Oct 14 nicklas 328   {
2832 20 Oct 14 nicklas 329     histology.findHeGlass(null, true);
2832 20 Oct 14 nicklas 330   }
2832 20 Oct 14 nicklas 331   
2832 20 Oct 14 nicklas 332   histology.createHeGlassSection = function(glass)
2832 20 Oct 14 nicklas 333   {
2832 20 Oct 14 nicklas 334     var html = '';
3026 11 Dec 14 nicklas 335     html += '<div class="he-glass bg-filled-50">';
6017 09 Oct 20 nicklas 336     html += '<div class="he-name bg-filled-100">';
6017 09 Oct 20 nicklas 337     html += Strings.encodeTags(glass.name || '');
6017 09 Oct 20 nicklas 338     html += '</div>';
2832 20 Oct 14 nicklas 339     
2832 20 Oct 14 nicklas 340     html += '<div class="he-info">';
3125 09 Feb 15 nicklas 341     if (glass.IHC != null)
3125 09 Feb 15 nicklas 342     {
3125 09 Feb 15 nicklas 343       html += '<span class="ihc">' + Strings.encodeTags(glass.IHC) + '</span>; ';
3125 09 Feb 15 nicklas 344     }
2832 20 Oct 14 nicklas 345     html += '<span class="he-tray">' +  Strings.encodeTags(glass.tray || '') + '</span>; <span class="he-position">' + Strings.encodeTags(glass.position || '') + '</span>';
2832 20 Oct 14 nicklas 346     html += '<div class="he-comment">' + Strings.encodeTags(glass.comments || '') + '</div>';
2832 20 Oct 14 nicklas 347     html += '</div>';
6051 12 Nov 20 nicklas 348     html += '<div class="he-thumb">';
6051 12 Nov 20 nicklas 349     if (glass.ndpiImage)
6051 12 Nov 20 nicklas 350     {
6055 13 Nov 20 nicklas 351       html += '<img class="ndpi-image link" title="Preview NanoZoomer Digital Pathology Image"';
6055 13 Nov 20 nicklas 352       html += ' src="../../thumbnails.jar/Thumbnails.servlet?ID='+App.getSessionId()+'&file='+glass.ndpiImage.id+'&size=LARGE&index=7"';
6055 13 Nov 20 nicklas 353       html += ' data-file-id="'+glass.ndpiImage.id+'" data-glass-name="'+Strings.encodeTags(glass.name)+'"';
6055 13 Nov 20 nicklas 354       html += '>';
6055 13 Nov 20 nicklas 355       html += '<img class="open-ndpi link" data-file-id="'+glass.ndpiImage.id+'" title="Download and open NanoZoomer Digital Pathology Image" src="../images/ndp.png">';
6051 12 Nov 20 nicklas 356     }
6051 12 Nov 20 nicklas 357     else
6051 12 Nov 20 nicklas 358     {
6051 12 Nov 20 nicklas 359       html += 'No scanned image exists for this slide';
6051 12 Nov 20 nicklas 360     }
6051 12 Nov 20 nicklas 361     html += '</div>';
2832 20 Oct 14 nicklas 362     html += '<table class="he-table">';
2832 20 Oct 14 nicklas 363     html += '<tr>';
2832 20 Oct 14 nicklas 364     html += '<td class="not-used" id="'+glass.id+'-A1"></td>';
2832 20 Oct 14 nicklas 365     html += '<td class="not-used" id="'+glass.id+'-A2"></td>';
2832 20 Oct 14 nicklas 366     html += '</tr>';
2832 20 Oct 14 nicklas 367     html += '<tr>';
2832 20 Oct 14 nicklas 368     html += '<td class="not-used" id="'+glass.id+'-B1"></td>';
2832 20 Oct 14 nicklas 369     html += '<td class="not-used" id="'+glass.id+'-B2"></td>';
2832 20 Oct 14 nicklas 370     html += '</tr>';
2832 20 Oct 14 nicklas 371     html += '<tr>';
2832 20 Oct 14 nicklas 372     html += '<td class="not-used" id="'+glass.id+'-C1"></td>';
2832 20 Oct 14 nicklas 373     html += '<td class="not-used" id="'+glass.id+'-C2"></td>';
2832 20 Oct 14 nicklas 374     html += '</tr>';
2832 20 Oct 14 nicklas 375     html += '</table>';
2832 20 Oct 14 nicklas 376     html += '</div>';
2832 20 Oct 14 nicklas 377
2832 20 Oct 14 nicklas 378     return html;
2832 20 Oct 14 nicklas 379   }
2832 20 Oct 14 nicklas 380
2832 20 Oct 14 nicklas 381   /**
2832 20 Oct 14 nicklas 382     Remember the original properties so that we know if
2832 20 Oct 14 nicklas 383     a sample has been modified.
2832 20 Oct 14 nicklas 384   */
2832 20 Oct 14 nicklas 385   histology.saveOriginalProperties = function(sample)
2832 20 Oct 14 nicklas 386   {
2832 20 Oct 14 nicklas 387     var o = {};
2832 20 Oct 14 nicklas 388     for (var i = 0; i < SCORES.length; i++)
2832 20 Oct 14 nicklas 389     {
2832 20 Oct 14 nicklas 390       var p = SCORES[i];
2832 20 Oct 14 nicklas 391       o[p] = sample[p];  
2832 20 Oct 14 nicklas 392     }
2832 20 Oct 14 nicklas 393     
2832 20 Oct 14 nicklas 394     o.GoodStain = sample.GoodStain;
2832 20 Oct 14 nicklas 395     o.ScoreComplete = sample.ScoreComplete;
2832 20 Oct 14 nicklas 396     o.comments = sample.comments;
3169 06 Mar 15 nicklas 397     o.IHCQuality = sample.IHCQuality;
2832 20 Oct 14 nicklas 398     sample.o = o;
2832 20 Oct 14 nicklas 399     sample.isModified = false;
2832 20 Oct 14 nicklas 400   }
2832 20 Oct 14 nicklas 401   
2832 20 Oct 14 nicklas 402   /**
2832 20 Oct 14 nicklas 403     Check if a sample has been modified.
2832 20 Oct 14 nicklas 404   */
2832 20 Oct 14 nicklas 405   histology.isModified = function(sample, useCache)
2832 20 Oct 14 nicklas 406   {
2832 20 Oct 14 nicklas 407     if (!useCache)
2832 20 Oct 14 nicklas 408     {
2832 20 Oct 14 nicklas 409       var o = sample.o;
2832 20 Oct 14 nicklas 410       sample.isModified = false;
2832 20 Oct 14 nicklas 411       for (var p in o)
2832 20 Oct 14 nicklas 412       {
2832 20 Oct 14 nicklas 413         if (o[p] != sample[p])
2832 20 Oct 14 nicklas 414         {
2832 20 Oct 14 nicklas 415           sample.isModified = true;
2832 20 Oct 14 nicklas 416           break;
2832 20 Oct 14 nicklas 417         }
2832 20 Oct 14 nicklas 418       }
2832 20 Oct 14 nicklas 419     }
2832 20 Oct 14 nicklas 420     return sample.isModified;
2832 20 Oct 14 nicklas 421   }
2832 20 Oct 14 nicklas 422
2832 20 Oct 14 nicklas 423   
2832 20 Oct 14 nicklas 424   histology.calculateTotalScore = function(sample)
2832 20 Oct 14 nicklas 425   {
2832 20 Oct 14 nicklas 426     var total = 0;
2832 20 Oct 14 nicklas 427     var numNull = 0;
2832 20 Oct 14 nicklas 428     for (var i = 0; i < SCORES.length; i++)
2832 20 Oct 14 nicklas 429     {
2832 20 Oct 14 nicklas 430       var score = sample[SCORES[i]];
2832 20 Oct 14 nicklas 431       total += histology.sumScore(score);
2832 20 Oct 14 nicklas 432       if (score == null) numNull++;
2832 20 Oct 14 nicklas 433     }
2832 20 Oct 14 nicklas 434     // Set summed total, null only if all values are null
2832 20 Oct 14 nicklas 435     sample.ScoreTotal = total == 0 && numNull == SCORES.length ? null : total;
2832 20 Oct 14 nicklas 436     sample.numNullScores = numNull;
2832 20 Oct 14 nicklas 437     return total;
2832 20 Oct 14 nicklas 438   }
2832 20 Oct 14 nicklas 439   
2832 20 Oct 14 nicklas 440   histology.sumScore = function(score)
2832 20 Oct 14 nicklas 441   {
2832 20 Oct 14 nicklas 442     return score || 0;
2832 20 Oct 14 nicklas 443   }
2832 20 Oct 14 nicklas 444
2832 20 Oct 14 nicklas 445   histology.setSampleClassName = function(sample)
2832 20 Oct 14 nicklas 446   {
2832 20 Oct 14 nicklas 447     var className = 'used';
2832 20 Oct 14 nicklas 448     if (sample.GoodStain)
2832 20 Oct 14 nicklas 449     {
2832 20 Oct 14 nicklas 450       className += ' good-stain';
2832 20 Oct 14 nicklas 451     }
3125 09 Feb 15 nicklas 452     else if (sample.IHC)
3125 09 Feb 15 nicklas 453     {
3125 09 Feb 15 nicklas 454       className += ' ihc';
3406 16 Jun 15 nicklas 455       if (sample.IHCQuality)
3406 16 Jun 15 nicklas 456       {
3406 16 Jun 15 nicklas 457         className += ' ihc-done';
3406 16 Jun 15 nicklas 458       }
3125 09 Feb 15 nicklas 459     }
2832 20 Oct 14 nicklas 460     else
2832 20 Oct 14 nicklas 461     {
2832 20 Oct 14 nicklas 462       if (histology.getGoodStainedSampleForLocation(sample.well.location) == null)
2832 20 Oct 14 nicklas 463       {
2832 20 Oct 14 nicklas 464         className += ' flag';
2832 20 Oct 14 nicklas 465       }
2832 20 Oct 14 nicklas 466     }
2832 20 Oct 14 nicklas 467     
2832 20 Oct 14 nicklas 468     if (sample.ScoreTotal == null)
2832 20 Oct 14 nicklas 469     {
2832 20 Oct 14 nicklas 470       className += ' score-none';
2832 20 Oct 14 nicklas 471     }
2832 20 Oct 14 nicklas 472     else if (sample.ScoreTotal != 100 || !sample.ScoreComplete)
2832 20 Oct 14 nicklas 473     {
2832 20 Oct 14 nicklas 474       className += ' score-incomplete';
2832 20 Oct 14 nicklas 475     }
2832 20 Oct 14 nicklas 476     else
2832 20 Oct 14 nicklas 477     {
2832 20 Oct 14 nicklas 478       className += ' score-complete';
2832 20 Oct 14 nicklas 479     }
2832 20 Oct 14 nicklas 480     
3369 08 Jun 15 nicklas 481     if (sample.image)
3367 05 Jun 15 nicklas 482     {
6055 13 Nov 20 nicklas 483       className += ' has-image can-delete';
3367 05 Jun 15 nicklas 484     }
3367 05 Jun 15 nicklas 485     
2832 20 Oct 14 nicklas 486     if (histology.isModified(sample))
2832 20 Oct 14 nicklas 487     {
2832 20 Oct 14 nicklas 488       className += ' modified';
2832 20 Oct 14 nicklas 489     }
2832 20 Oct 14 nicklas 490     
2832 20 Oct 14 nicklas 491     if (selectedSample && selectedSample.id == sample.id)
2832 20 Oct 14 nicklas 492     {
2832 20 Oct 14 nicklas 493       className += ' selected';
2832 20 Oct 14 nicklas 494     }
2832 20 Oct 14 nicklas 495     
2832 20 Oct 14 nicklas 496     var td = Doc.element(sample.heGlassId+'-'+sample.well.location);
2832 20 Oct 14 nicklas 497     td.className = className;
2832 20 Oct 14 nicklas 498   }
2832 20 Oct 14 nicklas 499
2832 20 Oct 14 nicklas 500   histology.getGoodStainedSampleForLocation = function(location)
2832 20 Oct 14 nicklas 501   {
2832 20 Oct 14 nicklas 502     // Find sample on given location that has GoodStain annotation
2832 20 Oct 14 nicklas 503     for (var glassNo = 0; glassNo < heGlass.length; glassNo++)
2832 20 Oct 14 nicklas 504     {
2832 20 Oct 14 nicklas 505       var glass = heGlass[glassNo];
2832 20 Oct 14 nicklas 506       for (var sampleNo = 0; sampleNo < glass.samples.length; sampleNo++)
2832 20 Oct 14 nicklas 507       {
2832 20 Oct 14 nicklas 508         var sample = glass.samples[sampleNo];
2832 20 Oct 14 nicklas 509         if (sample.well.location == location && sample.GoodStain)
2832 20 Oct 14 nicklas 510         {
2832 20 Oct 14 nicklas 511           return sample;
2832 20 Oct 14 nicklas 512         }
2832 20 Oct 14 nicklas 513       }
2832 20 Oct 14 nicklas 514     }
2832 20 Oct 14 nicklas 515     return null;
2832 20 Oct 14 nicklas 516   }
2832 20 Oct 14 nicklas 517
2832 20 Oct 14 nicklas 518   histology.sampleOnClick = function(event)
2832 20 Oct 14 nicklas 519   {
2832 20 Oct 14 nicklas 520     var td = event.currentTarget;
2832 20 Oct 14 nicklas 521     histology.selectSample(td.sample);
2832 20 Oct 14 nicklas 522   }
3169 06 Mar 15 nicklas 523   
3169 06 Mar 15 nicklas 524   histology.ihcOnClick = function(event)
3169 06 Mar 15 nicklas 525   {
3169 06 Mar 15 nicklas 526     var td = event.currentTarget;
3169 06 Mar 15 nicklas 527     histology.selectSample(td.sample);
3169 06 Mar 15 nicklas 528   }
2832 20 Oct 14 nicklas 529
2832 20 Oct 14 nicklas 530   histology.selectSample = function(sample)
2832 20 Oct 14 nicklas 531   {
2832 20 Oct 14 nicklas 532     var frm = document.forms['reggie'];
2832 20 Oct 14 nicklas 533     
2832 20 Oct 14 nicklas 534     // Sample name
2832 20 Oct 14 nicklas 535     Doc.element('sample.name').innerHTML = Strings.encodeTags(sample.name);
2832 20 Oct 14 nicklas 536     
3169 06 Mar 15 nicklas 537     if (sample.IHC)
2832 20 Oct 14 nicklas 538     {
3169 06 Mar 15 nicklas 539       Doc.hide('heSample');
3169 06 Mar 15 nicklas 540       Doc.show('ihcSample');
3169 06 Mar 15 nicklas 541       
3169 06 Mar 15 nicklas 542       Forms.selectListOption(frm.ihc_quality, sample.IHCQuality || '');
3169 06 Mar 15 nicklas 543       Doc.element('ihc_name').innerHTML = Strings.encodeTags(sample.IHC);
2832 20 Oct 14 nicklas 544     }
3169 06 Mar 15 nicklas 545     else
2832 20 Oct 14 nicklas 546     {
3169 06 Mar 15 nicklas 547       Doc.show('heSample');
3169 06 Mar 15 nicklas 548       Doc.hide('ihcSample');
3169 06 Mar 15 nicklas 549       
3169 06 Mar 15 nicklas 550       // Scores
3169 06 Mar 15 nicklas 551       for (var i = 0; i < SCORES.length; i++)
2832 20 Oct 14 nicklas 552       {
3169 06 Mar 15 nicklas 553         frm[FIELDS[i]].value = sample[SCORES[i]];
2832 20 Oct 14 nicklas 554       }
3169 06 Mar 15 nicklas 555       
3169 06 Mar 15 nicklas 556       // Total score + score complete
3169 06 Mar 15 nicklas 557       var total = histology.calculateTotalScore(sample);
3169 06 Mar 15 nicklas 558       Doc.element('score_total').innerHTML = total;
3169 06 Mar 15 nicklas 559       if (total == 100)
3169 06 Mar 15 nicklas 560       {
3169 06 Mar 15 nicklas 561         if (sample.numNullScores == 0)
3169 06 Mar 15 nicklas 562         {
3169 06 Mar 15 nicklas 563           frm.score_complete.disabled = false;
3169 06 Mar 15 nicklas 564           frm.score_complete.checked = sample.ScoreComplete;
3169 06 Mar 15 nicklas 565           Wizard.setInputStatus('score_total', 'valid');
3169 06 Mar 15 nicklas 566         }
3169 06 Mar 15 nicklas 567         else
3169 06 Mar 15 nicklas 568         {
3169 06 Mar 15 nicklas 569           frm.score_complete.disabled = true;
3169 06 Mar 15 nicklas 570           frm.score_complete.checked = false;
3169 06 Mar 15 nicklas 571           Wizard.setInputStatus('score_total', 'warning', 'Enter 0 in empty fields to complete scoring');
3169 06 Mar 15 nicklas 572         }
3169 06 Mar 15 nicklas 573       }
2832 20 Oct 14 nicklas 574       else
2832 20 Oct 14 nicklas 575       {
2832 20 Oct 14 nicklas 576         frm.score_complete.disabled = true;
2832 20 Oct 14 nicklas 577         frm.score_complete.checked = false;
3169 06 Mar 15 nicklas 578         Wizard.setInputStatus('score_total', 'warning', 'Not 100%');
2832 20 Oct 14 nicklas 579       }
3169 06 Mar 15 nicklas 580       
3169 06 Mar 15 nicklas 581       // Good stain
3169 06 Mar 15 nicklas 582       if (sample.GoodStain)
3169 06 Mar 15 nicklas 583       {
3169 06 Mar 15 nicklas 584         frm.good_stain.checked = true;
3169 06 Mar 15 nicklas 585       }
3169 06 Mar 15 nicklas 586       else
3169 06 Mar 15 nicklas 587       {
3169 06 Mar 15 nicklas 588         frm.good_stain.checked = false;
3169 06 Mar 15 nicklas 589       }
3169 06 Mar 15 nicklas 590       frm.score_invasive_cancer.focus();
2832 20 Oct 14 nicklas 591     }
3368 08 Jun 15 nicklas 592
3368 08 Jun 15 nicklas 593     // Image
3369 08 Jun 15 nicklas 594     Doc.element('he-image-name').innerHTML = Strings.encodeTags(sample.name);
3368 08 Jun 15 nicklas 595     Doc.hide('file-error');
3368 08 Jun 15 nicklas 596     if (sample.image)
3368 08 Jun 15 nicklas 597     {
3368 08 Jun 15 nicklas 598       Doc.element('he-image').src = App.getRoot() + 'filemanager/files/view/-'+App.getSessionId()+'-' + sample.image;
6055 13 Nov 20 nicklas 599       Data.set('he-image', 'file-id', 0);
3369 08 Jun 15 nicklas 600       Doc.addClass('he-image-container', 'has-image');
6055 13 Nov 20 nicklas 601       Doc.addClass('he-image-container', 'can-delete');
3368 08 Jun 15 nicklas 602     }
3368 08 Jun 15 nicklas 603     else
3368 08 Jun 15 nicklas 604     {
3369 08 Jun 15 nicklas 605       Doc.removeClass('he-image-container', 'has-image');
3368 08 Jun 15 nicklas 606     }
2832 20 Oct 14 nicklas 607     
2832 20 Oct 14 nicklas 608     // Comments
2832 20 Oct 14 nicklas 609     frm.comments.value = sample.comments || '';
2832 20 Oct 14 nicklas 610     
2832 20 Oct 14 nicklas 611     // Class name of selected table cell
2832 20 Oct 14 nicklas 612     if (selectedSample != null)
2832 20 Oct 14 nicklas 613     {
3282 29 Apr 15 nicklas 614       Doc.removeClass(selectedSample.heGlassId+'-'+selectedSample.well.location, 'selected');
2832 20 Oct 14 nicklas 615     }
2832 20 Oct 14 nicklas 616     
2832 20 Oct 14 nicklas 617     selectedSample = sample;
2832 20 Oct 14 nicklas 618     histology.setSampleClassName(sample);
2832 20 Oct 14 nicklas 619     
2832 20 Oct 14 nicklas 620   }
2832 20 Oct 14 nicklas 621   
2832 20 Oct 14 nicklas 622   histology.checkScores = function()
2832 20 Oct 14 nicklas 623   {
2832 20 Oct 14 nicklas 624     var frm = document.forms['reggie'];
2832 20 Oct 14 nicklas 625
2832 20 Oct 14 nicklas 626     for (var i = 0; i < SCORES.length; i++)
2832 20 Oct 14 nicklas 627     {
2832 20 Oct 14 nicklas 628       selectedSample[SCORES[i]] = histology.toScore(frm[FIELDS[i]].value);
2832 20 Oct 14 nicklas 629     }
2832 20 Oct 14 nicklas 630     
2832 20 Oct 14 nicklas 631     var oldTotal = selectedSample.ScoreTotal;
2832 20 Oct 14 nicklas 632     var oldNumNull = selectedSample.numNullScores;
2832 20 Oct 14 nicklas 633     
2832 20 Oct 14 nicklas 634     var total = histology.calculateTotalScore(selectedSample);
2832 20 Oct 14 nicklas 635     
2832 20 Oct 14 nicklas 636     Doc.element('score_total').innerHTML = total;
2832 20 Oct 14 nicklas 637     Doc.element(selectedSample.id+'.progress').innerHTML = total + '%';
2832 20 Oct 14 nicklas 638     
2832 20 Oct 14 nicklas 639     if (total == 100)
2832 20 Oct 14 nicklas 640     {
2832 20 Oct 14 nicklas 641       if (selectedSample.numNullScores == 0)
2832 20 Oct 14 nicklas 642       {
2832 20 Oct 14 nicklas 643         // All scores have been entered
2832 20 Oct 14 nicklas 644         frm.score_complete.disabled = false;
2832 20 Oct 14 nicklas 645         if (oldTotal != total || oldNumNull != selectedSample.numNullScores)
2832 20 Oct 14 nicklas 646         {
2832 20 Oct 14 nicklas 647           // Only check the 'Score complete' if value has changed
2832 20 Oct 14 nicklas 648           frm.score_complete.checked = true;
2832 20 Oct 14 nicklas 649           selectedSample.ScoreComplete = true;
2832 20 Oct 14 nicklas 650         }
2832 20 Oct 14 nicklas 651         Wizard.setInputStatus('score_total', 'valid');
2832 20 Oct 14 nicklas 652       }
2832 20 Oct 14 nicklas 653       else
2832 20 Oct 14 nicklas 654       {
2832 20 Oct 14 nicklas 655         frm.score_complete.disabled = true;
2832 20 Oct 14 nicklas 656         frm.score_complete.checked = false;
2832 20 Oct 14 nicklas 657         selectedSample.ScoreComplete = false;
2832 20 Oct 14 nicklas 658         Wizard.setInputStatus('score_total', 'warning', 'Enter 0 in empty fields to complete scoring');
2832 20 Oct 14 nicklas 659       }
2832 20 Oct 14 nicklas 660     }
2832 20 Oct 14 nicklas 661     else
2832 20 Oct 14 nicklas 662     {
2832 20 Oct 14 nicklas 663       frm.score_complete.disabled = true;
2832 20 Oct 14 nicklas 664       frm.score_complete.checked = false;
2832 20 Oct 14 nicklas 665
2832 20 Oct 14 nicklas 666       Wizard.setInputStatus('score_total', 'warning', 'Not 100%');
2832 20 Oct 14 nicklas 667       selectedSample.ScoreComplete = selectedSample.ScoreTotal == null ? null : false;
2832 20 Oct 14 nicklas 668     }
2832 20 Oct 14 nicklas 669
2832 20 Oct 14 nicklas 670     histology.setSampleClassName(selectedSample);
2832 20 Oct 14 nicklas 671     histology.saveToLocalStorage(selectedSample);
2832 20 Oct 14 nicklas 672   }
2832 20 Oct 14 nicklas 673
2832 20 Oct 14 nicklas 674   histology.toScore = function(value)
2832 20 Oct 14 nicklas 675   {
2832 20 Oct 14 nicklas 676     var score = parseInt(value);
2832 20 Oct 14 nicklas 677     return isNaN(score) ? null : score;
2832 20 Oct 14 nicklas 678   }
2832 20 Oct 14 nicklas 679
2832 20 Oct 14 nicklas 680   histology.goodStainOnClick = function()
2832 20 Oct 14 nicklas 681   {
2832 20 Oct 14 nicklas 682     var frm = document.forms['reggie'];
2832 20 Oct 14 nicklas 683     
2832 20 Oct 14 nicklas 684     var goodSample = histology.getGoodStainedSampleForLocation(selectedSample.well.location);
2832 20 Oct 14 nicklas 685     if (goodSample != null && goodSample != selectedSample)
2832 20 Oct 14 nicklas 686     {
2832 20 Oct 14 nicklas 687       // Reset the current GoodStain sample
2832 20 Oct 14 nicklas 688       goodSample.GoodStain = null;
2832 20 Oct 14 nicklas 689       histology.saveToLocalStorage(goodSample);
2832 20 Oct 14 nicklas 690     }
2832 20 Oct 14 nicklas 691     
2832 20 Oct 14 nicklas 692     selectedSample.GoodStain = frm.good_stain.checked ? true : null;
2832 20 Oct 14 nicklas 693     histology.saveToLocalStorage(selectedSample);
2832 20 Oct 14 nicklas 694     
2832 20 Oct 14 nicklas 695     // Repaint samples on current location
2832 20 Oct 14 nicklas 696     for (var glassNo = 0; glassNo < heGlass.length; glassNo++)
2832 20 Oct 14 nicklas 697     {
2832 20 Oct 14 nicklas 698       var glass = heGlass[glassNo];
2832 20 Oct 14 nicklas 699       
2832 20 Oct 14 nicklas 700       for (var sampleNo = 0; sampleNo < glass.samples.length; sampleNo++)
2832 20 Oct 14 nicklas 701       {
2832 20 Oct 14 nicklas 702         var sample = glass.samples[sampleNo];
2832 20 Oct 14 nicklas 703         if (sample.well.location == selectedSample.well.location)
2832 20 Oct 14 nicklas 704         {
2832 20 Oct 14 nicklas 705           histology.setSampleClassName(sample);
2832 20 Oct 14 nicklas 706         }
2832 20 Oct 14 nicklas 707       }
2832 20 Oct 14 nicklas 708     }
2832 20 Oct 14 nicklas 709   }
2832 20 Oct 14 nicklas 710   
2832 20 Oct 14 nicklas 711   histology.scoreCompleteOnClick = function()
2832 20 Oct 14 nicklas 712   {
2832 20 Oct 14 nicklas 713     var frm = document.forms['reggie'];
2832 20 Oct 14 nicklas 714     selectedSample.ScoreComplete = frm.score_complete.checked;
2832 20 Oct 14 nicklas 715     histology.setSampleClassName(selectedSample);
2832 20 Oct 14 nicklas 716     histology.saveToLocalStorage(selectedSample);
2832 20 Oct 14 nicklas 717   }
2832 20 Oct 14 nicklas 718
2832 20 Oct 14 nicklas 719   histology.commentsOnChange = function()
2832 20 Oct 14 nicklas 720   {
2832 20 Oct 14 nicklas 721     var frm = document.forms['reggie'];
2832 20 Oct 14 nicklas 722     selectedSample.comments = frm.comments.value;
2832 20 Oct 14 nicklas 723     histology.setSampleClassName(selectedSample);
2832 20 Oct 14 nicklas 724     histology.saveToLocalStorage(selectedSample);
2832 20 Oct 14 nicklas 725   }
3169 06 Mar 15 nicklas 726   
3169 06 Mar 15 nicklas 727   histology.ihcQualityOnChange = function()
3169 06 Mar 15 nicklas 728   {
3169 06 Mar 15 nicklas 729     var frm = document.forms['reggie'];
3169 06 Mar 15 nicklas 730     selectedSample.IHCQuality = frm.ihc_quality.value || null;
3169 06 Mar 15 nicklas 731     Doc.element(selectedSample.id+'.progress').innerHTML = Strings.encodeTags(selectedSample.IHC + ': ' + (selectedSample.IHCQuality || '?'));
3169 06 Mar 15 nicklas 732     histology.setSampleClassName(selectedSample);
3169 06 Mar 15 nicklas 733     histology.saveToLocalStorage(selectedSample);
3169 06 Mar 15 nicklas 734   }
2832 20 Oct 14 nicklas 735
3367 05 Jun 15 nicklas 736   // Open a popup with the full image
3367 05 Jun 15 nicklas 737   histology.imageOnClick = function()
3367 05 Jun 15 nicklas 738   {
3367 05 Jun 15 nicklas 739     var img = Doc.element('he-image');
6055 13 Nov 20 nicklas 740     var fileId = Data.int(img, 'file-id', 0);
6055 13 Nov 20 nicklas 741     if (fileId && fileId > 0)
3368 08 Jun 15 nicklas 742     {
6055 13 Nov 20 nicklas 743       Files.viewFile(fileId);
6055 13 Nov 20 nicklas 744     }
6055 13 Nov 20 nicklas 745     else if (img.src)
6055 13 Nov 20 nicklas 746     {
3369 08 Jun 15 nicklas 747       var options = 'toolbar=no,location=no,directories=no,status=no,menubar=no,scrollbars=yes,resizable=yes';
3369 08 Jun 15 nicklas 748       if (img.naturalHeight && img.naturalWidth)
3369 08 Jun 15 nicklas 749       {
3369 08 Jun 15 nicklas 750         options += ',width='+(img.naturalWidth+20)+',height='+(img.naturalHeight+20);
3369 08 Jun 15 nicklas 751       }
6055 13 Nov 20 nicklas 752       window.open(img.fullSrc || img.src, 'Image'+selectedSample.name, options);
3368 08 Jun 15 nicklas 753     }
3367 05 Jun 15 nicklas 754   }
3367 05 Jun 15 nicklas 755   
3369 08 Jun 15 nicklas 756   histology.selectFile = function()
3369 08 Jun 15 nicklas 757   {
3369 08 Jun 15 nicklas 758     Doc.element('selectFile').click();
3369 08 Jun 15 nicklas 759   }
3369 08 Jun 15 nicklas 760   
3369 08 Jun 15 nicklas 761   histology.fileSelected = function()
3369 08 Jun 15 nicklas 762   {
3369 08 Jun 15 nicklas 763     var files = Doc.element('selectFile').files;
3369 08 Jun 15 nicklas 764     if (files.length > 0)
3369 08 Jun 15 nicklas 765     {
3369 08 Jun 15 nicklas 766       // The file to upload
3369 08 Jun 15 nicklas 767       histology.uploadFile(files[0]);
3369 08 Jun 15 nicklas 768     }
3369 08 Jun 15 nicklas 769   }
3369 08 Jun 15 nicklas 770   
3367 05 Jun 15 nicklas 771   // Visual feedback when drop target zone is entered
6824 30 Aug 22 nicklas 772   histology.onDragEnter = function()
3367 05 Jun 15 nicklas 773   {
3367 05 Jun 15 nicklas 774     Doc.addClass('he-image-container', 'dragging');
3367 05 Jun 15 nicklas 775     Doc.hide('file-error');
3367 05 Jun 15 nicklas 776   }
3367 05 Jun 15 nicklas 777   
3367 05 Jun 15 nicklas 778   // Visual feedback when leaving drop target zone
6824 30 Aug 22 nicklas 779   histology.onDragLeave = function()
3367 05 Jun 15 nicklas 780   {
3367 05 Jun 15 nicklas 781     Doc.removeClass('he-image-container', 'dragging');
3367 05 Jun 15 nicklas 782   }
3367 05 Jun 15 nicklas 783
3367 05 Jun 15 nicklas 784   // Need to prevent default event to stop browser from loading the dropped file
3367 05 Jun 15 nicklas 785   histology.onDragOver = function(event)
3367 05 Jun 15 nicklas 786   {
3367 05 Jun 15 nicklas 787     event.preventDefault();
3367 05 Jun 15 nicklas 788   }
3367 05 Jun 15 nicklas 789
3367 05 Jun 15 nicklas 790   // A file has been dropped
3367 05 Jun 15 nicklas 791   histology.onDropFile = function(event)
3367 05 Jun 15 nicklas 792   {
3367 05 Jun 15 nicklas 793     event.preventDefault();
3367 05 Jun 15 nicklas 794     Doc.removeClass('he-image-container', 'dragging');
3367 05 Jun 15 nicklas 795     var files = event.dataTransfer.files;
3367 05 Jun 15 nicklas 796     if (files.length > 0)
3367 05 Jun 15 nicklas 797     {
3368 08 Jun 15 nicklas 798       // The file to upload
3369 08 Jun 15 nicklas 799       histology.uploadFile(files[0]);
3367 05 Jun 15 nicklas 800     }
3367 05 Jun 15 nicklas 801   }
3367 05 Jun 15 nicklas 802   
6016 09 Oct 20 nicklas 803   // Check if paste event contains an image
6016 09 Oct 20 nicklas 804   histology.pasteImage = function(event)
6016 09 Oct 20 nicklas 805   {
6016 09 Oct 20 nicklas 806     var clipboardItems = event.clipboardData.items;
6016 09 Oct 20 nicklas 807     if (!clipboardItems) return;
6016 09 Oct 20 nicklas 808     
6016 09 Oct 20 nicklas 809     for (var i = 0; i < clipboardItems.length; i++)
6016 09 Oct 20 nicklas 810     {
6016 09 Oct 20 nicklas 811       var item = clipboardItems[i];
6016 09 Oct 20 nicklas 812       if (item.type == 'image/png' || item.type == 'image/jpg' || item.type == 'image/tiff')
6016 09 Oct 20 nicklas 813       {
6016 09 Oct 20 nicklas 814         var file = item.getAsFile();
6016 09 Oct 20 nicklas 815         if (file) histology.uploadFile(file);
6016 09 Oct 20 nicklas 816         event.preventDefault();
6016 09 Oct 20 nicklas 817         return;
6016 09 Oct 20 nicklas 818       }
6016 09 Oct 20 nicklas 819     }
6016 09 Oct 20 nicklas 820   }
6016 09 Oct 20 nicklas 821   
3369 08 Jun 15 nicklas 822   histology.uploadFile = function(file)
3369 08 Jun 15 nicklas 823   {
3369 08 Jun 15 nicklas 824     if (selectedSample.image)
3369 08 Jun 15 nicklas 825     {
3369 08 Jun 15 nicklas 826       if (!confirm('Replace the current image with \'' + file.name + '\'?')) return;
3369 08 Jun 15 nicklas 827     }
3369 08 Jun 15 nicklas 828     
3372 09 Jun 15 nicklas 829     if (file.type != 'image/png' && file.type != 'image/jpeg' && file.type != 'image/tiff')
3369 08 Jun 15 nicklas 830     {
3372 09 Jun 15 nicklas 831       histology.showFileUploadError('The file must be a TIF, JPG or PNG file: ' + file.type);
3369 08 Jun 15 nicklas 832       return;
3369 08 Jun 15 nicklas 833     }
3369 08 Jun 15 nicklas 834     
3372 09 Jun 15 nicklas 835     Doc.removeClass('he-image-container', 'has-image');
3372 09 Jun 15 nicklas 836     Doc.addClass('he-image-container', 'uploading');
3372 09 Jun 15 nicklas 837
3369 08 Jun 15 nicklas 838     var url = '../Histology.servlet?ID='+App.getSessionId();
3369 08 Jun 15 nicklas 839     url += '&cmd=UploadImage';
3369 08 Jun 15 nicklas 840     url += '&sampleId='+selectedSample.id;
3369 08 Jun 15 nicklas 841     url += '&filename='+encodeURIComponent(file.name);
3369 08 Jun 15 nicklas 842
3369 08 Jun 15 nicklas 843     var upload = Ajax.getXmlHttpRequest();
3369 08 Jun 15 nicklas 844     upload.open('POST', url, true);
3369 08 Jun 15 nicklas 845     Ajax.setReadyStateHandler(upload, histology.fileLoaded, histology.fileLoaded);
3372 09 Jun 15 nicklas 846     upload.send(file);  
3369 08 Jun 15 nicklas 847   }
3369 08 Jun 15 nicklas 848   
3367 05 Jun 15 nicklas 849   histology.showFileUploadError = function(msg)
3367 05 Jun 15 nicklas 850   {
3367 05 Jun 15 nicklas 851     var errorDiv = Doc.element('file-error');
3367 05 Jun 15 nicklas 852     errorDiv.innerHTML = msg;
3367 05 Jun 15 nicklas 853     Doc.show(errorDiv);
3367 05 Jun 15 nicklas 854   }
3367 05 Jun 15 nicklas 855   
3367 05 Jun 15 nicklas 856   // Display the loaded file in the preview section
3368 08 Jun 15 nicklas 857   histology.fileLoaded = function(request)
3367 05 Jun 15 nicklas 858   {
3372 09 Jun 15 nicklas 859     Doc.removeClass('he-image-container', 'uploading');
3368 08 Jun 15 nicklas 860     response = JSON.parse(request.responseText);
3368 08 Jun 15 nicklas 861     if (response.status != 'ok')
3368 08 Jun 15 nicklas 862     {
3368 08 Jun 15 nicklas 863       histology.showFileUploadError(response.message || response.stacktrace);
3368 08 Jun 15 nicklas 864       return;
3368 08 Jun 15 nicklas 865     }
3368 08 Jun 15 nicklas 866
3368 08 Jun 15 nicklas 867     selectedSample.image = response.image+'?'+(new Date().getTime()); // To avoid problems with caching the old image
3368 08 Jun 15 nicklas 868     Doc.element('he-image').src = App.getRoot() + 'filemanager/files/view/-'+App.getSessionId()+'-' + selectedSample.image;
6055 13 Nov 20 nicklas 869     Data.set('he-image', 'file-id', 0);
3369 08 Jun 15 nicklas 870     Doc.addClass('he-image-container', 'has-image');
6055 13 Nov 20 nicklas 871     Doc.addClass('he-image-container', 'can-delete');
3368 08 Jun 15 nicklas 872     Doc.hide('file-error');
3368 08 Jun 15 nicklas 873     histology.setSampleClassName(selectedSample);
3367 05 Jun 15 nicklas 874   }
3367 05 Jun 15 nicklas 875   
3369 08 Jun 15 nicklas 876   histology.deleteImage = function()
3369 08 Jun 15 nicklas 877   {
3369 08 Jun 15 nicklas 878     if (!confirm('Delete this image?')) return;
3369 08 Jun 15 nicklas 879     
3369 08 Jun 15 nicklas 880     var url = '../Histology.servlet?ID='+App.getSessionId();
3369 08 Jun 15 nicklas 881     url += '&cmd=DeleteImage';
3369 08 Jun 15 nicklas 882     url += '&sampleId='+selectedSample.id;
3369 08 Jun 15 nicklas 883     
3369 08 Jun 15 nicklas 884     var req = Ajax.getXmlHttpRequest();
3369 08 Jun 15 nicklas 885     req.open('POST', url, true);
3369 08 Jun 15 nicklas 886     Ajax.setReadyStateHandler(req, histology.fileDeleted, histology.fileDeleted);
3369 08 Jun 15 nicklas 887     req.send();      
3369 08 Jun 15 nicklas 888   }
3369 08 Jun 15 nicklas 889   
3369 08 Jun 15 nicklas 890   histology.fileDeleted = function(request)
3369 08 Jun 15 nicklas 891   {
3369 08 Jun 15 nicklas 892     response = JSON.parse(request.responseText);
3369 08 Jun 15 nicklas 893     if (response.status != 'ok')
3369 08 Jun 15 nicklas 894     {
3369 08 Jun 15 nicklas 895       histology.showFileUploadError(response.message || response.stacktrace);
3369 08 Jun 15 nicklas 896       return;
3369 08 Jun 15 nicklas 897     }
3369 08 Jun 15 nicklas 898
3369 08 Jun 15 nicklas 899     selectedSample.image = null;
3369 08 Jun 15 nicklas 900     Doc.removeClass('he-image-container', 'has-image');
3369 08 Jun 15 nicklas 901     Doc.hide('file-error');
3369 08 Jun 15 nicklas 902     histology.setSampleClassName(selectedSample);
3369 08 Jun 15 nicklas 903   }
3369 08 Jun 15 nicklas 904   
2832 20 Oct 14 nicklas 905   histology.submit = function()
2832 20 Oct 14 nicklas 906   {
2832 20 Oct 14 nicklas 907     samples = [];
2832 20 Oct 14 nicklas 908     var glassInfo = [];
2832 20 Oct 14 nicklas 909     
2832 20 Oct 14 nicklas 910     for (var glassNo = 0; glassNo < heGlass.length; glassNo++)
2832 20 Oct 14 nicklas 911     {
2832 20 Oct 14 nicklas 912       var glass = heGlass[glassNo];
2832 20 Oct 14 nicklas 913       var scoreCompleteForGlass = true;
2832 20 Oct 14 nicklas 914       for (var sampleNo = 0; sampleNo < glass.samples.length; sampleNo++)
2832 20 Oct 14 nicklas 915       {
2832 20 Oct 14 nicklas 916         var sample = glass.samples[sampleNo];
2832 20 Oct 14 nicklas 917         if (histology.isModified(sample))
2832 20 Oct 14 nicklas 918         {
2832 20 Oct 14 nicklas 919           samples[samples.length] = sample;
2832 20 Oct 14 nicklas 920         }
2832 20 Oct 14 nicklas 921         
3169 06 Mar 15 nicklas 922         if (glass.IHC)
2832 20 Oct 14 nicklas 923         {
3169 06 Mar 15 nicklas 924           if (!sample.IHCQuality) scoreCompleteForGlass = false;
2832 20 Oct 14 nicklas 925         }
3169 06 Mar 15 nicklas 926         else
3169 06 Mar 15 nicklas 927         {
3169 06 Mar 15 nicklas 928           if (sample.GoodStain && sample.ScoreComplete != true || sample.ScoreComplete == false)
3169 06 Mar 15 nicklas 929           {
3169 06 Mar 15 nicklas 930             scoreCompleteForGlass = false;
3169 06 Mar 15 nicklas 931           }
3169 06 Mar 15 nicklas 932         }
2832 20 Oct 14 nicklas 933       }
2832 20 Oct 14 nicklas 934       
2832 20 Oct 14 nicklas 935       var tmp = {};
2832 20 Oct 14 nicklas 936       tmp.id = glass.id;
2832 20 Oct 14 nicklas 937       tmp.ScoreComplete = scoreCompleteForGlass;
2832 20 Oct 14 nicklas 938       glassInfo[glassInfo.length] = tmp;
2832 20 Oct 14 nicklas 939     }
2832 20 Oct 14 nicklas 940     
2832 20 Oct 14 nicklas 941     if (samples.length == 0)
2832 20 Oct 14 nicklas 942     {
2832 20 Oct 14 nicklas 943       if (!confirm('Nothing has changed! Continue saving?'))
2832 20 Oct 14 nicklas 944       {
2832 20 Oct 14 nicklas 945         return;
2832 20 Oct 14 nicklas 946       }
2832 20 Oct 14 nicklas 947     }
2832 20 Oct 14 nicklas 948     
2832 20 Oct 14 nicklas 949     Doc.hide('score-container');
2832 20 Oct 14 nicklas 950     Doc.addClass('he-glass-container', 'disabled');
2832 20 Oct 14 nicklas 951       
2832 20 Oct 14 nicklas 952     var submitInfo = {};
2832 20 Oct 14 nicklas 953     submitInfo.samples = samples;
2832 20 Oct 14 nicklas 954     submitInfo.heGlass = glassInfo;
2832 20 Oct 14 nicklas 955     
2832 20 Oct 14 nicklas 956     var url = '../Histology.servlet?ID='+App.getSessionId();
2832 20 Oct 14 nicklas 957     url += '&cmd=SaveHeScore';
2832 20 Oct 14 nicklas 958     Wizard.showLoadingAnimation('Saving...');
2832 20 Oct 14 nicklas 959     Wizard.asyncJsonRequest(url, histology.submissionResults, 'POST', JSON.stringify(submitInfo));
2832 20 Oct 14 nicklas 960   }
2832 20 Oct 14 nicklas 961   
2832 20 Oct 14 nicklas 962   histology.submissionResults = function(response)
2832 20 Oct 14 nicklas 963   {
2832 20 Oct 14 nicklas 964     // Reset changed properties and remove saved info
2832 20 Oct 14 nicklas 965     for (var sampleNo = 0; sampleNo < samples.length; sampleNo++)
2832 20 Oct 14 nicklas 966     {
2832 20 Oct 14 nicklas 967       var sample = samples[sampleNo];
2832 20 Oct 14 nicklas 968       histology.saveOriginalProperties(sample);
2832 20 Oct 14 nicklas 969       histology.setSampleClassName(sample);
2832 20 Oct 14 nicklas 970       histology.removeFromLocalStorage(sample);
2832 20 Oct 14 nicklas 971     }
2832 20 Oct 14 nicklas 972     
2832 20 Oct 14 nicklas 973     disableModificationCheck = true;
2832 20 Oct 14 nicklas 974     Wizard.showFinalMessage(response.messages);
2832 20 Oct 14 nicklas 975     Doc.show('gonext');
2832 20 Oct 14 nicklas 976   }
2832 20 Oct 14 nicklas 977
2832 20 Oct 14 nicklas 978   
2832 20 Oct 14 nicklas 979   /**
2832 20 Oct 14 nicklas 980     Confirm if leaving the page is ok. If no event is passed this method
2832 20 Oct 14 nicklas 981     is called manually and need to display dialog, otherwise the browser
2832 20 Oct 14 nicklas 982     is taking care of this automatically.
2832 20 Oct 14 nicklas 983   */
2832 20 Oct 14 nicklas 984   histology.confirmLeaveWizard = function(event)
2832 20 Oct 14 nicklas 985   {
2832 20 Oct 14 nicklas 986     if (disableModificationCheck) return;
2832 20 Oct 14 nicklas 987     
2832 20 Oct 14 nicklas 988     var numModified = 0;
2832 20 Oct 14 nicklas 989     for (var glassNo = 0; glassNo < heGlass.length; glassNo++)
2832 20 Oct 14 nicklas 990     {
2832 20 Oct 14 nicklas 991       var glass = heGlass[glassNo];
2832 20 Oct 14 nicklas 992       for (var sampleNo = 0; sampleNo < glass.samples.length; sampleNo++)
2832 20 Oct 14 nicklas 993       {
2832 20 Oct 14 nicklas 994         var sample = glass.samples[sampleNo];
2832 20 Oct 14 nicklas 995         if (histology.isModified(sample))
2832 20 Oct 14 nicklas 996         {
2832 20 Oct 14 nicklas 997           numModified++;
2832 20 Oct 14 nicklas 998         }
2832 20 Oct 14 nicklas 999       }
2832 20 Oct 14 nicklas 1000     }
2832 20 Oct 14 nicklas 1001     
2832 20 Oct 14 nicklas 1002     if (event) 
2832 20 Oct 14 nicklas 1003     {
2832 20 Oct 14 nicklas 1004       if (numModified > 0) event.preventDefault();
2832 20 Oct 14 nicklas 1005     }
2832 20 Oct 14 nicklas 1006     else
2832 20 Oct 14 nicklas 1007     {
2832 20 Oct 14 nicklas 1008       if (numModified > 0)
2832 20 Oct 14 nicklas 1009       {
2832 20 Oct 14 nicklas 1010         return confirm('There are unsaved modifications. Continue?');
2832 20 Oct 14 nicklas 1011       }
2832 20 Oct 14 nicklas 1012       return true;
2832 20 Oct 14 nicklas 1013     }
2832 20 Oct 14 nicklas 1014   }
2832 20 Oct 14 nicklas 1015
2832 20 Oct 14 nicklas 1016   
2832 20 Oct 14 nicklas 1017   /**
2832 20 Oct 14 nicklas 1018     Save score information to the local storage.
2832 20 Oct 14 nicklas 1019   */
2832 20 Oct 14 nicklas 1020   histology.saveToLocalStorage = function(sample)
2832 20 Oct 14 nicklas 1021   {
2832 20 Oct 14 nicklas 1022     if (histology.isModified(sample, true))
2832 20 Oct 14 nicklas 1023     {
2832 20 Oct 14 nicklas 1024       var storeKey = histology.getStoreKey(sample);
2832 20 Oct 14 nicklas 1025       App.setLocal(storeKey, JSON.stringify(sample));
2832 20 Oct 14 nicklas 1026       if (debug)
2832 20 Oct 14 nicklas 1027       {
2832 20 Oct 14 nicklas 1028         App.debug('saveToLocalStorage: ' + sample.name + '=' + App.getLocal(storeKey));
2832 20 Oct 14 nicklas 1029       }
2832 20 Oct 14 nicklas 1030     }
2832 20 Oct 14 nicklas 1031   }
2832 20 Oct 14 nicklas 1032   
2832 20 Oct 14 nicklas 1033   histology.removeFromLocalStorage = function(sample)
2832 20 Oct 14 nicklas 1034   {
2832 20 Oct 14 nicklas 1035     if (debug) App.debug('removeFromLocalStorage:' + sample.name);
2832 20 Oct 14 nicklas 1036     App.removeLocal(histology.getStoreKey(sample));
2832 20 Oct 14 nicklas 1037   }
2832 20 Oct 14 nicklas 1038   
2832 20 Oct 14 nicklas 1039   histology.restoreFromLocalStorage = function(sample)
2832 20 Oct 14 nicklas 1040   {
2832 20 Oct 14 nicklas 1041     try
2832 20 Oct 14 nicklas 1042     {
2832 20 Oct 14 nicklas 1043       var storeKey = histology.getStoreKey(sample);
2832 20 Oct 14 nicklas 1044       var stored = App.getLocal(storeKey);
2832 20 Oct 14 nicklas 1045       if (debug) App.debug(stored);
2832 20 Oct 14 nicklas 1046       if (!stored) return;
2832 20 Oct 14 nicklas 1047       
2832 20 Oct 14 nicklas 1048       var tmp = JSON.parse(stored);
2832 20 Oct 14 nicklas 1049       if (!tmp) return;
2832 20 Oct 14 nicklas 1050
2832 20 Oct 14 nicklas 1051       // Check that all original scores are the same, or someone has modified
2832 20 Oct 14 nicklas 1052       // this sample from another computer
2832 20 Oct 14 nicklas 1053       for (var p in sample.o)
2832 20 Oct 14 nicklas 1054       {
2832 20 Oct 14 nicklas 1055         if (sample.o[p] != tmp.o[p])
2832 20 Oct 14 nicklas 1056         {
2832 20 Oct 14 nicklas 1057           return;
2832 20 Oct 14 nicklas 1058         }
2832 20 Oct 14 nicklas 1059       }
2832 20 Oct 14 nicklas 1060       
2832 20 Oct 14 nicklas 1061       // Ok, copy stored info to the current sample
2832 20 Oct 14 nicklas 1062       for (var i = 0; i < SCORES.length; i++)
2832 20 Oct 14 nicklas 1063       {
2832 20 Oct 14 nicklas 1064         sample[SCORES[i]] = tmp[SCORES[i]];
2832 20 Oct 14 nicklas 1065       }
2832 20 Oct 14 nicklas 1066       sample.ScoreComplete = tmp.ScoreComplete;
2832 20 Oct 14 nicklas 1067       sample.GoodStain = tmp.GoodStain;
2832 20 Oct 14 nicklas 1068       sample.comments = tmp.comments;
3169 06 Mar 15 nicklas 1069       sample.IHCQuality = tmp.IHCQuality;
2832 20 Oct 14 nicklas 1070     }
2832 20 Oct 14 nicklas 1071     catch (e)
2832 20 Oct 14 nicklas 1072     {
2832 20 Oct 14 nicklas 1073       App.debug('Could not load stored information for sample ' + sample.name + ': ' + e);
2832 20 Oct 14 nicklas 1074     }
2832 20 Oct 14 nicklas 1075   }
2832 20 Oct 14 nicklas 1076   
2832 20 Oct 14 nicklas 1077   histology.getStoreKey = function(sample)
2832 20 Oct 14 nicklas 1078   {
2832 20 Oct 14 nicklas 1079     return 'reggie.histology.' + sample.id + '.scoreInfo';
2832 20 Oct 14 nicklas 1080   }
2832 20 Oct 14 nicklas 1081
2832 20 Oct 14 nicklas 1082   return histology;
2832 20 Oct 14 nicklas 1083 }();
2832 20 Oct 14 nicklas 1084
2832 20 Oct 14 nicklas 1085 Doc.onLoad(Histology.initPage);
2832 20 Oct 14 nicklas 1086