evolution r37077 - in trunk/calendar: . gui



Author: mcrha
Date: Thu Jan 15 11:19:25 2009
New Revision: 37077
URL: http://svn.gnome.org/viewvc/evolution?rev=37077&view=rev

Log:
2009-01-15  Milan Crha  <mcrha redhat com>

	** Fix for bug #246313

	* gui/e-day-view.c: (e_day_view_check_if_new_event_fits): Removed.
	* gui/e-day-view.h: (struct _EDayView):
	* gui/e-day-view.c: (e_day_view_init), (e_day_view_size_allocate),
	(e_day_view_recalc_main_canvas_size), (e_day_view_recalc_cell_sizes),
	(e_day_view_update_scroll_regions), (e_day_view_check_layout):
	* gui/e-day-view-layout.h: (e_day_view_layout_day_events):
	* gui/e-day-view-layout.c: (e_day_view_layout_day_events),
	(e_day_view_layout_day_event), (e_day_view_expand_day_event):
	Added ability to show all event in one-day view, but show only up
	to 6 columns in a multi-day view.
	* gui/print.c: (print_day_details): Always print all events.



Modified:
   trunk/calendar/ChangeLog
   trunk/calendar/gui/e-day-view-layout.c
   trunk/calendar/gui/e-day-view-layout.h
   trunk/calendar/gui/e-day-view.c
   trunk/calendar/gui/e-day-view.h
   trunk/calendar/gui/print.c

Modified: trunk/calendar/gui/e-day-view-layout.c
==============================================================================
--- trunk/calendar/gui/e-day-view-layout.c	(original)
+++ trunk/calendar/gui/e-day-view-layout.c	Thu Jan 15 11:19:25 2009
@@ -29,6 +29,7 @@
 #include <config.h>
 
 #include "e-day-view-layout.h"
+#include "e-util/e-bit-array.h"
 
 static void e_day_view_layout_long_event (EDayViewEvent	  *event,
 					  guint8	  *grid,
@@ -37,13 +38,14 @@
 					  gint		  *rows_in_top_display);
 
 static void e_day_view_layout_day_event (EDayViewEvent    *event,
-					 guint8	          *grid,
+					 EBitArray       **grid,
 					 guint16	  *group_starts,
 					 guint8	          *cols_per_row,
 					 gint	           rows,
-					 gint	           mins_per_row);
+					 gint	           mins_per_row,
+					 gint              max_cols);
 static void e_day_view_expand_day_event (EDayViewEvent    *event,
-					 guint8	          *grid,
+					 EBitArray       **grid,
 					 guint8	          *cols_per_row,
 					 gint	           mins_per_row);
 static void e_day_view_recalc_cols_per_row (gint           rows,
@@ -127,15 +129,17 @@
 }
 
 
-void
+/* returns maximum number of columns among all rows */
+gint
 e_day_view_layout_day_events (GArray	   *events,
 			      gint	    rows,
 			      gint	    mins_per_row,
-			      guint8	   *cols_per_row)
+			      guint8	   *cols_per_row,
+			      gint          max_cols)
 {
 	EDayViewEvent *event;
-	gint row, event_num;
-	guint8 *grid;
+	gint row, event_num, res;
+	EBitArray **grid;
 
 	/* This is a temporary array which keeps track of rows which are
 	   connected. When an appointment spans multiple rows then the number
@@ -145,18 +149,20 @@
 	   rows. */
 	guint16 group_starts[12 * 24];
 
+	/* 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. */
+	grid = g_new0 (EBitArray *, rows);
+
 	/* Reset the cols_per_row array, and initialize the connected rows so
 	   that all rows are not connected - each row is the start of a new
 	   group. */
 	for (row = 0; row < rows; row++) {
 		cols_per_row[row] = 0;
 		group_starts[row] = row;
-	}
-
-	/* 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. */
-	grid = g_new0 (guint8, rows * E_DAY_VIEW_MAX_COLUMNS);
 
+		/* row doesn't contain any event at the moment */
+		grid [row] = e_bit_array_new (0);
+	}
 
 	/* Iterate over the events, finding which rows they cover, and putting
 	   them in the first free column available. Increment the number of
@@ -166,7 +172,7 @@
 		event = &g_array_index (events, EDayViewEvent, event_num);
 
 		e_day_view_layout_day_event (event, grid, group_starts,
-					     cols_per_row, rows, mins_per_row);
+					     cols_per_row, rows, mins_per_row, max_cols);
 	}
 
 	/* Recalculate the number of columns needed in each row. */
@@ -180,8 +186,15 @@
 					     mins_per_row);
 	}
 
-	/* Free the grid. */
+	/* Free the grid and compute maximum number of columns used. */
+	res = 0;
+	for (row = 0; row < rows; row++) {
+		res = MAX (res, e_bit_array_bit_count (grid [row]));
+		g_object_unref (grid [row]);
+	}
 	g_free (grid);
