Exemplo n.º 1
0
    def render_cell(self, context, bounds, widget, flags, really=True):
        if not bounds:
            return -1
        x, y, cell_width, h = bounds

        self.selected_color = widget.get_style().text[gtk.STATE_SELECTED]
        self.normal_color = widget.get_style().text[gtk.STATE_NORMAL]

        g = graphics.Graphics(context)

        fact = self.data

        selected = flags and flags & gtk.CELL_RENDERER_SELECTED

        text_color = self.normal_color
        if selected:
            text_color = self.selected_color
        """ start time and end time at beginning of column """
        interval = fact.start_time.strftime("%H:%M -")
        if fact.end_time:
            interval = "%s %s" % (interval, fact.end_time.strftime("%H:%M"))

        self.interval_label.text = interval
        self.interval_label.color = text_color
        self.interval_label.x = self.col_padding
        self.interval_label.y = 2
        """ duration at the end """
        self.duration_label.text = stuff.format_duration(fact.delta)
        self.duration_label.color = text_color
        self.duration_label.x = cell_width - self.duration_label.width
        self.duration_label.y = 2
        """ activity, category, tags, description in middle """
        # we want our columns look aligned, so we will do fixed offset from
        # both sides, in letter length

        cell_start = widget.longest_interval
        cell_width = cell_width - widget.longest_interval - widget.longest_duration

        # align activity and category (ellipsize activity if it does not fit)
        category_width = 0

        self.category_label.text = ""
        if fact.category:
            self.category_label.text = " - <small>%s</small>" % stuff.escape_pango(
                fact.category)
            if not selected:
                category_color = graphics.Colors.contrast(text_color, 100)

                self.category_label.color = category_color
            else:
                self.category_label.color = text_color
            category_width = self.category_label.width

        self.activity_label.color = text_color
        self.activity_label.width = None
        self.activity_label.text = stuff.escape_pango(fact.name)

        # if activity label does not fit, we will shrink it
        if self.activity_label.width > cell_width - category_width:
            self.activity_label.width = (cell_width - category_width -
                                         self.col_padding)
            self.activity_label.ellipsize = pango.ELLIPSIZE_END
        else:
            self.activity_label.width = None
            #self.activity_label.ellipsize = None

        activity_width = self.activity_label.width

        y = 2

        self.activity_label.x = cell_start
        self.activity_label.y = y

        self.category_label.x = cell_start + activity_width
        self.category_label.y = y

        x = cell_start + activity_width + category_width + 12

        current_height = 0
        if fact.tags:
            # try putting tags on same line if they fit
            # otherwise move to the next line
            tags_end = cell_start + cell_width

            tag = Tag(fact.tags[0])

            if x + tag.width > tags_end:
                x = cell_start
                y = self.activity_label.height + 4

            for i, tag in enumerate(fact.tags):
                tag = Tag(tag)

                if x + tag.width >= tags_end:
                    x = cell_start
                    y += tag.height + 4

                tag.x, tag.y = x, y
                if really:
                    tag._draw(context)

                x += tag.width + 4

            current_height = y + tag.height + 4

        current_height = max(self.activity_label.height + 2, current_height)

        # see if we can fit in single line
        # if not, put description under activity
        self.description_label.text = ""
        if fact.description:
            self.description_label.text = "<small>%s</small>" % stuff.escape_pango(
                fact.description)
            self.description_label.color = text_color
            self.description_label.wrap = pango.WRAP_WORD

            description_width = self.description_label.width
            width = cell_width - x

            if description_width > width:
                x = cell_start
                y = current_height
                self.description_label.width = cell_width
            else:
                self.description_label.width = None

            self.description_label.x = x
            self.description_label.y = y

            current_height = max(
                current_height,
                self.description_label.y + self.description_label.height + 5)

        self.labels._draw(context)

        return current_height
