[tasque/viewmodel: 40/78] Move Preferences class to view model.



commit 17267c0f88a5873edd566d1115a5f62780b5df23
Author: Antonius Riha <antoniusriha gmail com>
Date:   Wed Aug 1 17:05:04 2012 +0200

    Move Preferences class to view model.
    
    Adjust existng parts of view model to class Preferences

 src/Tasque.Gtk/Preferences.cs                     |  320 -------------------
 src/Tasque.Gtk/Tasque.Gtk.csproj                  |    1 -
 src/libtasqueui/Legacy/MainWindowModel.cs         |   49 +++-
 src/libtasqueui/Legacy/MainWindowTopPanelModel.cs |   36 ++-
 src/libtasqueui/Legacy/NativeApplication.cs       |    6 +-
 src/libtasqueui/Legacy/Preferences.cs             |  355 +++++++++++++++++----
 src/libtasqueui/libtasqueui.csproj                |    3 +-
 7 files changed, 374 insertions(+), 396 deletions(-)
---
diff --git a/src/Tasque.Gtk/Tasque.Gtk.csproj b/src/Tasque.Gtk/Tasque.Gtk.csproj
index 7da3b28..36318c5 100644
--- a/src/Tasque.Gtk/Tasque.Gtk.csproj
+++ b/src/Tasque.Gtk/Tasque.Gtk.csproj
@@ -121,7 +121,6 @@
     <Compile Include="DateButton.cs" />
     <Compile Include="NoteDialog.cs" />
     <Compile Include="NoteWidget.cs" />
-    <Compile Include="Preferences.cs" />
     <Compile Include="PreferencesDialog.cs" />
     <Compile Include="TaskCalendar.cs" />
     <Compile Include="TaskGroup.cs" />
diff --git a/src/libtasqueui/Legacy/MainWindowModel.cs b/src/libtasqueui/Legacy/MainWindowModel.cs
index 0604c88..645c617 100644
--- a/src/libtasqueui/Legacy/MainWindowModel.cs
+++ b/src/libtasqueui/Legacy/MainWindowModel.cs
@@ -30,17 +30,17 @@ namespace Tasque.UIModel.Legacy
 {
 	public class MainWindowModel : ViewModelBase, ITimeAware
 	{
-		internal MainWindowModel ()
+		internal MainWindowModel (Preferences preferences)
 		{
-			if (Backend == null)
-				throw new ArgumentNullException ("backend");
-			if (Preferences == null)
+			if (preferences == null)
 				throw new ArgumentNullException ("preferences");
 			
 			UpdateCompletionDateRangeCompareDates ();
 			
-			this.Backend = Backend;
-			this.Preferences = Preferences;
+			Preferences = preferences;
+			showCompletedTasks = preferences.GetBool (Preferences.ShowCompletedTasksKey);
+			completionDateRange = GetCompletionDateRange ();
+			preferences.SettingChanged += HandleSettingChanged;
 			
 			Tasks = new ListCollectionView<Task> (Backend.Tasks);
 			Tasks.Filter = Filter;
@@ -52,12 +52,28 @@ namespace Tasque.UIModel.Legacy
 			
 			topPanel = new MainWindowTopPanelModel (this);
 		}
+
+		void HandleSettingChanged (Preferences preferences, string settingKey)
+		{
+			switch (settingKey) {
+			case Preferences.ShowCompletedTasksKey:
+				showCompletedTasks = preferences.GetBool (settingKey);
+				Tasks.Refresh ();
+				OnPropertyChanged ("ShowCompletedTasks");
+				break;
+			case Preferences.CompletedTasksRange:
+				completionDateRange = GetCompletionDateRange ();
+				Tasks.Refresh ();
+				OnPropertyChanged ("CompletionDateRange");
+				break;
+			}
+		}
 		
 		public CompletionDateRange CompletionDateRange {
-			get { return Preferences.CompletionDateRange; }
+			get { return completionDateRange; }
 			set {
-				Preferences.CompletionDateRange = value;
-				Tasks.Refresh ();
+				if (value != completionDateRange)
+					Preferences.Set (Preferences.CompletedTasksRange, value.ToString ());
 			}
 		}
 		
@@ -81,6 +97,8 @@ namespace Tasque.UIModel.Legacy
 			}
 		}
 		
+		public bool ShowCompletedTasks { get { return showCompletedTasks; } }
+		
 		public UICommand Hide { get { return hide ?? (hide = new UICommand ()); } }
 		
 		public UICommand Show {	get { return show ?? (show = new UICommand ());	} }
@@ -95,7 +113,7 @@ namespace Tasque.UIModel.Legacy
 			Tasks.Refresh ();
 		}
 		
