home *** CD-ROM | disk | FTP | other *** search
/ PC go! 2006 April / PCgo_0406_DVD.iso / lib / chrome / embed.jar / content / global / config.js < prev    next >
Encoding:
Text File  |  2003-01-20  |  13.6 KB  |  439 lines

  1. /* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
  2.  * The contents of this file are subject to the Netscape Public
  3.  * License Version 1.1 (the "License"); you may not use this file
  4.  * except in compliance with the License. You may obtain a copy of
  5.  * the License at http://www.mozilla.org/NPL/
  6.  * 
  7.  * Software distributed under the License is distributed on an "AS
  8.  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
  9.  * implied. See the License for the specific language governing
  10.  * rights and limitations under the License.
  11.  * 
  12.  * The Original Code is Mozilla Communicator client code, released
  13.  * March 31, 1998.
  14.  * 
  15.  * The Initial Developer of the Original Code is Netscape
  16.  * Communications Corporation. Portions created by Netscape are
  17.  * Copyright (C) 1998-1999 Netscape Communications Corporation. All
  18.  * Rights Reserved.
  19.  *
  20.  * Contributors:
  21.  *  Chip Clark <chipc@netscape.com>
  22.  *  Seth Spitzer <sspitzer@netscape.com>
  23.  *  Neil Rashbrook <neil@parkwaycc.co.uk>
  24.  */
  25.  
  26. const nsIPrefLocalizedString = Components.interfaces.nsIPrefLocalizedString;
  27. const nsISupportsString = Components.interfaces.nsISupportsString;
  28. const nsIPromptService = Components.interfaces.nsIPromptService;
  29. const nsIPrefService = Components.interfaces.nsIPrefService;
  30. const nsIPrefBranch = Components.interfaces.nsIPrefBranch;
  31. const nsIClipboardHelper = Components.interfaces.nsIClipboardHelper;
  32. const nsIAtomService = Components.interfaces.nsIAtomService;
  33.  
  34. const nsSupportsString_CONTRACTID = "@mozilla.org/supports-string;1";
  35. const nsPrompt_CONTRACTID = "@mozilla.org/embedcomp/prompt-service;1";
  36. const nsPrefService_CONTRACTID = "@mozilla.org/preferences-service;1";
  37. const nsClipboardHelper_CONTRACTID = "@mozilla.org/widget/clipboardhelper;1";
  38. const nsAtomService_CONTRACTID = "@mozilla.org/atom-service;1";
  39.  
  40. const gPromptService = Components.classes[nsPrompt_CONTRACTID].getService(nsIPromptService);
  41. const gPrefService = Components.classes[nsPrefService_CONTRACTID].getService(nsIPrefService);
  42. const gPrefBranch = gPrefService.getBranch(null).QueryInterface(Components.interfaces.nsIPrefBranchInternal);
  43. const gClipboardHelper = Components.classes[nsClipboardHelper_CONTRACTID].getService(nsIClipboardHelper);
  44. const gAtomService = Components.classes[nsAtomService_CONTRACTID].getService(nsIAtomService);
  45.  
  46. var gLockAtoms = [gAtomService.getAtom("default"), gAtomService.getAtom("user"), gAtomService.getAtom("locked")];
  47. // we get these from a string bundle
  48. var gLockStrs = [];
  49. var gTypeStrs = [];
  50.  
  51. const PREF_IS_DEFAULT_VALUE = 0;
  52. const PREF_IS_USER_SET = 1;
  53. const PREF_IS_LOCKED = 2;
  54.  
  55. var gPrefHash = {};
  56. var gPrefArray = [];
  57. var gFastIndex = 0;
  58. var gSortedColumn = "prefCol";
  59. var gSortFunction = null;
  60. var gSortDirection = 1; // 1 is ascending; -1 is descending
  61. var gConfigBundle = null;
  62.  
  63. var view = {
  64.   get rowCount() { return gPrefArray.length; },
  65.   getCellText : function(k, col) {
  66.     if (!(k in gPrefArray))
  67.       return "";
  68.     
  69.     var value = gPrefArray[k][col];
  70.  
  71.     switch (col) {
  72.       case "lockCol":           
  73.         return gLockStrs[value];
  74.       case "typeCol":
  75.         return gTypeStrs[value];
  76.       default:
  77.         return value;
  78.     }
  79.   },
  80.   getRowProperties : function(index, prop) {},
  81.   getCellProperties : function(index, col, prop) {
  82.     prop.AppendElement(gLockAtoms[gPrefArray[index].lockCol]);
  83.   },
  84.   getColumnProperties : function(col, elt, prop) {},
  85.   treebox : null,
  86.   selection : null,
  87.   isContainer : function(index) { return false; },
  88.   isContainerOpen : function(index) { return false; },
  89.   isContainerEmpty : function(index) { return false; },
  90.   isSorted : function() { return true; },
  91.   canDropOn : function(index) { return false; },
  92.   canDropBeforeAfter : function(index, before) { return false; },
  93.   drop : function(row,orientation) {},
  94.   setTree : function(out) { this.treebox = out; },
  95.   getParentIndex: function(rowIndex) { return -1; },
  96.   hasNextSibling: function(rowIndex, afterIndex) { return false; },
  97.   getLevel: function(index) { return 1; },
  98.   getImageSrc: function(row, colID) { return ""; },
  99.   toggleOpenState : function(index) {},
  100.   cycleHeader: function(colID, elt) {
  101.     var index = this.selection.currentIndex;
  102.     if (colID == gSortedColumn)
  103.       gSortDirection = -gSortDirection;
  104.     if (colID == gSortedColumn && gFastIndex == gPrefArray.length) {
  105.       gPrefArray.reverse();
  106.       if (index >= 0)
  107.         index = gPrefArray.length - index - 1;
  108.     }
  109.     else {
  110.       var pref = null;
  111.       if (index >= 0)
  112.         pref = gPrefArray[index];
  113.       var old = document.getElementById(gSortedColumn);
  114.       old.setAttribute("sortDirection", "");
  115.       gPrefArray.sort(gSortFunction = gSortFunctions[colID]);
  116.       gSortedColumn = colID;
  117.       if (pref)
  118.         index = getIndexOfPref(pref);
  119.     }
  120.     elt.setAttribute("sortDirection", gSortDirection > 0 ? "ascending" : "descending");
  121.     this.treebox.invalidate();
  122.     if (index >= 0) {
  123.       this.selection.select(index);
  124.       this.treebox.ensureRowIsVisible(index);
  125.     }
  126.     gFastIndex = gPrefArray.length;
  127.   },
  128.   selectionChanged : function() {},
  129.   cycleCell: function(row, colID) {},
  130.   isEditable: function(row, colID) {return false; },
  131.   setCellText: function(row, colID, value) {},
  132.   performAction: function(action) {},
  133.   performActionOnRow: function(action, row) {},
  134.   performActionOnCell: function(action, row, colID) {},
  135.   isSeparator: function(index) {return false; }
  136. };
  137.  
  138. // find the index in gPrefArray of a pref object
  139. // either one that was looked up in gPrefHash
  140. // or in case it was moved after sorting
  141. function getIndexOfPref(pref)
  142. {
  143.   var low = -1, high = gFastIndex;
  144.   var index = (low + high) >> 1;
  145.   while (index > low) {
  146.     var mid = gPrefArray[index];
  147.     if (mid == pref)
  148.       return index;
  149.     if (gSortFunction(mid, pref) < 0)
  150.       low = index;
  151.     else
  152.       high = index;
  153.     index = (low + high) >> 1;
  154.   }
  155.  
  156.   for (index = gFastIndex; index < gPrefArray.length; ++index)
  157.     if (gPrefArray[index] == pref)
  158.       break;
  159.   return index;
  160. }
  161.  
  162. function getNearestIndexOfPref(pref)
  163. {
  164.   var low = -1, high = gFastIndex;
  165.   var index = (low + high) >> 1;
  166.   while (index > low) {
  167.     if (gSortFunction(gPrefArray[index], pref) < 0)
  168.       low = index;
  169.     else
  170.       high = index;
  171.     index = (low + high) >> 1;
  172.   }
  173.   return high;
  174. }
  175.  
  176. var gPrefListener =
  177. {
  178.   observe: function(subject, topic, prefName)
  179.   {
  180.     if (topic != "nsPref:changed")
  181.       return;
  182.  
  183.     if (/capability/.test(prefName)) // avoid displaying "private" preferences
  184.       return;
  185.  
  186.     var index = gPrefArray.length;
  187.     if (prefName in gPrefHash) {
  188.       index = getIndexOfPref(gPrefHash[prefName]);
  189.       fetchPref(prefName, index);
  190.       view.treebox.invalidateRow(index);
  191.       if (gSortedColumn == "lockCol" || gSortedColumn == "valueCol")
  192.         gFastIndex = 1; // TODO: reinsert and invalidate range
  193.     } else {
  194.       fetchPref(prefName, index);
  195.       if (index == gFastIndex) {
  196.         // Keep the array sorted by reinserting the pref object
  197.         var pref = gPrefArray.pop();
  198.         index = getNearestIndexOfPref(pref);
  199.         gPrefArray.splice(index, 0, pref);
  200.         gFastIndex = gPrefArray.length;
  201.       }
  202.       view.treebox.rowCountChanged(index, 1);
  203.     }
  204.   }
  205. };
  206.  
  207. function prefObject(prefName, prefIndex)
  208. {
  209.   this.prefCol = prefName;
  210. }
  211.  
  212. prefObject.prototype =
  213. {
  214.   lockCol: PREF_IS_DEFAULT_VALUE,
  215.   typeCol: nsIPrefBranch.PREF_STRING,
  216.   valueCol: ""
  217. };
  218.  
  219. function fetchPref(prefName, prefIndex)
  220. {
  221.   var pref = new prefObject(prefName);
  222.  
  223.   gPrefHash[prefName] = pref;
  224.   gPrefArray[prefIndex] = pref;
  225.  
  226.   if (gPrefBranch.prefIsLocked(prefName))
  227.     pref.lockCol = PREF_IS_LOCKED;
  228.   else if (gPrefBranch.prefHasUserValue(prefName))
  229.     pref.lockCol = PREF_IS_USER_SET;
  230.  
  231.   try {
  232.     switch (gPrefBranch.getPrefType(prefName)) {
  233.       case gPrefBranch.PREF_BOOL:
  234.         pref.typeCol = gPrefBranch.PREF_BOOL;
  235.         // convert to a string
  236.         pref.valueCol = gPrefBranch.getBoolPref(prefName).toString();
  237.         break;
  238.       case gPrefBranch.PREF_INT:
  239.         pref.typeCol = gPrefBranch.PREF_INT;
  240.         // convert to a string
  241.         pref.valueCol = gPrefBranch.getIntPref(prefName).toString();
  242.         break;
  243.       default:
  244.       case gPrefBranch.PREF_STRING:
  245.         pref.valueCol = gPrefBranch.getComplexValue(prefName, nsISupportsString).data;
  246.         // Try in case it's a localized string (will throw an exception if not)
  247.         if (pref.lockCol == PREF_IS_DEFAULT_VALUE)
  248.           pref.valueCol = gPrefBranch.getComplexValue(prefName, nsIPrefLocalizedString).data;
  249.         break;
  250.     }
  251.   } catch (e) {
  252.     // Also catch obscure cases in which you can't tell in advance
  253.     // that the pref exists but has no user or default value...
  254.   }
  255. }
  256.  
  257. function onConfigLoad()
  258. {
  259.   // Load strings
  260.   gConfigBundle = document.getElementById("configBundle");
  261.   document.title = gConfigBundle.getString("title");
  262.  
  263.   gLockStrs[PREF_IS_DEFAULT_VALUE] = gConfigBundle.getString("default");
  264.   gLockStrs[PREF_IS_USER_SET] = gConfigBundle.getString("user");
  265.   gLockStrs[PREF_IS_LOCKED] = gConfigBundle.getString("locked");
  266.  
  267.   gTypeStrs[nsIPrefBranch.PREF_STRING] = gConfigBundle.getString("string");
  268.   gTypeStrs[nsIPrefBranch.PREF_INT] = gConfigBundle.getString("int");
  269.   gTypeStrs[nsIPrefBranch.PREF_BOOL] = gConfigBundle.getString("bool");
  270.  
  271.   var prefCount = { value: 0 };
  272.   var prefArray = gPrefBranch.getChildList("", prefCount);
  273.  
  274.   for (var i = 0; i < prefCount.value; ++i) 
  275.   {
  276.     var prefName = prefArray[i];
  277.     if (/capability/.test(prefName)) // avoid displaying "private" preferences
  278.       continue;
  279.  
  280.     fetchPref(prefName, gPrefArray.length);
  281.   }
  282.  
  283.   var descending = document.getElementsByAttribute("sortDirection", "descending");
  284.   if (descending.length) {
  285.     gSortedColumn = descending[0].id;
  286.     gSortDirection = -1;
  287.   }
  288.   else {
  289.     var ascending = document.getElementsByAttribute("sortDirection", "ascending");
  290.     if (ascending.length)
  291.       gSortedColumn = ascending[0].id;
  292.     else
  293.       document.getElementById(gSortedColumn).setAttribute("sortDirection", "ascending");
  294.   }
  295.   gSortFunction = gSortFunctions[gSortedColumn];
  296.   gPrefArray.sort(gSortFunction);
  297.   gFastIndex = gPrefArray.length;
  298.   
  299.   gPrefBranch.addObserver("", gPrefListener, false);
  300.  
  301.   document.getElementById("configTree").view = view;
  302. }
  303.  
  304. function onConfigUnload()
  305. {
  306.   gPrefBranch.removeObserver("", gPrefListener);
  307.   document.getElementById("configTree").view = null;
  308. }
  309.  
  310. function prefColSortFunction(x, y)
  311. {
  312.   if (x.prefCol > y.prefCol)
  313.     return gSortDirection;
  314.   if (x.prefCol < y.prefCol) 
  315.     return -gSortDirection;
  316.   return 0;
  317. }
  318.  
  319. function lockColSortFunction(x, y)
  320. {
  321.   if (x.lockCol != y.lockCol)
  322.     return gSortDirection * (y.lockCol - x.lockCol);
  323.   return prefColSortFunction(x, y);
  324. }
  325.  
  326. function typeColSortFunction(x, y)
  327. {
  328.   if (x.typeCol != y.typeCol) 
  329.     return gSortDirection * (y.typeCol - x.typeCol);
  330.   return prefColSortFunction(x, y);
  331. }
  332.  
  333. function valueColSortFunction(x, y)
  334. {
  335.   if (x.valueCol > y.valueCol)
  336.     return gSortDirection;
  337.   if (x.valueCol < y.valueCol) 
  338.     return -gSortDirection;
  339.   return prefColSortFunction(x, y);
  340. }
  341.  
  342. const gSortFunctions =
  343. {
  344.   prefCol: prefColSortFunction, 
  345.   lockCol: lockColSortFunction, 
  346.   typeCol: typeColSortFunction, 
  347.   valueCol: valueColSortFunction
  348. };
  349.  
  350. function updateContextMenu(popup) {
  351.   if (view.selection.currentIndex < 0)
  352.     return false;
  353.   var pref = gPrefArray[view.selection.currentIndex];
  354.   var reset = popup.lastChild;
  355.   reset.setAttribute("disabled", pref.lockCol != PREF_IS_USER_SET);
  356.   var modify = reset.previousSibling;
  357.   modify.setAttribute("disabled", pref.lockCol == PREF_IS_LOCKED);
  358.   return true;
  359. }
  360.  
  361. function copyName()
  362. {
  363.   gClipboardHelper.copyString(gPrefArray[view.selection.currentIndex].prefCol);
  364. }
  365.  
  366. function copyValue()
  367. {
  368.   gClipboardHelper.copyString(gPrefArray[view.selection.currentIndex].valueCol);
  369. }
  370.  
  371. function ModifySelected()
  372. {
  373.   ModifyPref(gPrefArray[view.selection.currentIndex]);
  374. }
  375.  
  376. function ResetSelected()
  377. {
  378.   var entry = gPrefArray[view.selection.currentIndex];
  379.   gPrefBranch.clearUserPref(entry.prefCol);
  380. }
  381.  
  382. function NewPref(type)
  383. {
  384.   var result = { value: "" };
  385.   var dummy = { value: 0 };
  386.   // XXX get these from a string bundle
  387.   if (gPromptService.prompt(window,
  388.                             gConfigBundle.getFormattedString("new_title", [gTypeStrs[type]]),
  389.                             gConfigBundle.getString("new_prompt"),
  390.                             result,
  391.                             null,
  392.                             dummy)) {
  393.     var pref;
  394.     if (result.value in gPrefHash)
  395.       pref = gPrefHash[result.value];
  396.     else
  397.       pref = { prefCol: result.value, lockCol: PREF_IS_DEFAULT_VALUE, typeCol: type, valueCol: "" };
  398.     if (ModifyPref(pref))
  399.       setTimeout(gotoPref, 0, result.value);
  400.   }
  401. }
  402.  
  403. function gotoPref(prefCol) {
  404.   var index = getIndexOfPref(gPrefHash[prefCol]);
  405.   view.selection.select(index);
  406.   view.treebox.ensureRowIsVisible(index);
  407. }
  408.  
  409. function ModifyPref(entry)
  410. {
  411.   if (entry.lockCol == PREF_IS_LOCKED)
  412.     return false;
  413.   var result = { value: entry.valueCol };
  414.   var dummy = { value: 0 };
  415.   // XXX get this from a string bundle
  416.   if (!gPromptService.prompt(window,
  417.                              gConfigBundle.getFormattedString("modify_title", [gTypeStrs[entry.typeCol]]),
  418.                              entry.prefCol,
  419.                              result,
  420.                              null,
  421.                              dummy))
  422.     return false;
  423.   switch (entry.typeCol) {
  424.     case nsIPrefBranch.PREF_BOOL:
  425.       gPrefBranch.setBoolPref(entry.prefCol, eval(result.value));
  426.       break;
  427.     case nsIPrefBranch.PREF_INT:
  428.       gPrefBranch.setIntPref(entry.prefCol, eval(result.value));
  429.       break;
  430.     default:
  431.     case nsIPrefBranch.PREF_STRING:
  432.       var supportsString = Components.classes[nsSupportsString_CONTRACTID].createInstance(nsISupportsString);
  433.       supportsString.data = result.value;
  434.       gPrefBranch.setComplexValue(entry.prefCol, nsISupportsString, supportsString);
  435.       break;
  436.   }
  437.   return true;
  438. }
  439.