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));
173
/// Return a list of tasks whose origin note is the note specified.
175
public List<Task> GetTasksForNote (Note note)
177
List<Task> list = new List<Task> ();
180
if (tasks.GetIterFirst (out iter)) {
182
Task task = tasks.GetValue (iter, 0) as Task;
183
if (task.OriginNoteUri != null &&
184
task.OriginNoteUri.CompareTo (note.Uri) == 0)
186
} while (tasks.IterNext (ref iter));
191
#endregion // Public Methods
194
public static event TasksChangedHandler TaskDeleted;
195
public static event TasksChangedHandler TaskAdded;
196
public static event TaskRenamedHandler TaskRenamed;
197
public static event TaskSavedHandler TaskSaved;
198
public static event TaskStatusChangedHandler TaskStatusChanged;
201
#region Private Methods
203
/// Create the notes directory if it doesn't exist yet.
205
void CreateTasksDir ()
207
if (!DirectoryExists (tasks_dir)) {
208
// First run. Create storage directory.
209
CreateDirectory (tasks_dir);
213
// For overriding in test methods.
214
protected virtual bool DirectoryExists (string directory)
216
return Directory.Exists (directory);
219
// For overriding in test methods.
220
protected virtual DirectoryInfo CreateDirectory (string directory)
222
return Directory.CreateDirectory (directory);
225
protected virtual bool FirstRun ()
227
return !DirectoryExists (tasks_dir);
231
/// Create a "Learn About Tomboy" task
233
protected virtual void CreateStartTasks ()
236
Task first_task = Create (Catalog.GetString ("Learn About Tomboy"));
239
"Click on the Tomboy icon in your panel and select " +
240
"\"Start Here\". You'll see more instructions on how " +
241
"to use Tomboy inside the \"Start Here\" note.\n\n" +
242
"When you've opened the \"Start Here\" note, mark this " +
243
"task as being complete.");
244
first_task.QueueSave (true);
245
} catch (Exception e) {
246
Logger.Warn ("Error creating the \"Learn About Tomboy\" task: {0}\n{1}",
247
e.Message, e.StackTrace);
251
protected virtual void LoadTasks ()
253
string [] files = Directory.GetFiles (tasks_dir, "*.task");
255
foreach (string file_path in files) {
257
Task task = Task.Load (file_path, this);
259
task.Renamed += OnTaskRenamed;
260
task.Saved += OnTaskSaved;
261
task.StatusChanged += OnTaskStatusChanged;
263
Gtk.TreeIter iter = tasks.Append ();
264
tasks.SetValue (iter, 0, task);
265
task_iters [task.Uri] = iter;
267
} catch (System.Xml.XmlException e) {
268
Logger.Log ("Error parsing task XML, skipping \"{0}\": {1}",
274
Logger.Debug ("{0} tasks loaded", task_iters.Count);
277
string MakeNewFileName ()
279
Guid guid = Guid.NewGuid ();
280
return Path.Combine (tasks_dir, guid.ToString () + ".task");
283
void EmitRowChangedForTask (Task task)
285
if (task_iters.ContainsKey (task.Uri)) {
286
Gtk.TreeIter iter = task_iters [task.Uri];
288
tasks.EmitRowChanged (tasks.GetPath (iter), iter);
292
#endregion // Private Methods
294
#region Event Handlers
295
void OnTaskRenamed (Task task, string old_summary)
297
EmitRowChangedForTask (task);
299
if (TaskRenamed != null)
300
TaskRenamed (task, old_summary);
303
void OnTaskSaved (Task task)
305
EmitRowChangedForTask (task);
307
if (TaskSaved != null)
311
void OnTaskStatusChanged (Task task)
313
EmitRowChangedForTask (task);
315
if (TaskStatusChanged != null)
316
TaskStatusChanged (task);
319
#endregion // Event Handlers