preferences.js
Go to the documentation of this file.
1 /* preferences.js
2  * This will be loaded into the main window, and manage all preference-
3  * related tasks.
4  */
5 // Make a namespace.
6 if (typeof foldersync == 'undefined') {
7  var foldersync = {};
8 };
9 
10 /* Preference controller
11  * Controller for all preference-related stuff, like Profiles, saved Folders,
12  * preference migration, etc.
13  */
14 foldersync.preferences={
15  // FolderSync's preference branch
16  _prefs: null,
17  /* The JSON object stored in a preference
18  * Structure:
19  * {
20  * version: <string>, // version for migrating issues. See _migrateIfNeeded
21  * profiles: [<profiles>], // the profiles, see createProfile for details
22  * favorites: [<favorites], // the favorites, see createFavorite
23  * defaulttags: {<strings>}, // the default value for each tag
24  * ui: {
25  * notifications: {
26  * isEnabled: <bool>, // if there should be global notifications
27  * onlyExclusive: <bool>, // if global notifications are exclusive
28  * },
29  * show: {
30  * favorites: <bool>, // if favorite UI elements should get displayed
31  * help: <bool>, // if help group should get displayed
32  * },
33  * lastUI: {<things>}, // the last UI data, see accesspane.js
34  * },
35  * }
36  */
37  _root: null,
38 
39  // Startup code for the preference controller
40  onLoad: function(e){
41  foldersync.central.logEvent("preferences", "Perference controller " +
42  "initialisation started.", 5);
43  try {
44  // Get the preferences
45  var prefs = Components.classes["@mozilla.org/preferences-service;1"].
46  getService(Components.interfaces.nsIPrefService);
47  this._prefs = prefs.getBranch("extensions.FolderSync.");
48  // Get JSON
49  try {
50  this._root = JSON.parse(this._prefs.getCharPref("JSON"));
51  } catch (e) {
52  this._root = {};
53  foldersync.central.logEvent("preferences",
54  "extensions.FolderSync.JSON is invalid. " +
55  "Fallback to default value.", 2,
56  "chrome://foldersync/content/" +
57  "preferences.js",
58  e.lineNumber);
59  }
60  // Perform migration if needed
61  this._migrateIfNeeded();
62  // We're done.
63  foldersync.central.logEvent("preferences",
64  "Preference controller started.", 4);
65  } catch (e) {
66  foldersync.central.logEvent("preferences",
67  "Startup of Preference controller " +
68  "failed:\n\n" + e, 1,
69  "chrome://foldersync/content/preferences.js",
70  e.lineNumber);
71  }
72  },
73  // Shutdown code for the preference controller
74  onUnload: function(e){
75  foldersync.central.logEvent("preferences", "Preference controller " +
76  "shutdown started.", 5);
77  // Remove temp profiles
78  for each (var profile in this._root.profiles)
79  if (profile.temporary)
80  this.removeProfile(profile);
81  // Save JSON
82  this._saveCurrent();
83  // We're done!
84  foldersync.central.logEvent("preferences",
85  "Preference controller stopped.", 4);
86  },
87 
88  // Migrates JSON preferences (_root), if needed
89  _migrateIfNeeded: function(){
90  /* FolderSync JSON Migration Structure
91  * For each FolderSync version with new/changed entrys in JSON there is a
92  * JSON version string (3.0.0.0 -> "3.0.0.0"). But not every FolderSync
93  * version needs a separate JSON version (so in 3.0.0.0b2 the current JSON
94  * version might be "3.0.0.0b1"). Final versions will have a non-beta
95  * version, so 3.0.0.0 can't get "3.0.0.0b1", although nothing changed.
96  * The migration will be performed in steps, if there are more than one
97  * JSON version between the saved preference and the installed release.
98  * Alpha and Beta Versions might have a own JSON version WITHOUT migration
99  * code needed (so there might be no migration from 3.0.0.0a1 to 3.0.0.0b1)
100  * There will be migration code for public beta releases in following
101  * releases with the same version number, but taken out in next releases.
102  */
103  // Migration from FolderSync < 3.0.0.0 OR fresh install
104  if (!this._root.version){
105  foldersync.central.logEvent("preferences", "Migration from FolderSync " +
106  "< 3.0.0.0 / fresh install", 4);
107  this._root.version = "3.0.0.0";
108 
109  // Create initial structure (with a default profile)
110  this._root.profiles = [];
111  this._root.favorites = [];
112  this._root.defaulttags = {
113  artist: "unknown",
114  title: "unknown",
115  album: "unknown",
116  albumartist: "unknown",
117  discnumber: "0",
118  tracknumber: "0",
119  genre: "Other",
120  rating: "0",
121  year: "0000",
122  disccount: "0",
123  composer: "unknown",
124  producer: "unknown"
125  };
126  this._root.ui = {
127  notifications: {
128  isEnabled: true,
129  onlyExclusive: true,
130  },
131  show: {
132  favorites: true,
133  help: true,
134  },
135  };
136  this.createProfile(foldersync.central.
137  getLocaleString("profile.defaultname"));
138 
139  // Detect < 3.0.0.0
140  var migrateFromOld = false;
141  try {
142  migrateFromOld = !this._prefs.getBoolPref("firstrun");
143  } catch (e){} // Drop exception if we haven't got a prior version
144  if (migrateFromOld){
145  foldersync.central.logEvent("preferences", "FolderSync < 3.0.0.0 " +
146  "detected.", 5);
147  // Migrate defaulttags, if there are any
148  try { // 2.4.0.0
149  this._root.defaulttags.artist = this._prefs.
150  getCharPref("defaultTag.artist");
151  } catch (e){} // Drop exception if we haven't got those tags
152  try {
153  this._root.defaulttags.title = this._prefs.
154  getCharPref("defaultTag.title");
155  } catch (e){} // Drop exception if we haven't got those tags
156  try {
157  this._root.defaulttags.album = this._prefs.
158  getCharPref("defaultTag.album");
159  } catch (e){} // Drop exception if we haven't got those tags
160  try {
161  this._root.defaulttags.albumartist = this._prefs.
162  getCharPref("defaultTag.albumartist");
163  } catch (e){} // Drop exception if we haven't got those tags
164  try {
165  this._root.defaulttags.discnumber = this._prefs.
166  getCharPref("defaultTag.discnumber");
167  } catch (e){} // Drop exception if we haven't got those tags
168  try {
169  this._root.defaulttags.tracknumber = this._prefs.
170  getCharPref("defaultTag.tracknumber");
171  } catch (e){} // Drop exception if we haven't got those tags
172  try {
173  this._root.defaulttags.genre = this._prefs.
174  getCharPref("defaultTag.genre");
175  } catch (e){} // Drop exception if we haven't got those tags
176  try {
177  this._root.defaulttags.rating = this._prefs.
178  getCharPref("defaultTag.rating");
179  } catch (e){} // Drop exception if we haven't got those tags
180  try {
181  this._root.defaulttags.year = this._prefs.
182  getCharPref("defaultTag.year");
183  } catch (e){} // Drop exception if we haven't got those tags
184  try {
185  this._root.defaulttags.disccount = this._prefs.
186  getCharPref("defaultTag.disccount");
187  } catch (e){} // Drop exception if we haven't got those tags
188  try { // 2.4.2.0
189  this._root.defaulttags.composer = this._prefs.
190  getCharPref("defaultTag.composer");
191  } catch (e){} // Drop exception if we haven't got those tags
192  try {
193  this._root.defaulttags.producer = this._prefs.
194  getCharPref("defaultTag.producer");
195  } catch (e){} // Drop exception if we haven't got those tags
196 
197  // Migrate default profile
198  var dProfile = this.getProfiles()[0];
199  try { // 1.0.0.0
200  dProfile.structure.isEnabled = this._prefs.getBoolPref("naming");
201  } catch (e){} // Drop exception if we haven't got those tags
202  try {
203  dProfile.structure.schema = this._prefs.getCharPref("namingString");
204  } catch (e){} // Drop exception if we haven't got those tags
205  try {
206  dProfile.playlists.isEnabled = this._prefs.getBoolPref("writeM3U");
207  } catch (e){} // Drop exception if we haven't got this pref
208  try { // 1.3.0.0
209  dProfile.flags.doDelete = true; // We had another default value
210  dProfile.flags.doDelete = this._prefs.getBoolPref("enabledelete");
211  } catch (e){} // Drop exception if we haven't got this pref
212  try { // 1.3.1.0
213  dProfile.structure.tnDigits = this._prefs.getIntPref("trackdigits");
214  } catch (e){} // Drop exception if we haven't got this pref
215  try { // 1.4.2.0
216  dProfile.playlists.splitChar = this._prefs.getCharPref("SplitChar");
217  } catch (e){} // Drop exception if we haven't got those tags
218  try {
219  dProfile.playlists.doRelativePoint = this._prefs.
220  getBoolPref("doPointSlash");
221  } catch (e){} // Drop exception if we haven't got those tags
222  try {
223  dProfile.playlists.format = this._prefs.getBoolPref("doExtendedM3U") ?
224  "m3uEx" : "m3u";
225  } catch (e){} // Drop exception if we haven't got this pref
226  try { // 1.4.3.2
227  var blChars = this._prefs.getCharPref("badcharacters").split("#");
228  dProfile.advanced.blockedChars = "";
229  for each (var c in blChars)
230  dProfile.advanced.blockedChars += c;
231  } catch (e){} // Drop exception if we haven't got those tags
232  try {
233  dProfile.advanced.cutReplaced = this._prefs.getBoolPref("cutoff");
234  } catch (e){} // Drop exception if we haven't got this pref
235  try { // 1.4.4.0
236  dProfile.flags.doUpdate = this._prefs.getBoolPref("ChangeCheck");
237  } catch (e){} // Drop exception if we haven't got this pref
238  try { // 2.3.0.0
239  dProfile.structure.doCovers = this._prefs.getBoolPref("writecover");
240  } catch (e){} // Drop exception if we haven't got those tags
241  try {
242  dProfile.structure.coverSchema = this._prefs.
243  getCharPref("coverfolder");
244  } catch (e){} // Drop exception if we haven't got those tags
245  try {
246  dProfile.structure.coverFile = this._prefs.
247  getCharPref("coverfilename");
248  } catch (e){} // Drop exception if we haven't got those tags
249  try {
250  dProfile.playlists.toFolder = this._prefs.getCharPref("m3ufolder");
251  } catch (e){} // Drop exception if we haven't got this pref
252  try { // 2.5.0.0
253  dProfile.flags.doRockbox = this._prefs.getBoolPref("RockboxSyncBack");
254  } catch (e){} // Drop exception if we haven't got this pref
255 
256  // Migrate other profiles
257  try {
258  var oldProfiles = this._prefs.getCharPref("Profiles").split(";?&?;");
259  if (oldProfiles[0] == "")
260  throw "No profile in there";
261  for each (var oProfile in oldProfiles){
262  var pParts = oProfile.split(";!&!;");
263  // Create profile for old data
264  var profile = this.createProfile(unescape(pParts[0]));
265 
266  // Playlist prefs weren't part of profile...
267  profile.playlists.splitChar = dProfile.playlists.splitChar;
268  profile.playlists.doRelativePoint = dProfile.playlists.
269  doRelativePoint;
270  profile.playlists.format = dProfile.playlists.format;
271 
272  // Advanced prefs weren't part of profile...
273  profile.advanced.cutReplaced = dProfile.advanced.cutReplaced;
274  profile.advanced.blockedChars = dProfile.advanced.blockedChars;
275 
276  // Copy data
277  profile.structure.schema = unescape(pParts[1]);
278  profile.structure.isEnabled = unescape(pParts[2]) == "true";
279  profile.playlists.isEnabled = unescape(pParts[3]) == "true";
280  profile.flags.doDelete = unescape(pParts[4]) == "true";
281  profile.structure.tnDigits = unescape(pParts[5])*1;
282  profile.flags.doUpdate = unescape(pParts[6]) == "true";
283  if (pParts.length == 7)
284  continue;
285  profile.structure.doCovers = unescape(pParts[7]) == "true";
286  profile.structure.coverSchema = unescape(pParts[8]);
287  profile.structure.coverFile = unescape(pParts[9]);
288  profile.playlists.toFolder = unescape(pParts[10]);
289  if (pParts.length == 11)
290  continue;
291  profile.flags.doRockbox = unescape(pParts[11]) == "true";
292  }
293  } catch (e){} // Drop exception if we haven't got profiles
294 
295  // Migrate favorites
296  try {
297  var sString = this._prefs.getCharPref("selections");
298  var sParts = sString.split(";!&");
299  for each (var part in sParts){
300  // Migrate Data
301  var parts = part.split("!;&");
302  var pParts = parts[1].split("&!;");
303  var plists = [];
304  for each (var plist in pParts)
305  if (plist != "")
306  plists.push(plist);
307  var pName = parts.length > 2 ? parts[2] : null;
308  var profiles = this.getProfiles();
309  var pGUID = dProfile.GUID;
310  for each (var profile in profiles)
311  if (profile.name == pName)
312  pGUID = profile.GUID;
313  // Add migrated data to Favorite list
314  var sync = foldersync.sync.generateSync(parts[0], pGUID, plists);
315  this.createFavorite(parts[0], sync);
316  }
317  } catch(e){} // Drop exception if we haven't got favorites
318 
319  // Migrate UI preferences
320  var ui = this.getUIPrefs();
321  // Show help / preference button -> show help area
322  var sHelp = ui.show.help;
323  try {
324  sHelp = this._prefs.getBoolPref("showHelpLink");
325  } catch(e){} // Drop exception if we haven't got this pref
326  try{
327  sHelp = sHelp || this._prefs.getBoolPref("showPrefBtn");
328  } catch(e){} // Drop exception if we haven't got this pref
329  ui.show.help = sHelp;
330  // Last shown UI
331  ui.lastUI = {
332  target: "",
333  playlists: [],
334  profile: dProfile,
335  };
336  try {
337  ui.lastUI.target = this._prefs.getCharPref("lastfolder");
338  } catch(e){} // Drop exception if we haven't got this pref
339  try {
340  var parts = this._prefs.getCharPref("lastselection").split("&!;");
341  for each (var part in parts)
342  if (part != "")
343  ui.lastUI.playlists.push(part);
344  } catch(e){} // Drop exception if we haven't got this pref
345  try {
346  var pName = this._prefs.getCharPref("lastProfileName");
347  var profiles = this.getProfiles();
348  for each (var profile in profiles)
349  if (profile.name == pName)
350  ui.lastUI.profile = profile;
351  } catch(e){} // Drop exception if we haven't got this pref
352  }
353  }
354 
355  // Migration from FolderSync 3.0.0.0 to 3.0.2.0
356  if (this._root.version == "3.0.0.0"){
357  foldersync.central.logEvent("preferences", "Migration from 3.0.0.0 " +
358  "to 3.0.2.0", 5);
359  this._root.version = "3.0.2.0";
360  // Move lastUI profiles to normal profile list, and set its GUID
361  if (this._root.ui.lastUI){
362  var profile = this.getProfileByGUID(this._root.ui.lastUI.profile.GUID);
363  // Not a user defined profile?
364  if (!profile){
365  profile.temporary = false;
366  this._root.profiles.push(profile);
367  }
368  this._root.ui.lastUI.profile = profile.GUID;
369  }
370  // Migrate profiles
371  for each (var profile in this.getProfiles()){
372  profile.playlists.isSorted = false;
373  profile.playlists.sortingScheme = "%albumartist:a%,%album%,%tracknumber%,%title%";
374  }
375  }
376  // Migration from FolderSync 3.0.2.0 to 3.0.3.0
377  if (this._root.version == "3.0.2.0"){
378  foldersync.central.logEvent("preferences", "Migration from 3.0.2.0 " +
379  "to 3.0.3.0", 5);
380  this._root.version = "3.0.3.0";
381  // Add Fallback for album artist
382  this._root.fallbacks = {
383  albumartist: true,
384  };
385  }
386  // If we weren't able to migrate, log a fatal error message and reset
387  // everything.
388  if (this._root.version != "3.0.3.0"){
389  foldersync.central.logEvent("preferences", "There is no rule to " +
390  "migrate from JSON version " +
391  this._root.version + ". Fallback to empty " +
392  "JSON root.", 2, "chrome://" +
393  "foldersync/content/preferences.js");
394  this._root = {};
395  this._migrateIfNeeded();
396  }
397  },
398 
399  // Saves current JSON (_root) to preferences
400  _saveCurrent: function(){
401  try {
402  foldersync.central.logEvent("preferences",
403  "Save JSON preferences", 5);
404  this._prefs.setCharPref("JSON", JSON.stringify(this._root));
405  } catch (e){
406  foldersync.central.logEvent("preferences",
407  "Saving of JSON preferences failed:\n\n" + e,
408  1,
409  "chrome://foldersync/content/preferences.js",
410  e.lineNumber);
411  }
412  },
413 
414  // Returns the array of all Profiles
415  getProfiles: function(){
416  try {
417  return this._root.profiles;
418  } catch (e){
419  foldersync.central.logEvent("preferences",
420  "Getting Profile list failed:\n\n" + e, 1,
421  "chrome://foldersync/content/preferences.js",
422  e.lineNumber);
423  }
424  return null;
425  },
426 
427  /* Returns the profile with the given GUID
428  * guid (string): the GUID of the requested Profile
429  */
430  getProfileByGUID: function(guid){
431  try {
432  for each (var profile in this._root.profiles){
433  if (profile.GUID == guid)
434  return profile;
435  }
436  foldersync.central.logEvent("preferences",
437  "Getting Profile " + guid + " failed:\n\n" +
438  guid + " is no registered profile", 1,
439  "chrome://foldersync/content/" +
440  "preferences.js");
441  } catch (e){
442  foldersync.central.logEvent("preferences",
443  "Getting Profile " + guid + " failed:\n\n" +
444  e, 1,
445  "chrome://foldersync/content/preferences.js",
446  e.lineNumber);
447  }
448  return null;
449  },
450 
451  /* Generate a new Profile
452  * name (string): the name of the profile
453  */
454  createProfile: function(name){
455  // generate a profile with the given name and the default values
456  var result = {
457  name: name, // The profile's name
458  GUID: Components.classes["@mozilla.org/uuid-generator;1"].
459  getService(Components.interfaces.nsIUUIDGenerator).generateUUID().
460  toString(), // A unique ID for referencing purposes
461  temporary: false, // set this to true if the profile should get deleted
462  visible: true, // visible to user?
463 
464  flags: {
465  doDelete: false, // Delete files that aren't part of the sync
466  doUpdate: true, // Overwrite files that changed since last sync
467  doRockbox: false, // Do a Rockbox back-sync
468  },
469 
470  structure: {
471  isEnabled: false, // Use filename scheme
472  schema: "%artist%/%album%/%title%", // The filename scheme
473  tnDigits: 0, // The minimal number of digits
474 
475  doCovers: false, // Write Album cover
476  coverSchema: "%album%", // The schema of the folder covers go to
477  coverFile: "cover", // The filename of covers ("cover"->"cover.jpg")
478  },
479 
480  playlists: {
481  isEnabled: false, // Write M3U playlists
482  toFolder: ".", // The relative folder playlists go to
483 
484  splitChar: "/", // The split character in file paths
485  doRelativePoint: true, // Start a relative path with .[splitChar]
486 
487  format: "m3uEx", // Playlist format, see foldersync.sync.getPFormats
488  encoding: "UTF-8", // The encoding (for nsIConverterOutputStream)
489 
490  isSorted: false, // Sort playlists' content
491  sortingScheme: "%albumartist:a%,%album%,%tracknumber%,%title%", // Sorting scheme
492  },
493 
494  advanced: {
495  blockedChars: '/\\:*?><|".', // Characters that will get replaced
496  replaceChar: "_", // Character to use inserted instead of a blocked one
497  cutReplaced: true, // Cut off replace characters on the end of a tag
498  cutSpaces: true, // Cut off spaces at beginning/end of a file/folder
499 
500  fMaxLength: 150, // Maximum length for a file name
501 
502  compareCase: false, // see up- and downcase as different folders
503  },
504  };
505  // append and return the profile
506  foldersync.central.logEvent("preferences",
507  "Create Profile "+result.GUID, 5);
508  try {
509  this._root.profiles.push(result);
510  return result;
511  } catch (e){
512  foldersync.central.logEvent("preferences",
513  "Adding of profile failed:\n\n" + e, 1,
514  "chrome://foldersync/content/preferences.js",
515  e.lineNumber);
516  }
517  return null;
518  },
519 
520  /* Removes the given Profile from the profile list
521  * profile (profile): the profile to remove
522  */
523  removeProfile: function(profile){
524  try {
525  foldersync.central.logEvent("preferences",
526  "Remove Profile "+profile.GUID, 5);
527  var deleted = false;
528  for (var i = 0; i < this._root.profiles.length; i++){
529  if (this._root.profiles[i] == profile){
530  this._root.profiles.splice(i,1);
531  deleted = true;
532  }
533  }
534  if (!deleted)
535  foldersync.central.logEvent("preferences",
536  "Removing of profile failed:\n\n" +
537  profile.GUID + " is no registered" +
538  " profile", 3, "chrome://" +
539  "foldersync/content/preferences.js");
540  } catch (e){
541  foldersync.central.logEvent("preferences",
542  "Removing of profile failed:\n\n" + e, 1,
543  "chrome://foldersync/content/preferences.js",
544  e.lineNumber);
545  }
546  },
547 
548  // Returns the array of all Favorites
549  getFavorites: function(){
550  try {
551  return this._root.favorites;
552  } catch (e){
553  foldersync.central.logEvent("preferences",
554  "Getting Favorite list failed:\n\n" + e, 1,
555  "chrome://foldersync/content/preferences.js",
556  e.lineNumber);
557  }
558  return null;
559  },
560 
561  /* Returns the favorite with the given GUID
562  * guid (string): the GUID of the requested Favorite
563  */
564  getFavoriteByGUID: function(guid){
565  try {
566  for each (var fav in this._root.favorites){
567  if (fav.GUID == guid)
568  return fav;
569  }
570  foldersync.central.logEvent("preferences",
571  "Getting Favorite " + guid + " failed:\n\n" +
572  guid + " is no registered Favorite", 1,
573  "chrome://foldersync/content/" +
574  "preferences.js");
575  } catch (e){
576  foldersync.central.logEvent("preferences",
577  "Getting Favorite " + guid + " failed:\n\n" +
578  e, 1,
579  "chrome://foldersync/content/preferences.js",
580  e.lineNumber);
581  }
582  return null;
583  },
584 
585  /* Generate a new Sync Fav
586  * name (string): the favorite's name
587  * sync (sync): a sync (see foldersync.sync.generateSync)
588  */
589  createFavorite: function(name,sync){
590  // generate a fav with the given attributes
591  var result = {
592  GUID: Components.classes["@mozilla.org/uuid-generator;1"].
593  getService(Components.interfaces.nsIUUIDGenerator).generateUUID().
594  toString(), // A unique ID for referencing purposes
595  name: name, // The Favorite's name
596  sync: sync, // The Favorite's sync
597  };
598  // append and return the fav
599  foldersync.central.logEvent("preferences",
600  "Create Favorite '" + result.name + "'", 5);
601  try {
602  this._root.favorites.push(result);
603  return result;
604  } catch (e){
605  foldersync.central.logEvent("preferences",
606  "Adding of favorite failed:\n\n" + e, 1,
607  "chrome://foldersync/content/preferences.js",
608  e.lineNumber);
609  }
610  return null;
611  },
612 
613  /* Removes the given Favorite from the favorites list
614  * favorite (favorite): the favorite to remove
615  */
616  removeFavorite: function(favorite){
617  try {
618  foldersync.central.logEvent("preferences",
619  "Remove Favorite "+favorite.name, 5);
620  var deleted = false;
621  for (var i = 0; i < this._root.favorites.length; i++){
622  if (this._root.favorites[i] == favorite){
623  this._root.favorites.splice(i,1);
624  deleted = true;
625  }
626  }
627  if (!deleted)
628  foldersync.central.logEvent("preferences",
629  "Removing of favorite failed:\n\n" +
630  "'" + favorite.name + "' is no " +
631  "registered favorite", 3, "chrome://" +
632  "foldersync/content/preferences.js");
633  } catch (e){
634  foldersync.central.logEvent("preferences",
635  "Removing of favorite failed:\n\n" + e, 1,
636  "chrome://foldersync/content/preferences.js",
637  e.lineNumber);
638  }
639  },
640 
641  /* Get the internal event logging level for FolderSync, return values:
642  * 0: do not log anything
643  * 1: log only fatal errors
644  * 2: log all errors (default)
645  * 3: log all errors and warnings
646  * 4: log all errors, warnings and essential debug messages
647  * 5: log everything
648  */
649  getEvtLogLevel: function(){
650  /* We can't use _prefs here because this function might be called before
651  * onLoad, hence we might want to log things before the preferences are up.
652  */
653  return Components.classes["@mozilla.org/preferences-service;1"].
654  getService(Components.interfaces.nsIPrefService).
655  getBranch("extensions.FolderSync.").getIntPref("debugLevel");
656  },
657 
658  // Get the array of default tags
659  getDefaultTags: function(){
660  return this._root.defaulttags;
661  },
662 
663  // Get the ui preference root
664  getUIPrefs: function(){
665  return this._root.ui;
666  },
667 
668  // Get the array of fallbacks
669  getFallbacks: function(){
670  return this._root.fallbacks;
671  },
672 };
dataSBHighestRatedArtists SBProperties rating
Definition: tuner2.js:867
sbDeviceFirmwareAutoCheckForUpdate prototype flags
foldersync sync
Definition: sync.js:14
function getBoolPref(prefname, def)
getService(Ci.sbIFaceplateManager)
var getService(Components.interfaces.nsIWindowMediator).getMostRecentWindow('Songbird SBProperties artist
Definition: tuner2.js:40
Lastfm onLoad
Definition: mini.js:36
return null
Definition: FeedWriter.js:1143
RDFHelper help
Definition: RDFHelper.jsm:170
var prefs
Definition: FeedWriter.js:1169
Sanitizer _prefs
Definition: sanitize.js:435
var JSON
function onUnload()
onUnload - called when the cover preview window unloads.
Definition: coverPreview.js:36
_getSelectedPageStyle s i