3
using System.Collections.Generic;
10
public delegate void TasksChangedHandler (TaskManager manager, Task task);
12
public class TaskManager
14
#region Private Members
19
Dictionary<string, Gtk.TreeIter> task_iters;
20
#endregion // Private Members
23
public TaskManager (string directory) :
24
this (directory, Path.Combine (directory, "Archive"))
28
public TaskManager (string directory, string archive_directory)
30
Logger.Log ("TaskManager created with path \"{0}\".", directory);
32
tasks_dir = directory;
33
archive_dir = archive_directory;
35
tasks = new Gtk.ListStore (typeof (Task));
36
task_iters = new Dictionary<string,Gtk.TreeIter> ();
38
bool first_run = FirstRun ();
42
// First run. Create "Learn About Tomboy" task.
48
#endregion // Constructors
50
#region Public Properties
51
public Gtk.ListStore Tasks
55
#endregion // Public Properties
57
#region Public Methods
59
/// Delete the specified task from the system.
61
public void Delete (Task task)
63
if (File.Exists (task.FilePath)) {
64
if (archive_dir != null) {
65
// FIXME: Instead of moving deleted tasks into the archive dir, move them into a backup dir
66
if (!Directory.Exists (archive_dir))
67
Directory.CreateDirectory (archive_dir);
70
Path.Combine (archive_dir,
71
Path.GetFileName (task.FilePath));
72
if (File.Exists (archive_path))
73
File.Delete (archive_path);
75
File.Move (task.FilePath, archive_path);
77
File.Delete (task.FilePath);
80
string uri = task.Uri;
81
if (task_iters.ContainsKey (uri)) {
82
Gtk.TreeIter iter = task_iters [uri];
83
tasks.Remove (ref iter);
84
task_iters.Remove (uri);
88
Logger.Log ("Deleting task '{0}'.", task.Summary);
90
if (TaskDeleted != null)
91
TaskDeleted (this, task);
95
/// Create a new Task with the specified summary.
96
/// <param name="summary">The summary of the new task. This may be an
97
/// empty string but should not be null.</param>
99
public Task Create (string summary)
102
throw new ArgumentNullException ("summary", "You cannot create the a new task with a null summary. Use String.Empty instead.");
104
// if (summary.Length > 0 && Find (summary) != null)
105
// throw new Exception ("A task with this summary already exists");
107
string filename = MakeNewFileName ();
109
Task new_task = Task.CreateNewTask (summary, filename, this);
110
new_task.Renamed += OnTaskRenamed;
111
new_task.Saved += OnTaskSaved;
112
new_task.StatusChanged += OnTaskStatusChanged;
114
Gtk.TreeIter iter = tasks.Append ();
115
tasks.SetValue (iter, 0, new_task);
116
task_iters [new_task.Uri] = iter;
118
if (TaskAdded != null)
119
TaskAdded (this, new_task);
121
new_task.QueueSave (true);
127
/// Find an existing task with the specified summary.
128
/// <param name="summary">The summary string to search for.</param>
130
public Task Find (string summary)
133
if (tasks.GetIterFirst (out iter)) {
135
Task task = tasks.GetValue (iter, 0) as Task;
136
if (task.Summary.ToLower () == summary.ToLower ())
138
} while (tasks.IterNext (ref iter));
144
public Task FindByUri (string uri)
146
if (task_iters.ContainsKey (uri)) {
147
Gtk.TreeIter iter = task_iters [uri];
148
Task task = tasks.GetValue (iter, 0) as Task;
156
/// Save any task that hasn't been saved already.
157
/// This should only be called by TasksApplicationAddin.Shutdown ().
159
public void Shutdown ()
161
Logger.Log ("Saving unsaved tasks...");
164
if (tasks.GetIterFirst (out iter)) {
166
Task task = tasks.GetValue (iter, 0) as Task;
168
} while (tasks.IterNext (ref iter));
171
#endregion // Public Methods
174
public static event TasksChangedHandler TaskDeleted;
175
public static event TasksChangedHandler TaskAdded;
176
public static event TaskRenamedHandler TaskRenamed;
177
public static event TaskSavedHandler TaskSaved;
178
public static event TaskStatusChangedHandler TaskStatusChanged;
181
#region Private Methods
183
/// Create the notes directory if it doesn't exist yet.
185
void CreateTasksDir ()
187
if (!DirectoryExists (tasks_dir)) {
188
// First run. Create storage directory.
189
CreateDirectory (tasks_dir);
193
// For overriding in test methods.
194
protected virtual bool DirectoryExists (string directory)
196
return Directory.Exists (directory);
199
// For overriding in test methods.
200
protected virtual DirectoryInfo CreateDirectory (string directory)
202
return Directory.CreateDirectory (directory);
205
protected virtual bool FirstRun ()
207
return !DirectoryExists (tasks_dir);
211
/// Create a "Learn About Tomboy" task
213
protected virtual void CreateStartTasks ()
216
Task first_task = Create (Catalog.GetString ("Learn About Tomboy"));
219
"Click on the Tomboy icon in your panel and select " +
220
"\"Start Here\". You'll see more instructions on how " +
221
"to use Tomboy inside the \"Start Here\" note.\n\n" +
222
"When you've opened the \"Start Here\" note, mark this " +
223
"task as being complete.");
224
first_task.QueueSave (true);
225
} catch (Exception e) {
226
Logger.Warn ("Error creating the \"Learn About Tomboy\" task: {0}\n{1}",
227
e.Message, e.StackTrace);
231
protected virtual void LoadTasks ()
233
string [] files = Directory.GetFiles (tasks_dir, "*.task");
235
foreach (string file_path in files) {
237
Task task = Task.Load (file_path, this);
239
task.Renamed += OnTaskRenamed;
240
task.Saved += OnTaskSaved;
241
task.StatusChanged += OnTaskStatusChanged;
243
Gtk.TreeIter iter = tasks.Append ();
244
tasks.SetValue (iter, 0, task);
245
task_iters [task.Uri] = iter;
247
} catch (System.Xml.XmlException e) {
248
Logger.Log ("Error parsing task XML, skipping \"{0}\": {1}",
254
Logger.Debug ("{0} tasks loaded", task_iters.Count);
257
string MakeNewFileName ()
259
Guid guid = Guid.NewGuid ();
260
return Path.Combine (tasks_dir, guid.ToString () + ".task");
263
void EmitRowChangedForTask (Task task)
265
if (task_iters.ContainsKey (task.Uri)) {
266
Gtk.TreeIter iter = task_iters [task.Uri];
268
tasks.EmitRowChanged (tasks.GetPath (iter), iter);
272
#endregion // Private Methods
274
#region Event Handlers
275
void OnTaskRenamed (Task task, string old_summary)
277
EmitRowChangedForTask (task);
279
if (TaskRenamed != null)
280
TaskRenamed (task, old_summary);
283
void OnTaskSaved (Task task)
285
EmitRowChangedForTask (task);
287
if (TaskSaved != null)
291
void OnTaskStatusChanged (Task task)
293
EmitRowChangedForTask (task);
295
if (TaskStatusChanged != null)
296
TaskStatusChanged (task);
299
#endregion // Event Handlers