/// <summary> /// This method should be called during a large deletion of a /// range of text so it can properly remove all the task tags. /// </summary> void RemoveTaskTagsFromRange(Gtk.TextIter start, Gtk.TextIter end) { TaskTag task_tag; Gtk.TextIter line; Gtk.TextIter line_start; Gtk.TextIter line_end; if (start.Line == end.Line) { // The iters are on the same line. // If there's only one character being deleted, don't do // anything here. This condition will be taken care of // in ApplyTaskTagToBlock (). if (end.LineOffset - start.LineOffset == 1) { return; } // Determine whether this line contains a TaskTag. If it // does, determine whether deleting the range will delete // the todo. line = start; task_tag = GetTaskTagFromLineIter(ref line); if (task_tag != null) { if (start.LineIndex == 0) { // Start iter is at beginning of line if (end.LineOffset >= Catalog.GetString("todo:").Length) { RemoveTaskTagFromLine(start); } } else if (start.LineIndex < Catalog.GetString("todo:").Length) { // The start of the range is inside the "todo:" area, // so the TaskTag needs to be removed. RemoveTaskTagFromLine(start); } else { // Do nothing. The deletion is just inside the // summary of the task. } } } else { // The iters are on different lines line = start; do { task_tag = GetTaskTagFromLineIter(ref line); if (task_tag != null) { // Handle the first and last lines special since their // range may not span the entire line. if (line.Line == start.Line) { // This is the first line line_end = line; while (line_end.EndsLine() == false) { line_end.ForwardChar(); } // line_end.ForwardToLineEnd (); RemoveTaskTagsFromRange(start, line_end); } else if (line.Line == end.Line) { // This is the last line line_start = line; while (line_start.StartsLine() == false) { line_start.BackwardChar(); } RemoveTaskTagsFromRange(line_start, end); } else { // This line is in the middle of the range // so it's completely safe to remove the TaskTag RemoveTaskTagFromLine(line); } // Delete the task TaskManager task_mgr = TasksApplicationAddin.DefaultTaskManager; Task task = task_mgr.FindByUri(task_tag.Uri); if (task != null) { task_mgr.Delete(task); } } } while (line.ForwardLine() && line.Line <= end.Line); } }
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; } }