-		internal Backend Backend { get; private set; }
+		internal Backend Backend { get; set; }
 		
 		internal Preferences Preferences { get; private set; }
 		
@@ -112,7 +130,7 @@ namespace Tasque.UIModel.Legacy
 			if (!task.IsComplete)
 				return true;
 			
-			if (!Preferences.ShowCompletedTasks)
+			if (!showCompletedTasks)
 				return false;
 			
 			// account for completion date range setting
@@ -133,6 +151,12 @@ namespace Tasque.UIModel.Legacy
 			}
 		}
 		
+		void GetCompletionDateRange ()
+		{
+			return (CompletionDateRange)Enum.Parse (typeof (CompletionDateRange),
+			                                        Preferences.Get (Preferences.CompletedTasksRange));
+		}
+		
 		void UpdateCompletionDateRangeCompareDates ()
 		{
 			var today = DateTime.Today.Date;
@@ -160,5 +184,8 @@ namespace Tasque.UIModel.Legacy
 		
 		UICommand hide;
 		UICommand show;
+		
+		bool showCompletedTasks;
+		CompletionDateRange completionDateRange;
 	}
 }
diff --git a/src/libtasqueui/Legacy/MainWindowTopPanelModel.cs b/src/libtasqueui/Legacy/MainWindowTopPanelModel.cs
index 26c8395..4705112 100644
--- a/src/libtasqueui/Legacy/MainWindowTopPanelModel.cs
+++ b/src/libtasqueui/Legacy/MainWindowTopPanelModel.cs
@@ -23,6 +23,7 @@
 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 // THE SOFTWARE.
+using System.Linq;
 using CollectionTransforms;
 
 namespace Tasque.UIModel.Legacy
@@ -32,21 +33,34 @@ namespace Tasque.UIModel.Legacy
 		internal MainWindowTopPanelModel (MainWindowModel mainWindowModel)
 		{
 			tasks = mainWindowModel.Tasks;
-			preferences = mainWindowModel.Preferences;
+			
 			Categories = new ReadOnlySortedNotifyCollection<Category> (mainWindowModel.Backend.Categories);
+			
+			preferences = mainWindowModel.Preferences;
+			selectedCategory = GetSelectedCategory ();
+			preferences.SettingChanged += HandleSettingChanged;
+			
 			addTaskCommand = new AddTaskCommand (mainWindowModel.Backend);
 		}
+
+		void HandleSettingChanged (Preferences preferences, string settingKey)
+		{
+			switch (settingKey) {
+			case Preferences.SelectedCategoryKey:
+				selectedCategory = GetSelectedCategory ();
+				tasks.Refresh ();
+				OnPropertyChanged ("SelectedCategory");
+				break;
+			}
+		}
 		
 		public ReadOnlySortedNotifyCollection<Category> Categories { get; private set; }
 		
 		public Category SelectedCategory {
-			get { return preferences.SelectedCategory; }
+			get { return selectedCategory; }
 			set {
-				if (value != null && !Categories.Contains (value))
-					value = null;
-				preferences.SelectedCategory = value;
-				tasks.Refresh ();
-				OnPropertyChanged ("SelectedCategory");
+				if (value != selectedCategory)
+					preferences.Set (Preferences.SelectedCategoryKey, value.Name);
 			}
 		}
 		
@@ -72,9 +86,17 @@ namespace Tasque.UIModel.Legacy
 			}
 		}
 		
+		void GetSelectedCategory ()
+		{
+			var selectedCategoryName = preferences.Get (Preferences.SelectedCategoryKey);
+			return Categories.SingleOrDefault (c => c.Name == selectedCategoryName);
+		}
+		
 		Preferences preferences;
 		ListCollectionView<Task> tasks;
 		
 		AddTaskCommand addTaskCommand;
+		
+		Category selectedCategory;
 	}
 }
diff --git a/src/libtasqueui/Legacy/NativeApplication.cs b/src/libtasqueui/Legacy/NativeApplication.cs
index 5293429..4589b9a 100644
--- a/src/libtasqueui/Legacy/NativeApplication.cs
+++ b/src/libtasqueui/Legacy/NativeApplication.cs
@@ -24,8 +24,8 @@
 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 // THE SOFTWARE.
 using System;
-using System.Diagnostics;
 using System.Collections.ObjectModel;
+using System.Diagnostics;
 
 namespace Tasque.UIModel.Legacy
 {
@@ -60,6 +60,8 @@ namespace Tasque.UIModel.Legacy
 				if (MainWindowModel != null && MainWindowModel.Show.CanExecute)
 					MainWindowModel.Show.Execute ();
 			};
