diff options
author | Matthew Barnes <mbarnes@redhat.com> | 2009-09-22 07:25:41 +0800 |
---|---|---|
committer | Matthew Barnes <mbarnes@redhat.com> | 2009-09-22 22:34:26 +0800 |
commit | 7be192643685acdc081332fc9177417d67870c53 (patch) | |
tree | 1c04a080735ed962b6dd89594e16efbf62ed5123 /calendar/gui/e-day-view-time-item.c | |
parent | 5a80f92d37e7e8a814f70f826b7b33f5d21b0f72 (diff) | |
download | gsoc2013-evolution-7be192643685acdc081332fc9177417d67870c53.tar.gz gsoc2013-evolution-7be192643685acdc081332fc9177417d67870c53.tar.zst gsoc2013-evolution-7be192643685acdc081332fc9177417d67870c53.zip |
Calendar canvas item cleanup.
Diffstat (limited to 'calendar/gui/e-day-view-time-item.c')
-rw-r--r-- | calendar/gui/e-day-view-time-item.c | 460 |
1 files changed, 286 insertions, 174 deletions
diff --git a/calendar/gui/e-day-view-time-item.c b/calendar/gui/e-day-view-time-item.c index 8c4a2fdf07..5068ed47e0 100644 --- a/calendar/gui/e-day-view-time-item.c +++ b/calendar/gui/e-day-view-time-item.c @@ -55,12 +55,24 @@ #define E_DVTMI_LARGE_HOUR_Y_PAD 1 #define E_DVTMI_SMALL_FONT_Y_PAD 1 -static void e_day_view_time_item_set_property (GObject *object, - guint property_id, - const GValue *value, - GParamSpec *pspec); +#define E_DAY_VIEW_TIME_ITEM_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE \ + ((obj), E_TYPE_DAY_VIEW_TIME_ITEM, EDayViewTimeItemPrivate)) -static void e_day_view_time_item_finalize (GObject *object); +struct _EDayViewTimeItemPrivate { + /* The parent EDayView widget. */ + EDayView *day_view; + + /* The width of the time column. */ + gint column_width; + + /* TRUE if we are currently dragging the selection times. */ + gboolean dragging_selection; + + /* The second timezone if shown, or else NULL. */ + guint second_zone_changed_id; + icaltimezone *second_zone; +}; static void e_day_view_time_item_update (GnomeCanvasItem *item, double *affine, @@ -78,37 +90,107 @@ static gint e_day_view_time_item_event (GnomeCanvasItem *item, static void e_day_view_time_item_increment_time (gint *hour, gint *minute, gint mins_per_row); -static void e_day_view_time_item_show_popup_menu (EDayViewTimeItem *dvtmitem, +static void e_day_view_time_item_show_popup_menu (EDayViewTimeItem *time_item, GdkEvent *event); static void e_day_view_time_item_on_set_divisions (GtkWidget *item, - EDayViewTimeItem *dvtmitem); -static void e_day_view_time_item_on_button_press (EDayViewTimeItem *dvtmitem, + EDayViewTimeItem *time_item); +static void e_day_view_time_item_on_button_press (EDayViewTimeItem *time_item, GdkEvent *event); -static void e_day_view_time_item_on_button_release (EDayViewTimeItem *dvtmitem, +static void e_day_view_time_item_on_button_release (EDayViewTimeItem *time_item, GdkEvent *event); -static void e_day_view_time_item_on_motion_notify (EDayViewTimeItem *dvtmitem, +static void e_day_view_time_item_on_motion_notify (EDayViewTimeItem *time_item, GdkEvent *event); -static gint e_day_view_time_item_convert_position_to_row (EDayViewTimeItem *dvtmitem, +static gint e_day_view_time_item_convert_position_to_row (EDayViewTimeItem *time_item, gint y); static void edvti_second_zone_changed_cb (GConfClient *client, guint cnxn_id, GConfEntry *entry, gpointer user_data); -/* The arguments we take */ + enum { PROP_0, PROP_DAY_VIEW }; -G_DEFINE_TYPE (EDayViewTimeItem, e_day_view_time_item, GNOME_TYPE_CANVAS_ITEM) +static gpointer parent_class; + +static void +day_view_time_item_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec) +{ + switch (property_id) { + case PROP_DAY_VIEW: + e_day_view_time_item_set_day_view ( + E_DAY_VIEW_TIME_ITEM (object), + g_value_get_object (value)); + return; + } + + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); +} + +static void +day_view_time_item_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec) +{ + switch (property_id) { + case PROP_DAY_VIEW: + g_value_set_object ( + value, e_day_view_time_item_get_day_view ( + E_DAY_VIEW_TIME_ITEM (object))); + return; + } + + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); +} + +static void +day_view_time_item_dispose (GObject *object) +{ + EDayViewTimeItemPrivate *priv; + + priv = E_DAY_VIEW_TIME_ITEM_GET_PRIVATE (object); + + if (priv->day_view != NULL) { + g_object_unref (priv->day_view); + priv->day_view = NULL; + } + + /* Chain up to parent's dispose() method. */ + G_OBJECT_CLASS (parent_class)->dispose (object); +} + +static void +day_view_time_item_finalize (GObject *object) +{ + EDayViewTimeItem *time_item; + + time_item = E_DAY_VIEW_TIME_ITEM (object); + + if (time_item->priv->second_zone_changed_id) + calendar_config_remove_notification (time_item->priv->second_zone_changed_id); + time_item->priv->second_zone_changed_id = 0; + + /* Chain up to parent's dispose() method. */ + G_OBJECT_CLASS (parent_class)->finalize (object); +} static void -e_day_view_time_item_class_init (EDayViewTimeItemClass *class) +day_view_time_item_class_init (EDayViewTimeItemClass *class) { - GObjectClass *object_class; + GObjectClass *object_class; GnomeCanvasItemClass *item_class; + parent_class = g_type_class_peek_parent (class); + g_type_class_add_private (class, sizeof (EDayViewTimeItemPrivate)); + object_class = G_OBJECT_CLASS (class); - object_class->set_property = e_day_view_time_item_set_property; - object_class->finalize = e_day_view_time_item_finalize; + object_class->set_property = day_view_time_item_set_property; + object_class->get_property = day_view_time_item_get_property; + object_class->dispose = day_view_time_item_dispose; + object_class->finalize = day_view_time_item_finalize; item_class = GNOME_CANVAS_ITEM_CLASS (class); item_class->update = e_day_view_time_item_update; @@ -119,64 +201,60 @@ e_day_view_time_item_class_init (EDayViewTimeItemClass *class) g_object_class_install_property ( object_class, PROP_DAY_VIEW, - g_param_spec_pointer ( - "day_view", - NULL, + g_param_spec_object ( + "day-view", + "Day View", NULL, - G_PARAM_WRITABLE)); + E_TYPE_DAY_VIEW, + G_PARAM_READWRITE)); } static void -e_day_view_time_item_init (EDayViewTimeItem *dvtmitem) +day_view_time_item_init (EDayViewTimeItem *time_item) { gchar *last; - dvtmitem->dragging_selection = FALSE; - dvtmitem->second_zone = NULL; + time_item->priv = E_DAY_VIEW_TIME_ITEM_GET_PRIVATE (time_item); + + time_item->priv->dragging_selection = FALSE; + time_item->priv->second_zone = NULL; last = calendar_config_get_day_second_zone (); if (last) { if (*last) - dvtmitem->second_zone = icaltimezone_get_builtin_timezone (last); + time_item->priv->second_zone = icaltimezone_get_builtin_timezone (last); g_free (last); } - dvtmitem->second_zone_changed_id = calendar_config_add_notification_day_second_zone (edvti_second_zone_changed_cb, dvtmitem); + time_item->priv->second_zone_changed_id = calendar_config_add_notification_day_second_zone (edvti_second_zone_changed_cb, time_item); } -static void -e_day_view_time_item_set_property (GObject *object, - guint property_id, - const GValue *value, - GParamSpec *pspec) +GType +e_day_view_time_item_get_type (void) { - EDayViewTimeItem *dvtmitem; - - dvtmitem = E_DAY_VIEW_TIME_ITEM (object); - - switch (property_id) { - case PROP_DAY_VIEW: - dvtmitem->day_view = g_value_get_pointer (value); - return; + static GType type = 0; + + if (G_UNLIKELY (type == 0)) { + const GTypeInfo type_info = { + sizeof (EDayViewTimeItemClass), + (GBaseInitFunc) NULL, + (GBaseFinalizeFunc) NULL, + (GClassInitFunc) day_view_time_item_class_init, + (GClassFinalizeFunc) NULL, + NULL, /* class_data */ + sizeof (EDayViewTimeItem), + 0, /* n_preallocs */ + (GInstanceInitFunc) day_view_time_item_init, + NULL /* value_table */ + }; + + type = g_type_register_static ( + GNOME_TYPE_CANVAS_ITEM, "EDayViewTimeItem", + &type_info, 0); } - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); -} - -static void -e_day_view_time_item_finalize (GObject *object) -{ - EDayViewTimeItem *dvtmitem; - - dvtmitem = E_DAY_VIEW_TIME_ITEM (object); - - if (dvtmitem->second_zone_changed_id) - calendar_config_remove_notification (dvtmitem->second_zone_changed_id); - dvtmitem->second_zone_changed_id = 0; - - if (G_OBJECT_CLASS (e_day_view_time_item_parent_class)->finalize) - G_OBJECT_CLASS (e_day_view_time_item_parent_class)->finalize (object); + return type; } static void @@ -185,8 +263,8 @@ e_day_view_time_item_update (GnomeCanvasItem *item, ArtSVP *clip_path, gint flags) { - if (GNOME_CANVAS_ITEM_CLASS (e_day_view_time_item_parent_class)->update) - (* GNOME_CANVAS_ITEM_CLASS (e_day_view_time_item_parent_class)->update) (item, affine, clip_path, flags); + if (GNOME_CANVAS_ITEM_CLASS (parent_class)->update) + (* GNOME_CANVAS_ITEM_CLASS (parent_class)->update) (item, affine, clip_path, flags); /* The item covers the entire canvas area. */ item->x1 = 0; @@ -195,75 +273,6 @@ e_day_view_time_item_update (GnomeCanvasItem *item, item->y2 = INT_MAX; } -/* Returns the minimum width needed for the column, by adding up all the - maximum widths of the strings. The string widths are all calculated in - the style_set handlers of EDayView and EDayViewTimeCanvas. */ -gint -e_day_view_time_item_get_column_width (EDayViewTimeItem *dvtmitem) -{ - EDayView *day_view; - GtkStyle *style; - gint digit, large_digit_width, max_large_digit_width = 0; - gint max_suffix_width, max_minute_or_suffix_width; - gint column_width_default, column_width_60_min_rows; - - day_view = dvtmitem->day_view; - g_return_val_if_fail (day_view != NULL, 0); - - style = gtk_widget_get_style (GTK_WIDGET (day_view)); - g_return_val_if_fail (style != NULL, 0); - - /* Find the maximum width a digit can have. FIXME: We could use pango's - * approximation function, but I worry it won't be precise enough. Also - * it needs a language tag that I don't know where to get. */ - for (digit = '0'; digit <= '9'; digit++) { - PangoLayout *layout; - gchar digit_str [2]; - - digit_str [0] = digit; - digit_str [1] = '\0'; - - layout = gtk_widget_create_pango_layout (GTK_WIDGET (day_view), digit_str); - pango_layout_set_font_description (layout, day_view->large_font_desc); - pango_layout_get_pixel_size (layout, &large_digit_width, NULL); - - g_object_unref (layout); - - max_large_digit_width = MAX (max_large_digit_width, - large_digit_width); - } - - /* Calculate the width of each time column, using the maximum of the - default format with large hour numbers, and the 60-min divisions - format which uses small text. */ - max_suffix_width = MAX (day_view->am_string_width, - day_view->pm_string_width); - - max_minute_or_suffix_width = MAX (max_suffix_width, - day_view->max_minute_width); - - column_width_default = max_large_digit_width * 2 - + max_minute_or_suffix_width - + E_DVTMI_MIN_X_PAD * 2 - + E_DVTMI_HOUR_L_PAD - + E_DVTMI_HOUR_R_PAD - + E_DVTMI_TIME_GRID_X_PAD * 2; - - column_width_60_min_rows = day_view->max_small_hour_width - + day_view->colon_width - + max_minute_or_suffix_width - + E_DVTMI_60_MIN_X_PAD * 2 - + E_DVTMI_TIME_GRID_X_PAD * 2; - - dvtmitem->column_width = MAX (column_width_default, - column_width_60_min_rows); - - if (dvtmitem->second_zone) - return (2 * dvtmitem->column_width) - E_DVTMI_TIME_GRID_X_PAD; - - return dvtmitem->column_width; -} - /* * DRAWING ROUTINES - functions to paint the canvas item. */ @@ -278,7 +287,7 @@ edvti_draw_zone (GnomeCanvasItem *canvas_item, icaltimezone *use_zone) { EDayView *day_view; - EDayViewTimeItem *dvtmitem; + EDayViewTimeItem *time_item; ECalModel *model; GtkStyle *style; const gchar *suffix; @@ -299,8 +308,8 @@ edvti_draw_zone (GnomeCanvasItem *canvas_item, cr = gdk_cairo_create (drawable); - dvtmitem = E_DAY_VIEW_TIME_ITEM (canvas_item); - day_view = dvtmitem->day_view; + time_item = E_DAY_VIEW_TIME_ITEM (canvas_item); + day_view = e_day_view_time_item_get_day_view (time_item); g_return_if_fail (day_view != NULL); model = e_calendar_view_get_model (E_CALENDAR_VIEW (day_view)); @@ -319,7 +328,7 @@ edvti_draw_zone (GnomeCanvasItem *canvas_item, /* The start and end of the long horizontal line between hours. */ long_line_x1 = (use_zone ? 0 : E_DVTMI_TIME_GRID_X_PAD) - x + x_offset; - long_line_x2 = dvtmitem->column_width - E_DVTMI_TIME_GRID_X_PAD - x - (use_zone ? E_DVTMI_TIME_GRID_X_PAD : 0) + x_offset; + long_line_x2 = time_item->priv->column_width - E_DVTMI_TIME_GRID_X_PAD - x - (use_zone ? E_DVTMI_TIME_GRID_X_PAD : 0) + x_offset; if (day_view->mins_per_row == 60) { /* The right edge of the complete time string in 60-min @@ -613,15 +622,15 @@ e_day_view_time_item_draw (GnomeCanvasItem *canvas_item, gint width, gint height) { - EDayViewTimeItem *dvtmitem; + EDayViewTimeItem *time_item; - dvtmitem = E_DAY_VIEW_TIME_ITEM (canvas_item); - g_return_if_fail (dvtmitem != NULL); + time_item = E_DAY_VIEW_TIME_ITEM (canvas_item); + g_return_if_fail (time_item != NULL); edvti_draw_zone (canvas_item, drawable, x, y, width, height, 0, NULL); - if (dvtmitem->second_zone) - edvti_draw_zone (canvas_item, drawable, x, y, width, height, dvtmitem->column_width, dvtmitem->second_zone); + if (time_item->priv->second_zone) + edvti_draw_zone (canvas_item, drawable, x, y, width, height, time_item->priv->column_width, time_item->priv->second_zone); } /* Increment the time by the 5/10/15/30/60 minute interval. @@ -654,27 +663,27 @@ static gint e_day_view_time_item_event (GnomeCanvasItem *item, GdkEvent *event) { - EDayViewTimeItem *dvtmitem; + EDayViewTimeItem *time_item; - dvtmitem = E_DAY_VIEW_TIME_ITEM (item); + time_item = E_DAY_VIEW_TIME_ITEM (item); switch (event->type) { case GDK_BUTTON_PRESS: if (event->button.button == 1) { - e_day_view_time_item_on_button_press (dvtmitem, event); + e_day_view_time_item_on_button_press (time_item, event); } else if (event->button.button == 3) { - e_day_view_time_item_show_popup_menu (dvtmitem, event); + e_day_view_time_item_show_popup_menu (time_item, event); return TRUE; } break; case GDK_BUTTON_RELEASE: if (event->button.button == 1) - e_day_view_time_item_on_button_release (dvtmitem, + e_day_view_time_item_on_button_release (time_item, event); break; case GDK_MOTION_NOTIFY: - e_day_view_time_item_on_motion_notify (dvtmitem, event); + e_day_view_time_item_on_motion_notify (time_item, event); break; default: @@ -687,28 +696,30 @@ e_day_view_time_item_event (GnomeCanvasItem *item, static void edvti_second_zone_changed_cb (GConfClient *client, guint cnxn_id, GConfEntry *entry, gpointer user_data) { - EDayViewTimeItem *dvtmitem = user_data; + EDayViewTimeItem *time_item = user_data; + EDayView *day_view; gchar *location; g_return_if_fail (user_data != NULL); - g_return_if_fail (E_IS_DAY_VIEW_TIME_ITEM (dvtmitem)); + g_return_if_fail (E_IS_DAY_VIEW_TIME_ITEM (time_item)); location = calendar_config_get_day_second_zone (); - dvtmitem->second_zone = location ? icaltimezone_get_builtin_timezone (location) : NULL; + time_item->priv->second_zone = location ? icaltimezone_get_builtin_timezone (location) : NULL; g_free (location); - gtk_widget_set_size_request (dvtmitem->day_view->time_canvas, e_day_view_time_item_get_column_width (dvtmitem), -1); - gtk_widget_queue_draw (dvtmitem->day_view->time_canvas); + day_view = e_day_view_time_item_get_day_view (time_item); + gtk_widget_set_size_request (day_view->time_canvas, e_day_view_time_item_get_column_width (time_item), -1); + gtk_widget_queue_draw (day_view->time_canvas); } static void -edvti_on_select_zone (GtkWidget *item, EDayViewTimeItem *dvtmitem) +edvti_on_select_zone (GtkWidget *item, EDayViewTimeItem *time_item) { calendar_config_select_day_second_zone (); } static void -edvti_on_set_zone (GtkWidget *item, EDayViewTimeItem *dvtmitem) +edvti_on_set_zone (GtkWidget *item, EDayViewTimeItem *time_item) { if (!gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (item))) return; @@ -717,7 +728,7 @@ edvti_on_set_zone (GtkWidget *item, EDayViewTimeItem *dvtmitem) } static void -e_day_view_time_item_show_popup_menu (EDayViewTimeItem *dvtmitem, +e_day_view_time_item_show_popup_menu (EDayViewTimeItem *time_item, GdkEvent *event) { static gint divisions[] = { 60, 30, 15, 10, 5 }; @@ -729,7 +740,7 @@ e_day_view_time_item_show_popup_menu (EDayViewTimeItem *dvtmitem, gint current_divisions, i; icaltimezone *zone; - day_view = dvtmitem->day_view; + day_view = e_day_view_time_item_get_day_view (time_item); g_return_if_fail (day_view != NULL); current_divisions = e_day_view_get_mins_per_row (day_view); @@ -760,7 +771,7 @@ e_day_view_time_item_show_popup_menu (EDayViewTimeItem *dvtmitem, GINT_TO_POINTER (divisions[i])); g_signal_connect (item, "toggled", - G_CALLBACK (e_day_view_time_item_on_set_divisions), dvtmitem); + G_CALLBACK (e_day_view_time_item_on_set_divisions), time_item); } item = gtk_separator_menu_item_new (); @@ -787,10 +798,10 @@ e_day_view_time_item_show_popup_menu (EDayViewTimeItem *dvtmitem, group = NULL; item = gtk_radio_menu_item_new_with_label (group, _("None")); group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (item)); - if (!dvtmitem->second_zone) + if (!time_item->priv->second_zone) gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item), TRUE); gtk_menu_shell_append (GTK_MENU_SHELL (submenu), item); - g_signal_connect (item, "toggled", G_CALLBACK (edvti_on_set_zone), dvtmitem); + g_signal_connect (item, "toggled", G_CALLBACK (edvti_on_set_zone), time_item); recent_zones = calendar_config_get_day_second_zones (); for (s = recent_zones; s != NULL; s = s->next) { @@ -801,11 +812,11 @@ e_day_view_time_item_show_popup_menu (EDayViewTimeItem *dvtmitem, item = gtk_radio_menu_item_new_with_label (group, icaltimezone_get_display_name (zone)); group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (item)); /* both comes from builtin, thus no problem to compare pointers */ - if (zone == dvtmitem->second_zone) + if (zone == time_item->priv->second_zone) gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item), TRUE); gtk_menu_shell_append (GTK_MENU_SHELL (submenu), item); g_object_set_data_full (G_OBJECT (item), "timezone", g_strdup (s->data), g_free); - g_signal_connect (item, "toggled", G_CALLBACK (edvti_on_set_zone), dvtmitem); + g_signal_connect (item, "toggled", G_CALLBACK (edvti_on_set_zone), time_item); } calendar_config_free_day_second_zones (recent_zones); @@ -813,7 +824,7 @@ e_day_view_time_item_show_popup_menu (EDayViewTimeItem *dvtmitem, gtk_menu_shell_append (GTK_MENU_SHELL (submenu), item); item = gtk_menu_item_new_with_label (_("Select...")); - g_signal_connect (item, "activate", G_CALLBACK (edvti_on_select_zone), dvtmitem); + g_signal_connect (item, "activate", G_CALLBACK (edvti_on_select_zone), time_item); gtk_menu_shell_append (GTK_MENU_SHELL (submenu), item); gtk_widget_show_all (submenu); @@ -824,12 +835,12 @@ e_day_view_time_item_show_popup_menu (EDayViewTimeItem *dvtmitem, static void e_day_view_time_item_on_set_divisions (GtkWidget *item, - EDayViewTimeItem *dvtmitem) + EDayViewTimeItem *time_item) { EDayView *day_view; gint divisions; - day_view = dvtmitem->day_view; + day_view = e_day_view_time_item_get_day_view (time_item); g_return_if_fail (day_view != NULL); if (!gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (item))) @@ -841,19 +852,19 @@ e_day_view_time_item_on_set_divisions (GtkWidget *item, } static void -e_day_view_time_item_on_button_press (EDayViewTimeItem *dvtmitem, +e_day_view_time_item_on_button_press (EDayViewTimeItem *time_item, GdkEvent *event) { EDayView *day_view; GnomeCanvas *canvas; gint row; - day_view = dvtmitem->day_view; + day_view = e_day_view_time_item_get_day_view (time_item); g_return_if_fail (day_view != NULL); - canvas = GNOME_CANVAS_ITEM (dvtmitem)->canvas; + canvas = GNOME_CANVAS_ITEM (time_item)->canvas; - row = e_day_view_time_item_convert_position_to_row (dvtmitem, + row = e_day_view_time_item_convert_position_to_row (time_item, event->button.y); if (row == -1) @@ -867,30 +878,30 @@ e_day_view_time_item_on_button_press (EDayViewTimeItem *dvtmitem, | GDK_BUTTON_RELEASE_MASK, NULL, NULL, event->button.time) == 0) { e_day_view_start_selection (day_view, -1, row); - dvtmitem->dragging_selection = TRUE; + time_item->priv->dragging_selection = TRUE; } } static void -e_day_view_time_item_on_button_release (EDayViewTimeItem *dvtmitem, +e_day_view_time_item_on_button_release (EDayViewTimeItem *time_item, GdkEvent *event) { EDayView *day_view; - day_view = dvtmitem->day_view; + day_view = e_day_view_time_item_get_day_view (time_item); g_return_if_fail (day_view != NULL); - if (dvtmitem->dragging_selection) { + if (time_item->priv->dragging_selection) { gdk_pointer_ungrab (event->button.time); e_day_view_finish_selection (day_view); e_day_view_stop_auto_scroll (day_view); } - dvtmitem->dragging_selection = FALSE; + time_item->priv->dragging_selection = FALSE; } static void -e_day_view_time_item_on_motion_notify (EDayViewTimeItem *dvtmitem, +e_day_view_time_item_on_motion_notify (EDayViewTimeItem *time_item, GdkEvent *event) { EDayView *day_view; @@ -898,16 +909,16 @@ e_day_view_time_item_on_motion_notify (EDayViewTimeItem *dvtmitem, gdouble window_y; gint y, row; - if (!dvtmitem->dragging_selection) + if (!time_item->priv->dragging_selection) return; - day_view = dvtmitem->day_view; + day_view = e_day_view_time_item_get_day_view (time_item); g_return_if_fail (day_view != NULL); - canvas = GNOME_CANVAS_ITEM (dvtmitem)->canvas; + canvas = GNOME_CANVAS_ITEM (time_item)->canvas; y = event->motion.y; - row = e_day_view_time_item_convert_position_to_row (dvtmitem, y); + row = e_day_view_time_item_convert_position_to_row (time_item, y); if (row != -1) { gnome_canvas_world_to_window (canvas, 0, event->motion.y, @@ -919,13 +930,13 @@ e_day_view_time_item_on_motion_notify (EDayViewTimeItem *dvtmitem, /* Returns the row corresponding to the y position, or -1. */ static gint -e_day_view_time_item_convert_position_to_row (EDayViewTimeItem *dvtmitem, +e_day_view_time_item_convert_position_to_row (EDayViewTimeItem *time_item, gint y) { EDayView *day_view; gint row; - day_view = dvtmitem->day_view; + day_view = e_day_view_time_item_get_day_view (time_item); g_return_val_if_fail (day_view != NULL, -1); if (y < 0) @@ -937,3 +948,104 @@ e_day_view_time_item_convert_position_to_row (EDayViewTimeItem *dvtmitem, return row; } + +EDayView * +e_day_view_time_item_get_day_view (EDayViewTimeItem *time_item) +{ + g_return_val_if_fail (E_IS_DAY_VIEW_TIME_ITEM (time_item), NULL); + + return time_item->priv->day_view; +} + +void +e_day_view_time_item_set_day_view (EDayViewTimeItem *time_item, + EDayView *day_view) +{ + g_return_if_fail (E_IS_DAY_VIEW_TIME_ITEM (time_item)); + g_return_if_fail (E_IS_DAY_VIEW (day_view)); + + if (time_item->priv->day_view != NULL) + g_object_unref (time_item->priv->day_view); + + time_item->priv->day_view = g_object_ref (day_view); + + g_object_notify (G_OBJECT (time_item), "day-view"); +} + +/* Returns the minimum width needed for the column, by adding up all the + maximum widths of the strings. The string widths are all calculated in + the style_set handlers of EDayView and EDayViewTimeCanvas. */ +gint +e_day_view_time_item_get_column_width (EDayViewTimeItem *time_item) +{ + EDayView *day_view; + GtkStyle *style; + gint digit, large_digit_width, max_large_digit_width = 0; + gint max_suffix_width, max_minute_or_suffix_width; + gint column_width_default, column_width_60_min_rows; + + day_view = e_day_view_time_item_get_day_view (time_item); + g_return_val_if_fail (day_view != NULL, 0); + + style = gtk_widget_get_style (GTK_WIDGET (day_view)); + g_return_val_if_fail (style != NULL, 0); + + /* Find the maximum width a digit can have. FIXME: We could use pango's + * approximation function, but I worry it won't be precise enough. Also + * it needs a language tag that I don't know where to get. */ + for (digit = '0'; digit <= '9'; digit++) { + PangoLayout *layout; + gchar digit_str [2]; + + digit_str [0] = digit; + digit_str [1] = '\0'; + + layout = gtk_widget_create_pango_layout (GTK_WIDGET (day_view), digit_str); + pango_layout_set_font_description (layout, day_view->large_font_desc); + pango_layout_get_pixel_size (layout, &large_digit_width, NULL); + + g_object_unref (layout); + + max_large_digit_width = MAX (max_large_digit_width, + large_digit_width); + } + + /* Calculate the width of each time column, using the maximum of the + default format with large hour numbers, and the 60-min divisions + format which uses small text. */ + max_suffix_width = MAX (day_view->am_string_width, + day_view->pm_string_width); + + max_minute_or_suffix_width = MAX (max_suffix_width, + day_view->max_minute_width); + + column_width_default = max_large_digit_width * 2 + + max_minute_or_suffix_width + + E_DVTMI_MIN_X_PAD * 2 + + E_DVTMI_HOUR_L_PAD + + E_DVTMI_HOUR_R_PAD + + E_DVTMI_TIME_GRID_X_PAD * 2; + + column_width_60_min_rows = day_view->max_small_hour_width + + day_view->colon_width + + max_minute_or_suffix_width + + E_DVTMI_60_MIN_X_PAD * 2 + + E_DVTMI_TIME_GRID_X_PAD * 2; + + time_item->priv->column_width = + MAX (column_width_default, column_width_60_min_rows); + + if (time_item->priv->second_zone) + return (2 * time_item->priv->column_width) - + E_DVTMI_TIME_GRID_X_PAD; + + return time_item->priv->column_width; +} + +icaltimezone * +e_day_view_time_item_get_second_zone (EDayViewTimeItem *time_item) +{ + g_return_val_if_fail (E_IS_DAY_VIEW_TIME_ITEM (time_item), NULL); + + return time_item->priv->second_zone; +} |