[tasque/transition: 68/213] Change Categories type from Gtk.TreeModel to ObservableCollection<T>.
- From: Antonius Riha <antoniusri src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [tasque/transition: 68/213] Change Categories type from Gtk.TreeModel to ObservableCollection<T>.
- Date: Wed, 29 Aug 2012 18:39:44 +0000 (UTC)
commit 236ee81e81f013fd89972d4e6e5ad58bdc45ab08
Author: Antonius Riha <antoniusriha gmail com>
Date: Mon Jul 9 16:10:16 2012 +0200
Change Categories type from Gtk.TreeModel to ObservableCollection<T>.
* ICategory.cs: must be INotifyPropertyChanged in order to work with CollectionView.
+++
NOTE: This should not be necessary and must be fixed in CollectionView, preferably by adopting the .NET implementation of CollectionView/ListCollectionView/...
Issue has been filed on Github.
+++
src/libtasque/IBackend.cs | 6 +-
src/libtasque/ICategory.cs | 34 ++++++++++++---
src/tasque/AllCategory.cs | 11 +++++
src/tasque/Backends/Dummy/DummyBackend.cs | 65 ++++++++--------------------
src/tasque/Backends/Dummy/DummyCategory.cs | 14 ++++++
src/tasque/CompletedTaskGroup.cs | 17 +------
src/tasque/PreferencesDialog.cs | 33 +++-----------
src/tasque/RemoteControl.cs | 63 ++++++---------------------
src/tasque/TaskGroup.cs | 22 ++-------
src/tasque/TaskWindow.cs | 52 +++++++++-------------
10 files changed, 124 insertions(+), 193 deletions(-)
---
diff --git a/src/libtasque/IBackend.cs b/src/libtasque/IBackend.cs
index 8bfaf4a..2917256 100644
--- a/src/libtasque/IBackend.cs
+++ b/src/libtasque/IBackend.cs
@@ -46,9 +46,9 @@ namespace Tasque.Backends
/// <value>
/// This returns all the ICategory items from the backend.
/// </value>
- Gtk.TreeModel Categories {
- get;
- }
+ ObservableCollection<ICategory> Categories { get; }
+
+ IEnumerable SortedCategories { get; }
/// <value>
/// Indication that the backend has enough information
diff --git a/src/libtasque/ICategory.cs b/src/libtasque/ICategory.cs
index 3ba1794..08427d6 100644
--- a/src/libtasque/ICategory.cs
+++ b/src/libtasque/ICategory.cs
@@ -3,17 +3,39 @@
//
// To change standard headers go to Edit->Preferences->Coding->Standard Headers
//
-
+//
+// ICategory.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.
using System;
+using System.ComponentModel;
namespace Tasque
{
- public interface ICategory
+ public interface ICategory : IComparable<ICategory>, INotifyPropertyChanged
{
- string Name
- {
- get;
- }
+ string Name { get; }
bool ContainsTask(ITask task);
}
diff --git a/src/tasque/AllCategory.cs b/src/tasque/AllCategory.cs
index 0e5505b..dc45b56 100644
--- a/src/tasque/AllCategory.cs
+++ b/src/tasque/AllCategory.cs
@@ -50,5 +50,16 @@ namespace Tasque
categoriesToHide =
preferences.GetStringList (Preferences.HideInAllCategory);
}
+
+ #region IComparable implementation
+ public int CompareTo (ICategory other)
+ {
+ return -1;
+ }
+ #endregion
+
+ #region INotifyPropertyChanged implementation
+ public event PropertyChangedEventHandler PropertyChanged;
+ #endregion
}
}
diff --git a/src/tasque/Backends/Dummy/DummyBackend.cs b/src/tasque/Backends/Dummy/DummyBackend.cs
index be9eb9d..fa04125 100644
--- a/src/tasque/Backends/Dummy/DummyBackend.cs
+++ b/src/tasque/Backends/Dummy/DummyBackend.cs
@@ -19,12 +19,9 @@ namespace Tasque.Backends.Dummy
/// Key = Task ID
/// Value = Gtk.TreeIter in taskStore
/// </summary>
- private int newTaskId;
- private bool initialized;
- private bool configured = true;
-
- private Gtk.ListStore categoryListStore;
- private Gtk.TreeModelSort sortedCategoriesModel;
+ int newTaskId;
+ bool initialized;
+ bool configured = true;
public event BackendInitializedHandler BackendInitialized;
public event BackendSyncStartedHandler BackendSyncStarted;
@@ -39,19 +36,18 @@ namespace Tasque.Backends.Dummy
initialized = false;
newTaskId = 0;
Tasks = new ObservableCollection<ITask> ();
- var cv = new CollectionView<ITask> (Tasks);
+ var cvTasks = new CollectionView<ITask> (Tasks);
/*
* this invokes the default comparer, which in turn
* will use the IComparable implmentation of Task
*/
- cv.SortDescriptions.Add (new SortDescription ());
- SortedTasks = cv;
-
- categoryListStore = new Gtk.ListStore (typeof(ICategory));
+ cvTasks.SortDescriptions.Add (new SortDescription ());
+ SortedTasks = cvTasks;
- sortedCategoriesModel = new Gtk.TreeModelSort (categoryListStore);
- sortedCategoriesModel.SetSortFunc (0, new Gtk.TreeIterCompareFunc (CompareCategorySortFunc));
- sortedCategoriesModel.SetSortColumnId (0, Gtk.SortType.Ascending);
+ Categories = new ObservableCollection<ICategory> ();
+ var cvCategories = new CollectionView<ICategory> (Categories);
+ cvCategories.SortDescriptions.Add (new SortDescription ());
+ SortedCategories = cvCategories;
}
#region Public Properties
@@ -69,9 +65,9 @@ namespace Tasque.Backends.Dummy
/// <value>
/// This returns all the task lists (categories) that exist.
/// </value>
- public Gtk.TreeModel Categories {
- get { return sortedCategoriesModel; }
- }
+ public IEnumerable SortedCategories { get; private set; }
+
+ public ObservableCollection<ICategory> Categories { get; private set; }
/// <value>
/// Indication that the dummy backend is configured
@@ -116,29 +112,23 @@ namespace Tasque.Backends.Dummy
public void Initialize ()
{
- Gtk.TreeIter iter;
-
//
// Add in the "All" Category
//
- AllCategory allCategory = new Tasque.AllCategory ();
- iter = categoryListStore.Append ();
- categoryListStore.SetValue (iter, 0, allCategory);
+ AllCategory allCategory = new AllCategory ();
+ Categories.Add (allCategory);
//
// Add in some fake categories
//
homeCategory = new DummyCategory ("Home");
- iter = categoryListStore.Append ();
- categoryListStore.SetValue (iter, 0, homeCategory);
+ Categories.Add (homeCategory);
workCategory = new DummyCategory ("Work");
- iter = categoryListStore.Append ();
- categoryListStore.SetValue (iter, 0, workCategory);
+ Categories.Add (workCategory);
projectsCategory = new DummyCategory ("Projects");
- iter = categoryListStore.Append ();
- categoryListStore.SetValue (iter, 0, projectsCategory);
+ Categories.Add (projectsCategory);
//
// Add in some fake tasks
@@ -240,25 +230,6 @@ namespace Tasque.Backends.Dummy
#endregion // Public Methods
#region Private Methods
-
- static int CompareCategorySortFunc (Gtk.TreeModel model,
- Gtk.TreeIter a,
- Gtk.TreeIter b)
- {
- ICategory categoryA = model.GetValue (a, 0) as ICategory;
- ICategory categoryB = model.GetValue (b, 0) as ICategory;
-
- if (categoryA == null || categoryB == null)
- return 0;
-
- if (categoryA is Tasque.AllCategory)
- return -1;
- else if (categoryB is Tasque.AllCategory)
- return 1;
-
- return (categoryA.Name.CompareTo (categoryB.Name));
- }
-
public void UpdateTask (DummyTask task)
{
if (!Tasks.Contains (task))
diff --git a/src/tasque/Backends/Dummy/DummyCategory.cs b/src/tasque/Backends/Dummy/DummyCategory.cs
index 5ef4e6c..2d68ee1 100644
--- a/src/tasque/Backends/Dummy/DummyCategory.cs
+++ b/src/tasque/Backends/Dummy/DummyCategory.cs
@@ -33,5 +33,19 @@ namespace Tasque.Backends.Dummy
return false;
}
+ public int CompareTo (ICategory other)
+ {
+ if (other == null)
+ return -1;
+
+ if (other is AllCategory)
+ return 1;
+
+ return name.CompareTo (other.Name);
+ }
+
+ #region INotifyPropertyChanged implementation
+ public event PropertyChangedEventHandler PropertyChanged;
+ #endregion
}
}
diff --git a/src/tasque/CompletedTaskGroup.cs b/src/tasque/CompletedTaskGroup.cs
index 43e5c0b..d41fbf4 100644
--- a/src/tasque/CompletedTaskGroup.cs
+++ b/src/tasque/CompletedTaskGroup.cs
@@ -114,21 +114,10 @@ namespace Tasque
{
ICategory foundCategory = null;
- string cat = Application.Preferences.Get (
- Preferences.SelectedCategoryKey);
+ string cat = Application.Preferences.Get (Preferences.SelectedCategoryKey);
if (cat != null) {
- TreeIter iter;
- TreeModel model = Application.Backend.Categories;
-
- if (model.GetIterFirst (out iter)) {
- do {
- ICategory category = model.GetValue (iter, 0) as ICategory;
- if (category.Name.CompareTo (cat) == 0) {
- foundCategory = category;
- break;
- }
- } while (model.IterNext (ref iter));
- }
+ var categories = Application.Backend.Categories;
+ foundCategory = categories.SingleOrDefault (c => c.Name == cat);
}
return foundCategory;
diff --git a/src/tasque/PreferencesDialog.cs b/src/tasque/PreferencesDialog.cs
index 6c288cb..5e586f5 100644
--- a/src/tasque/PreferencesDialog.cs
+++ b/src/tasque/PreferencesDialog.cs
@@ -31,6 +31,7 @@ using System.Collections.Generic;
using Gtk;
using Mono.Unix;
using Tasque.Backends;
+using CollectionTransforms;
namespace Tasque
{
@@ -50,7 +51,7 @@ namespace Tasque
Dictionary<int, IBackend> backendComboMap; // track backends
int selectedBackend;
Gtk.CheckButton showCompletedTasksCheckButton;
- Gtk.TreeModelFilter filteredCategories;
+ CollectionView<ICategory> filteredCategories;
List<string> categoriesToHide;
Gtk.TreeView categoriesTree;
@@ -593,36 +594,16 @@ namespace Tasque
}
IBackend backend = backendComboMap [selectedBackend];
- filteredCategories = new TreeModelFilter (backend.Categories, null);
- filteredCategories.VisibleFunc = FilterFunc;
- categoriesTree.Model = filteredCategories;
+ filteredCategories = new CollectionView<ICategory> (backend.SortedCategories);
+ // Filter out the AllCategory
+ filteredCategories.Filter = c => c != null && !(c is AllCategory);
+ var adapter = new TreeModelListAdapter<ICategory> (filteredCategories);
+ categoriesTree.Model = adapter;
}
void OnShown (object sender, EventArgs args)
{
RebuildCategoryTree ();
}
-
- /// <summary>
- /// Filter out the AllCategory
- /// </summary>
- /// <param name="model">
- /// A <see cref="Gtk.TreeModel"/>
- /// </param>
- /// <param name="iter">
- /// A <see cref="Gtk.TreeIter"/>
- /// </param>
- /// <returns>
- /// A <see cref="System.Boolean"/>
- /// </returns>
- protected bool FilterFunc (Gtk.TreeModel model,
- Gtk.TreeIter iter)
- {
- ICategory category = model.GetValue (iter, 0) as ICategory;
- if (category == null || category is AllCategory)
- return false;
-
- return true;
- }
}
}
diff --git a/src/tasque/RemoteControl.cs b/src/tasque/RemoteControl.cs
index df51eab..d2aea30 100644
--- a/src/tasque/RemoteControl.cs
+++ b/src/tasque/RemoteControl.cs
@@ -85,37 +85,23 @@ namespace Tasque
public string CreateTask (string categoryName, string taskName,
bool enterEditMode, bool parseDate)
{
- Gtk.TreeIter iter;
- Gtk.TreeModel model = Application.Backend.Categories;
+ var categories = Application.Backend.Categories;
//
// Validate the input parameters. Don't allow null or empty strings
// be passed-in.
//
- if (categoryName == null || categoryName.Trim () == string.Empty
- || taskName == null || taskName.Trim () == string.Empty) {
+ if (string.IsNullOrWhiteSpace (categoryName) || string.IsNullOrWhiteSpace (taskName))
return string.Empty;
- }
//
// Look for the specified category
//
- if (!model.GetIterFirst (out iter)) {
- return string.Empty;
- }
-
ICategory category = null;
- do {
- ICategory tempCategory = model.GetValue (iter, 0) as ICategory;
- if (tempCategory.Name.ToLower ().CompareTo (categoryName.ToLower ()) == 0) {
- // Found a match
- category = tempCategory;
- }
- } while (model.IterNext (ref iter));
+ categories.SingleOrDefault (c => c.Name.ToLower () == categoryName.ToLower ());
- if (category == null) {
+ if (category == null)
return string.Empty;
- }
// If enabled, attempt to parse due date information
// out of the taskName.
@@ -167,20 +153,14 @@ namespace Tasque
public string[] GetCategoryNames ()
{
List<string> categories = new List<string> ();
- string[] emptyArray = categories.ToArray ();
-
- Gtk.TreeIter iter;
- Gtk.TreeModel model = Application.Backend.Categories;
-
- if (!model.GetIterFirst (out iter))
- return emptyArray;
+ var model = Application.Backend.SortedCategories;
- do {
- ICategory category = model.GetValue (iter, 0) as ICategory;
- if (category is AllCategory)
- continue; // Prevent the AllCategory from being returned
- categories.Add (category.Name);
- } while (model.IterNext (ref iter));
+ foreach (var item in model) {
+ if (item is AllCategory)
+ continue;
+
+ categories.Add (((ICategory)item).Name);
+ }
return categories.ToArray ();
}
@@ -280,29 +260,14 @@ namespace Tasque
/// A <see cref="System.Boolean"/>, true for success, false
/// for failure.
/// </returns>
- public bool SetCategoryForTaskById (string id,
- string categoryName)
+ public bool SetCategoryForTaskById (string id, string categoryName)
{
ITask task = GetTaskById (id);
if (task == null)
- {
- return false;
- }
- Gtk.TreeIter iter;
- Gtk.TreeModel model = Application.Backend.Categories;
-
- if (!model.GetIterFirst (out iter))
return false;
- do {
- ICategory category = model.GetValue (iter, 0) as ICategory;
- if (string.Compare(category.Name,categoryName)==0)
- {
- task.Category = category;
- return true;
- }
- } while (model.IterNext (ref iter));
- return false;
+ var categories = Application.Backend.Categories;
+ return categories.Contains (task.Category);
}
/// <summary>
diff --git a/src/tasque/TaskGroup.cs b/src/tasque/TaskGroup.cs
index 0e4d29f..0fb2154 100644
--- a/src/tasque/TaskGroup.cs
+++ b/src/tasque/TaskGroup.cs
@@ -26,8 +26,9 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
using System;
-using Gtk;
using System.Collections;
+using System.Linq;
+using Gtk;
namespace Tasque
{
@@ -375,7 +376,7 @@ namespace Tasque
/// <returns>
/// A <see cref="ICategory"/>
/// </returns>
- private ICategory GetSelectedCategory ()
+ ICategory GetSelectedCategory ()
{
// TODO: Move this code into some function in the backend/somewhere
// with the signature of GetCategoryForName (string catName):ICategory
@@ -383,21 +384,8 @@ namespace Tasque
Application.Preferences.Get (Preferences.SelectedCategoryKey);
if (selectedCategoryName != null) {
- Gtk.TreeIter iter;
- Gtk.TreeModel model = Application.Backend.Categories;
-
- // Iterate through (yeah, I know this is gross!) and find the
- // matching category
- if (model.GetIterFirst (out iter)) {
- do {
- ICategory cat = model.GetValue (iter, 0) as ICategory;
- if (cat == null)
- continue; // Needed for some reason to prevent crashes from some backends
- if (cat.Name.CompareTo (selectedCategoryName) == 0) {
- return cat;
- }
- } while (model.IterNext (ref iter));
- }
+ var categories = Application.Backend.Categories;
+ return categories.SingleOrDefault (c => c.Name == selectedCategoryName);
}
return null;
diff --git a/src/tasque/TaskWindow.cs b/src/tasque/TaskWindow.cs
index 1b80947..a71368a 100644
--- a/src/tasque/TaskWindow.cs
+++ b/src/tasque/TaskWindow.cs
@@ -35,6 +35,8 @@ using Gtk;
using Mono.Unix;
using Tasque.Backends;
+using CollectionTransforms;
+using System.Collections;
namespace Tasque
{
@@ -356,7 +358,8 @@ namespace Tasque
// Set up the combo box (after the above to set the current filter)
- categoryComboBox.Model = Application.Backend.Categories;
+ var adapter = new TreeModelListAdapter<ICategory> (Application.Backend.SortedCategories);
+ categoryComboBox.Model = adapter;
// Read preferences for the last-selected category and select it
string selectedCategoryName =
@@ -689,24 +692,18 @@ namespace Tasque
}
}
- private void RebuildAddTaskMenu (Gtk.TreeModel categoriesModel)
+ void RebuildAddTaskMenu (CollectionView<ICategory> categories)
{
- Gtk.Menu menu = new Menu ();
+ Menu menu = new Menu ();
- Gtk.TreeIter iter;
- if (categoriesModel.GetIterFirst (out iter)) {
- do {
- ICategory category =
- categoriesModel.GetValue (iter, 0) as ICategory;
-
- if (category is AllCategory)
- continue; // Skip this one
-
- CategoryMenuItem item = new CategoryMenuItem (category);
- item.Activated += OnNewTaskByCategory;
- item.ShowAll ();
- menu.Add (item);
- } while (categoriesModel.IterNext (ref iter));
+ foreach (var cat in categories) {
+ if (cat is AllCategory)
+ continue;
+
+ CategoryMenuItem item = new CategoryMenuItem ((ICategory)cat);
+ item.Activated += OnNewTaskByCategory;
+ item.ShowAll ();
+ menu.Add (item);
}
addTaskButton.Menu = menu;
@@ -1081,26 +1078,19 @@ namespace Tasque
* here in order to enable changing categories. The list of available categories
* is pre-filtered as to not contain the current category and the AllCategory.
*/
- TreeModelFilter filteredCategories = new TreeModelFilter(Application.Backend.Categories, null);
- filteredCategories.VisibleFunc = delegate(TreeModel t, TreeIter i) {
- ICategory category = t.GetValue (i, 0) as ICategory;
- if (category == null || category is AllCategory || category.Equals(clickedTask.Category))
- return false;
- return true;
- };
+ var cvCategories = new CollectionView<ICategory> (Application.Backend.SortedCategories);
+ cvCategories.Filter = c => c != null && !(c is AllCategory) && !c.Equals(clickedTask.Category);
// The categories submenu is only created in case we actually provide at least one category.
- if (filteredCategories.GetIterFirst(out iter))
- {
+ if (cvCategories.Count > 0) {
Menu categoryMenu = new Menu();
CategoryMenuItem categoryItem;
- filteredCategories.Foreach(delegate(TreeModel t, TreePath p, TreeIter i) {
- categoryItem = new CategoryMenuItem((ICategory)t.GetValue(i, 0));
+ foreach (var cat in cvCategories) {
+ categoryItem = new CategoryMenuItem((ICategory)cat);
categoryItem.Activated += OnChangeCategory;
categoryMenu.Add(categoryItem);
- return false;
- });
+ }
// TODO Needs translation.
item = new ImageMenuItem(Catalog.GetString("_Change category"));
@@ -1186,7 +1176,7 @@ namespace Tasque
status = string.Format (Catalog.GetString ("Tasks loaded: {0}"), now);
TaskWindow.lastLoadedTime = now;
TaskWindow.ShowStatus (status);
- RebuildAddTaskMenu (Application.Backend.Categories);
+ RebuildAddTaskMenu ((CollectionView<ICategory>)Application.Backend.SortedCategories);
addTaskEntry.Sensitive = true;
categoryComboBox.Sensitive = true;
// Keep insensitive text color
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]