Exemplo n.º 2
0
class FactCellRenderer(gtk.GenericCellRenderer):
    """ We need all kinds of wrapping and spanning and the treeview just does
        not cut it"""

    __gproperties__ = {
        "data": (gobject.TYPE_PYOBJECT, "Data", "Data", gobject.PARAM_READWRITE),
    }

    def __init__(self):
        gtk.GenericCellRenderer.__init__(self)
        self.height = 0
        self.data = None

        font = gtk.Style().font_desc
        self.default_size = font.get_size() / pango.SCALE

        self.labels = graphics.Sprite()

        self.date_label = graphics.Label(size = self.default_size)

        self.interval_label = graphics.Label(size = self.default_size)
        self.labels.add_child(self.interval_label)

        self.activity_label = graphics.Label(size = self.default_size)
        self.labels.add_child(self.activity_label)

        self.category_label = graphics.Label(size = self.default_size)
        self.labels.add_child(self.category_label)

        self.description_label = graphics.Label(size = self.default_size)
        self.labels.add_child(self.description_label)

        self.duration_label = graphics.Label(size=self.default_size)
        self.labels.add_child(self.duration_label)

        default_font = gtk.Style().font_desc.to_string()

        self.tag = Tag("")

        self.selected_color = None
        self.normal_color = None

        self.col_padding = 10
        self.row_padding = 4

    def do_set_property (self, pspec, value):
        setattr(self, pspec.name, value)

    def do_get_property(self, pspec):
        return getattr (self, pspec.name)


    def on_render (self, window, widget, background_area, cell_area, expose_area, flags):
        if not self.data:
            return

        """
          ASCII Art
          --------------+--------------------------------------------+-------+---+
          13:12 - 17:18 | Some activity - category  tag, tag, tag,   | 14:44 | E |
                        | tag, tag, some description                 |       |   |
          --------------+--------------------------------------------+-------+---+
        """
        # set the colors
        self.selected_color = widget.get_style().text[gtk.STATE_SELECTED]
        self.normal_color = widget.get_style().text[gtk.STATE_NORMAL]

        context = window.cairo_create()

        if isinstance(self.data, FactRow):
            fact, parent = self.data, None
        else:
            parent, fact = self.data, None


        x, y, width, height = cell_area
        context.translate(x, y)

        if flags & gtk.CELL_RENDERER_SELECTED:
            text_color = self.selected_color
        else:
            text_color = self.normal_color

        self.date_label.color = text_color
        self.duration_label.color = text_color

        if parent:
            self.date_label.text = "<b>%s</b>" % stuff.escape_pango(parent.label)
            self.date_label.x = 5

            if self.data.first:
                y = 5
            else:
                y = 20

            self.date_label.y = y


            self.duration_label.text = "<b>%s</b>" % stuff.format_duration(parent.duration)
            self.duration_label.x = width - self.duration_label.width
            self.duration_label.y = y

            self.date_label._draw(context)
            self.duration_label._draw(context)
        else:
            self.render_cell(context, (x,y,width,height), widget, flags)


    def render_cell(self, context, bounds, widget, flags, really = True):
        if not bounds:
            return -1
        x, y, cell_width, h = bounds

        self.selected_color = widget.get_style().text[gtk.STATE_SELECTED]
        self.normal_color = widget.get_style().text[gtk.STATE_NORMAL]

        g = graphics.Graphics(context)

        fact = self.data

        selected = flags and flags & gtk.CELL_RENDERER_SELECTED

        text_color = self.normal_color
        if selected:
            text_color = self.selected_color



        """ start time and end time at beginning of column """
        interval = fact.start_time.strftime("%H:%M -")
        if fact.end_time:
            interval = "%s %s" % (interval, fact.end_time.strftime("%H:%M"))

        self.interval_label.text = interval
        self.interval_label.color = text_color
        self.interval_label.x = self.col_padding
        self.interval_label.y = 2


        """ duration at the end """
        self.duration_label.text = stuff.format_duration(fact.delta)
        self.duration_label.color = text_color
        self.duration_label.x = cell_width - self.duration_label.width
        self.duration_label.y = 2


        """ activity, category, tags, description in middle """
        # we want our columns look aligned, so we will do fixed offset from
        # both sides, in letter length

        cell_start = widget.longest_interval
        cell_width = cell_width - widget.longest_interval - widget.longest_duration


        # align activity and category (ellipsize activity if it does not fit)
        category_width = 0

        self.category_label.text = ""
        if fact.category:
            self.category_label.text = " - <small>%s</small>" % stuff.escape_pango(fact.category)
            if not selected:
                category_color = graphics.Colors.contrast(text_color,  100)

                self.category_label.color = category_color
            else:
                self.category_label.color = text_color
            category_width = self.category_label.width


        self.activity_label.color = text_color
        self.activity_label.width = None
        if isinstance(fact, RedmineFactRow):
            text = fact.name
            text += " "
            text += fact.fact.redmine_tag()
            self.activity_label.text = stuff.escape_pango(text)
        else:
            self.activity_label.text = stuff.escape_pango(fact.name)

        # if activity label does not fit, we will shrink it
        if self.activity_label.width > cell_width - category_width:
            self.activity_label.width = (cell_width - category_width - self.col_padding)
            self.activity_label.ellipsize = pango.ELLIPSIZE_END
        else:
            self.activity_label.width = None
            #self.activity_label.ellipsize = None

        activity_width = self.activity_label.width

        y = 2

        self.activity_label.x = cell_start
        self.activity_label.y = y


        self.category_label.x = cell_start + activity_width
        self.category_label.y = y


        x = cell_start + activity_width + category_width + 12

        current_height = 0
        if fact.tags:
            # try putting tags on same line if they fit
            # otherwise move to the next line
            tags_end = cell_start + cell_width

            if x + self.tag.width > tags_end:
                x = cell_start
                y = self.activity_label.height + 4


            for i, tag in enumerate(fact.tags):
                self.tag.text = tag

                if x + self.tag.width >= tags_end:
                    x = cell_start
                    y += self.tag.height + 4

                self.tag.x, self.tag.y = x, y
                if really:
                    self.tag._draw(context)

                x += self.tag.width + 4

            current_height = y + self.tag.height + 4


        current_height = max(self.activity_label.height + 2, current_height)


        # see if we can fit in single line
        # if not, put description under activity
        self.description_label.text = ""
        if fact.description:
            self.description_label.text = "<small>%s</small>" % stuff.escape_pango(fact.description)
            self.description_label.color = text_color
            self.description_label.wrap = pango.WRAP_WORD

            description_width = self.description_label.width
            width = cell_width - x

            if description_width > width:
                x = cell_start
                y = current_height
                self.description_label.width = cell_width
            else:
                self.description_label.width = None

            self.description_label.x = x
            self.description_label.y = y

            current_height = max(current_height, self.description_label.y + self.description_label.height + 5)

        self.labels._draw(context)

        return current_height


    def on_get_size(self, widget, cell_area):
        if isinstance(self.data, GroupRow):
            if self.data.first:
                return (0, 0, 0, int((self.default_size + 10) * 1.5))
            else:
                return (0, 0, 0, (self.default_size + 10) * 2)


        context = gtk.gdk.CairoContext(cairo.Context(cairo.ImageSurface(cairo.FORMAT_A1, 0, 0)))
        area = widget.get_allocation()

        area.width -= 40 # minus the edit column, scrollbar and padding (and the scrollbar part is quite lame)

        cell_height = self.render_cell(context, area, widget, None, False)
        return (0, 0, -1, cell_height)