+			
+			preferences = new Preferences ();
 		}
 
 		public virtual void InitializeIdle () {}
@@ -97,5 +99,7 @@ namespace Tasque.UIModel.Legacy
 			Dispose (false);
 		}
 		#endregion
+		
+		Preferences preferences;
 	}
 }
diff --git a/src/libtasqueui/Legacy/Preferences.cs b/src/libtasqueui/Legacy/Preferences.cs
index 462c61d..cbf1d65 100644
--- a/src/libtasqueui/Legacy/Preferences.cs
+++ b/src/libtasqueui/Legacy/Preferences.cs
@@ -1,75 +1,320 @@
-// 
-// Preferences.cs
-//  
-// Author:
-//       Antonius Riha <antoniusriha gmail com>
-// 
-// Copyright (c) 2012 Antonius Riha
-// 
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-// 
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-// 
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
+/***************************************************************************
+ *  Preferences.cs
+ *
+ *  Copyright (C) 2008 Novell, Inc.
+ *  Written by:
+ *      Calvin Gaisford <calvinrg gmail com>
+ *      Boyd Timothy <btimothy gmail com>
+ ****************************************************************************/
+
+/*  THIS FILE IS LICENSED UNDER THE MIT LICENSE AS OUTLINED IMMEDIATELY BELOW: 
+ *
+ *  Permission is hereby granted, free of charge, to any person obtaining a
+ *  copy of this software and associated documentation files (the "Software"),  
+ *  to deal in the Software without restriction, including without limitation  
+ *  the rights to use, copy, modify, merge, publish, distribute, sublicense,  
+ *  and/or sell copies of the Software, and to permit persons to whom the  
+ *  Software is furnished to do so, subject to the following conditions:
+ *
+ *  The above copyright notice and this permission notice shall be included in 
+ *  all copies or substantial portions of the Software.
+ *
+ *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
+ *  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
+ *  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 
+ *  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
+ *  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
+ *  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
+ *  DEALINGS IN THE SOFTWARE.
+ */
+
 using System;
-using System.ComponentModel;
+using System.Collections.Generic;
+using System.Xml;
+using System.IO;
+using System.Diagnostics;
 
