示例#1
0
    def __init__(self, cal, **kwargs):
        """
        Constructor.
        """
        CanvasTable.__init__(self, **kwargs)

        self.cal = cal
        self.range = kwargs.get('range')
        self.active_range = self.range
        self.selected = None

        # Create canvas items.
        self.scroll = hippo.CanvasScrollbars()
        self.hbox_top = hippo.CanvasBox(
            orientation=hippo.ORIENTATION_HORIZONTAL)
        self.vbox_top = hippo.CanvasBox()
        self.day_captions = CanvasTable()
        self.timeline = CanvasTimeline(self.cal)
        self.padding_left = hippo.CanvasBox()
        self.padding_right = hippo.CanvasBox()
        self.allday_view = CanvasHEventView(self.cal,
                                            yalign=hippo.ALIGNMENT_FILL)
        self.grid = CanvasGrid(self._new_cell)
        self.gridbox = hippo.CanvasBox(
            orientation=hippo.ORIENTATION_HORIZONTAL)
        self.vevent_views = {}
        self.hevent_views = {}
        self.allocs = {}
        self.allocs[self.padding_left] = (0, 0, 0, 0)
        self.allocs[self.padding_right] = (0, 0, 0, 0)

        self.vbox_top.append(self.day_captions)
        self.vbox_top.append(self.allday_view)
        self.day_captions.set_homogeneus_columns(True)

        self.hbox_top.append(self.padding_left)
        self.hbox_top.append(self.vbox_top, hippo.PACK_EXPAND)
        self.hbox_top.append(self.padding_right)

        self.gridbox.append(self.timeline)
        self.gridbox.append(self.grid, hippo.PACK_EXPAND)
        self.scroll.set_root(self.gridbox)

        self.add(self.hbox_top, 0, 1, 0, 1)
        self.add(self.scroll, 0, 1, 1, 2)
        self.set_row_expand(1, True)
        self.set_column_expand(0, True)
        self.allday_view.show_normal = False
        self.allday_view.connect('event-clicked', self.on_view_event_clicked)
        self.grid.connect('paint', self.on_grid_paint)
        self.grid.set_homogeneus_columns(True)
示例#2
0
    def __init__(self, cal, **kwargs):
        """
        Constructor.
        """
        CanvasTable.__init__(self, **kwargs)

        self.cal          = cal
        self.range        = kwargs.get('range')
        self.active_range = self.range
        self.selected     = None

        # Create canvas items.
        self.scroll        = hippo.CanvasScrollbars()
        self.hbox_top      = hippo.CanvasBox(orientation = hippo.ORIENTATION_HORIZONTAL)
        self.vbox_top      = hippo.CanvasBox()
        self.day_captions  = CanvasTable()
        self.timeline      = CanvasTimeline(self.cal)
        self.padding_left  = hippo.CanvasBox()
        self.padding_right = hippo.CanvasBox()
        self.allday_view   = CanvasHEventView(self.cal, yalign = hippo.ALIGNMENT_FILL)
        self.grid          = CanvasGrid(self._new_cell)
        self.gridbox       = hippo.CanvasBox(orientation = hippo.ORIENTATION_HORIZONTAL)
        self.vevent_views  = {}
        self.hevent_views  = {}
        self.allocs        = {}
        self.allocs[self.padding_left]  = (0, 0, 0, 0)
        self.allocs[self.padding_right] = (0, 0, 0, 0)

        self.vbox_top.append(self.day_captions)
        self.vbox_top.append(self.allday_view)
        self.day_captions.set_homogeneus_columns(True)

        self.hbox_top.append(self.padding_left)
        self.hbox_top.append(self.vbox_top, hippo.PACK_EXPAND)
        self.hbox_top.append(self.padding_right)

        self.gridbox.append(self.timeline)
        self.gridbox.append(self.grid, hippo.PACK_EXPAND)
        self.scroll.set_root(self.gridbox)

        self.add(self.hbox_top, 0, 1, 0, 1)
        self.add(self.scroll,   0, 1, 1, 2)
        self.set_row_expand(1, True)
        self.set_column_expand(0, True)
        self.allday_view.show_normal = False
        self.allday_view.connect('event-clicked', self.on_view_event_clicked)
        self.grid.connect('paint', self.on_grid_paint)
        self.grid.set_homogeneus_columns(True)
