Esempio n. 1
0
    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
Esempio n. 2
0
    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
Esempio n. 3
0
    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
Esempio n. 4
0
    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