home *** CD-ROM | disk | FTP | other *** search
/ PC World 2007 March / PCWorld_2007-03_cd.bin / komunikace / nvu / nvu-1.0-cs-CZ.win32.installer.exe / chrome / toolkit.jar / content / global / config.js < prev    next >
Text File  |  2004-02-23  |  16KB  |  514 lines

  1. /* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
  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 gPrefView = gPrefArray; // share the JS array
  58. var gFastIndex = 0;
  59. var gSortedColumn = "prefCol";
  60. var gSortFunction = null;
  61. var gSortDirection = 1; // 1 is ascending; -1 is descending
  62. var gConfigBundle = null;
  63.  
  64. var view = {
  65.   get rowCount() { return gPrefView.length; },
  66.   getCellText : function(index, col) {
  67.     if (!(index in gPrefView))
  68.       return "";
  69.     
  70.     var value = gPrefView[index][col];
  71.  
  72.     switch (col) {
  73.       case "lockCol":           
  74.         return gLockStrs[value];
  75.       case "typeCol":
  76.         return gTypeStrs[value];
  77.       default:
  78.         return value;
  79.     }
  80.   },
  81.   getRowProperties : function(index, prop) {},
  82.   getCellProperties : function(index, col, prop) {
  83.     if (index in gPrefView)
  84.       prop.AppendElement(gLockAtoms[gPrefView[index].lockCol]);
  85.   },
  86.   getColumnProperties : function(col, elt, prop) {},
  87.   treebox : null,
  88.   selection : null,
  89.   isContainer : function(index) { return false; },
  90.   isContainerOpen : function(index) { return false; },
  91.   isContainerEmpty : function(index) { return false; },
  92.   isSorted : function() { return true; },
  93.   canDropOn : function(index) { return false; },
  94.   canDropBeforeAfter : function(index, before) { return false; },
  95.   drop : function(row,orientation) {},
  96.   setTree : function(out) { this.treebox = out; },
  97.   getParentIndex: function(rowIndex) { return -1; },
  98.   hasNextSibling: function(rowIndex, afterIndex) { return false; },
  99.   getLevel: function(index) { return 1; },
  100.   getImageSrc: function(row, colID) { return ""; },
  101.   toggleOpenState : function(index) {},
  102.   cycleHeader: function(colID, elt) {
  103.     var index = this.selection.currentIndex;
  104.     if (colID == gSortedColumn)
  105.       gSortDirection = -gSortDirection;
  106.     if (colID == gSortedColumn && gFastIndex == gPrefArray.length) {
  107.       gPrefArray.reverse();
  108.       if (gPrefView != gPrefArray)
  109.         gPrefView.reverse();
  110.       if (index >= 0)
  111.         index = gPrefView.length - index - 1;
  112.     }
  113.     else {
  114.       var pref = null;
  115.       if (index >= 0) {
  116.         if (gPrefArray != gPrefView)
  117.           index = gPrefView.length - index - 1;
  118.         else
  119.           pref = gPrefArray[index];
  120.       }
  121.       var old = document.getElementById(gSortedColumn);
  122.       old.setAttribute("sortDirection", "");
  123.       gPrefArray.sort(gSortFunction = gSortFunctions[colID]);
  124.       if (gPrefView != gPrefArray) {
  125.         if (colID == gSortedColumn)
  126.           gPrefView.reverse();
  127.         else
  128.           gPrefView.sort(gSortFunction);
  129.       }
  130.       gSortedColumn = colID;
  131.       if (pref)
  132.         index = getIndexOfPref(pref);
  133.     }
  134.     elt.setAttribute("sortDirection", gSortDirection > 0 ? "ascending" : "descending");
  135.     this.treebox.invalidate();
  136.     if (index >= 0) {
  137.       this.selection.select(index);
  138.       this.treebox.ensureRowIsVisible(index);
  139.     }
  140.     gFastIndex = gPrefArray.length;
  141.   },
  142.   selectionChanged : function() {},
  143.   cycleCell: function(row, colID) {},
  144.   isEditable: function(row, colID) {return false; },
  145.   setCellText: function(row, colID, value) {},
  146.   performAction: function(action) {},
  147.   performActionOnRow: function(action, row) {},
  148.   performActionOnCell: function(action, row, colID) {},
  149.   isSeparator: function(index) {return false; }
  150. };
  151.  
  152. // find the index in gPrefView of a pref object
  153. // or -1 if it does not exist in the filtered view
  154. function getViewIndexOfPref(pref)
  155. {
  156.   var low = -1, high = gPrefView.length;
  157.   var index = (low + high) >> 1;
  158.   while (index > low) {
  159.     var mid = gPrefView[index];
  160.     if (mid == pref)
  161.       return index;
  162.     if (gSortFunction(mid, pref) < 0)
  163.       low = index;
  164.     else
  165.       high = index;
  166.     index = (low + high) >> 1;
  167.   }
  168.   return -1;
  169. }
  170.  
  171. // find the index in gPrefArray of a pref object
  172. // either one that was looked up in gPrefHash
  173. // or in case it was moved after sorting
  174. function getIndexOfPref(pref)
  175. {
  176.   var low = -1, high = gFastIndex;
  177.   var index = (low + high) >> 1;
  178.   while (index > low) {
  179.     var mid = gPrefArray[index];
  180.     if (mid == pref)
  181.       return index;
  182.     if (gSortFunction(mid, pref) < 0)
  183.       low = index;
  184.     else
  185.       high = index;
  186.     index = (low + high) >> 1;
  187.   }
  188.  
  189.   for (index = gFastIndex; index < gPrefArray.length; ++index)
  190.     if (gPrefArray[index] == pref)
  191.       break;
  192.   return index;
  193. }
  194.  
  195. function getNearestIndexOfPref(pref)
  196. {
  197.   var low = -1, high = gFastIndex;
  198.   var index = (low + high) >> 1;
  199.   while (index > low) {
  200.     if (gSortFunction(gPrefArray[index], pref) < 0)
  201.       low = index;
  202.     else
  203.       high = index;
  204.     index = (low + high) >> 1;
  205.   }
  206.   return high;
  207. }
  208.  
  209. var gPrefListener =
  210. {
  211.   observe: function(subject, topic, prefName)
  212.   {
  213.     if (topic != "nsPref:changed")
  214.       return;
  215.  
  216.     if (/^capability\./.test(prefName)) // avoid displaying "private" preferences
  217.       return;
  218.  
  219.     var index = gPrefArray.length;
  220.     if (prefName in gPrefHash) {
  221.       index = getViewIndexOfPref(gPrefHash[prefName]);
  222.       fetchPref(prefName, getIndexOfPref(gPrefHash[prefName]));
  223.       if (index >= 0) {
  224.         // Might need to update the filtered view
  225.         gPrefView[index] = gPrefHash[prefName];
  226.         view.treebox.invalidateRow(index);
  227.       }
  228.       if (gSortedColumn == "lockCol" || gSortedColumn == "valueCol")
  229.         gFastIndex = 1; // TODO: reinsert and invalidate range
  230.     } else {
  231.       fetchPref(prefName, index);
  232.       if (index == gFastIndex) {
  233.         // Keep the array sorted by reinserting the pref object
  234.         var pref = gPrefArray.pop();
  235.         index = getNearestIndexOfPref(pref);
  236.         gPrefArray.splice(index, 0, pref);
  237.         gFastIndex = gPrefArray.length;
  238.       }
  239.       if (gPrefView == gPrefArray)
  240.         view.treebox.rowCountChanged(index, 1);
  241.     }
  242.   }
  243. };
  244.  
  245. function prefObject(prefName, prefIndex)
  246. {
  247.   this.prefCol = prefName;
  248. }
  249.  
  250. prefObject.prototype =
  251. {
  252.   lockCol: PREF_IS_DEFAULT_VALUE,
  253.   typeCol: nsIPrefBranch.PREF_STRING,
  254.   valueCol: ""
  255. };
  256.  
  257. function fetchPref(prefName, prefIndex)
  258. {
  259.   var pref = new prefObject(prefName);
  260.  
  261.   gPrefHash[prefName] = pref;
  262.   gPrefArray[prefIndex] = pref;
  263.  
  264.   if (gPrefBranch.prefIsLocked(prefName))
  265.     pref.lockCol = PREF_IS_LOCKED;
  266.   else if (gPrefBranch.prefHasUserValue(prefName))
  267.     pref.lockCol = PREF_IS_USER_SET;
  268.  
  269.   try {
  270.     switch (gPrefBranch.getPrefType(prefName)) {
  271.       case gPrefBranch.PREF_BOOL:
  272.         pref.typeCol = gPrefBranch.PREF_BOOL;
  273.         // convert to a string
  274.         pref.valueCol = gPrefBranch.getBoolPref(prefName).toString();
  275.         break;
  276.       case gPrefBranch.PREF_INT:
  277.         pref.typeCol = gPrefBranch.PREF_INT;
  278.         // convert to a string
  279.         pref.valueCol = gPrefBranch.getIntPref(prefName).toString();
  280.         break;
  281.       default:
  282.       case gPrefBranch.PREF_STRING:
  283.         pref.valueCol = gPrefBranch.getComplexValue(prefName, nsISupportsString).data;
  284.         // Try in case it's a localized string (will throw an exception if not)
  285.         if (pref.lockCol == PREF_IS_DEFAULT_VALUE &&
  286.             /^chrome:\/\/.+\/locale\/.+\.properties/.test(pref.valueCol))
  287.           pref.valueCol = gPrefBranch.getComplexValue(prefName, nsIPrefLocalizedString).data;
  288.         break;
  289.     }
  290.   } catch (e) {
  291.     // Also catch obscure cases in which you can't tell in advance
  292.     // that the pref exists but has no user or default value...
  293.   }
  294. }
  295.  
  296. function onConfigLoad()
  297. {
  298.   // Load strings
  299.   gConfigBundle = document.getElementById("configBundle");
  300.   document.title = gConfigBundle.getString("title");
  301.  
  302.   gLockStrs[PREF_IS_DEFAULT_VALUE] = gConfigBundle.getString("default");
  303.   gLockStrs[PREF_IS_USER_SET] = gConfigBundle.getString("user");
  304.   gLockStrs[PREF_IS_LOCKED] = gConfigBundle.getString("locked");
  305.  
  306.   gTypeStrs[nsIPrefBranch.PREF_STRING] = gConfigBundle.getString("string");
  307.   gTypeStrs[nsIPrefBranch.PREF_INT] = gConfigBundle.getString("int");
  308.   gTypeStrs[nsIPrefBranch.PREF_BOOL] = gConfigBundle.getString("bool");
  309.  
  310.   var prefCount = { value: 0 };
  311.   var prefArray = gPrefBranch.getChildList("", prefCount);
  312.  
  313.   for (var i = 0; i < prefCount.value; ++i) 
  314.   {
  315.     var prefName = prefArray[i];
  316.     if (/^capability\./.test(prefName)) // avoid displaying "private" preferences
  317.       continue;
  318.  
  319.     fetchPref(prefName, gPrefArray.length);
  320.   }
  321.  
  322.   var descending = document.getElementsByAttribute("sortDirection", "descending");
  323.   if (descending.length) {
  324.     gSortedColumn = descending[0].id;
  325.     gSortDirection = -1;
  326.   }
  327.   else {
  328.     var ascending = document.getElementsByAttribute("sortDirection", "ascending");
  329.     if (ascending.length)
  330.       gSortedColumn = ascending[0].id;
  331.     else
  332.       document.getElementById(gSortedColumn).setAttribute("sortDirection", "ascending");
  333.   }
  334.   gSortFunction = gSortFunctions[gSortedColumn];
  335.   gPrefArray.sort(gSortFunction);
  336.   gFastIndex = gPrefArray.length;
  337.   
  338.   gPrefBranch.addObserver("", gPrefListener, false);
  339.  
  340.   document.getElementById("configTree").view = view;
  341.   
  342.   document.getElementById("textbox").focus();
  343. }
  344.  
  345. function onConfigUnload()
  346. {
  347.   gPrefBranch.removeObserver("", gPrefListener);
  348.   document.getElementById("configTree").view = null;
  349. }
  350.  
  351. function FilterPrefs()
  352. {
  353.   var substring = document.getElementById("textbox").value.toLowerCase();
  354.   var prefCol = view.selection.currentIndex < 0 ? null : gPrefView[view.selection.currentIndex].prefCol;
  355.   var array = gPrefView;
  356.   gPrefView = gPrefArray;
  357.   if (substring) {
  358.     gPrefView = [];
  359.     for (var i = 0; i < gPrefArray.length; ++i)
  360.       if (gPrefArray[i].prefCol.toLowerCase().indexOf(substring) >= 0)
  361.         gPrefView.push(gPrefArray[i]);
  362.     if (gFastIndex < gPrefArray.length)
  363.       gPrefView.sort(gSortFunction);
  364.   }
  365.   view.treebox.invalidate();
  366.   view.treebox.rowCountChanged(array.length, gPrefView.length - array.length);
  367.   gotoPref(prefCol);
  368.   document.getElementById("button").disabled = !substring;
  369. }
  370.  
  371. function ClearFilter(button)
  372. {
  373.   var textbox = document.getElementById("textbox");
  374.   textbox.value = "";
  375.   textbox.focus();
  376.   FilterPrefs();
  377. }
  378.  
  379. function prefColSortFunction(x, y)
  380. {
  381.   if (x.prefCol > y.prefCol)
  382.     return gSortDirection;
  383.   if (x.prefCol < y.prefCol) 
  384.     return -gSortDirection;
  385.   return 0;
  386. }
  387.  
  388. function lockColSortFunction(x, y)
  389. {
  390.   if (x.lockCol != y.lockCol)
  391.     return gSortDirection * (y.lockCol - x.lockCol);
  392.   return prefColSortFunction(x, y);
  393. }
  394.  
  395. function typeColSortFunction(x, y)
  396. {
  397.   if (x.typeCol != y.typeCol) 
  398.     return gSortDirection * (y.typeCol - x.typeCol);
  399.   return prefColSortFunction(x, y);
  400. }
  401.  
  402. function valueColSortFunction(x, y)
  403. {
  404.   if (x.valueCol > y.valueCol)
  405.     return gSortDirection;
  406.   if (x.valueCol < y.valueCol) 
  407.     return -gSortDirection;
  408.   return prefColSortFunction(x, y);
  409. }
  410.  
  411. const gSortFunctions =
  412. {
  413.   prefCol: prefColSortFunction, 
  414.   lockCol: lockColSortFunction, 
  415.   typeCol: typeColSortFunction, 
  416.   valueCol: valueColSortFunction
  417. };
  418.  
  419. function updateContextMenu(popup) {
  420.   if (view.selection.currentIndex < 0)
  421.     return false;
  422.   var pref = gPrefView[view.selection.currentIndex];
  423.   var reset = popup.lastChild;
  424.   reset.setAttribute("disabled", pref.lockCol != PREF_IS_USER_SET);
  425.   var modify = reset.previousSibling;
  426.   modify.setAttribute("disabled", pref.lockCol == PREF_IS_LOCKED);
  427.   return true;
  428. }
  429.  
  430. function copyName()
  431. {
  432.   gClipboardHelper.copyString(gPrefView[view.selection.currentIndex].prefCol);
  433. }
  434.  
  435. function copyValue()
  436. {
  437.   gClipboardHelper.copyString(gPrefView[view.selection.currentIndex].valueCol);
  438. }
  439.  
  440. function ModifySelected()
  441. {
  442.   ModifyPref(gPrefView[view.selection.currentIndex]);
  443. }
  444.  
  445. function ResetSelected()
  446. {
  447.   var entry = gPrefView[view.selection.currentIndex];
  448.   gPrefBranch.clearUserPref(entry.prefCol);
  449. }
  450.  
  451. function NewPref(type)
  452. {
  453.   var result = { value: "" };
  454.   var dummy = { value: 0 };
  455.   // XXX get these from a string bundle
  456.   if (gPromptService.prompt(window,
  457.                             gConfigBundle.getFormattedString("new_title", [gTypeStrs[type]]),
  458.                             gConfigBundle.getString("new_prompt"),
  459.                             result,
  460.                             null,
  461.                             dummy)) {
  462.     var pref;
  463.     if (result.value in gPrefHash)
  464.       pref = gPrefHash[result.value];
  465.     else
  466.       pref = { prefCol: result.value, lockCol: PREF_IS_DEFAULT_VALUE, typeCol: type, valueCol: "" };
  467.     if (ModifyPref(pref))
  468.       setTimeout(gotoPref, 0, result.value);
  469.   }
  470. }
  471.  
  472. function gotoPref(pref) {
  473.   // make sure the pref exists and is displayed in the current view
  474.   var index = pref in gPrefHash ? getViewIndexOfPref(gPrefHash[pref]) : -1;
  475.   if (index >= 0) {
  476.     view.selection.select(index);
  477.     view.treebox.ensureRowIsVisible(index);
  478.   } else {
  479.     view.selection.clearSelection();
  480.     view.selection.currentIndex = -1;
  481.   }
  482. }
  483.  
  484. function ModifyPref(entry)
  485. {
  486.   if (entry.lockCol == PREF_IS_LOCKED)
  487.     return false;
  488.   var result = { value: entry.valueCol };
  489.   var dummy = { value: 0 };
  490.   // XXX get this from a string bundle
  491.   if (!gPromptService.prompt(window,
  492.                              gConfigBundle.getFormattedString("modify_title", [gTypeStrs[entry.typeCol]]),
  493.                              entry.prefCol,
  494.                              result,
  495.                              null,
  496.                              dummy))
  497.     return false;
  498.   switch (entry.typeCol) {
  499.     case nsIPrefBranch.PREF_BOOL:
  500.       gPrefBranch.setBoolPref(entry.prefCol, eval(result.value));
  501.       break;
  502.     case nsIPrefBranch.PREF_INT:
  503.       gPrefBranch.setIntPref(entry.prefCol, eval(result.value));
  504.       break;
  505.     default:
  506.     case nsIPrefBranch.PREF_STRING:
  507.       var supportsString = Components.classes[nsSupportsString_CONTRACTID].createInstance(nsISupportsString);
  508.       supportsString.data = result.value;
  509.       gPrefBranch.setComplexValue(entry.prefCol, nsISupportsString, supportsString);
  510.       break;
  511.   }
  512.   return true;
  513. }
  514.