示例#3
0
class CanvasDayRange(CanvasTable, hippo.CanvasItem):
    """
    A canvas item that shows a range of days.
    """
    def __init__(self, cal, **kwargs):
        """
        Constructor.
        """
        CanvasTable.__init__(self, **kwargs)

        self.cal          = cal
        self.range        = kwargs.get('range')
        self.active_range = self.range
        self.selected     = None

        # Create canvas items.
        self.scroll        = hippo.CanvasScrollbars()
        self.hbox_top      = hippo.CanvasBox(orientation = hippo.ORIENTATION_HORIZONTAL)
        self.vbox_top      = hippo.CanvasBox()
        self.day_captions  = CanvasTable()
        self.timeline      = CanvasTimeline(self.cal)
        self.padding_left  = hippo.CanvasBox()
        self.padding_right = hippo.CanvasBox()
        self.allday_view   = CanvasHEventView(self.cal, yalign = hippo.ALIGNMENT_FILL)
        self.grid          = CanvasGrid(self._new_cell)
        self.gridbox       = hippo.CanvasBox(orientation = hippo.ORIENTATION_HORIZONTAL)
        self.vevent_views  = {}
        self.hevent_views  = {}
        self.allocs        = {}
        self.allocs[self.padding_left]  = (0, 0, 0, 0)
        self.allocs[self.padding_right] = (0, 0, 0, 0)

        self.vbox_top.append(self.day_captions)
        self.vbox_top.append(self.allday_view)
        self.day_captions.set_homogeneus_columns(True)

        self.hbox_top.append(self.padding_left)
        self.hbox_top.append(self.vbox_top, hippo.PACK_EXPAND)
        self.hbox_top.append(self.padding_right)

        self.gridbox.append(self.timeline)
        self.gridbox.append(self.grid, hippo.PACK_EXPAND)
        self.scroll.set_root(self.gridbox)

        self.add(self.hbox_top, 0, 1, 0, 1)
        self.add(self.scroll,   0, 1, 1, 2)
        self.set_row_expand(1, True)
        self.set_column_expand(0, True)
        self.allday_view.show_normal = False
        self.allday_view.connect('event-clicked', self.on_view_event_clicked)
        self.grid.connect('paint', self.on_grid_paint)
        self.grid.set_homogeneus_columns(True)


    def on_day_button_press_event(self, widget, event):
        date = datetime.datetime(*widget.date.timetuple()[:3])
        self.emit('time-clicked', date, event)
        self.emit('day-clicked', widget.date, event)


    def on_view_time_clicked(self, view, item, ev, time):
        date = datetime.date(*time.timetuple()[:3])
        self.emit('time-clicked', time, ev)
        self.emit('day-clicked', date, ev)


    def on_view_event_clicked(self, view, item, ev):
        self.emit('event-clicked', item.event, ev)


    def _new_cell(self):
        cell = CanvasDay(self.cal, xalign = hippo.ALIGNMENT_FILL)
        cell.connect('button-press-event', self.on_day_button_press_event)
        return cell


    def is_active(self, date):
        return self.active_range[0] <= date <= self.active_range[1]


    def _get_event_view(self, row, start, end, horizontal):
        if horizontal:
            if row in self.hevent_views:
                view = self.hevent_views[row]
                view.set_range(start, end)
                return view
            view = CanvasHEventView(self.cal, start, end)
            self.hevent_views[row] = view
        else:
            if row in self.vevent_views:
                view = self.vevent_views[row]
                view.set_range(start, end)
                return view
            view = CanvasVEventView(self.cal, start, end)
            self.vevent_views[row] = view
        view.connect('time-clicked',  self.on_view_time_clicked)
        view.connect('event-clicked', self.on_view_event_clicked)
        self.allocs[view] = (0, 0, 0, 0)
        self.gridbox.append(view, hippo.PACK_FIXED)
        return view


    def _remove_vevent_view(self, cell):
        if cell not in self.vevent_views:
            return
        view = self.vevent_views[cell]
        self.gridbox.remove(view)
        del self.vevent_views[cell]
        del self.allocs[view]


    def _remove_hevent_view(self, cell):
        if cell not in self.hevent_views:
            return
        view = self.hevent_views[cell]
        self.gridbox.remove(view)
        del self.hevent_views[cell]
        del self.allocs[view]


    def update_one_row(self):
        self.scroll.set_policy(hippo.ORIENTATION_VERTICAL,
                               hippo.SCROLLBAR_ALWAYS)
        self.grid.set_properties(box_height = 800)
        self.allday_view.set_range(*self.range)
        self.allday_view.set_visible(True)
        self.padding_left.set_visible(True)
        self.padding_right.set_visible(True)

        # Hide all event views.
        for cell in [c for c in self.hevent_views]:
            self._remove_hevent_view(cell)
        current_children = self.grid.get_children()
        for cell in [c for c in self.vevent_views]:
            if cell not in current_children:
                self._remove_vevent_view(cell)

        # Create an event view on top of each cell.
        for child in self.grid.get_children():
            start = child.date
            end   = util.end_of_day(child.date)
            view  = self._get_event_view(child, start, end, False)
            self.allocs[view] = (0, 0, 0, 0)
            view.update()


    def update_multi_row(self):
        self.scroll.set_policy(hippo.ORIENTATION_VERTICAL,
                               hippo.SCROLLBAR_NEVER)
        self.grid.set_properties(box_height = -1)
        self.allday_view.set_visible(False)
        self.padding_left.set_visible(False)
        self.padding_right.set_visible(False)

        # Hide all event views.
        for cell in [c for c in self.vevent_views]:
            self._remove_vevent_view(cell)
        current_children = self.grid.get_children()
        for cell in [c for c in self.hevent_views]:
            if cell not in current_children:
                self._remove_hevent_view(cell)

        # Create an event view on top of each row.
        for row in self.grid.get_rows():
            start = row[0].date
            end   = row[-1].date
            view  = self._get_event_view(row[0], start, end, True)
            self.allocs[view] = (0, 0, 0, 0)
            view.update()


    def update(self):
        date  = self.range[0]
        days  = (self.range[1] - self.range[0]).days + 1
        rows  = int(math.ceil(float(days) / 7.0))
        cols  = days
        today = datetime.date(*time.localtime(time.time())[:3])
        if days > 7:
            cols = int(math.ceil(float(days) / float(rows)))

        # Update the timeline.
        self.timeline.set_visible(rows == 1)

        # Show captions for the day.
        if cols == 7 or rows == 1:
            for child in self.day_captions.get_children():
                self.day_captions.remove(child)
            for col in range(cols):
                this_date = self.range[0] + datetime.timedelta(col)
                day_name  = self.cal.model.get_day_name(this_date)
                text      = hippo.CanvasText(text      = day_name,
                                             xalign    = hippo.ALIGNMENT_CENTER,
                                             size_mode = hippo.CANVAS_SIZE_ELLIPSIZE_END)
                self.day_captions.add(text, col, col + 1, 0, 1)
                self.day_captions.set_column_expand(col, True)
            self.day_captions.set_visible(True)
        else:
            self.day_captions.set_visible(False)

        # Update the grid.
        self.grid.set_size(rows, cols)
        for row in range(rows):
            self.grid.set_row_expand(row, True)
        for child in self.grid.get_children():
            child.set_active(self.is_active(date))
            child.set_show_title(rows != 1)
            child.set_show_rulers(rows == 1)
            child.set_selected(date == self.selected)
            child.set_highlighted(date == today)
            child.set_date(date)
            child.update()
            date = util.next_day(date)

        if rows == 1:
            self.update_one_row()
        else:
            self.update_multi_row()


    def do_allocate_one_row(self, width, height, origin_changed):
        grid_x, grid_y = self.gridbox.get_position(self.grid)
        for cell in self.grid.get_children():
            cell_x_off,  cell_y_off  = self.grid.get_position(cell)
            cell_w,      cell_h      = cell.get_allocation()
            x                        = grid_x + cell_x_off
            y                        = grid_y + cell_y_off
            w                        = cell_w
            h                        = cell_h
            view                     = self.vevent_views[cell]
            alloc                    = (x, y, w, h)

            if self.allocs[view] == alloc:
                continue
            self.allocs[view] = alloc
            self.gridbox.set_position(view, alloc[0], alloc[1])
            view.set_properties(box_width  = alloc[2],
                                box_height = alloc[3])


    def do_allocate_multi_row(self, width, height, origin_changed):
        days           = (self.range[1] - self.range[0]).days + 1
        rows           = int(math.ceil(float(days) / 7.0))
        cols           = days
        grid_x, grid_y = self.gridbox.get_position(self.grid)
        if days > 7:
            cols = int(math.ceil(float(days) / float(rows)))

        for row in self.grid.get_rows():
            start = row[0].date
            end   = row[-1].date
            view  = self._get_event_view(row[0], start, end, True)
            view.set_column_count(cols)

            # Find the position of the writable area of the row.
            grid_w,      grid_h      = self.grid.get_allocation()
            row_x_off,   row_y_off   = self.grid.get_position(row[0])
            cell_w,      cell_h      = row[0].get_allocation()
            title_x_off, title_y_off = row[0].get_body_position()
            x                        = grid_x + row_x_off
            y                        = grid_y + row_y_off + title_y_off
            w                        = grid_w
            h                        = cell_h - title_y_off
            alloc                    = (x, y, w, h)

            if self.allocs[view] == alloc:
                continue
            self.allocs[view] = alloc
            self.gridbox.set_position(view, alloc[0], alloc[1])
            view.set_properties(box_width  = alloc[2],
                                box_height = alloc[3])


    def do_allocate(self, width, height, origin_changed): 
        days           = (self.range[1] - self.range[0]).days + 1
        rows           = int(math.ceil(float(days) / 7.0))
        cols           = days
        grid_x, grid_y = self.gridbox.get_position(self.grid)
        if days > 7:
            cols = int(math.ceil(float(days) / float(rows)))

        # Show the items for one-row mode or multi-row mode.
        if rows == 1:
            self.do_allocate_one_row(width, height, origin_changed)
        else:
            self.do_allocate_multi_row(width, height, origin_changed)
        hippo.CanvasBox.do_allocate(self, width, height, origin_changed)


    def on_grid_paint_one_row(self):
        w,          h          = self.get_allocation()
        grid_x,     grid_y     = self.gridbox.get_position(self.grid)
        grid_w,     grid_h     = self.grid.get_allocation()
        timeline_w, timeline_h = self.timeline.get_allocation()
        padding_left           = timeline_w
        padding_right          = w - timeline_w - grid_w

        if self.allocs[self.padding_left][2] != padding_left:
            self.allocs[self.padding_left] = (0, 0, padding_left, 0)
            self.padding_left.set_properties(box_width = padding_left)
        if self.allocs[self.padding_right][2] != padding_right:
            self.allocs[self.padding_right] = (0, 0, padding_right, 0)
            self.padding_right.set_properties(box_width = padding_right)


    def on_grid_paint(self, grid, ptr, rect):
        # catching this signal is ugly, but trying to do this  
        # in do_allocate() will result in painful to avoid event 
        # loops.
        days = (self.range[1] - self.range[0]).days + 1
        rows = int(math.ceil(float(days) / 7.0))

        if rows == 1:
            self.on_grid_paint_one_row()