-namespace Tasque.UIModel.Legacy
+namespace Tasque 
 {
-	public class Preferences : INotifyPropertyChanged
+	// <summary>
+	// Class used to store Tasque preferences
+	// </summary>
+	public class Preferences
 	{
-		public CompletionDateRange CompletionDateRange {
-			get { return completionDateRange; }
-			set {
-				if (value != completionDateRange) {
-					completionDateRange = value;
-					OnPropertyChanged ("CompletionDateRange");
-				}
+		private System.Xml.XmlDocument document;
+		private string location;
+		
+		public const string AuthTokenKey = "AuthToken";
+		public const string CurrentBackend = "CurrentBackend";
+		public const string InactivateTimeoutKey = "InactivateTimeout";
+		public const string SelectedCategoryKey = "SelectedCategory";
+		public const string ParseDateEnabledKey = "ParseDateEnabled";
+		public const string TodayTaskTextColor = "TodayTaskTextColor";
+		public const string OverdueTaskTextColor = "OverdueTaskTextColor";
+
+		/// <summary>
+		/// A list of category names to show in the TaskWindow when the "All"
+		/// category is selected.
+		/// </summary>
+		public const string HideInAllCategory = "HideInAllCategory";
+		public const string ShowCompletedTasksKey = "ShowCompletedTasks";
+		public const string UserNameKey = "UserName";
+		public const string UserIdKey = "UserID";
+		
+		/// <summary>
+		/// This setting allows a user to specify how many completed tasks to
+		/// show in the Completed Tasks Category.  The setting should be one of:
+		/// "Yesterday", "Last7Days", "LastMonth", "LastYear", or "All".
+		/// </summary>
+		/// <param name="settingKey">
+		/// A <see cref="System.String"/>
+		/// </param>
+		/// <returns>
+		/// A <see cref="System.String"/>
+		/// </returns>
+		public const string CompletedTasksRange = "CompletedTasksRange";
+		
+		public delegate void SettingChangedHandler (Preferences preferences,
+													string settingKey);
+		public event SettingChangedHandler SettingChanged;
+		
+		public string Get (string settingKey)
+		{
+			if (settingKey == null || settingKey.Trim () == string.Empty)
+				throw new ArgumentNullException ("settingKey", "Preferences.Get() called with a null/empty settingKey");
+			
+			string xPath = string.Format ("//{0}", settingKey.Trim ());
+			XmlNode node = document.SelectSingleNode (xPath);
+			if (node == null || !(node is XmlElement))
+				return SetDefault (settingKey);
+			
+			XmlElement element = node as XmlElement;
+			if( (element == null) || (element.InnerText.Length < 1) )
+				return SetDefault (settingKey);
+			else
+				return element.InnerText;
+		}
+		
+		private string SetDefault (string settingKey)
+		{
+			string val = GetDefault (settingKey);
+			if (val != null)
+				Set (settingKey, val);
+			return val;
+		}
+		
+		private string GetDefault (string settingKey)
+		{
+			switch (settingKey) {
+			case ParseDateEnabledKey:
+				return true.ToString ();
+			case TodayTaskTextColor:
+				return "#181AB7";
+			case OverdueTaskTextColor:
+				return "#EB3320";
+			default:
+				return null;
 			}
 		}
 		
-		public bool ShowCompletedTasks {
-			get { return showCompletedTasks; }
-			set {
-				if (value != showCompletedTasks) {
-					showCompletedTasks = value;
-					OnPropertyChanged ("ShowCompletedTasks");
-				}
+		public void Set (string settingKey, string settingValue)
+		{
+			if (settingKey == null || settingKey.Trim () == string.Empty)
+				throw new ArgumentNullException ("settingKey", "Preferences.Set() called with a null/empty settingKey");
+			
+			string xPath = string.Format ("//{0}", settingKey.Trim ());
+			XmlNode node = document.SelectSingleNode (xPath);
+			XmlElement element = null;
+			if (node != null && node is XmlElement)
+				element = node as XmlElement;
+			
+			if (element == null) {
+				element = document.CreateElement(settingKey);
+				document.DocumentElement.AppendChild (element);
 			}
+			
+			if (settingValue == null)
+				element.InnerText = string.Empty;
+			else
+				element.InnerText = settingValue;
+			
+			SavePrefs();
+			
+			NotifyHandlersOfSettingChange (settingKey.Trim ());
+		}
+		
+		public int GetInt (string settingKey)
+		{
+			string val = Get (settingKey);
+			if (val == null)
+				return -1;
+			
+			return int.Parse (val);
+		}
+		
+		public void SetInt (string settingKey, int settingValue)
+		{
+			Set (settingKey, string.Format ("{0}", settingValue));
 		}
 		
-		public Category SelectedCategory {
-			get { return selectedCategory; }
-			set {
-				if (value != selectedCategory) {
-					selectedCategory = value;
-					OnPropertyChanged ("SelectedCategory");
+		public bool GetBool (string settingKey)
+		{
+			string val = Get (settingKey);
+			if (val == null)
+				return false;
+			
+			return bool.Parse (val);
+		}
+		
+		public void SetBool (string settingKey, bool settingValue)
+		{
+			Set (settingKey, settingValue.ToString ());
+		}
+		
+		public List<string> GetStringList (string settingKey)
+		{
+			if (settingKey == null || settingKey.Trim () == string.Empty)
+				throw new ArgumentNullException ("settingKey", "Preferences.GetStringList() called with a null/empty settingKey");
+			
+			List<string> stringList = new List<string> ();
+			
+			// Select all nodes whose parent is the settingKey
+			string xPath = string.Format ("//{0}/*", settingKey.Trim ());
+			XmlNodeList list = document.SelectNodes (xPath);
+			if (list == null)
+				return stringList;
+			
+			foreach (XmlNode node in list) {
+				if (node.InnerText != null && node.InnerText.Length > 0)
+					stringList.Add (node.InnerText);
+			}
+			
+			return stringList;
+		}
+		
+		public void SetStringList (string settingKey, List<string> stringList)
+		{
+			if (settingKey == null || settingKey.Trim () == string.Empty)
+				throw new ArgumentNullException ("settingKey", "Preferences.SetStringList() called with null/empty settingKey");
+			
+			// Assume that the caller meant to null out an existing list
+			if (stringList == null)
+				stringList = new List<string> ();
+			
+			// Select the specific node
+			string xPath = string.Format ("//{0}", settingKey.Trim ());
+			XmlNode node = document.SelectSingleNode (xPath);
+			XmlElement element = null;
+			if (node != null && node is XmlElement) {
+				element = node as XmlElement;
+				// Clear out any old children
+				if (element.HasChildNodes) {
+					element.RemoveAll ();
 				}
 			}
+			
+			if (element == null) {
+				element = document.CreateElement(settingKey);
+				document.DocumentElement.AppendChild (element);
+			}
+			
+			foreach (string listItem in stringList) {
+				XmlElement child = document.CreateElement ("list-item");
+				child.InnerText = listItem;
+				element.AppendChild (child);
+			}
+			
+			SavePrefs();
+			
+			NotifyHandlersOfSettingChange (settingKey.Trim ());
+		}
+
+		public Preferences (string confDir)
+		{
+			document = new XmlDocument();
+			location = Path.Combine (confDir, "preferences");
+			if(!File.Exists(location)) {
+				CreateDefaultPrefs();
+			} else {
+				try {
+					document.Load(location);
+				} catch {
+					CreateDefaultPrefs ();
+					document.Load (location);
+				}
+			}
+			
+			ValidatePrefs ();
+		}
+		
+		/// <summary>
+		/// Validate existing preferences just in case we're running on a
+		/// machine that already has an existing file without having the
+		/// settings specified here.
+		/// </summary>
+		private void ValidatePrefs ()
+		{
+			if (GetInt (Preferences.InactivateTimeoutKey) <= 0)
+				SetInt (Preferences.InactivateTimeoutKey, 5);
 		}
 
-		public event PropertyChangedEventHandler PropertyChanged;
 
-		protected void OnPropertyChanged (string propertyName)
+		private void SavePrefs()
 		{
-			if (PropertyChanged != null)
-				PropertyChanged (this, new PropertyChangedEventArgs (propertyName));
+			XmlTextWriter writer = new XmlTextWriter(location, System.Text.Encoding.UTF8);
+			writer.Formatting = Formatting.Indented;
+			document.WriteTo( writer );
+			writer.Flush();
+			writer.Close();
 		}
 
-		CompletionDateRange completionDateRange;
-		bool showCompletedTasks;
-		Category selectedCategory;
+
+		private void CreateDefaultPrefs()
+		{
+			try {
+				Directory.CreateDirectory(Path.GetDirectoryName(location));
+
+       			document.LoadXml(
+       				"<tasqueprefs></tasqueprefs>");
+				SavePrefs();
+/* 
+		       // Create a new element node.
+		       XmlNode newElem = doc.CreateNode("element", "pages", "");  
+		       newElem.InnerText = "290";
+		     
+		       Console.WriteLine("Add the new element to the document...");
+		       XmlElement root = doc.DocumentElement;
+		       root.AppendChild(newElem);
+		     
+		       Console.WriteLine("Display the modified XML document...");
+		       Console.WriteLine(doc.OuterXml);
+*/
+			} catch (Exception e) {
+				Debug.WriteLine("Exception thrown in Preferences {0}", e);
+				return;
+			}
+
+		}
+		
+		/// <summary>
+		/// Notify all SettingChanged event handlers that the specified
+		/// setting has changed.
+		/// </summary>
+		/// <param name="settingKey">
+		/// A <see cref="System.String"/>.  The setting that changed.
+		/// </param>
+		private void NotifyHandlersOfSettingChange (string settingKey)
+		{
+			// Notify SettingChanged handlers of the change
+			if (SettingChanged != null) {
+				try {
+					SettingChanged (this, settingKey);
+				} catch (Exception e) {
+					Trace.TraceWarning ("Exception calling SettingChangedHandlers for setting '{0}': {1}",
+								 settingKey,
+								 e.Message);
+				}
+			}
+		}
 	}
 }
diff --git a/src/libtasqueui/libtasqueui.csproj b/src/libtasqueui/libtasqueui.csproj
index f453061..b93a8b4 100644
--- a/src/libtasqueui/libtasqueui.csproj
+++ b/src/libtasqueui/libtasqueui.csproj
@@ -79,6 +79,7 @@
   </PropertyGroup>
   <ItemGroup>
     <Reference Include="System" />
+    <Reference Include="System.Xml" />
   </ItemGroup>
   <ItemGroup>
     <Compile Include="Properties\AssemblyInfo.cs" />
@@ -98,7 +99,6 @@
     <Compile Include="Legacy\DueDateConverter.cs" />
     <Compile Include="Legacy\TaskComparer.cs" />
     <Compile Include="Legacy\CompletionDateRange.cs" />
-    <Compile Include="Legacy\Preferences.cs" />
     <Compile Include="ITimeAware.cs" />
     <Compile Include="ICommand.cs" />
     <Compile Include="CommandBase.cs" />
@@ -112,6 +112,7 @@
     <Compile Include="TaskGroupModelFactory.cs" />
     <Compile Include="CompletedTaskGroupModel.cs" />
     <Compile Include="Point.cs" />
+    <Compile Include="Legacy\Preferences.cs" />
   </ItemGroup>
   <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
   <ItemGroup>



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]