otsdaq_utilities  v2_05_02_indev
DesktopIcons.js
1 //=====================================================================================
2 //
3 // Created Mar, 2013
4 // by Ryan Rivera ((rrivera at fnal.gov))
5 //
6 // DesktopIcons.js
7 //
8 // This is the desktop code for the user interface for ots. ots is the DAQ
9 // and control software for the Fermi Strips Telescope.
10 //
11 // The desktop consists of icons to launch windows
12 //
13 //=====================================================================================
14 
15 
16 if (typeof Debug == 'undefined')
17  alert('ERROR: Debug is undefined! Must include Debug.js before DesktopIcons.js');
18 
19 if (typeof SimpleContextMenu == 'undefined')
20  Debug.log('ERROR: SimpleContextMenu is undefined! Must include SimpleContextMenu.js before DesktopIcons.js',Debug.HIGH_PRIORITY);
21 if (typeof MultiSelectBox == 'undefined') //used for folders
22  Debug.log('ERROR: MultiSelectBox is undefined! Must include MultiSelectBox.js before DesktopIcons.js',Debug.HIGH_PRIORITY);
23 if (typeof DesktopContent == 'undefined') //used for getting solid window color for folders
24  Debug.log('ERROR: DesktopContent is undefined! Must include DesktopContent.js before DesktopIcons.js',Debug.HIGH_PRIORITY);
25 
26 
27 if (typeof Desktop == 'undefined')
28  Debug.log('ERROR: Desktop is undefined! Must include Desktop.js before DesktopIcons.js',Debug.HIGH_PRIORITY);
29 else {
30 
31 
34  //define Desktop.createIcons to return dashboard class
37  Desktop.createIcons = function(userPermissions, z) {
38  if(false === (this instanceof Desktop.createIcons)) {
39  //here to correct if called as "var v = Desktop.createIcons();"
40  // instead of "var v = new Desktop.createIcons();"
41  return new Desktop.createIcons(userPermissions, z);
42  }
43 
44 
45  //------------------------------------------------------------------
46  //create private members variables ----------------------
47  //------------------------------------------------------------------
48 
49  //all units in pixels unless otherwise specified
50 
51  var _defaultIconsMargin = 50; //margin to desktop border for all icons
52  var _defaultIconWidth = 64;
53  var _defaultIconHeight = 64;
54  var _defaultIconTextWidth = 90;
55  var _defaultIconTextHeight = 24;
56  var _permissions = 0;
57 
58  var _iconsElement;
59 
60  var _numOfIcons = 0;
61 
62  var _deepClickTimer = 0;
63 
64  var _folders = [{},[]]; // a folder is a an Object of subfolders and an array of icons
65  // It has an array of icon objects (in case icon names are not unique,
66  // the array index makes them unique).
67  // Subfolder names must be unique.
68  var _openFolderPtr; // always points to the currently open folder within the _folders object
69  // so that subfolders can easily navigate
70  var _openFolderPath = "";
71  var _openFolderElement;
72 
73  var _iconNameToPathMap = {/* "name": [path,unique] */}; //used to open icons programatically
74 
75 
76  //------------------------------------------------------------------
77  //create public members variables ----------------------
78  //------------------------------------------------------------------
79  this.iconsElement;
80  this.folders = _folders;
81  this.deepClickTimer = _deepClickTimer;
82  this.iconNameToPathMap = _iconNameToPathMap;
83 
84 
85  //------------------------------------------------------------------
86  //create PRIVATE members functions ----------------------
87  //------------------------------------------------------------------
88 
89  var _redrawIcons = function() {
90 
91  _iconsElement.style.left = Desktop.desktop.getDesktopContentX()+_defaultIconsMargin+"px";
92  _iconsElement.style.top = Desktop.desktop.getDesktopContentY()+_defaultIconsMargin+"px";
93  _iconsElement.style.width = Desktop.desktop.getDesktopContentWidth()-_defaultIconsMargin-_defaultIconsMargin+"px";
94  _iconsElement.style.height = Desktop.desktop.getDesktopContentHeight()-_defaultIconsMargin-_defaultIconsMargin+"px";
95 
96  }
97 
98  //------------------------------------------------------------------
99  //create PUBLIC members functions ----------------------
100  //------------------------------------------------------------------
101 
102  this.redrawIcons = _redrawIcons;
103 
104  //=====================================================================================
105  // this.resetWithPermissions ~~
106  this.resetWithPermissions = function(permissions, keepSamePermissions)
107  {
108  Debug.log("Desktop resetWithPermissions " + permissions +
109  ", " + keepSamePermissions,Debug.LOW_PRIORITY);
110 
111  if(permissions === undefined && !keepSamePermissions)
112  return;
113  else if(!keepSamePermissions)
114  _permissions = permissions;
116 
117 
118  if(!Desktop.isWizardMode())
119  { //This is satisfied for Digest Access Authorization and No Security on OTS
120  Desktop.XMLHttpRequest("Request?RequestType=getDesktopIcons", "",
121  iconRequestHandler);
122  return;
123  }
124  else //it is the sequence for OtsWizardConfiguration
125  {
126  Debug.log("OtsWizardConfiguration");
127  Desktop.XMLHttpRequest("requestIcons", "sequence=" +
128  Desktop.desktop.security, iconRequestHandler);
129  if(!_permissions) _permissions = 1;
130  return;
131  }
132 
133  } //end resetWithPermissions()
134 
135  //=====================================================================================
136  //_iconRequestHandler
137  //adds the icons from the hardcoded, C++ in OtsConfigurationWizard
138  var iconRequestHandler = function(req)
139  {
140 
141  //clear folder object
142  Desktop.desktop.icons.folders = [{},[]];
143  Desktop.desktop.icons.iconNameToPathMap = {} ; //clear map
144 
145  _iconsElement.innerHTML = ""; //clear existing icons
146  _numOfIcons = 0;
147 
148  var iconArray;
149 
150  if(!Desktop.isWizardMode())
151  { //This is satisfied for Digest Access Authorization and No Security on OTS
152 
153  var err;
154  if((err = Desktop.getXMLValue(req,"Error")) && err != "")
155  {
156  Debug.log("Error: " + err, Debug.HIGH_PRIORITY);
157  return;
158  }
159 
160  iconArray = Desktop.getXMLValue(req,"iconList");
161  //Debug.log("icon Array unsplit: " + iconArray);
162 
163  if(iconArray)
164  iconArray = iconArray.split(",");
165  else
166  iconArray = [];
167  }
168  else //it is the wizard
169  {
170  iconArray = req.responseText.split(",");
171  }
172 
173  Debug.log("icon Array split: " + iconArray);
174  //Debug.log(_permissions);
175 
176  //an icon is 7 fields.. give comma-separated
177  //0 - subtext = text below icon
178  //1 - altText = text icon if no image given
179  //2 - uniqueWin = if true, only one window is allowed, else multiple instances of window
180  //3 - permissions = security level needed to see icon
181  //4 - picfn = icon image filename
182  //5 - linkurl = url of the window to open
183  //6 - folderPath = folder and subfolder location '/' separated
184 
185  // //debugging
186  // var depth = 10;
187  // var breadth = 20;
188  // var folder = "";
189  // for(var i=0;i<depth;++i)
190  // {
191  // folder += "/folder-" +i;
192  // for(var j=0;j<breadth;++j)
193  // Desktop.desktop.icons.addIcon("title-"+i + "-"+j,
194  // "alt",
195  // iconArray[j%4*7+5],
196  // 1,
197  // "0",//iconArray[j%4*7+4],
198  // folder);
199  // }
200  // Desktop.desktop.icons.openFolder(100,100,"folder-0");
201  // return;
202 
203 
204 
205  var numberOfIconFields = 7;
206  for(var i=0;i<(iconArray.length);i+=numberOfIconFields) //add icons
207  {
208  if(_permissions >= iconArray[i+3])
209  Desktop.desktop.icons.addIcon(iconArray[i],iconArray[i+1],iconArray[i+5],iconArray[i+2]|0,iconArray[i+4],iconArray[i+6]);
210  }
211 
212 
213  }
214 
215  //=====================================================================================
216  // this.addIcon ~~
217  // adds an icon subtext wording underneath and image icon (if picfn defined, else alt text icon)
218  this.addIcon = function(subtext, altText, linkurl, uniqueWin, picfn, folderPath)
219  {
220 
221  //Debug.log("this.addIcon");
222 
223  //same as in DesktopContent.openNewBrowserTab
224  //for linkurl, need to check lid=## is terminated with /
225  // check from = that there is nothing but numbers
226  try
227  {
228  var i = linkurl.indexOf("urn:xdaq-application:lid=") + ("urn:xdaq-application:lid=").length;
229  var isAllNumbers = true;
230  for(i;i<linkurl.length;++i)
231  {
232  //Debug.log(linkurl[i]);
233 
234  if(linkurl[i] < "0" || linkurl[i] > "9")
235  {
236  isAllNumbers = false;
237  break;
238  }
239  }
240  if(isAllNumbers)
241  linkurl += "/";
242  }
243  catch(e)
244  {
245  Debug.log("An error occurred while trying to parse the window url. " +
246  "The window path seems to be invalid: " + e, Debug.HIGH_PRIORITY);
247  return;
248  }
249 
250  this.iconNameToPathMap[subtext] = [linkurl,uniqueWin];
251 
252  var iconContainer = document.createElement("div");
253  iconContainer.setAttribute("class", "DesktopIcons-iconContainer");
254 
255  var link;
256  var div;
257 
258 
259  //if folder path is non-empty,
260  // create the full folder structure in the _folders object
261  // and show the top level folder icon (if new to _folders object)
262  //else
263  // just show icon
264 
265  var folderSplit = folderPath.split('/'); //root folder is first non empty index
266  var rootFolderIndex;
267  var folderPtr;
268  var folders = this.folders;
269  for(var i=0;i<folderSplit.length;++i)
270  {
271  if(folderSplit[i] == "") continue;
272 
273  if(folderPtr === undefined)
274  folderPtr = folders; //init to root folder first time
275 
276  //check if folder exists (this is root or subfolder level)
277  if(folderPtr[0][folderSplit[i]] === undefined)
278  {
279  //need to create folder object
280  folderPtr[0][folderSplit[i]] = [{},[]]; // a folder is a an Object of subfolders and an array of icons
281 
282  if(folderPtr == folders &&
283  rootFolderIndex === undefined) //found new root icon
284  rootFolderIndex = folderSplit[i]; //need to display icon on desktop
285  }
286 
287  folderPtr = folderPtr[0][folderSplit[i]];
288  }
289 
290  //if folderPath, add icon to structure at folderPtr
291  if(folderPtr !== undefined)
292  {
293  Debug.log("folderPtr.length = " + folderPtr.length);
294 
295  //push new icon object
296  folderPtr[1].push([subtext, altText, linkurl, uniqueWin, picfn]);
297  console.log(folders);
298 
299  //check if this is first icon encountered in this root folder
300  // if so, need to display on desktop
301  if(rootFolderIndex !== undefined)
302  {
303  //there is a new folder to be displayed on desktop
304  Debug.log("folderPath = " + folderPath);
305  Debug.log("rootFolderIndex = " + rootFolderIndex);
306 
307  //add the folder icon to desktop
308  subtext = rootFolderIndex;
309  altText = "F";
310  linkurl = "folder";
311  uniqueWin = 1;
312  picfn = "icon-Folder.png";
313  }
314  else //this icon is in a folder, and the root folder is already displayed
315  return;
316  }
317 
318 
319 
320  //var jsCmd = "Javascript:var newWin = Desktop.desktop.addWindow(\""+ subtext + "\",\"" + ""
321  // + "\",\"" + linkurl + "\","+uniqueWin+");";
322 
323  //create icon square
324  link = document.createElement("a");
325  link.setAttribute("class", "DesktopIcons-iconLink");
326  link.title = subtext;
327  //link.href = "#";//jsCmd;
328 
329  if(linkurl == "folder")
330  {
331  var iconsObj = this;
332  link.addEventListener("click", function(e) {
333  iconsObj.openFolder(
334  e.clientX-this.parentNode.parentNode.offsetLeft,
335  e.clientY-this.parentNode.parentNode.offsetTop,
336  subtext);
337  }, false);
338  }
339  else
340  {
341  link.addEventListener("click", function(e) {
342  Desktop.desktop.addWindow(subtext,"",linkurl,uniqueWin);
343  }, false);
344  }
345 
346  div = document.createElement("div");
347  div.setAttribute("class", "DesktopIcons-iconDiv");
348  div.style.width = _defaultIconWidth + "px";
349  div.style.height = _defaultIconHeight + "px";
350  div.style.marginLeft = (_defaultIconTextWidth-_defaultIconWidth-2)/2 + "px"; //extra 2 for border
351 
352  //define icon content
353  if(picfn != "0" && picfn != "DEFAULT" && picfn != "")
354  { //if icon image
355  if(picfn[0] != '/')
356  div.style.backgroundImage = "url(/WebPath/images/iconImages/" + picfn+")";
357  else
358  div.style.backgroundImage = "url(" + picfn+")";
359 
360  var div2 = document.createElement("div");
361  div2.setAttribute("class", "DesktopIcons-iconDiv");
362  div2.style.width = _defaultIconWidth + "px";
363  div2.style.height = _defaultIconHeight + "px";
364  div2.style.marginLeft = (-1) + "px"; //put effect over top of background image and line up with border
365  div2.style.marginTop = (-1) + "px";
366  div.appendChild(div2);
367  }
368  else { //if text only icon, gets effect from .css
369  div.innerHTML = "<table width='100%' height='100%'><td width='100%' height='100%' valign='middle' align='center'>"+
370  altText+"</td></table>";
371  }
372 
373  link.appendChild(div);
374  iconContainer.appendChild(link); //add square to icon container
375 
376  //create icon sub text
377  link = document.createElement("a");
378  link.setAttribute("class", "DesktopIcons-iconLink");
379  link.title = subtext;
380  //link.href = "#";////link.href = jsCmd;
381  if(linkurl == "folder")
382  {
383  var iconsObj = this;
384  link.addEventListener("click", function(e) {
385  iconsObj.openFolder(
386  e.clientX-this.parentNode.parentNode.offsetLeft,
387  e.clientY-this.parentNode.parentNode.offsetTop,
388  subtext);
389  }, false);
390  }
391  else
392  {
393  link.addEventListener("click", function(e) {
394  Desktop.desktop.addWindow(subtext,"",linkurl,uniqueWin);
395  }, false);
396  }
397 
398 
399  div = document.createElement("div");
400  div.setAttribute("class", "DesktopIcons-iconSubText");
401  div.style.width = _defaultIconTextWidth + "px";
402  div.style.height = _defaultIconTextHeight + "px";
403  div.innerHTML = subtext;
404 
405  link.appendChild(div);
406  iconContainer.appendChild(link); //add subtext to icon container
407 
408  if(linkurl != "folder") //if not folder, add context click menu handlers
409  {
410  //add context click menu handlers
411  // mouseup and contextMenu to stop default right-click behavior
412  // and mousedown to start the menu (so "deep clicks" work)
413  iconContainer.addEventListener("mouseup", function(event) {
414  if(_deepClickTimer)
415  {
416  window.clearTimeout(_deepClickTimer);
417  _deepClickTimer = 0;
418  }
419  }); //end onmouseup event
420 
421  var deepClickHandler = function(event) {
422  event.cancelBubble = true; //prevent default behavior
423  event.preventDefault();
424  _deepClickTimer = window.setTimeout(function() {
425 
426  Debug.log("Create Icon Menu");
427  var menuItems = [
428  "Open and Maximize Window",
429  "Open in New Browser Tab",
430  "Open and Tile All Windows"
431  ];
432  var menuItemHandlers = [
433  "Desktop.desktop.addWindow(\""+ subtext + "\",\"" + ""
434  + "\",\"" + linkurl + "\","+uniqueWin+",2);", // 2 for maximize
435  "Desktop.openNewBrowserTab(\""+ subtext + "\",\"" + ""
436  + "\",\"" + linkurl + "\","+uniqueWin+");", // 2 for maximize
437  "Desktop.desktop.addWindow(\""+ subtext + "\",\"" + ""
438  + "\",\"" + linkurl + "\","+uniqueWin+",1);", // 1 for tile
439  ];
440  Debug.log("createEditTableMenu()");
441  SimpleContextMenu.createMenu(
442  menuItems,
443  menuItemHandlers,
444  "DesktopIconContextMenu", //element ID
445  event.pageX-1,event.pageY-1, //top left position
446  Desktop.desktop.dashboard.getDefaultDashboardColor(), //primary color
447  "white" //secondary color
448  );
449 
450  },500); //end timeout handler
451 
452  }; //end deepClickHandler event
453 
454  //FIXME ... debug touchstart on android to block browser context
455  // iconContainer.addEventListener("touchstart", function(event) {
456  // event.preventDefault();
457  //
458  // deepClickHandler(event);
459  // return false;
460  // });
461  iconContainer.addEventListener("mousedown", deepClickHandler);
462  }
463 
464  _iconsElement.appendChild(iconContainer); //add to desktop icon element
465 
466  ++_numOfIcons; //maintain icon count
467 
468  //reset icon arrangement based on _numOfIcons
469  if(_numOfIcons > 1)
470  {
471  { //get rid of all clearDivs
472  var cdArr;
473  while((cdArr = _iconsElement.getElementsByClassName("iconsClearDiv")) &&
474  cdArr.length)
475  cdArr[0].parentNode.removeChild(cdArr[0]);
476  }
477 
478  var newLine = Math.ceil((-1 + Math.sqrt(_numOfIcons*8+1))/2);
479  var newLineOff = newLine;
480 
481  var currChild = _iconsElement.childNodes[0];
482  for(var i=0;i<_numOfIcons;++i) {
483  if(i == newLine) { //add new line before currChild
484  div = document.createElement("div");
485  div.setAttribute("id", "clearDiv");
486  div.setAttribute("class", "iconsClearDiv");
487  _iconsElement.insertBefore(div,currChild);
488  newLine += --newLineOff; //update new line index
489  }
490  currChild = currChild.nextSibling; //get next child
491  }
492  }
493  } //end this.addIcon()
494 
495  //=====================================================================================
496  //this.openFolder ~~
497  // this version is called from desktop icons
498  // it opens up the div content at a position
499  // while openSubFolder is called by subfolder icons
500  // it navigates to the next level folder
501  // after the div is displayed openFolder makes use of openSubFolder.
502  this.openFolder = function(x,y,folderName) {
503 
504  this.closeFolder(); //close any open folders
505 
506  var div = document.createElement("div");
507  div.setAttribute("class", "DesktopIcons-folderDiv");
508  div.style.padding = "0 5px 5px 12px";
509  div.style.backgroundColor = DesktopContent.getDefaultWindowColor();//Desktop.desktop.defaultWindowFrameColor;
510  div.style.position = "absolute";
511  div.style.width = (300) + "px";
512  div.style.left = (x) + "px";
513  div.style.top = (y) + "px";
514  //each mouse up events.. because mouseup on desktop closes folder
515  div.onmouseup = function(event) {event.stopPropagation();};
516  this.iconsElement.appendChild(div);
517  _openFolderElement = div;
518 
519  div = document.createElement("div");
520  //div.style.width = 300 + "px";
521  div.style.height = 250 + "px";
522  div.style.position = "relative";
523  _openFolderElement.appendChild(div);
524  _openFolderElement = div;
525 
526  this.openSubFolder(folderName);
527  }
528 
529  //=====================================================================================
530  //this.openSubFolder ~~
531  // folderArray is a list of folder and icon objects
532  this.openSubFolder = function(folderName) {
533 
534  //handle dot dots "../" to go back in path
535  // manipulate _openFolderPath, _openFolderPtr, and folderName
536 
537  if(folderName.indexOf("../") >= 0)
538  {
539  var folderSplit = _openFolderPath.split('/');
540  var fullDepth = 0;
541  //get depth
542  for(var i=0;i<folderSplit.length;++i)
543  if(folderSplit[i] != "") ++fullDepth;
544  var backPathCount = 1;
545  while(folderName.indexOf("../",backPathCount*3) >= 0) ++backPathCount;
546 
547  Debug.log("fullDepth " + fullDepth);
548  Debug.log("backPathCount " + backPathCount);
549 
550  fullDepth -= backPathCount; //new depth
551  _openFolderPtr = this.folders; //reset folder Ptr
552  _openFolderPath = "/"; //reset folder path
553  //repurpose backPathCount to count aggregate depth
554  for(var i=0,backPathCount=0;backPathCount<fullDepth && i<folderSplit.length;++i)
555  if(folderSplit[i] != "")
556  {
557  _openFolderPtr = _openFolderPtr[0][folderSplit[i]];
558  _openFolderPath += folderSplit[i] + "/";
559  ++backPathCount;
560  }
561 
562  Debug.log("_openFolderPath " + _openFolderPath);
563  Debug.log("folderName " + folderName);
564  }
565  else if(folderName != ".") //normal subfolder handling (if not "stay here")
566  {
567  _openFolderPath += "/" + folderName;
568  if(_openFolderPtr)
569  _openFolderPtr = _openFolderPtr[0][folderName];
570  else
571  _openFolderPtr = this.folders[0][folderName];
572  }
573 
574  Debug.log("_openFolderPath = " + _openFolderPath);
575  console.log(_openFolderPtr);
576 
577  if(!_openFolderPtr) {Debug.log("Should never happen??!"); return;}//throw("What");
578  //if(!_openFolderPtr) this.resetWithPermissions = function(_permissions);
579 
580  var noMultiSelect = true; // true or false (false for multiselect functionality)
581  var maintainPreviousSelections = false; //true or false (true means redraw select box using the js array selects left over from the last time this box was drawn using the same element id)
582 
583 
584  var vals = [];//["One little piggy","two little piggies","three little piggies","one","two","three"];
585  var keys = [];//["one","two","three","one","two","three"];
586  var types = [];//["number","numbers","numbers","one","two","three"];
587  var imgURLs = [];
588 
589 
590  //show folders first, then icons
591 
592  //subfolders
593  var subfolders = Object.keys(_openFolderPtr[0]);
594  for(var i=0;i<subfolders.length;++i)
595  {
596  vals.push(subfolders[i]);
597  types.push("folder");
598  keys.push(i);
599 
600  imgURLs.push("/WebPath/images/iconImages/" +
601  "icon-Folder.png");
602  }
603  //then icons
604  //Icon object array (0-subtext, 1-altText, 2-linkurl, 3-uniqueWin, 4-picfn)
605  for(var i=0;i<_openFolderPtr[1].length;++i)
606  {
607  vals.push(_openFolderPtr[1][i][0]);
608  types.push("icon");
609  keys.push(i);
610 
611  if(_openFolderPtr[1][i][4] != "0" &&
612  _openFolderPtr[1][i][4] != "DEFAULT" &&
613  _openFolderPtr[1][i][4] != "") //if icon image
614  {
615 
616  if(_openFolderPtr[1][i][4][0] != '/')
617  imgURLs.push("/WebPath/images/iconImages/" +
618  _openFolderPtr[1][i][4]);
619  else
620  imgURLs.push(_openFolderPtr[1][i][4]);
621  }
622  else
623  imgURLs.push("=" + _openFolderPtr[1][i][1]);
624  }
625 
626  //make link title
627  var str = "";
628  var pathSplit = _openFolderPath.split("/");
629 
630  str += "/";
631  var navPath;
632 
633  //count depth first
634  var folderDepth = 0;
635  for(var i=0;i<pathSplit.length;++i)
636  if(pathSplit[i] != "") ++folderDepth;
637  Debug.log("folderDepth " + folderDepth);
638 
639  var subfolderCount = 0;
640  for(var i=0;i<pathSplit.length;++i)
641  {
642  if(pathSplit[i] == "") continue; //skip empty
643 
644  navPath = "";
645  for(var j=0;j<folderDepth-i;++j)
646  navPath += "../";
647  if(navPath == "") navPath = "."; //already here
648 
649 
650  Debug.log("navPath " + navPath);
651  ++subfolderCount;
652 
653  //need to do .. .. depending on depth
654  str += "<a href='#' onclick='Desktop.desktop.icons.openSubFolder(\"" +
655  navPath + "\");'>" +
656  pathSplit[i] + "</a>/";
657  Debug.log(str);
658 
659  }
660 
661  //write to a particular div
662  //var el1 = document.getElementById('box1Div');
663  MultiSelectBox.createSelectBox(_openFolderElement,
664  "DesktopFolderMultiSelectBox",
665  str,
666  vals,keys,types,
667  "Desktop.desktop.icons.clickFolderContents",
668  noMultiSelect,0,imgURLs,
669  "Desktop.desktop.icons.mouseDownFolderContents",
670  "Desktop.desktop.icons.mouseUpFolderContents");
671  MultiSelectBox.initMySelectBoxes(!maintainPreviousSelections);
672  }
673 
674  //=====================================================================================
675  //this.closeFolder ~~
676  this.closeFolder = function() {
677  //Debug.log("Close folder");
678  try
679  {
680  if(_openFolderElement)
681  _openFolderElement.parentNode.parentNode.removeChild(_openFolderElement.parentNode);
682  }
683  catch(e)
684  {
685  Debug.log("Ignoring close folder error: " + e);
686  }
687  _openFolderElement = 0;
688  _openFolderPath = ""; //clear
689  _openFolderPtr = undefined; //clear
690  }
691 
692  //=====================================================================================
693  //this.clickFolderContents ~~
694  this.clickFolderContents = function(el) {
695 
696  var i = MultiSelectBox.getSelectedIndex(el);
697  var selArr = MultiSelectBox.getSelectionArray(el);
698  var val = el.textContent;
699  var type = el.getAttribute("type-value");
700  var key = el.getAttribute("key-value")|0;
701 
702 
703  MultiSelectBox.dbg("Chosen element index:",i,
704  " value:",val,
705  " key:",key,
706  " type:",type);
707 
708 
709 
710  if(type == "icon")
711  {
712  var target = _openFolderPtr[1][key];
713  //Icon object array (0-subtext, 1-altText, 2-linkurl, 3-uniqueWin, 4-picfn)
714  Desktop.desktop.addWindow(target[0],"",target[2],target[3]);
715  //this.closeFolder();
716  }
717  else
718  this.openSubFolder(val);
719  }
720 
721  //=====================================================================================
722  //this.mouseUpFolderContents ~~
723  // this functionality should mirror addIcon()
724  this.mouseUpFolderContents = function(el,event) {
725  if(this.deepClickTimer)
726  {
727  window.clearTimeout(this.deepClickTimer);
728  this.deepClickTimer = 0;
729  }
730  }
731 
732  //=====================================================================================
733  //this.mouseDownFolderContents ~~
734  // this functionality should mirror local function
735  // deepClickHandler() in addIcon()
736  this.mouseDownFolderContents = function(el,event) {
737  var i = MultiSelectBox.getSelectedIndex(el);
738  var selArr = MultiSelectBox.getSelectionArray(el);
739  var val = el.textContent;
740  var type = el.getAttribute("type-value");
741  var key = el.getAttribute("key-value")|0;
742 
743  MultiSelectBox.dbg("mouseDownFolderContents Chosen element index:",i,
744  " value:",val,
745  " key:",key,
746  " type:",type);
747 
748  if(type != "icon") return;
749 
750  //only deep click functionality for icons
751 
752  var target = _openFolderPtr[1][key];
753  //Icon object array (0-subtext, 1-altText, 2-linkurl, 3-uniqueWin, 4-picfn)
754 
755 
756  //========================
757  // this functionality should mirror local function
758  // deepClickHandler() in addIcon()
759 
760  event.cancelBubble = true; //prevent default behavior
761  event.preventDefault();
762  this.deepClickTimer = window.setTimeout(function() {
763 
764  Debug.log("Create Icon Menu");
765  var menuItems = [
766  "Open and Maximize Window",
767  "Open in New Browser Tab",
768  "Open and Tile All Windows"
769  ];
770  var menuItemHandlers = [
771  "Desktop.desktop.addWindow(\""+ target[0] + "\",\"" + ""
772  + "\",\"" + target[2] + "\","+target[3]+",2);", // 2 for maximize
773  "Desktop.openNewBrowserTab(\""+ target[0] + "\",\"" + ""
774  + "\",\"" + target[2] + "\","+target[3]+");", // 2 for maximize
775  "Desktop.desktop.addWindow(\""+ target[0] + "\",\"" + ""
776  + "\",\"" + target[2] + "\","+target[3]+",1);", // 1 for tile
777  ];
778  Debug.log("createEditTableMenu()");
779  SimpleContextMenu.createMenu(
780  menuItems,
781  menuItemHandlers,
782  "DesktopIconContextMenu", //element ID
783  event.pageX-1,event.pageY-1, //top left position
784  Desktop.desktop.dashboard.getDefaultDashboardColor(), //primary color
785  "white" //secondary color
786  );
787 
788  },500); //end timeout handler
789 
790  }
791 
792  //------------------------------------------------------------------
793  //handle class construction ----------------------
794  //------------------------------------------------------------------
795 
796  this.iconsElement = _iconsElement = document.createElement("div");
797  this.iconsElement.setAttribute("class", "DesktopIcons");
798  this.iconsElement.setAttribute("id", "DesktopIcons");
799  this.iconsElement.style.position = "absolute";
800  this.iconsElement.style.zIndex = z;
801 
802 
803 
804  Debug.log("Desktop Icons created",Debug.LOW_PRIORITY);
805  } // end of createIcons()
806 
807 }
808 
809 
810 
811 
812 
813 
814 
815 
816 
817