示例#4
0
class CanvasDayRange(CanvasTable, hippo.CanvasItem):
    """
    A canvas item that shows a range of days.
    """
    def __init__(self, cal, **kwargs):
        """
        Constructor.
        """
        CanvasTable.__init__(self, **kwargs)

        self.cal = cal
        self.range = kwargs.get('range')
        self.active_range = self.range
        self.selected = None

        # Create canvas items.
        self.scroll = hippo.CanvasScrollbars()
        self.hbox_top = hippo.CanvasBox(
            orientation=hippo.ORIENTATION_HORIZONTAL)
        self.vbox_top = hippo.CanvasBox()
        self.day_captions = CanvasTable()
        self.timeline = CanvasTimeline(self.cal)
        self.padding_left = hippo.CanvasBox()
        self.padding_right = hippo.CanvasBox()
        self.allday_view = CanvasHEventView(self.cal,
                                            yalign=hippo.ALIGNMENT_FILL)
        self.grid = CanvasGrid(self._new_cell)
        self.gridbox = hippo.CanvasBox(
            orientation=hippo.ORIENTATION_HORIZONTAL)
        self.vevent_views = {}
        self.hevent_views = {}
        self.allocs = {}
        self.allocs[self.padding_left] = (0, 0, 0, 0)
        self.allocs[self.padding_right] = (0, 0, 0, 0)

        self.vbox_top.append(self.day_captions)
        self.vbox_top.append(self.allday_view)
        self.day_captions.set_homogeneus_columns(True)

        self.hbox_top.append(self.padding_left)
        self.hbox_top.append(self.vbox_top, hippo.PACK_EXPAND)
        self.hbox_top.append(self.padding_right)

        self.gridbox.append(self.timeline)
        self.gridbox.append(self.grid, hippo.PACK_EXPAND)
        self.scroll.set_root(self.gridbox)

        self.add(self.hbox_top, 0, 1, 0, 1)
        self.add(self.scroll, 0, 1, 1, 2)
        self.set_row_expand(1, True)
        self.set_column_expand(0, True)
        self.allday_view.show_normal = False
        self.allday_view.connect('event-clicked', self.on_view_event_clicked)
        self.grid.connect('paint', self.on_grid_paint)
        self.grid.set_homogeneus_columns(True)

    def on_day_button_press_event(self, widget, event):
        date = datetime.datetime(*widget.date.timetuple()[:3])
        self.emit('time-clicked', date, event)
        self.emit('day-clicked', widget.date, event)

    def on_view_time_clicked(self, view, item, ev, time):
        date = datetime.date(*time.timetuple()[:3])
        self.emit('time-clicked', time, ev)
        self.emit('day-clicked', date, ev)

    def on_view_event_clicked(self, view, item, ev):
        self.emit('event-clicked', item.event, ev)

    def _new_cell(self):
        cell = CanvasDay(self.cal, xalign=hippo.ALIGNMENT_FILL)
        cell.connect('button-press-event', self.on_day_button_press_event)
        return cell

    def is_active(self, date):
        return self.active_range[0] <= date <= self.active_range[1]

    def _get_event_view(self, row, start, end, horizontal):
        if horizontal:
            if row in self.hevent_views:
                view = self.hevent_views[row]
                view.set_range(start, end)
                return view
            view = CanvasHEventView(self.cal, start, end)
            self.hevent_views[row] = view
        else:
            if row in self.vevent_views:
                view = self.vevent_views[row]
                view.set_range(start, end)
                return view
            view = CanvasVEventView(self.cal, start, end)
            self.vevent_views[row] = view
        view.connect('time-clicked', self.on_view_time_clicked)
        view.connect('event-clicked', self.on_view_event_clicked)
        self.allocs[view] = (0, 0, 0, 0)
        self.gridbox.append(view, hippo.PACK_FIXED)
        return view

    def _remove_vevent_view(self, cell):
        if cell not in self.vevent_views:
            return
        view = self.vevent_views[cell]
        self.gridbox.remove(view)
        del self.vevent_views[cell]
        del self.allocs[view]

    def _remove_hevent_view(self, cell):
        if cell not in self.hevent_views:
            return
        view = self.hevent_views[cell]
        self.gridbox.remove(view)
        del self.hevent_views[cell]
        del self.allocs[view]

    def update_one_row(self):
        self.scroll.set_policy(hippo.ORIENTATION_VERTICAL,
                               hippo.SCROLLBAR_ALWAYS)
        self.grid.set_properties(box_height=800)
        self.allday_view.set_range(*self.range)
        self.allday_view.set_visible(True)
        self.padding_left.set_visible(True)
        self.padding_right.set_visible(True)

        # Hide all event views.
        for cell in [c for c in self.hevent_views]:
            self._remove_hevent_view(cell)
        current_children = self.grid.get_children()
        for cell in [c for c in self.vevent_views]:
            if cell not in current_children:
                self._remove_vevent_view(cell)

        # Create an event view on top of each cell.
        for child in self.grid.get_children():
            start = child.date
            end = util.end_of_day(child.date)
            view = self._get_event_view(child, start, end, False)
            self.allocs[view] = (0, 0, 0, 0)
            view.update()

    def update_multi_row(self):
        self.scroll.set_policy(hippo.ORIENTATION_VERTICAL,
                               hippo.SCROLLBAR_NEVER)
        self.grid.set_properties(box_height=-1)
        self.allday_view.set_visible(False)
        self.padding_left.set_visible(False)
        self.padding_right.set_visible(False)

        # Hide all event views.
        for cell in [c for c in self.vevent_views]:
            self._remove_vevent_view(cell)
        current_children = self.grid.get_children()
        for cell in [c for c in self.hevent_views]:
            if cell not in current_children:
                self._remove_hevent_view(cell)

        # Create an event view on top of each row.
        for row in self.grid.get_rows():
            start = row[0].date
            end = row[-1].date
            view = self._get_event_view(row[0], start, end, True)
            self.allocs[view] = (0, 0, 0, 0)
            view.update()

    def update(self):
        date = self.range[0]
        days = (self.range[1] - self.range[0]).days + 1
        rows = int(math.ceil(float(days) / 7.0))
        cols = days
        today = datetime.date(*time.localtime(time.time())[:3])
        if days > 7:
            cols = int(math.ceil(float(days) / float(rows)))

        # Update the timeline.
        self.timeline.set_visible(rows == 1)

        # Show captions for the day.
        if cols == 7 or rows == 1:
            for child in self.day_captions.get_children():
                self.day_captions.remove(child)
            for col in range(cols):
                this_date = self.range[0] + datetime.timedelta(col)
                day_name = self.cal.model.get_day_name(this_date)
                text = hippo.CanvasText(
                    text=day_name,
                    xalign=hippo.ALIGNMENT_CENTER,
                    size_mode=hippo.CANVAS_SIZE_ELLIPSIZE_END)
                self.day_captions.add(text, col, col + 1, 0, 1)
                self.day_captions.set_column_expand(col, True)
            self.day_captions.set_visible(True)
        else:
            self.day_captions.set_visible(False)

        # Update the grid.
        self.grid.set_size(rows, cols)
        for row in range(rows):
            self.grid.set_row_expand(row, True)
        for child in self.grid.get_children():
            child.set_active(self.is_active(date))
            child.set_show_title(rows != 1)
            child.set_show_rulers(rows == 1)
            child.set_selected(date == self.selected)
            child.set_highlighted(date == today)
            child.set_date(date)
            child.update()
            date = util.next_day(date)

        if rows == 1:
            self.update_one_row()
        else:
            self.update_multi_row()

    def do_allocate_one_row(self, width, height, origin_changed):
        grid_x, grid_y = self.gridbox.get_position(self.grid)
        grid_w, grid_h = self.grid.get_allocation()

        for cell in self.grid.get_children():
            cell_x_off, cell_y_off = self.grid.get_position(cell)

            # the 18 number is for the size of the scrollbar on the right
            # (don't know how to get it)
            cell_x_off = math.ceil(
                (float(cell_x_off)) * (width - grid_x - 18) / grid_w)

            cell_w, cell_h = cell.get_allocation()
            x = int(grid_x + cell_x_off)
            y = int(grid_y + cell_y_off)
            w = cell_w
            h = cell_h
            view = self.vevent_views[cell]
            alloc = (x, y, w, h)

            if self.allocs[view] == alloc:
                continue
            self.allocs[view] = alloc
            self.gridbox.set_position(view, alloc[0], alloc[1])
            view.set_properties(box_width=alloc[2], box_height=alloc[3])

    def do_allocate_multi_row(self, width, height, origin_changed):
        days = (self.range[1] - self.range[0]).days + 1
        rows = int(math.ceil(float(days) / 7.0))
        cols = days
        grid_x, grid_y = self.gridbox.get_position(self.grid)
        if days > 7:
            cols = int(math.ceil(float(days) / float(rows)))

        for row in self.grid.get_rows():
            start = row[0].date
            end = row[-1].date
            view = self._get_event_view(row[0], start, end, True)
            view.set_column_count(cols)

            # Find the position of the writable area of the row.
            grid_w, grid_h = self.grid.get_allocation()
            grid_w, grid_h = (width, height)
            row_x_off, row_y_off = self.grid.get_position(row[0])
            cell_w, cell_h = row[0].get_allocation()
            title_x_off, title_y_off = row[0].get_body_position()
            x = grid_x + row_x_off
            y = grid_y + row_y_off + title_y_off
            w = grid_w
            h = cell_h - title_y_off
            alloc = (x, y, w, h)

            if self.allocs[view] == alloc:
                continue
            self.allocs[view] = alloc
            self.gridbox.set_position(view, alloc[0], alloc[1])
            view.set_properties(box_width=alloc[2], box_height=alloc[3])

    def do_allocate(self, width, height, origin_changed):
        days = (self.range[1] - self.range[0]).days + 1
        rows = int(math.ceil(float(days) / 7.0))
        cols = days
        grid_x, grid_y = self.gridbox.get_position(self.grid)
        if days > 7:
            cols = int(math.ceil(float(days) / float(rows)))

        # Show the items for one-row mode or multi-row mode.
        if rows == 1:
            self.do_allocate_one_row(width, height, origin_changed)
        else:
            self.do_allocate_multi_row(width, height, origin_changed)
        hippo.CanvasBox.do_allocate(self, width, height, origin_changed)

    def on_grid_paint_one_row(self):
        w, h = self.get_allocation()
        grid_x, grid_y = self.gridbox.get_position(self.grid)
        grid_w, grid_h = self.grid.get_allocation()
        timeline_w, timeline_h = self.timeline.get_allocation()
        padding_left = timeline_w
        padding_right = w - timeline_w - grid_w

        if self.allocs[self.padding_left][2] != padding_left:
            self.allocs[self.padding_left] = (0, 0, padding_left, 0)
            self.padding_left.set_properties(box_width=padding_left)
        if self.allocs[self.padding_right][2] != padding_right:
            self.allocs[self.padding_right] = (0, 0, padding_right, 0)
            self.padding_right.set_properties(box_width=padding_right)

    def on_grid_paint(self, grid, ptr, rect):
        # catching this signal is ugly, but trying to do this
        # in do_allocate() will result in painful to avoid event
        # loops.
        days = (self.range[1] - self.range[0]).days + 1
        rows = int(math.ceil(float(days) / 7.0))

        if rows == 1:
            self.on_grid_paint_one_row()