def follow_if_link(self, text_view: 'LinkedTimeView', itr: Gtk.TextIter) -> bool: """Looks at all tags covered by the TextIter position in the text view, and if one of them is a time link, emit a signal to display the timer """ blue = Gdk.RGBA(red=0., green=0, blue=1., alpha=1.) tags = itr.get_tags() for tag in tags: color = tag.get_property('foreground-rgba') if color and color == blue: # By Gourmet convention, only links have color start_sentence = itr.copy() start_sentence.backward_sentence_start() end_sentence = itr.copy() if not end_sentence.ends_sentence(): end_sentence.forward_sentence_end() sentence = self.get_buffer().get_slice(start_sentence, end_sentence, False) start_ts = itr.copy() start_ts.backward_to_tag_toggle(tag) itr.forward_to_tag_toggle(tag) end_ts = itr.copy() time_string = self.get_buffer().get_slice(start_ts, end_ts, False) self.emit("time-link-activated", time_string, sentence) return True return False
def follow_if_link(self, text_view: 'LinkedTextView', itr: Gtk.TextIter) -> None: """Looks at all tags covering the position of iter in the text view, and if one of them is a link, follow it by showing the page identified by the data attached to it. """ blue = Gdk.RGBA(red=0, green=0, blue=1., alpha=1.) tags = itr.get_tags() for tag in tags: color = tag.get_property('foreground-rgba') if color and color == blue: begin = itr.copy() begin.forward_to_tag_toggle(tag) end = itr.copy() end.backward_to_tag_toggle(tag) link_text = text_view.get_buffer().get_text(begin, end) target = text_view.get_buffer().markup_dict[link_text] self.emit('link-activated', target) break
def detect_subtasks(self, text: str, start: Gtk.TextIter) -> bool: """Detect a subtask line. Returns True if a subtask was found.""" # This function has three paths: # * "Initial" Path: We find the line starts with '- ' and has text. # * "Modified" Path: We find the line starts with a subtask tag # * "None" Path: The line doesn't have any subtasks # The structure of a subtask in terms of text tags is: # <subtask> # <checkbox>[ ]</checkbox> # <internal-link>Subtask name</internal-link> # </subtask> # Add a new subtask if text.startswith('- ') and len(text[2:]) > 0: # Remove the - delete_end = start.copy() delete_end.forward_chars(2) self.buffer.delete(start, delete_end) # Add new subtask tid = self.new_subtask_cb(text[2:]) task = self.req.get_task(tid) status = task.get_status() if task else 'Active' # Add the checkbox self.add_checkbox(tid, start) after_checkbox = start.copy() after_checkbox.forward_char() # Add the internal link link_tag = InternalLinkTag(tid, status) self.table.add(link_tag) end = start.copy() end.forward_to_line_end() self.buffer.apply_tag(link_tag, after_checkbox, end) self.tags_applied.append(link_tag) # Add the subtask tag start.backward_char() subtask_tag = SubTaskTag(tid) self.table.add(subtask_tag) self.buffer.apply_tag(subtask_tag, start, end) self.subtasks['tags'].append(tid) return True # A subtask already exists elif start.starts_tag(): # Detect if it's a subtask tag sub_tag = None for tag in start.get_tags(): if type(tag) == SubTaskTag: sub_tag = tag # Otherwise return early if not sub_tag: return False # Don't auto-remove it tid = sub_tag.tid task = self.req.get_task(tid) parents = task.get_parents() # Remove if its not a child of this task if not parents or parents[0] != self.tid: log.debug('Task %s is not a subtask of %s', tid, self.tid) log.debug('Removing subtask %s from content', tid) end = start.copy() end.forward_to_line_end() # Move the start iter to take care of the newline at # the previous line start.backward_chars(2) self.buffer.delete(start, end) return False # Check that we still have a checkbox after_checkbox = start.copy() after_checkbox.forward_char() has_checkbox = any(type(t) == CheckboxTag for t in after_checkbox.get_tags()) if not has_checkbox: check = self.buffer.get_slice(start, after_checkbox, True) # Check that there's still a checkbox. If the user has # deleted all text including the space after the checkbox, # the check for the tag will return False. In this case # we want to check if the checkbox is still around, if it # is the user might still type a new name for the task. # Otherwise, if the checkbox was deleted, we return and let # the text tags be deleted. if check != u'\uFFFC': return False try: self.subtasks['to_delete'].remove(tid) except ValueError: pass self.rename_subtask_cb(tid, text) # Get the task and instantiate an internal link tag status = task.get_status() if task else 'Active' link_tag = InternalLinkTag(tid, status) self.table.add(link_tag) # Apply the new internal link tag (which was removed # by process()) end = start.copy() end.forward_to_line_end() self.buffer.apply_tag(link_tag, after_checkbox, end) self.tags_applied.append(link_tag) # Re-apply the subtask tag too self.table.remove(sub_tag) subtask_tag = SubTaskTag(tid) self.table.add(subtask_tag) self.buffer.apply_tag(subtask_tag, start, end) return True # No subtask, no fun else: return False
def detect_subtasks(self, text: str, start: Gtk.TextIter) -> bool: """Detect a subtask line. Returns True if a subtask was found.""" # This function has three paths: # * "Initial" Path: We find the line starts with '- ' and has text. # * "Modified" Path: We find the line starts with a subtask tag # * "None" Path: The line doesn't have any subtasks # The structure of a subtask in terms of text tags is: # <subtask> # <checkbox>[ ]</checkbox> # <internal-link>Subtask name</internal-link> # </subtask> # Add a new subtask if text.startswith('- ') and len(text[2:]) > 0: # Remove the - delete_end = start.copy() delete_end.forward_chars(2) self.buffer.delete(start, delete_end) # Add new subtask tid = self.new_subtask_cb(text[2:]) task = self.req.get_task(tid) status = task.get_status() if task else 'Active' # Add the checkbox self.add_checkbox(tid, start) after_checkbox = start.copy() after_checkbox.forward_char() # Add the internal link link_tag = InternalLinkTag(tid, status) self.table.add(link_tag) end = start.copy() end.forward_to_line_end() self.buffer.apply_tag(link_tag, after_checkbox, end) self.tags_applied.append(link_tag) # Add the subtask tag start.backward_char() subtask_tag = SubTaskTag(tid) self.table.add(subtask_tag) self.buffer.apply_tag(subtask_tag, start, end) self.subtasks['tags'].append(tid) return True # A subtask already exists elif start.starts_tag(): # Detect if it's a subtask tag sub_tag = None for tag in start.get_tags(): if type(tag) == SubTaskTag: sub_tag = tag # Otherwise return early if not sub_tag: return False # Check that we still have a checkbox after_checkbox = start.copy() after_checkbox.forward_char() has_checkbox = any(type(t) == CheckboxTag for t in after_checkbox.get_tags()) if not has_checkbox: return False # Don't auto-remove it tid = sub_tag.tid try: self.subtasks['to_delete'].remove(tid) except ValueError: pass self.rename_subtask_cb(tid, text) # Get the task and instantiate an internal link tag task = self.req.get_task(tid) status = task.get_status() if task else 'Active' link_tag = InternalLinkTag(tid, status) self.table.add(link_tag) # Apply the new internal link tag (which was removed # by process()) end = start.copy() end.forward_to_line_end() self.buffer.apply_tag(link_tag, after_checkbox, end) self.tags_applied.append(link_tag) # Re-apply the subtask tag too self.table.remove(sub_tag) subtask_tag = SubTaskTag(tid) self.table.add(subtask_tag) self.buffer.apply_tag(subtask_tag, start, end) return True # No subtask, no fun else: return False