Back to index

lightning-sunbird  0.9+nobinonly
preferences.cs
Go to the documentation of this file.
00001 /* -*- Mode: C#; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
00002  *
00003  * ***** BEGIN LICENSE BLOCK *****
00004  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00005  *
00006  * The contents of this file are subject to the Mozilla Public License Version
00007  * 1.1 (the "License"); you may not use this file except in compliance with
00008  * the License. You may obtain a copy of the License at
00009  * http://www.mozilla.org/MPL/
00010  *
00011  * Software distributed under the License is distributed on an "AS IS" basis,
00012  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00013  * for the specific language governing rights and limitations under the
00014  * License.
00015  *
00016  * The Original Code is Manticore.
00017  *
00018  * The Initial Developer of the Original Code is
00019  * Silverstone Interactive.
00020  * Portions created by the Initial Developer are Copyright (C) 2001
00021  * the Initial Developer. All Rights Reserved.
00022  *
00023  * Contributor(s):
00024  *   Ben Goodger <ben@netscape.com>
00025  *
00026  * Alternatively, the contents of this file may be used under the terms of
00027  * either the GNU General Public License Version 2 or later (the "GPL"), or
00028  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00029  * in which case the provisions of the GPL or the LGPL are applicable instead
00030  * of those above. If you wish to allow use of your version of this file only
00031  * under the terms of either the GPL or the LGPL, and not to allow others to
00032  * use your version of this file under the terms of the MPL, indicate your
00033  * decision by deleting the provisions above and replace them with the notice
00034  * and other provisions required by the GPL or the LGPL. If you do not delete
00035  * the provisions above, a recipient may use your version of this file under
00036  * the terms of any one of the MPL, the GPL or the LGPL.
00037  *
00038  * ***** END LICENSE BLOCK ***** */
00039 
00040 namespace Silverstone.Manticore.Core
00041 {
00042   using System;
00043   using System.Collections;
00044 
00045   using System.IO;
00046   using System.Xml;
00047   using System.Text;
00048 
00049   public class Preferences 
00050   {
00051     XmlDocument mDefaultsDocument;
00052     XmlDocument mPrefsDocument;
00053 
00054     public Preferences()
00055     {
00056       mDefaultsDocument = new XmlDocument();
00057       mPrefsDocument = new XmlDocument();
00058     }
00059 
00060     public void InitializeDefaults()
00061     {
00062       // Do we ever want to support multiple defaults files? For now, no.
00063       // XXX need a better place for this file.
00064       ReadDocument(@"defaults\default-prefs.xml", mDefaultsDocument);
00065     }
00066 
00067     private void ReadDocument(String aFile, XmlDocument aDocument)
00068     {
00069       XmlTextReader reader = new XmlTextReader(aFile);
00070       reader.WhitespaceHandling = WhitespaceHandling.None;
00071       reader.MoveToContent();
00072       String xml = reader.ReadOuterXml();
00073       reader.Close();
00074       aDocument.LoadXml(xml);
00075     }
00076 
00077     // Called once at Startup
00078     public void LoadPreferencesFile(String aFile)
00079     {
00080       ReadDocument(aFile, mPrefsDocument);
00081 
00082       mPrefsDocument.NodeChanged += new XmlNodeChangedEventHandler(OnNodeChanged);
00083       mPrefsDocument.NodeRemoved += new XmlNodeChangedEventHandler(OnNodeRemoved);
00084       mPrefsDocument.NodeInserted += new XmlNodeChangedEventHandler(OnNodeInserted);
00085     }
00086 
00087     public void LoadUserPreferences()
00088     {
00089       String manticoreAppData = FileLocator.GetManticorePath("AppData");
00090       String prefPath = FileLocator.GetManticorePath("UserPrefs");
00091       try {
00092         LoadPreferencesFile(prefPath);
00093       }
00094       catch (XmlException) {
00095         // Something went wrong, we'll just assume a malformed or non-existant 
00096         // preferences file, blow it away and insert a new one. Could potentially
00097         // be dangerous. 
00098         try {
00099           File.Copy(@"defaults\user-prefs.xml", prefPath, true);
00100         }
00101         catch (DirectoryNotFoundException) {
00102           Directory.CreateDirectory(manticoreAppData);
00103           File.Copy(@"defaults\user-prefs.xml", prefPath, true);
00104         }
00105         LoadPreferencesFile(prefPath);
00106       }
00107     }
00108 
00109     public void FlushUserPreferences()
00110     {
00111       FlushPreferencesFile(FileLocator.GetManticorePath("UserPrefs"));
00112     }
00113 
00114     public void OnNodeChanged(object sender, XmlNodeChangedEventArgs e)
00115     {
00116     }
00117 
00118     public void OnNodeRemoved(object sender, XmlNodeChangedEventArgs e)
00119     {
00120     }
00121 
00122     public void OnNodeInserted(object sender, XmlNodeChangedEventArgs e)
00123     {
00124     }
00125 
00126     public void FlushPreferencesFile(String aFile)
00127     {
00128       UTF8Encoding enc = new UTF8Encoding();
00129       XmlTextWriter writer = new XmlTextWriter(aFile, enc);
00130       writer.Formatting = Formatting.Indented;
00131       mPrefsDocument.WriteTo(writer);
00132       writer.Flush();
00133     }
00134  
00135     //
00136     // The Manticore preferences file takes the following (XML) format:
00137     // 
00138     // <preferences>
00139     //   <foopy>
00140     //     <noopy type="int" value="42">
00141     //       <noo type="bool" value="true"/>
00142     //       <goo type="string" value="goats"/>
00143     //     </noopy>
00144     //   </foopy>
00145     // </preferences>
00146     //
00147     // where this maps to preferences called:
00148     // foopy.noopy (int pref, value 42)
00149     // foopy.noopy.noo (bool pref, value true);
00150     // foopy.noopy.goo (string pref, value "goats");
00151     //
00152     private XmlElement CreateBranch(String aPrefName) 
00153     {
00154       String[] names = aPrefName.Split('.');
00155       XmlElement elt = mPrefsDocument.DocumentElement;
00156       for (int i = 0; i < names.Length; ++i)
00157         elt = CreateBranch(names[i], elt);
00158       return elt;
00159     }
00160 
00161     private XmlElement CreateBranch(String aBranchName, XmlElement aRoot) 
00162     {
00163       XmlElement elt = GetBranch(aBranchName, aRoot);
00164       if (elt == null) {
00165         elt = mPrefsDocument.CreateElement(aBranchName);
00166         aRoot.AppendChild(elt);
00167       }
00168       return elt;
00169     }
00170 
00171     private XmlElement GetBranchElement(String aBranchName) 
00172     {
00173       String[] names = aBranchName.Split('.');
00174       XmlElement elt = mPrefsDocument.DocumentElement;
00175       for (int i = 0; i < names.Length && elt != null; ++i)
00176         elt = GetBranch(names[i], elt);
00177       
00178       // The preference wasn't found in the user preferences
00179       // file, look in the default preferences file. 
00180       if (elt == null) {
00181         elt = mDefaultsDocument.DocumentElement;
00182         for (int i = 0; i < names.Length; ++i)
00183           elt = GetBranch(names[i], elt);
00184       }
00185 
00186       return elt;
00187     }
00188 
00189     private XmlElement GetBranch(String aBranchName, XmlElement aRoot) 
00190     {
00191       // First, check to see if the specified root already has a branch
00192       // specified. If it exists, hand that root back. 
00193       int childCount = aRoot.ChildNodes.Count;
00194       for (int i = 0; i < childCount; ++i) {
00195         if (aRoot.ChildNodes[i].LocalName == aBranchName)
00196           return aRoot.ChildNodes[i] as XmlElement;
00197       }
00198       return null;
00199     }
00200 
00201     public PrefBranch GetBranch(String aBranchName)
00202     {
00203       return new PrefBranch(aBranchName, GetBranchElement(aBranchName));
00204     }
00205 
00206     public void RemoveBranch(String aBranchName) 
00207     {
00208       XmlElement elt = GetBranchElement(aBranchName);
00209       XmlNode parent = elt.ParentNode;
00210       parent.RemoveChild(elt);
00211       while (parent != null && 
00212              parent != (mPrefsDocument.DocumentElement as XmlNode)) {
00213         if (!parent.HasChildNodes) {
00214           parent.ParentNode.RemoveChild(parent);
00215           parent = parent.ParentNode;
00216         }
00217         else 
00218           break;
00219       }
00220     }
00221 
00222     public bool GetBoolPref(String aPrefName)
00223     {
00224       XmlElement elt = GetBranchElement(aPrefName);
00225       return elt != null ? elt.GetAttribute("value") == "true" : false;
00226     }
00227 
00228     public void SetBoolPref(String aPrefName, bool aPrefValue)
00229     {
00230       XmlElement childElt = CreateBranch(aPrefName);
00231       if (childElt != null) 
00232         childElt.SetAttribute("value", aPrefValue ? "true" : "false");
00233     }
00234 
00235     public void RemovePref(String aPrefName)
00236     {
00237       RemoveBranch(aPrefName);
00238     }
00239 
00240     public int GetIntPref(String aPrefName)
00241     {
00242       XmlElement elt = GetBranchElement(aPrefName);
00243       return elt != null ? Int32.Parse(elt.GetAttribute("value")) : 0;
00244     }
00245 
00246     public void SetIntPref(String aPrefName, int aPrefValue)
00247     {
00248       XmlElement elt = CreateBranch(aPrefName);
00249       if (elt != null) {
00250         Object o = aPrefValue;
00251         elt.SetAttribute("value", o.ToString());
00252       }
00253     }
00254 
00255     public String GetStringPref(String aPrefName)
00256     {
00257       XmlElement elt = GetBranchElement(aPrefName);
00258       return elt != null ? elt.GetAttribute("value") : "";
00259     }
00260 
00261     public void SetStringPref(String aPrefName, String aPrefValue)
00262     {
00263       XmlElement elt = CreateBranch(aPrefName);
00264       if (elt != null)
00265         elt.SetAttribute("value", aPrefValue);
00266     }
00267 
00268     public static String ResolvePref(XmlElement aElement)
00269     {
00270       String rv = aElement.LocalName;
00271       XmlElement temp = aElement;
00272       while (true) {
00273         temp = temp.ParentNode as XmlElement;
00274         if (temp == null || temp.LocalName == "preferences")
00275           break;
00276         rv = temp.LocalName + "." + rv;
00277       }
00278       return rv;
00279     }
00280   }
00281 
00282   public class PrefBranch : IEnumerator
00283   {
00284     //private XmlElement mRoot;
00285     private String mBranchName;
00286     private XmlElement mRoot;
00287     private XmlElement mCurrent = null;
00288 
00289     public PrefBranch(String aPrefBranchName, XmlElement aBranchRoot)
00290     {
00291       mBranchName = aPrefBranchName;
00292       mRoot = aBranchRoot;
00293     }
00294 
00295     public Object Current
00296     {
00297       get 
00298       {
00299         return Preferences.ResolvePref(mCurrent) as Object; 
00300       }
00301     }
00302 
00303     public bool MoveNext()
00304     {
00305       if (mCurrent != null) 
00306       {
00307         if (mCurrent.NextSibling != null) 
00308           mCurrent = mCurrent.NextSibling as XmlElement;
00309         else 
00310           return false;
00311       }
00312       else 
00313         mCurrent = mRoot.FirstChild as XmlElement;
00314       return true;
00315     }
00316 
00317     public void Reset()
00318     {
00319       mCurrent = mRoot.FirstChild as XmlElement;
00320     }
00321   }
00322 }