bool OpenOrCreateLink(Gtk.TextIter start, Gtk.TextIter end) { string link_name = start.GetText(end); Note link = Manager.Find(link_name); if (link == null) { Logger.Debug("Creating note '{0}'...", link_name); try { link = Manager.Create(link_name); } catch { // Fail silently. } } // FIXME: We used to also check here for (link != this.Note), but // somehow this was causing problems receiving clicks for the // wrong instance of a note (see bug #413234). Since a // link:internal tag is never applied around text that's the same // as the current note's title, it's safe to omit this check and // also works around the bug. if (link != null) { Logger.Debug("Opening note '{0}' on click...", link_name); link.Window.Present(); return(true); } return(false); }
void ApplyWikiwordToBlock(Gtk.TextIter start, Gtk.TextIter end) { NoteBuffer.GetBlockExtents(ref start, ref end, 80 /* max wiki name */, broken_link_tag); Buffer.RemoveTag(broken_link_tag, start, end); for (Match match = regex.Match(start.GetText(end)); match.Success; match = match.NextMatch()) { System.Text.RegularExpressions.Group group = match.Groups [1]; Logger.Debug("Highlighting wikiword: '{0}' at offset {1}", group, group.Index); Gtk.TextIter start_cpy = start; start_cpy.ForwardChars(group.Index); end = start_cpy; end.ForwardChars(group.Length); if (Manager.Find(group.ToString()) == null) { Buffer.ApplyTag(broken_link_tag, start_cpy, end); } } }
/// <summary> /// Remove the task from the line specified by the TextIter. This /// will remove the TextTag and also the "todo:" portion of the line /// so it will no longer be a task. The task summary text will be /// left on the line. /// <param name="iter">The TextIter specifying the line where the /// task should be removed.</param> /// <returns>True if a task was removed, otherwise False.</returns> /// </summary> bool RemoveTaskFromLine(ref Gtk.TextIter iter) { if (RemoveTaskTagFromLine(iter) == false) { return(false); } while (iter.StartsLine() == false) { iter.BackwardChar(); } Gtk.TextIter line_end = iter; while (line_end.EndsLine() == false) { line_end.ForwardChar(); } // line_end.ForwardToLineEnd (); string text = iter.GetText(line_end); Buffer.Delete(ref iter, ref line_end); text = GetTaskSummaryFromLine(text); if (text.Length > 0) { Buffer.Insert(ref iter, text); } return(true); }
void HighlightNoteInBlock(Note find_note, Gtk.TextIter start, Gtk.TextIter end) { string buffer_text = start.GetText(end).ToLower(); string find_title_lower = find_note.Title.ToLower(); int idx = 0; while (true) { idx = buffer_text.IndexOf(find_title_lower, idx); if (idx < 0) { break; } TrieHit hit = new TrieHit(idx, idx + find_title_lower.Length, find_title_lower, find_note); DoHighlight(hit, start, end); idx += find_title_lower.Length; } }
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; } }