/// <summary> /// If the deleted task is included inside this note, this /// handler removes the TextTag surrounding the task. /// </summary> private void OnTaskDeleted(TaskManager manager, Task task) { if (task.OriginNoteUri == null || task.OriginNoteUri != Note.Uri) { return; } // Search through the note looking for the TaskTag so that it can // be renamed // Iterate through the lines looking for tasks Gtk.TextIter iter = Buffer.StartIter; iter.ForwardLine(); // Move past the note's title do { TaskTag task_tag = (TaskTag) Buffer.GetDynamicTag("task", iter); if (task_tag != null) { if (task_tag.Uri != task.Uri) { continue; } RemoveTaskFromLine(ref iter); break; } } while (iter.ForwardLine()); }
/// <summary> /// If the specified task is included inside this note, this /// handler will update the task's status representation. /// </summary> private void OnTaskStatusChanged(Task task) { if (task.OriginNoteUri == null || task.OriginNoteUri != Note.Uri) { return; } // Search through the note looking for the TaskTag so that it can // be updated // Iterate through the lines looking for tasks Gtk.TextIter iter = Buffer.StartIter; iter.ForwardLine(); // Move past the note's title do { TaskTag task_tag = (TaskTag) Buffer.GetDynamicTag("task", iter); if (task_tag != null) { if (task_tag.Uri != task.Uri) { continue; } task_tag.CompletionDate = task.CompletionDate; break; } } while (iter.ForwardLine()); }
/// <summary> /// Remove the task tag on the line specified by the TextIter. This /// will not remove the "todo:" text (i.e., it will not modify the /// actual characters of the TextBuffer. /// <param name="iter">The TextIter specifying the line where the /// TaskTag should be removed.</param> /// <returns>True if a TaskTag was removed, otherwise False.</returns> /// </summary> bool RemoveTaskTagFromLine(Gtk.TextIter iter) { Gtk.TextIter start = iter; Gtk.TextIter end = iter; TaskTag task_tag = GetTaskTagFromLineIter(ref start); if (task_tag == null) { return(false); } while (start.StartsLine() == false) { start.BackwardChar(); } while (end.EndsLine() == false) { end.ForwardChar(); } // end.ForwardToLineEnd (); last_removed_tag = null; Buffer.RemoveTag(task_tag, start, end); return(true); }
void OnTagRemoved(object sender, Gtk.TagRemovedArgs args) { TaskTag task_tag = args.Tag as TaskTag; if (task_tag == null) { return; } last_removed_tag = task_tag; }
/// <summary> /// If the renamed task is included inside this note, this /// handler will update the task summary in the note buffer. /// </summary> private void OnTaskRenamed(Task task, string old_title) { if (task.OriginNoteUri == null || task.OriginNoteUri != Note.Uri) { return; } // Search through the note looking for the TaskTag so that it can // be renamed if (!ContainsText(old_title)) { return; } // Iterate through the lines looking for tasks Gtk.TextIter iter = Buffer.StartIter; iter.ForwardLine(); // Move past the note's title do { TaskTag task_tag = (TaskTag) Buffer.GetDynamicTag("task", iter); if (task_tag != null) { if (task_tag.Uri != task.Uri) { continue; } Gtk.TextIter line_start = iter; while (line_start.StartsLine() == false) { line_start.BackwardChar(); } Gtk.TextIter line_end = iter; while (line_end.EndsLine() == false) { line_end.ForwardChar(); } // line_end.ForwardToLineEnd (); Buffer.Delete(ref line_start, ref line_end); last_removed_tag = task_tag; Buffer.Insert(ref line_start, string.Format("{0}: {1}", Catalog.GetString("todo"), task.Summary)); task_tag.fillByData(task.Data); break; } } while (iter.ForwardLine()); }
TaskTag GetTaskTagFromLineIter(ref Gtk.TextIter line_iter) { TaskTag task_tag = null; while (line_iter.StartsLine() == false) { line_iter.BackwardChar(); } task_tag = (TaskTag)Buffer.GetDynamicTag("task", line_iter); return(task_tag); }
/// <summary> /// Each time the user enters a newline (presses enter), /// evaluate the previous line to see if a new task should /// be created or the previous one removed... /// </summary> bool ProcessNewline() { Gtk.TextIter iter = Buffer.GetIterAtMark(Buffer.InsertMark); Gtk.TextIter prev_line = iter; if (prev_line.BackwardLine() == false) { return(false); } TaskTag task_tag = GetTaskTagFromLineIter(ref prev_line); if (task_tag == null) { return(false); // nothing to do with tasks here! } Task task = TasksApplicationAddin.DefaultTaskManager.FindByUri(task_tag.Uri); if (task == null) { // This shouldn't happen, but just in case we have a left-over // TaskTag without a real task, go ahead and remove the TaskTag // FIXME: Remove TaskTag from the line return(false); } if (task.Summary == string.Empty) { // If the previous line's task summary is empty, delete the task Logger.Debug("Previous line's task summary is empty, deleting it..."); TasksApplicationAddin.DefaultTaskManager.Delete(task); } else { // If the previous line's task summary is not empty, create a new // task on the current line. // I'm disabling the following code for now. It automatically // starts up a new task on the newline. But since this modifies // the buffer, it sometimes causes problems. // TODO: Make the auto-newline work // Buffer.InsertAtCursor ( // string.Format ("{0}: ", // Catalog.GetString ("todo"))); } return(true); // The buffer was modified }
void UpdateTaskTagStatuses() { // FIXME: Should really just create an enumerator class for // enumerating a Buffer's TaskTags instead of doing it this // way in almost every method. Gtk.TextIter iter = Buffer.StartIter; iter.ForwardLine(); // Move past the note's title do { TaskTag task_tag = (TaskTag) Buffer.GetDynamicTag("task", iter); if (task_tag == null) { continue; } task_tag.UpdateStatus(); } while (iter.ForwardLine()); }
void OnPopulatePopup(object sender, Gtk.PopulatePopupArgs args) { Gtk.TextIter click_iter = Buffer.GetIterAtMark(click_mark); TaskTag task_tag = (TaskTag) Buffer.GetDynamicTag("task", click_iter); if (task_tag == null) { return; } Gtk.MenuItem item; item = new Gtk.SeparatorMenuItem(); item.Show(); args.Menu.Prepend(item); item = new Gtk.MenuItem(Catalog.GetString("Open To Do List")); item.Activated += OnOpenTaskListWindow; item.Show(); args.Menu.Prepend(item); item = new TaskMenuItem(task_tag.Uri, Catalog.GetString("To Do Options")); item.Activated += OnOpenTaskOptions; item.ShowAll(); args.Menu.Prepend(item); item = new TaskMenuItem( task_tag.Uri, task_tag.CompletionDate == DateTime.MinValue ? Catalog.GetString("Mark Complete") : Catalog.GetString("Mark Undone")); item.Activated += OnToggleCompletionStatus; item.ShowAll(); args.Menu.Prepend(item); }
void OnTagRemoved (object sender, Gtk.TagRemovedArgs args) { TaskTag task_tag = args.Tag as TaskTag; if (task_tag == null) return; last_removed_tag = task_tag; }
void OnInsertText (object sender, Gtk.InsertTextArgs args) { Gtk.TextIter start = args.Pos; //Logger.Debug ("TaskNoteAddin.OnInsertText:\n" + // "\tLength: {0}\n" + // "\tText: {1}\n" + // "\tLine: {2}", // args.Length, // args.Text, // args.Pos.Line); if (args.Length == 1 && args.Text == "\n") { Gtk.TextIter curr_line = args.Pos; TaskTag task_tag = GetTaskTagFromLineIter (ref curr_line); Gtk.TextIter prev_line = args.Pos; prev_line.BackwardLine (); /*TaskTag*/ task_tag = GetTaskTagFromLineIter (ref prev_line); if (task_tag != null) { // If the user just entered a newline and the previous // line was a task, do some special processing...but // we have to do it on idle since there are other // Buffer.InsertText handlers that we'll screw up if // we modify anything here. args.RetVal = ProcessNewline (); } else { // Check to see if the previous line is a todo: line while (prev_line.StartsLine () == false) { prev_line.BackwardChar (); } Gtk.TextIter prev_line_end = prev_line; while (prev_line_end.EndsLine () == false) { prev_line_end.ForwardChar (); } string prev_line_text = prev_line.GetText (prev_line_end); Match match = regex.Match (prev_line_text); if (match.Success && last_removed_tag != null) { TaskManager task_mgr = TasksApplicationAddin.DefaultTaskManager; Task task; task = task_mgr.FindByUri (last_removed_tag.Uri); if (task != null) { // Update the task's summary and make sure that // the previous line is appropriately tagged. string summary = GetTaskSummaryFromLine (prev_line_text); task.Summary = summary; Buffer.ApplyTag (last_removed_tag, prev_line, prev_line_end); } else { Logger.Debug ("Shouldn't ever hit this code (hopefully)"); } } last_removed_tag = null; } } else { ApplyTaskTagToBlock (ref start, args.Pos); } }
/// <summary> /// If the renamed task is included inside this note, this /// handler will update the task summary in the note buffer. /// </summary> private void OnTaskRenamed (Task task, string old_title) { if (task.OriginNoteUri == null || task.OriginNoteUri != Note.Uri) return; // Search through the note looking for the TaskTag so that it can // be renamed if (!ContainsText (old_title)) return; // Iterate through the lines looking for tasks Gtk.TextIter iter = Buffer.StartIter; iter.ForwardLine (); // Move past the note's title do { TaskTag task_tag = (TaskTag) Buffer.GetDynamicTag ("task", iter); if (task_tag != null) { if (task_tag.Uri != task.Uri) continue; Gtk.TextIter line_start = iter; while (line_start.StartsLine () == false) line_start.BackwardChar (); Gtk.TextIter line_end = iter; while (line_end.EndsLine () == false) { line_end.ForwardChar (); } // line_end.ForwardToLineEnd (); Buffer.Delete (ref line_start, ref line_end); last_removed_tag = task_tag; Buffer.Insert (ref line_start, string.Format ("{0}: {1}", Catalog.GetString ("todo"), task.Summary)); break; } } while (iter.ForwardLine()); }
/// <summary> /// Remove the task tag on the line specified by the TextIter. This /// will not remove the "todo:" text (i.e., it will not modify the /// actual characters of the TextBuffer. /// <param name="iter">The TextIter specifying the line where the /// TaskTag should be removed.</param> /// <returns>True if a TaskTag was removed, otherwise False.</returns> /// </summary> bool RemoveTaskTagFromLine (Gtk.TextIter iter) { Gtk.TextIter start = iter; Gtk.TextIter end = iter; TaskTag task_tag = GetTaskTagFromLineIter (ref start); if (task_tag == null) return false; while (start.StartsLine () == false) { start.BackwardChar (); } while (end.EndsLine () == false) { end.ForwardChar (); } // end.ForwardToLineEnd (); last_removed_tag = null; Buffer.RemoveTag (task_tag, start, end); return true; }
void ApplyTaskTagToBlock (ref Gtk.TextIter start, Gtk.TextIter end) { Gtk.TextIter line_end = start; while (line_end.EndsLine () == false) { line_end.ForwardChar (); } // For some reason, the above code behaves like it should (i.e., // without advancing to the next line). The line below that's // commented out doesn't work. It ends up advancing the iter to // the end of the next line. Very strange! // line_end.ForwardToLineEnd (); TaskTag task_tag = GetTaskTagFromLineIter (ref start); if (task_tag != null) { Buffer.RemoveTag (task_tag, start, line_end); } else { task_tag = last_removed_tag; } string text = start.GetText (line_end); // Logger.Debug ("Evaluating with regex: {0}", text); TaskManager task_mgr = TasksApplicationAddin.DefaultTaskManager; Task task; Match match = regex.Match (text); if (match.Success) { string summary = GetTaskSummaryFromLine (text); if (task_tag == null) { task = task_mgr.Create (summary); task.QueueSave (true); task.OriginNoteUri = Note.Uri; task_tag = (TaskTag) Note.TagTable.CreateDynamicTag ("task"); task_tag.Uri = task.Uri; } else { task = task_mgr.FindByUri (task_tag.Uri); if (task != null) { task.Summary = summary; } else { Logger.Debug ("FIXME: Add code to remove the task tag if this case is hit"); } } Buffer.ApplyTag (task_tag, start, line_end); last_removed_tag = null; } else if (task_tag != null) { // This task should be deleted task = task_mgr.FindByUri (task_tag.Uri); if (task != null) { task_mgr.Delete (task); } last_removed_tag = null; } }
void OnInsertText(object sender, Gtk.InsertTextArgs args) { Gtk.TextIter start = args.Pos; //Logger.Debug ("TaskNoteAddin.OnInsertText:\n" + // "\tLength: {0}\n" + // "\tText: {1}\n" + // "\tLine: {2}", // args.Length, // args.Text, // args.Pos.Line); if (args.Length == 1 && args.Text == "\n") { Gtk.TextIter curr_line = args.Pos; TaskTag task_tag = GetTaskTagFromLineIter(ref curr_line); Gtk.TextIter prev_line = args.Pos; prev_line.BackwardLine(); /*TaskTag*/ task_tag = GetTaskTagFromLineIter(ref prev_line); if (task_tag != null) { // If the user just entered a newline and the previous // line was a task, do some special processing...but // we have to do it on idle since there are other // Buffer.InsertText handlers that we'll screw up if // we modify anything here. args.RetVal = ProcessNewline(); } else { // Check to see if the previous line is a todo: line while (prev_line.StartsLine() == false) { prev_line.BackwardChar(); } Gtk.TextIter prev_line_end = prev_line; while (prev_line_end.EndsLine() == false) { prev_line_end.ForwardChar(); } string prev_line_text = prev_line.GetText(prev_line_end); Match match = regex.Match(prev_line_text); if (match.Success && last_removed_tag != null) { TaskManager task_mgr = TasksApplicationAddin.DefaultTaskManager; Task task; task = task_mgr.FindByUri(last_removed_tag.Uri); if (task != null) { // Update the task's summary and make sure that // the previous line is appropriately tagged. string summary = GetTaskSummaryFromLine(prev_line_text); task.Summary = summary; Buffer.ApplyTag(last_removed_tag, prev_line, prev_line_end); } else { Logger.Debug("Shouldn't ever hit this code (hopefully)"); } } last_removed_tag = null; } } else { ApplyTaskTagToBlock(ref start, args.Pos); } }
void ApplyTaskTagToBlock(ref Gtk.TextIter start, Gtk.TextIter end) { Gtk.TextIter line_end = start; while (line_end.EndsLine() == false) { line_end.ForwardChar(); } // For some reason, the above code behaves like it should (i.e., // without advancing to the next line). The line below that's // commented out doesn't work. It ends up advancing the iter to // the end of the next line. Very strange! // line_end.ForwardToLineEnd (); TaskTag task_tag = GetTaskTagFromLineIter(ref start); if (task_tag != null) { Buffer.RemoveTag(task_tag, start, line_end); } else { task_tag = last_removed_tag; } string text = start.GetText(line_end); // Logger.Debug ("Evaluating with regex: {0}", text); TaskManager task_mgr = TasksApplicationAddin.DefaultTaskManager; Task task; Match match = regex.Match(text); if (match.Success) { string summary = GetTaskSummaryFromLine(text); if (task_tag == null) { task = task_mgr.Create(summary); task.QueueSave(true); task.OriginNoteUri = Note.Uri; task_tag = (TaskTag) Note.TagTable.CreateDynamicTag("task"); task_tag.Uri = task.Uri; } else { task = task_mgr.FindByUri(task_tag.Uri); if (task != null) { task.Summary = summary; } else { Logger.Debug("FIXME: Add code to remove the task tag if this case is hit"); } } Buffer.ApplyTag(task_tag, start, line_end); last_removed_tag = null; } else if (task_tag != null) { // This task should be deleted task = task_mgr.FindByUri(task_tag.Uri); if (task != null) { task_mgr.Delete(task); } last_removed_tag = null; } }