aboutsummaryrefslogtreecommitdiffstats
path: root/calendar/gui/e-week-view.c
diff options
context:
space:
mode:
Diffstat (limited to 'calendar/gui/e-week-view.c')
-rw-r--r--calendar/gui/e-week-view.c373
1 files changed, 31 insertions, 342 deletions
diff --git a/calendar/gui/e-week-view.c b/calendar/gui/e-week-view.c
index 447fce8b77..adadd5d42a 100644
--- a/calendar/gui/e-week-view.c
+++ b/calendar/gui/e-week-view.c
@@ -50,6 +50,7 @@
#include "goto.h"
#include "e-meeting-edit.h"
#include "e-week-view-event-item.h"
+#include "e-week-view-layout.h"
#include "e-week-view-main-item.h"
#include "e-week-view-titles-item.h"
@@ -63,11 +64,6 @@
#define E_WEEK_VIEW_SMALL_FONT_FALLBACK \
"-adobe-helvetica-medium-r-normal-*-*-80-*-*-p-*-iso8859-*"
-/* We use a 7-bit field to store row numbers in EWeekViewEventSpan, so the
- maximum number or rows we can allow is 127. It is very unlikely to be
- reached anyway. */
-#define E_WEEK_VIEW_MAX_ROWS_PER_CELL 127
-
#define E_WEEK_VIEW_JUMP_BUTTON_WIDTH 16
#define E_WEEK_VIEW_JUMP_BUTTON_HEIGHT 8
@@ -115,23 +111,11 @@ static gboolean e_week_view_add_event (CalComponent *comp,
time_t end,
gpointer data);
static void e_week_view_check_layout (EWeekView *week_view);
-static void e_week_view_layout_events (EWeekView *week_view);
-static void e_week_view_layout_event (EWeekView *week_view,
- EWeekViewEvent *event,
- guint8 *grid,
- GArray *spans);
static void e_week_view_ensure_events_sorted (EWeekView *week_view);
-static gint e_week_view_event_sort_func (const void *arg1,
- const void *arg2);
static void e_week_view_reshape_events (EWeekView *week_view);
static void e_week_view_reshape_event_span (EWeekView *week_view,
gint event_num,
gint span_num);
-static gint e_week_view_find_day (EWeekView *week_view,
- time_t time_to_find,
- gboolean include_midnight_in_prev_day);
-static gint e_week_view_find_span_end (EWeekView *week_view,
- gint day);
static void e_week_view_recalc_day_starts (EWeekView *week_view,
time_t lower);
static void e_week_view_on_adjustment_changed (GtkAdjustment *adjustment,
@@ -1751,85 +1735,22 @@ e_week_view_get_day_position (EWeekView *week_view,
gint *day_w,
gint *day_h)
{
- gint week, day_of_week, row, col, weekend_col, box, weekend_box;
-
- *day_x = *day_y = *day_w = *day_h = 0;
- g_return_if_fail (day >= 0);
-
- if (week_view->multi_week_view) {
- g_return_if_fail (day < week_view->weeks_shown * 7);
-
- week = day / 7;
- col = day % 7;
- day_of_week = (week_view->display_start_day + day) % 7;
- if (week_view->compress_weekend && day_of_week >= 5) {
- /* In the compressed view Saturday is above Sunday and
- both have just one row as opposed to 2 for all the
- other days. */
- if (day_of_week == 5) {
- *day_y = week_view->row_offsets[week * 2];
- *day_h = week_view->row_heights[week * 2];
- } else {
- *day_y = week_view->row_offsets[week * 2 + 1];
- *day_h = week_view->row_heights[week * 2 + 1];
- col--;
- }
- /* Both Saturday and Sunday are in the same column. */
- *day_x = week_view->col_offsets[col];
- *day_w = week_view->col_widths[col];
- } else {
- /* If the weekend is compressed and the day is after
- the weekend we have to move back a column. */
- if (week_view->compress_weekend) {
- /* Calculate where the weekend column is.
- Note that 5 is Saturday. */
- weekend_col = (5 + 7 - week_view->display_start_day) % 7;
- if (col > weekend_col)
- col--;
- }
+ gint cell_x, cell_y, cell_h;
- *day_y = week_view->row_offsets[week * 2];
- *day_h = week_view->row_heights[week * 2]
- + week_view->row_heights[week * 2 + 1];
- *day_x = week_view->col_offsets[col];
- *day_w = week_view->col_widths[col];
- }
- } else {
- g_return_if_fail (day < 7);
-
- /* Calculate which box to place the day in, from 0-5.
- Note that in the week view the weekends are always
- compressed and share a box. */
- box = day;
- day_of_week = (week_view->display_start_day + day) % 7;
- weekend_box = (5 + 7 - week_view->display_start_day) % 7;
- if (box > weekend_box)
- box--;
-
- if (box < 3) {
- *day_x = week_view->col_offsets[0];
- *day_w = week_view->col_widths[0];
- } else {
- *day_x = week_view->col_offsets[1];
- *day_w = week_view->col_widths[1];
- }
+ e_week_view_layout_get_day_position (day,
+ week_view->multi_week_view,
+ week_view->weeks_shown,
+ week_view->display_start_day,
+ week_view->compress_weekend,
+ &cell_x, &cell_y, &cell_h);
- row = (box % 3) * 2;
- if (day_of_week < 5) {
- *day_y = week_view->row_offsets[row];
- *day_h = week_view->row_heights[row]
- + week_view->row_heights[row + 1];
- } else if (day_of_week == 5) {
- /* Saturday. */
- *day_y = week_view->row_offsets[row];
- *day_h = week_view->row_heights[row];
+ *day_x = week_view->col_offsets[cell_x];
+ *day_y = week_view->row_offsets[cell_y];
- } else {
- /* Sunday. */
- *day_y = week_view->row_offsets[row + 1];
- *day_h = week_view->row_heights[row + 1];
- }
- }
+ *day_w = week_view->col_widths[cell_x];
+ *day_h = week_view->row_heights[cell_y];
+ if (cell_h == 2)
+ *day_h += week_view->row_heights[cell_y + 1];
}
@@ -1851,7 +1772,7 @@ e_week_view_get_span_position (EWeekView *week_view,
{
EWeekViewEvent *event;
EWeekViewEventSpan *span;
- gint end_day_of_week, num_days;
+ gint num_days;
gint start_x, start_y, start_w, start_h;
gint end_x, end_y, end_w, end_h;
@@ -1865,35 +1786,14 @@ e_week_view_get_span_position (EWeekView *week_view,
span = &g_array_index (week_view->spans, EWeekViewEventSpan,
event->spans_index + span_num);
- if (span->row >= week_view->rows_per_cell)
+ if (!e_week_view_layout_get_span_position (event, span,
+ week_view->rows_per_cell,
+ week_view->rows_per_compressed_cell,
+ week_view->display_start_day,
+ week_view->multi_week_view,
+ week_view->compress_weekend,
+ &num_days)) {
return FALSE;
-
- end_day_of_week = (week_view->display_start_day + span->start_day + span->num_days - 1) % 7;
- num_days = span->num_days;
- /* Check if the row will not be visible in compressed cells. */
- if (span->row >= week_view->rows_per_compressed_cell) {
- if (week_view->multi_week_view) {
- if (week_view->compress_weekend) {
- /* If it ends on a Saturday and is 1 day long
- we skip it, else we shorten it. If it ends
- on a Sunday it must be 1 day long and we
- skip it. */
- if (end_day_of_week == 5) { /* Sat */
- if (num_days == 1) {
- return FALSE;
- } else {
- num_days--;
- }
- } else if (end_day_of_week == 6) { /* Sun */
- return FALSE;
- }
- }
- } else {
- /* All spans are 1 day long in the week view, so we
- just skip it. */
- if (end_day_of_week > 4)
- return FALSE;
- }
}
e_week_view_get_day_position (week_view, span->start_day,
@@ -2235,7 +2135,14 @@ e_week_view_check_layout (EWeekView *week_view)
e_week_view_ensure_events_sorted (week_view);
if (week_view->events_need_layout)
- e_week_view_layout_events (week_view);
+ week_view->spans = e_week_view_layout_events
+ (week_view->events, week_view->spans,
+ week_view->multi_week_view,
+ week_view->weeks_shown,
+ week_view->compress_weekend,
+ week_view->display_start_day,
+ week_view->day_starts,
+ week_view->rows_per_day);
if (week_view->events_need_layout || week_view->events_need_reshape)
e_week_view_reshape_events (week_view);
@@ -2246,154 +2153,6 @@ e_week_view_check_layout (EWeekView *week_view)
static void
-e_week_view_layout_events (EWeekView *week_view)
-{
- EWeekViewEvent *event;
- EWeekViewEventSpan *span;
- gint num_days, day, event_num, span_num;
- guint8 *grid;
- GArray *spans, *old_spans;
-
- /* This is a temporary 2-d grid which is used to place events.
- Each element is 0 if the position is empty, or 1 if occupied.
- We allocate the maximum size possible here, assuming that each
- event will need its own row. */
- grid = g_new0 (guint8, E_WEEK_VIEW_MAX_ROWS_PER_CELL * 7
- * E_WEEK_VIEW_MAX_WEEKS);
-
- /* We create a new array of spans, which will replace the old one. */
- spans = g_array_new (FALSE, FALSE, sizeof (EWeekViewEventSpan));
-
- /* Clear the number of rows used per day. */
- num_days = week_view->multi_week_view ? week_view->weeks_shown * 7 : 7;
- for (day = 0; day <= num_days; day++) {
- week_view->rows_per_day[day] = 0;
- }
-
- /* Iterate over the events, finding which weeks they cover, and putting
- them in the first free row available. */
- for (event_num = 0; event_num < week_view->events->len; event_num++) {
- event = &g_array_index (week_view->events, EWeekViewEvent,
- event_num);
- e_week_view_layout_event (week_view, event, grid, spans);
- }
-
- /* Free the grid. */
- g_free (grid);
-
- /* Replace the spans array. */
- old_spans = week_view->spans;
- week_view->spans = spans;
-
- /* Destroy the old spans array, destroying any unused canvas items. */
- if (old_spans) {
- for (span_num = 0; span_num < old_spans->len; span_num++) {
- span = &g_array_index (old_spans, EWeekViewEventSpan,
- span_num);
- if (span->background_item)
- gtk_object_destroy (GTK_OBJECT (span->background_item));
- if (span->text_item)
- gtk_object_destroy (GTK_OBJECT (span->text_item));
- }
- g_array_free (old_spans, TRUE);
- }
-}
-
-
-static void
-e_week_view_layout_event (EWeekView *week_view,
- EWeekViewEvent *event,
- guint8 *grid,
- GArray *spans)
-{
- gint start_day, end_day, span_start_day, span_end_day, rows_per_cell;
- gint free_row, row, day, span_num, spans_index, num_spans, max_day;
- EWeekViewEventSpan span, *old_span;
-
- start_day = e_week_view_find_day (week_view, event->start, FALSE);
- end_day = e_week_view_find_day (week_view, event->end, TRUE);
- max_day = week_view->multi_week_view ? week_view->weeks_shown * 7 - 1
- : 7 - 1;
- start_day = CLAMP (start_day, 0, max_day);
- end_day = CLAMP (end_day, 0, max_day);
-
-#if 0
- g_print ("In e_week_view_layout_event Start:%i End: %i\n",
- start_day, end_day);
-#endif
-
- /* Iterate through each of the spans of the event, where each span
- is a sequence of 1 or more days displayed next to each other. */
- span_start_day = start_day;
- rows_per_cell = E_WEEK_VIEW_MAX_ROWS_PER_CELL;
- span_num = 0;
- spans_index = spans->len;
- num_spans = 0;
- while (span_start_day <= end_day) {
- span_end_day = e_week_view_find_span_end (week_view,
- span_start_day);
- span_end_day = MIN (span_end_day, end_day);
-#if 0
- g_print (" Span start:%i end:%i\n", span_start_day,
- span_end_day);
-#endif
- /* Try each row until we find a free one or we fall off the
- bottom of the available rows. */
- row = 0;
- free_row = -1;
- while (free_row == -1 && row < rows_per_cell) {
- free_row = row;
- for (day = span_start_day; day <= span_end_day;
- day++) {
- if (grid[day * rows_per_cell + row]) {
- free_row = -1;
- break;
- }
- }
- row++;
- };
-
- if (free_row != -1) {
- /* Mark the cells as full. */
- for (day = span_start_day; day <= span_end_day;
- day++) {
- grid[day * rows_per_cell + free_row] = 1;
- week_view->rows_per_day[day] = MAX (week_view->rows_per_day[day], free_row + 1);
- }
-#if 0
- g_print (" Span start:%i end:%i row:%i\n",
- span_start_day, span_end_day, free_row);
-#endif
- /* Add the span to the array, and try to reuse any
- canvas items from the old spans. */
- span.start_day = span_start_day;
- span.num_days = span_end_day - span_start_day + 1;
- span.row = free_row;
- span.background_item = NULL;
- span.text_item = NULL;
- if (event->num_spans > span_num) {
- old_span = &g_array_index (week_view->spans, EWeekViewEventSpan, event->spans_index + span_num);
- span.background_item = old_span->background_item;
- span.text_item = old_span->text_item;
- old_span->background_item = NULL;
- old_span->text_item = NULL;
- }
-
- g_array_append_val (spans, span);
- num_spans++;
- }
-
- span_start_day = span_end_day + 1;
- span_num++;
- }
-
- /* Set the event's spans. */
- event->spans_index = spans_index;
- event->num_spans = num_spans;
-}
-
-
-static void
e_week_view_ensure_events_sorted (EWeekView *week_view)
{
if (!week_view->events_sorted) {
@@ -2406,7 +2165,7 @@ e_week_view_ensure_events_sorted (EWeekView *week_view)
}
-static gint
+gint
e_week_view_event_sort_func (const void *arg1,
const void *arg2)
{
@@ -2708,76 +2467,6 @@ e_week_view_reshape_event_span (EWeekView *week_view,
}
-/* Finds the day containing the given time.
- If include_midnight_in_prev_day is TRUE then if the time exactly
- matches the start of a day the previous day is returned. This is useful
- when calculating the end day of an event. */
-static gint
-e_week_view_find_day (EWeekView *week_view,
- time_t time_to_find,
- gboolean include_midnight_in_prev_day)
-{
- gint num_days, day;
- time_t *day_starts;
-
- num_days = week_view->multi_week_view ? week_view->weeks_shown * 7 : 7;
- day_starts = week_view->day_starts;
-
- if (time_to_find < day_starts[0])
- return -1;
- if (time_to_find > day_starts[num_days])
- return num_days;
-
- for (day = 1; day <= num_days; day++) {
- if (time_to_find <= day_starts[day]) {
- if (time_to_find == day_starts[day]
- && !include_midnight_in_prev_day)
- return day;
- return day - 1;
- }
- }
-
- g_assert_not_reached ();
- return num_days;
-}
-
-
-/* This returns the last possible day in the same span as the given day.
- A span is all the days which are displayed next to each other from left to
- right. In the week view all spans are only 1 day, since Tuesday is below
- Monday rather than beside it etc. In the month view, if the weekends are not
- compressed then each week is a span, otherwise we have to break a span up
- on Saturday, use a separate span for Sunday, and start again on Monday. */
-static gint
-e_week_view_find_span_end (EWeekView *week_view,
- gint day)
-{
- gint week, col, sat_col, end_col;
-
- if (week_view->multi_week_view) {
- week = day / 7;
- col = day % 7;
-
- /* We default to the last column in the row. */
- end_col = 6;
-
- /* If the weekend is compressed we must end any spans on
- Saturday and Sunday. */
- if (week_view->compress_weekend) {
- sat_col = (5 + 7 - week_view->display_start_day) % 7;
- if (col <= sat_col)
- end_col = sat_col;
- else if (col == sat_col + 1)
- end_col = sat_col + 1;
- }
-
- return week * 7 + end_col;
- } else {
- return day;
- }
-}
-
-
static void
e_week_view_on_adjustment_changed (GtkAdjustment *adjustment,
EWeekView *week_view)