Exemplo n.º 3
0
    def render_cell(self, context, bounds, widget, flags, really = True):
        if not bounds:
            return -1
        x, y, cell_width, h = bounds

        self.selected_color = widget.get_style().text[gtk.STATE_SELECTED]
        self.normal_color = widget.get_style().text[gtk.STATE_NORMAL]

        g = graphics.Graphics(context)

        fact = self.data

        selected = flags and flags & gtk.CELL_RENDERER_SELECTED

        text_color = self.normal_color
        if selected:
            text_color = self.selected_color



        """ start time and end time at beginning of column """
        interval = fact.start_time.strftime("%H:%M -")
        if fact.end_time:
            interval = "%s %s" % (interval, fact.end_time.strftime("%H:%M"))

        self.interval_label.text = interval
        self.interval_label.color = text_color
        self.interval_label.x = self.col_padding
        self.interval_label.y = 2


        """ duration at the end """
        self.duration_label.text = stuff.format_duration(fact.delta)
        self.duration_label.color = text_color
        self.duration_label.x = cell_width - self.duration_label.width
        self.duration_label.y = 2


        """ activity, category, tags, description in middle """
        # we want our columns look aligned, so we will do fixed offset from
        # both sides, in letter length

        cell_start = widget.longest_interval
        cell_width = cell_width - widget.longest_interval - widget.longest_duration


        # align activity and category (ellipsize activity if it does not fit)
        category_width = 0

        self.category_label.text = ""
        if fact.category:
            self.category_label.text = " - <small>%s</small>" % stuff.escape_pango(fact.category)
            if not selected:
                category_color = graphics.Colors.contrast(text_color,  100)

                self.category_label.color = category_color
            else:
                self.category_label.color = text_color
            category_width = self.category_label.width


        self.activity_label.color = text_color
        self.activity_label.width = None
        self.activity_label.text = stuff.escape_pango(fact.name)

        # if activity label does not fit, we will shrink it
        if self.activity_label.width > cell_width - category_width:
            self.activity_label.width = (cell_width - category_width - self.col_padding)
            self.activity_label.ellipsize = pango.ELLIPSIZE_END
        else:
            self.activity_label.width = None
            #self.activity_label.ellipsize = None

        activity_width = self.activity_label.width

        y = 2

        self.activity_label.x = cell_start
        self.activity_label.y = y


        self.category_label.x = cell_start + activity_width
        self.category_label.y = y


        x = cell_start + activity_width + category_width + 12

        current_height = 0
        if fact.tags:
            # try putting tags on same line if they fit
            # otherwise move to the next line
            tags_end = cell_start + cell_width

            tag = Tag(fact.tags[0])

            if x + tag.width > tags_end:
                x = cell_start
                y = self.activity_label.height + 4


            for i, tag in enumerate(fact.tags):
                tag = Tag(tag)

                if x + tag.width >= tags_end:
                    x = cell_start
                    y += tag.height + 4

                tag.x, tag.y = x, y
                if really:
                    tag._draw(context)

                x += tag.width + 4

            current_height = y + tag.height + 4


        current_height = max(self.activity_label.height + 2, current_height)


        # see if we can fit in single line
        # if not, put description under activity
        self.description_label.text = ""
        if fact.description:
            self.description_label.text = "<small>%s</small>" % stuff.escape_pango(fact.description)
            self.description_label.color = text_color
            self.description_label.wrap = pango.WRAP_WORD

            description_width = self.description_label.width
            width = cell_width - x

            if description_width > width:
                x = cell_start
                y = current_height
                self.description_label.width = cell_width
            else:
                self.description_label.width = None

            self.description_label.x = x
            self.description_label.y = y

            current_height = max(current_height, self.description_label.y + self.description_label.height + 5)

        self.labels._draw(context)

        return current_height