+
+	return res;
 }
 
 
@@ -190,11 +203,12 @@
    sure they are all in one group. */
 static void
 e_day_view_layout_day_event (EDayViewEvent *event,
-			     guint8	   *grid,
+			     EBitArray    **grid,
 			     guint16	   *group_starts,
 			     guint8	   *cols_per_row,
 			     gint	    rows,
-			     gint	    mins_per_row)
+			     gint	    mins_per_row,
+			     gint           max_cols)
 {
 	gint start_row, end_row, free_col, col, row, group_start;
 
@@ -214,10 +228,11 @@
 	end_row = CLAMP (end_row, 0, rows - 1);
 
 	/* Try each column until we find a free one. */
-	for (col = 0; col < E_DAY_VIEW_MAX_COLUMNS; col++) {
+	for (col = 0; max_cols <= 0 || col < max_cols; col++) {
 		free_col = col;
 		for (row = start_row; row <= end_row; row++) {
-			if (grid[row * E_DAY_VIEW_MAX_COLUMNS + col]) {
+			if (e_bit_array_bit_count (grid [row]) > col &&
+			    e_bit_array_value_at (grid [row], col)) {
 				free_col = -1;
 				break;
 			}
@@ -243,7 +258,11 @@
 	   all the events have been layed out. Also make sure all the rows that
 	   the event covers are in one group. */
 	for (row = start_row; row <= end_row; row++) {
-		grid[row * E_DAY_VIEW_MAX_COLUMNS + free_col] = 1;
+		/* resize the array if necessary */
+		if (e_bit_array_bit_count (grid [row]) <= free_col)
+			e_bit_array_insert (grid [row], e_bit_array_bit_count (grid [row]), free_col - e_bit_array_bit_count (grid [row]) + 1);
+
+		e_bit_array_change_one_row (grid [row], free_col, TRUE);
 		cols_per_row[row]++;
 		group_starts[row] = group_start;
 	}
@@ -284,7 +303,7 @@
 /* Expands the event horizontally to fill any free space. */
 static void
 e_day_view_expand_day_event (EDayViewEvent *event,
-			     guint8	   *grid,
+			     EBitArray    **grid,
 			     guint8	   *cols_per_row,
 			     gint	    mins_per_row)
 {
@@ -300,7 +319,8 @@
 	clashed = FALSE;
 	for (col = event->start_row_or_col + 1; col < cols_per_row[start_row]; col++) {
 		for (row = start_row; row <= end_row; row++) {
-			if (grid[row * E_DAY_VIEW_MAX_COLUMNS + col]) {
+			if (e_bit_array_bit_count (grid [row]) > col &&
+			    e_bit_array_value_at (grid [row], col)) {
 				clashed = TRUE;
 				break;
 			}

Modified: trunk/calendar/gui/e-day-view-layout.h
==============================================================================
--- trunk/calendar/gui/e-day-view-layout.h	(original)
+++ trunk/calendar/gui/e-day-view-layout.h	Thu Jan 15 11:19:25 2009
@@ -39,10 +39,11 @@
 					 gint	   *rows_in_top_display);
 
 
-void e_day_view_layout_day_events	(GArray	   *events,
+gint e_day_view_layout_day_events	(GArray	   *events,
 					 gint	    rows,
 					 gint	    mins_per_row,
-					 guint8	   *cols_per_row);
+					 guint8	   *cols_per_row,
+					 gint       max_cols);
 
 gboolean   e_day_view_find_long_event_days	(EDayViewEvent	*event,
 						 gint		 days_shown,

Modified: trunk/calendar/gui/e-day-view.c
==============================================================================
--- trunk/calendar/gui/e-day-view.c	(original)
+++ trunk/calendar/gui/e-day-view.c	Thu Jan 15 11:19:25 2009
@@ -182,8 +182,6 @@
 
 static void e_day_view_update_top_scroll (EDayView *day_view, gboolean scroll_to_top);
 
-static gboolean e_day_view_check_if_new_event_fits (EDayView *day_view);
-
 static void e_day_view_on_canvas_realized (GtkWidget *widget,
 					   EDayView *day_view);
 
@@ -987,6 +985,10 @@
 	/*
 	 * Scrollbar.
 	 */
+	day_view->mc_hscrollbar = gtk_hscrollbar_new (GTK_LAYOUT (day_view->main_canvas)->hadjustment);
+	gtk_table_attach (GTK_TABLE (day_view), day_view->mc_hscrollbar, 1, 2, 2, 3, GTK_FILL, 0, 0, 0);
+	gtk_widget_show (day_view->mc_hscrollbar);
+
 	day_view->tc_vscrollbar = gtk_vscrollbar_new (GTK_LAYOUT (day_view->top_canvas)->vadjustment);
 	gtk_table_attach (GTK_TABLE (day_view), day_view->tc_vscrollbar,
 			  2, 3, 0, 1, 0, GTK_FILL, 0, 0);
@@ -1461,28 +1463,19 @@
 	pango_font_metrics_unref (font_metrics);
 }
 
-/* This recalculates the sizes of each column. */
 static void
-e_day_view_size_allocate (GtkWidget *widget, GtkAllocation *allocation)
+e_day_view_recalc_main_canvas_size (EDayView *day_view)
 {
-	EDayView *day_view;
 	gint day, scroll_y;
 	gboolean need_reshape;
 
-#if 0
-	g_print ("In e_day_view_size_allocate\n");
-#endif
-	day_view = E_DAY_VIEW (widget);
-
-	(*GTK_WIDGET_CLASS (e_day_view_parent_class)->size_allocate) (widget, allocation);
-
-	e_day_view_recalc_cell_sizes (day_view);
-
 	/* Set the scroll region of the top canvas */
 	e_day_view_update_top_scroll (day_view, TRUE);
 
 	need_reshape = e_day_view_update_scroll_regions (day_view);
 
+	e_day_view_recalc_cell_sizes (day_view);
+
 	/* Scroll to the start of the working day, if this is the initial
 	   allocation. */
 	if (day_view->scroll_to_work_day) {
@@ -1503,6 +1496,17 @@
 	}
 }
 
+/* This recalculates the sizes of each column. */
+static void
+e_day_view_size_allocate (GtkWidget *widget, GtkAllocation *allocation)
+{
+#if 0
+	g_print ("In e_day_view_size_allocate\n");
+#endif
+	(*GTK_WIDGET_CLASS (e_day_view_parent_class)->size_allocate) (widget, allocation);
+
+	e_day_view_recalc_main_canvas_size (E_DAY_VIEW (widget));
+}
 
 static void
 e_day_view_recalc_cell_sizes	(EDayView	*day_view)
@@ -1529,6 +1533,8 @@
 	   get divided evenly. Note that we use one more element than the
 	   number of columns, to make it easy to get the column widths. */
 	width = day_view->main_canvas->allocation.width;
+	if (day_view->days_shown == 1)
+		width = MAX (width, day_view->max_cols * (E_DAY_VIEW_MIN_DAY_COL_WIDTH + E_DAY_VIEW_GAP_WIDTH) - E_DAY_VIEW_MIN_DAY_COL_WIDTH - 1);
 	width /= day_view->days_shown;
 	offset = 0;
 	for (day = 0; day <= day_view->days_shown; day++) {
@@ -2673,12 +2679,21 @@
 	gnome_canvas_get_scroll_region (GNOME_CANVAS (day_view->main_canvas),
 					NULL, NULL, &old_x2, &old_y2);
 	new_x2 = day_view->main_canvas->allocation.width - 1;
+
+	if (day_view->days_shown == 1)
+		new_x2 = MAX (new_x2, day_view->max_cols * (E_DAY_VIEW_MIN_DAY_COL_WIDTH + E_DAY_VIEW_GAP_WIDTH) - E_DAY_VIEW_MIN_DAY_COL_WIDTH - 1);
+
 	if (old_x2 != new_x2 || old_y2 != new_y2) {
 		need_reshape = TRUE;
 		gnome_canvas_set_scroll_region (GNOME_CANVAS (day_view->main_canvas),
 						0, 0, new_x2, new_y2);
 	}
 
+	if (new_x2 <= day_view->main_canvas->allocation.width - 1)
+		gtk_widget_hide (day_view->mc_hscrollbar);
+	else
+		gtk_widget_show (day_view->mc_hscrollbar);
+
 	return need_reshape;
 }
 
@@ -4262,13 +4277,13 @@
 	return TRUE;
 }
 
-
 /* This lays out the short (less than 1 day) events in the columns.
    Any long events are simply skipped. */
 void
 e_day_view_check_layout (EDayView *day_view)
 {
 	gint day, rows_in_top_display;
+	gint max_cols = -1;
 
 	/* Don't bother if we aren't visible. */
 	if (!E_CALENDAR_VIEW (day_view)->in_focus)
@@ -4278,11 +4293,17 @@
 	e_day_view_ensure_events_sorted (day_view);
 
 	for (day = 0; day < day_view->days_shown; day++) {
-		if (day_view->need_layout[day])
-			e_day_view_layout_day_events (day_view->events[day],
+		if (day_view->need_layout[day]) {
+			gint cols;
+
+			cols = e_day_view_layout_day_events (day_view->events[day],
 						      day_view->rows,
 						      day_view->mins_per_row,
-						      day_view->cols_per_row[day]);
+						      day_view->cols_per_row[day],
+						      day_view->days_shown == 1 ? -1 : E_DAY_VIEW_MULTI_DAY_MAX_COLUMNS);
+
+			max_cols = MAX (cols, max_cols);
+		}
 
 		if (day_view->need_layout[day]
 		    || day_view->need_reshape[day]) {
@@ -4308,13 +4329,17 @@
 		}
 	}
 
-
 	if (day_view->long_events_need_layout
 	    || day_view->long_events_need_reshape)
 		e_day_view_reshape_long_events (day_view);
 
 	day_view->long_events_need_layout = FALSE;
 	day_view->long_events_need_reshape = FALSE;
+
+	if (max_cols != -1 && max_cols != day_view->max_cols) {
+		day_view->max_cols = max_cols;
+		e_day_view_recalc_main_canvas_size (day_view);
+	}
 }
 
 
@@ -4927,13 +4952,6 @@
 	if (day_view->selection_start_day == -1)
 		return FALSE;
 
-	/* Check if there is room for a new event to be typed in. If there
-	   isn't we don't want to add an event as we will then add a new
-	   event for every key press. */
-	if (!e_day_view_check_if_new_event_fits (day_view)) {
-		return FALSE;
-	}
-
 	/* We only want to start an edit with a return key or a simple
 	   character. */
 	if ((keyval != GDK_Return) &&
@@ -5581,33 +5599,6 @@
 	gtk_adjustment_set_value (adj, new_value);
 }
 
-static gboolean
-e_day_view_check_if_new_event_fits (EDayView *day_view)
-{
-	gint day, start_row, end_row, row;
-
-	day = day_view->selection_start_day;
-	start_row = day_view->selection_start_row;
-	end_row = day_view->selection_end_row;
-
-	/* Long events always fit, since we keep adding rows to the top
-	   canvas. */
-	if (day != day_view->selection_end_day)
-		return TRUE;
-	if (start_row == 0 && end_row == day_view->rows)
-		return TRUE;
-
-	/* If any of the rows already have E_DAY_VIEW_MAX_COLUMNS columns,
-	   return FALSE. */
-	for (row = start_row; row <= end_row; row++) {
-		if (day_view->cols_per_row[day][row] >= E_DAY_VIEW_MAX_COLUMNS)
-			return FALSE;
-	}
-
-	return TRUE;
-}
-
-
 void
 e_day_view_ensure_rows_visible (EDayView *day_view,
 				gint start_row,

Modified: trunk/calendar/gui/e-day-view.h
==============================================================================
--- trunk/calendar/gui/e-day-view.h	(original)
+++ trunk/calendar/gui/e-day-view.h	Thu Jan 15 11:19:25 2009
@@ -45,8 +45,11 @@
    of a normal event. */
 #define E_DAY_VIEW_LONG_EVENT		E_DAY_VIEW_MAX_DAYS
 
-/* The maximum number of columns of appointments within a day. */
-#define E_DAY_VIEW_MAX_COLUMNS		6
+/* The maximum number of columns of appointments within a day in multi-day view. */
+#define E_DAY_VIEW_MULTI_DAY_MAX_COLUMNS 6
+
+/* minimum width of the event in one-day view in pixels */
+#define E_DAY_VIEW_MIN_DAY_COL_WIDTH	60
 
 /* The width of the gap between appointments. This should be at least
    E_DAY_VIEW_BAR_WIDTH, since in the top canvas we use this space to draw
@@ -204,6 +207,9 @@
 	/* scrollbar for top_canvas */
 	GtkWidget *tc_vscrollbar;
 
+	/* horizontal scrollbar for main_canvas */
+	GtkWidget *mc_hscrollbar;
+
 	/* The main canvas where the rest of the appointments are shown. */
 	GtkWidget *main_canvas;
 	GnomeCanvasItem *main_canvas_item;
@@ -310,6 +316,8 @@
 	   Note that there are a maximum of 12 * 24 rows (when a row is 5 mins)
 	   but we don't always have that many rows. */
 	guint8 cols_per_row[E_DAY_VIEW_MAX_DAYS][12 * 24];
+	/* The maximum number of columns from all rows in cols_per_row */
+	gint max_cols;
 
 	/* Sizes of the various time strings. */
 	gint small_hour_widths[24];

Modified: trunk/calendar/gui/print.c
==============================================================================
--- trunk/calendar/gui/print.c	(original)
+++ trunk/calendar/gui/print.c	Thu Jan 15 11:19:25 2009
@@ -1335,7 +1335,7 @@
 
 	/* lay out the short events, within the day. */
 	e_day_view_layout_day_events (pdi.events[0], DAY_VIEW_ROWS,
-				      DAY_VIEW_MINS_PER_ROW, pdi.cols_per_row);
+				      DAY_VIEW_MINS_PER_ROW, pdi.cols_per_row, -1);
 
 	/* print the short events. */
 	if (top > bottom )



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]