diff options
author | Damon Chaplin <damon@helixcode.com> | 2000-09-30 23:29:22 +0800 |
---|---|---|
committer | Damon Chaplin <damon@src.gnome.org> | 2000-09-30 23:29:22 +0800 |
commit | 0ff98664ba2f06f71508288247b3b25ffb7f8f47 (patch) | |
tree | 8bf1505d4c16c605042d8ab058ee85099863b093 /calendar/gui | |
parent | 32d2e7c670ebc72b8f60172e8f6fddcc5ae7f45d (diff) | |
download | gsoc2013-evolution-0ff98664ba2f06f71508288247b3b25ffb7f8f47.tar gsoc2013-evolution-0ff98664ba2f06f71508288247b3b25ffb7f8f47.tar.gz gsoc2013-evolution-0ff98664ba2f06f71508288247b3b25ffb7f8f47.tar.bz2 gsoc2013-evolution-0ff98664ba2f06f71508288247b3b25ffb7f8f47.tar.lz gsoc2013-evolution-0ff98664ba2f06f71508288247b3b25ffb7f8f47.tar.xz gsoc2013-evolution-0ff98664ba2f06f71508288247b3b25ffb7f8f47.tar.zst gsoc2013-evolution-0ff98664ba2f06f71508288247b3b25ffb7f8f47.zip |
updated to support RDATE end times or durations. Note that if you have two
2000-09-29 Damon Chaplin <damon@helixcode.com>
* cal-util/cal-recur.c: updated to support RDATE end times or
durations. Note that if you have two RDATEs with the same start times,
but with different end dates/durations set, the results are
unpredictable. So the event editor dialog should check for this.
* gui/e-week-view-main-item.c (e_week_view_main_item_draw_day):
make strftime() strings translatable, and changed the formats a bit.
* NOTE: someone needs to check print.c to make sure strftime strings
are OK for i18n.
* gui/e-day-view.h: Changed EDayViewDateFormat enum. We now try to
include the weekday if possible. Also changed EDayView struct so we
store the month & weekdays with the longest names rather than the
actual widths. This helps i18n.
* gui/e-day-view.c (e_day_view_recalc_cell_sizes): used _() for
strftime strings, tried to see if weekday fits, and rearranged a
bit to make i18n easier.
* gui/e-day-view-top-item.c (e_day_view_top_item_draw): used _() for
strftime strings, and updated to use new formats.
* gui/calendar-model.c: added use_24_hour_format boolean to
CalendarModelPrivate so we can display dates in 12-hour format if
requested. This meant adding a CalendarModel argument to a few
functions. Also added get/set functions to set use_24_hour_format.
I suppose ideally we should have an ECellDate renderer and this option
should go there.
svn path=/trunk/; revision=5646
Diffstat (limited to 'calendar/gui')
-rw-r--r-- | calendar/gui/calendar-model.c | 249 | ||||
-rw-r--r-- | calendar/gui/calendar-model.h | 5 | ||||
-rw-r--r-- | calendar/gui/e-day-view-top-item.c | 18 | ||||
-rw-r--r-- | calendar/gui/e-day-view.c | 138 | ||||
-rw-r--r-- | calendar/gui/e-day-view.h | 17 | ||||
-rw-r--r-- | calendar/gui/e-week-view-main-item.c | 33 |
6 files changed, 352 insertions, 108 deletions
diff --git a/calendar/gui/calendar-model.c b/calendar/gui/calendar-model.c index 7274c13e18..fa05ba407a 100644 --- a/calendar/gui/calendar-model.c +++ b/calendar/gui/calendar-model.c @@ -52,6 +52,9 @@ struct _CalendarModelPrivate { /* UID -> array index hash */ GHashTable *uid_index_hash; + /* Whether we display dates in 24-hour format. */ + gboolean use_24_hour_format; + /* HACK: so that ETable can do its stupid append_row() thing */ guint appending_row : 1; }; @@ -157,6 +160,7 @@ calendar_model_init (CalendarModel *model) priv->objects = g_array_new (FALSE, TRUE, sizeof (CalComponent *)); priv->uid_index_hash = g_hash_table_new (g_str_hash, g_str_equal); + priv->use_24_hour_format = TRUE; } /* Called from g_hash_table_foreach_remove(), frees a stored UID->index @@ -261,10 +265,11 @@ calendar_model_row_count (ETableModel *etm) /* Creates a nice string representation of a time value */ static char* -get_time_t (time_t *t, gboolean skip_midnight) +get_time_t (CalendarModel *model, time_t *t, gboolean skip_midnight) { - static char buffer[32]; + static char buffer[64]; struct tm *tmp_tm; + char *format; if (*t <= 0) { buffer[0] = '\0'; @@ -273,9 +278,18 @@ get_time_t (time_t *t, gboolean skip_midnight) if (skip_midnight && tmp_tm->tm_hour == 0 && tmp_tm->tm_min == 0 && tmp_tm->tm_sec == 0) - strftime (buffer, 32, "%a %x", tmp_tm); + /* strftime format of a weekday and a date. */ + format = _("%a %m/%d/%Y"); + else if (model->priv->use_24_hour_format) + /* strftime format of a weekday, a date and a time, + in 24-hour format. */ + format = _("%a %m/%d/%Y %H:%M:%S"); else - strftime (buffer, 32, "%a %x %T", tmp_tm); + /* strftime format of a weekday, a date and a time, + in 12-hour format. */ + format = _("%a %m/%d/%Y %I:%M:%S %p"); + + strftime (buffer, sizeof (buffer), format, tmp_tm); } return buffer; @@ -346,7 +360,8 @@ get_classification (CalComponent *comp) /* Builds a string for the COMPLETED property of a calendar component */ static char * -get_completed (CalComponent *comp) +get_completed (CalendarModel *model, + CalComponent *comp) { struct icaltimetype *completed; time_t t; @@ -360,12 +375,12 @@ get_completed (CalComponent *comp) cal_component_free_icaltimetype (completed); } - return get_time_t (&t, FALSE); + return get_time_t (model, &t, FALSE); } /* Builds a string for and frees a date/time value */ static char * -get_and_free_datetime (CalComponentDateTime dt) +get_and_free_datetime (CalendarModel *model, CalComponentDateTime dt) { time_t t; @@ -376,37 +391,37 @@ get_and_free_datetime (CalComponentDateTime dt) cal_component_free_datetime (&dt); - return get_time_t (&t, FALSE); + return get_time_t (model, &t, FALSE); } /* Builds a string for the DTEND property of a calendar component */ static char * -get_dtend (CalComponent *comp) +get_dtend (CalendarModel *model, CalComponent *comp) { CalComponentDateTime dt; cal_component_get_dtend (comp, &dt); - return get_and_free_datetime (dt); + return get_and_free_datetime (model, dt); } /* Builds a string for the DTSTART property of a calendar component */ static char * -get_dtstart (CalComponent *comp) +get_dtstart (CalendarModel *model, CalComponent *comp) { CalComponentDateTime dt; cal_component_get_dtstart (comp, &dt); - return get_and_free_datetime (dt); + return get_and_free_datetime (model, dt); } /* Builds a string for the DUE property of a calendar component */ static char * -get_due (CalComponent *comp) +get_due (CalendarModel *model, CalComponent *comp) { CalComponentDateTime dt; cal_component_get_due (comp, &dt); - return get_and_free_datetime (dt); + return get_and_free_datetime (model, dt); } /* Builds a string for the GEO property of a calendar component */ @@ -546,8 +561,6 @@ get_is_complete (CalComponent *comp) struct icaltimetype *t; gboolean retval; - /* May not be reliable, especially at the moment when - we can't set a Completed Date to None. */ cal_component_get_completed (comp, &t); retval = (t != NULL); @@ -627,16 +640,16 @@ calendar_model_value_at (ETableModel *etm, int col, int row) return get_classification (comp); case CAL_COMPONENT_FIELD_COMPLETED: - return get_completed (comp); + return get_completed (model, comp); case CAL_COMPONENT_FIELD_DTEND: - return get_dtend (comp); + return get_dtend (model, comp); case CAL_COMPONENT_FIELD_DTSTART: - return get_dtstart (comp); + return get_dtstart (model, comp); case CAL_COMPONENT_FIELD_DUE: - return get_due (comp); + return get_due (model, comp); case CAL_COMPONENT_FIELD_GEO: return get_geo (comp); @@ -712,16 +725,24 @@ string_is_empty (const char *value) /* FIXME: We need to set the "transient_for" property for the dialog, but the model doesn't know anything about the windows. */ static void -show_date_warning (void) +show_date_warning (CalendarModel *model) { GtkWidget *dialog; - char buffer[32], message[256]; + char buffer[64], message[256], *format; time_t t; struct tm *tmp_tm; t = time (NULL); tmp_tm = localtime (&t); - strftime (buffer, 32, "%a %x %T", tmp_tm); + + if (model->priv->use_24_hour_format) + /* strftime format of a weekday, a date and a time, 24-hour. */ + format = _("%a %m/%d/%Y %H:%M:%S"); + else + /* strftime format of a weekday, a date and a time, 12-hour. */ + format = _("%a %m/%d/%Y %I:%M:%S %p"); + + strftime (buffer, sizeof (buffer), format, tmp_tm); g_snprintf (message, 256, _("The date must be entered in the format: \n\n%s"), @@ -801,62 +822,137 @@ set_categories (CalComponent *comp, const char *value) static time_t parse_time (const char *value) { - struct tm tmp_tm; + struct tm discard_tm, date_tm, time_tm; struct tm *today_tm; time_t t; - const char *p; + const char *pos, *parse_end; + char *format[4]; + gboolean parsed_date = FALSE, parsed_time = FALSE; + gint i; if (string_is_empty (value)) return 0; - /* Skip any weekday name. */ - p = strptime (value, "%a", &tmp_tm); - if (!p) - p = value; + pos = value; - /* Try to match the full date & time, or without the seconds, - or just the date, or just the time with/without seconds. - The info pages say we should clear the tm before calling - strptime. It also means that if we don't match a time we - get 00:00:00 which is good. */ - memset (&tmp_tm, 0, sizeof (tmp_tm)); - if (!strptime (value, "%x %T", &tmp_tm)) { - memset (&tmp_tm, 0, sizeof (tmp_tm)); - if (!strptime (value, "%x %H:%M", &tmp_tm)) { - memset (&tmp_tm, 0, sizeof (tmp_tm)); - if (!strptime (value, "%x", &tmp_tm)) { - memset (&tmp_tm, 0, sizeof (tmp_tm)); - if (!strptime (value, "%T", &tmp_tm)) { - memset (&tmp_tm, 0, sizeof (tmp_tm)); - if (!strptime (value, "%H:%M", &tmp_tm)) - return -1; /* Could not parse it */ - } - - /* We only got a time, so we use the - current day. */ - t = time (NULL); - today_tm = localtime (&t); - tmp_tm.tm_mday = today_tm->tm_mday; - tmp_tm.tm_mon = today_tm->tm_mon; - tmp_tm.tm_year = today_tm->tm_year; - } + /* Skip any whitespace. */ + while (isspace (*pos)) + pos++; + + /* Skip any weekday name, full or abbreviated. */ + parse_end = strptime (pos, "%a ", &discard_tm); + if (parse_end) + pos = parse_end; + + memset (&date_tm, 0, sizeof (date_tm)); + /* strptime format for a date. */ + parse_end = strptime (pos, _("%m/%d/%Y"), &date_tm); + if (parse_end) { + pos = parse_end; + parsed_date = TRUE; + } + + /* Skip any whitespace. */ + while (isspace (*pos)) + pos++; + + /* Skip any weekday name, full or abbreviated, again. */ + parse_end = strptime (pos, "%a ", &discard_tm); + if (parse_end) + pos = parse_end; + + + /* strptime format for a time of day, in 12-hour format. + If it is is not appropriate in the locale set to an empty string. */ + format[0] = _("%I:%M:%S %p%n"); + + /* strptime format for a time of day, in 24-hour format. */ + format[1] = _("%H:%M:%S%n"); + + /* strptime format for time of day, without seconds, 12-hour format. + If it is is not appropriate in the locale set to an empty string. */ + format[2] = _("%I:%M %p%n"); + + /* strptime format for time of day, without seconds 24-hour format. */ + format[3] = _("%H:%M%n"); + + for (i = 0; i < sizeof (format) / sizeof (format[0]); i++) { + memset (&time_tm, 0, sizeof (time_tm)); + parse_end = strptime (pos, format[i], &time_tm); + if (parse_end) { + pos = parse_end; + parsed_time = TRUE; + break; + } + } + + /* Skip any whitespace. */ + while (isspace (*pos)) + pos++; + + /* If we haven't already parsed a date, try again. */ + if (!parsed_date) { + memset (&date_tm, 0, sizeof (date_tm)); + /* strptime format for a date. */ + parse_end = strptime (pos, _("%m/%d/%Y"), &date_tm); + if (parse_end) { + pos = parse_end; + parsed_date = TRUE; } } - tmp_tm.tm_isdst = -1; - return mktime (&tmp_tm); + /* If we don't have a date or a time it must be invalid. */ + if (!parsed_date && !parsed_time) + return -1; + + + if (parsed_date) { + /* If a 2-digit year was used we use the current century. */ + if (date_tm.tm_year < 0) { + t = time (NULL); + today_tm = localtime (&t); + + /* This should convert it into a value from 0 to 99. */ + date_tm.tm_year += 1900; + + /* Now add on the century. */ + date_tm.tm_year += today_tm->tm_year + - (today_tm->tm_year % 100); + } + } else { + /* If we didn't get a date we use the current day. */ + t = time (NULL); + today_tm = localtime (&t); + date_tm.tm_mday = today_tm->tm_mday; + date_tm.tm_mon = today_tm->tm_mon; + date_tm.tm_year = today_tm->tm_year; + } + + if (parsed_time) { + date_tm.tm_hour = time_tm.tm_hour; + date_tm.tm_min = time_tm.tm_min; + date_tm.tm_sec = time_tm.tm_sec; + } else { + date_tm.tm_hour = 0; + date_tm.tm_min = 0; + date_tm.tm_sec = 0; + } + + + date_tm.tm_isdst = -1; + return mktime (&date_tm); } /* Called to set the "Date Completed" field. We also need to update the Status and Percent fields to make sure they match. */ static void -set_completed (CalComponent *comp, const char *value) +set_completed (CalendarModel *model, CalComponent *comp, const char *value) { time_t t; t = parse_time (value); if (t == -1) { - show_date_warning (); + show_date_warning (model); } else if (t == 0) { ensure_task_not_complete (comp); } else { @@ -866,14 +962,14 @@ set_completed (CalComponent *comp, const char *value) /* Sets a CalComponentDateTime value */ static void -set_datetime (CalComponent *comp, const char *value, +set_datetime (CalendarModel *model, CalComponent *comp, const char *value, void (* set_func) (CalComponent *comp, CalComponentDateTime *dt)) { time_t t; t = parse_time (value); if (t == -1) { - show_date_warning (); + show_date_warning (model); return; } else if (t == 0) { (* set_func) (comp, NULL); @@ -1073,21 +1169,21 @@ calendar_model_set_value_at (ETableModel *etm, int col, int row, const void *val /* FIXME: CLASSIFICATION requires an option menu cell renderer */ case CAL_COMPONENT_FIELD_COMPLETED: - set_completed (comp, value); + set_completed (model, comp, value); break; case CAL_COMPONENT_FIELD_DTEND: /* FIXME: Need to reset dtstart if dtend happens before it */ - set_datetime (comp, value, cal_component_set_dtend); + set_datetime (model, comp, value, cal_component_set_dtend); break; case CAL_COMPONENT_FIELD_DTSTART: /* FIXME: Need to reset dtend if dtstart happens after it */ - set_datetime (comp, value, cal_component_set_dtstart); + set_datetime (model, comp, value, cal_component_set_dtstart); break; case CAL_COMPONENT_FIELD_DUE: - set_datetime (comp, value, cal_component_set_due); + set_datetime (model, comp, value, cal_component_set_due); break; case CAL_COMPONENT_FIELD_GEO: @@ -1904,3 +2000,26 @@ ensure_task_not_complete (CalComponent *comp) } +/* Whether we use 24 hour format to display the times. */ +gboolean +calendar_model_get_use_24_hour_format (CalendarModel *model) +{ + g_return_val_if_fail (IS_CALENDAR_MODEL (model), TRUE); + + return model->priv->use_24_hour_format; +} + + +void +calendar_model_set_use_24_hour_format (CalendarModel *model, + gboolean use_24_hour_format) +{ + g_return_if_fail (IS_CALENDAR_MODEL (model)); + + if (model->priv->use_24_hour_format != use_24_hour_format) { + model->priv->use_24_hour_format = use_24_hour_format; + /* Get the views to redraw themselves. */ + e_table_model_changed (E_TABLE_MODEL (model)); + } +} + diff --git a/calendar/gui/calendar-model.h b/calendar/gui/calendar-model.h index 3a1685e90c..ed04706090 100644 --- a/calendar/gui/calendar-model.h +++ b/calendar/gui/calendar-model.h @@ -70,6 +70,11 @@ void calendar_model_delete_task (CalendarModel *model, CalComponent* calendar_model_get_cal_object (CalendarModel *model, gint row); +/* Whether we use 24 hour format to display the times. */ +gboolean calendar_model_get_use_24_hour_format (CalendarModel *model); +void calendar_model_set_use_24_hour_format (CalendarModel *model, + gboolean use_24_hour_format); + END_GNOME_DECLS diff --git a/calendar/gui/e-day-view-top-item.c b/calendar/gui/e-day-view-top-item.c index b6b8a565b5..6b00f34a60 100644 --- a/calendar/gui/e-day-view-top-item.c +++ b/calendar/gui/e-day-view-top-item.c @@ -183,7 +183,7 @@ e_day_view_top_item_draw (GnomeCanvasItem *canvas_item, EDayView *day_view; GtkStyle *style; GdkGC *fg_gc, *bg_gc, *light_gc, *dark_gc; - gchar buffer[128]; + gchar buffer[128], *format; GdkRectangle clip_rect; GdkFont *font; gint canvas_width, canvas_height, left_edge, day, date_width, date_x; @@ -256,12 +256,22 @@ e_day_view_top_item_draw (GnomeCanvasItem *canvas_item, day_start = localtime (&day_view->day_starts[day]); if (day_view->date_format == E_DAY_VIEW_DATE_FULL) - strftime (buffer, 128, "%d %B", day_start); + /* strftime format %A = full weekday name, %d = day of month, + %B = full month name. Don't use any other specifiers. */ + format = _("%A %d %B"); else if (day_view->date_format == E_DAY_VIEW_DATE_ABBREVIATED) - strftime (buffer, 128, "%d %b", day_start); + /* strftime format %a = abbreviated weekday name, %d = day of month, + %b = abbreviated month name. Don't use any other specifiers. */ + format = _("%a %d %b"); + else if (day_view->date_format == E_DAY_VIEW_DATE_NO_WEEKDAY) + /* strftime format %d = day of month, %b = abbreviated month name. + Don't use any other specifiers. */ + format = _("%d %b"); else - strftime (buffer, 128, "%d", day_start); + format = "%d"; + strftime (buffer, sizeof (buffer), format, day_start); + clip_rect.x = day_view->day_offsets[day] - x; clip_rect.y = 2 - y; clip_rect.width = day_view->day_widths[day]; diff --git a/calendar/gui/e-day-view.c b/calendar/gui/e-day-view.c index af402722cd..76925be0bd 100644 --- a/calendar/gui/e-day-view.c +++ b/calendar/gui/e-day-view.c @@ -961,10 +961,12 @@ e_day_view_style_set (GtkWidget *widget, EDayView *day_view; GdkFont *font; gint top_rows, top_canvas_height; - gint month, max_month_width, max_abbr_month_width, number_width; - gint hour, max_large_hour_width, month_width; + gint hour, max_large_hour_width; gint minute, max_minute_width, i; - GDate date; + gint month, day, width; + gint longest_month_width, longest_abbreviated_month_width; + gint longest_weekday_width, longest_abbreviated_weekday_width; + struct tm date_tm; gchar buffer[128]; gint times_width; @@ -975,7 +977,7 @@ e_day_view_style_set (GtkWidget *widget, font = widget->style->font; /* Recalculate the height of each row based on the font size. */ - day_view->row_height = font->ascent + font->descent + E_DAY_VIEW_EVENT_BORDER_HEIGHT * 2 + E_DAY_VIEW_EVENT_Y_PAD * 2 + 2 /* FIXME */; + day_view->row_height = font->ascent + font->descent + E_DAY_VIEW_EVENT_BORDER_HEIGHT + E_DAY_VIEW_EVENT_Y_PAD * 2 + 2 /* FIXME */; day_view->row_height = MAX (day_view->row_height, E_DAY_VIEW_ICON_HEIGHT + E_DAY_VIEW_ICON_Y_PAD + 2); GTK_LAYOUT (day_view->main_canvas)->vadjustment->step_increment = day_view->row_height; @@ -988,27 +990,59 @@ e_day_view_style_set (GtkWidget *widget, top_canvas_height = (top_rows + 2) * day_view->top_row_height; gtk_widget_set_usize (day_view->top_canvas, -1, top_canvas_height); - /* Find the biggest full month name. */ - g_date_clear (&date, 1); - g_date_set_dmy (&date, 20, 1, 2000); - max_month_width = 0; - max_abbr_month_width = 0; - for (month = 1; month <= 12; month++) { - g_date_set_month (&date, month); + /* Find the longest full & abbreviated month names. */ + memset (&date_tm, 0, sizeof (date_tm)); + date_tm.tm_year = 100; + date_tm.tm_mday = 1; + date_tm.tm_isdst = -1; + + longest_month_width = 0; + longest_abbreviated_month_width = 0; + for (month = 0; month < 12; month++) { + date_tm.tm_mon = month; + + strftime (buffer, sizeof (buffer), "%B", &date_tm); + width = gdk_string_width (font, buffer); + if (width > longest_month_width) { + longest_month_width = width; + day_view->longest_month_name = month; + } + + strftime (buffer, sizeof (buffer), "%b", &date_tm); + width = gdk_string_width (font, buffer); + if (width > longest_abbreviated_month_width) { + longest_abbreviated_month_width = width; + day_view->longest_abbreviated_month_name = month; + } + } + + /* Find the longest full & abbreviated weekday names. */ + memset (&date_tm, 0, sizeof (date_tm)); + date_tm.tm_year = 100; + date_tm.tm_mon = 0; + date_tm.tm_isdst = -1; + + longest_weekday_width = 0; + longest_abbreviated_weekday_width = 0; + for (day = 0; day < 7; day++) { + date_tm.tm_mday = 2 + day; + date_tm.tm_wday = day; - g_date_strftime (buffer, 128, "%B", &date); - month_width = gdk_string_width (font, buffer); - max_month_width = MAX (max_month_width, month_width); + strftime (buffer, sizeof (buffer), "%A", &date_tm); + width = gdk_string_width (font, buffer); + if (width > longest_weekday_width) { + longest_weekday_width = width; + day_view->longest_weekday_name = day; + } - g_date_strftime (buffer, 128, "%b", &date); - month_width = gdk_string_width (font, buffer); - max_abbr_month_width = MAX (max_abbr_month_width, month_width); + strftime (buffer, sizeof (buffer), "%a", &date_tm); + width = gdk_string_width (font, buffer); + if (width > longest_abbreviated_weekday_width) { + longest_abbreviated_weekday_width = width; + day_view->longest_abbreviated_weekday_name = day; + } } - number_width = gdk_string_width (font, "31 "); - day_view->long_format_width = number_width + max_month_width - + E_DAY_VIEW_DATE_X_PAD; - day_view->abbreviated_format_width = number_width - + max_abbr_month_width + E_DAY_VIEW_DATE_X_PAD; + /* Calculate the widths of all the time strings necessary. */ day_view->max_small_hour_width = 0; @@ -1090,8 +1124,18 @@ e_day_view_size_allocate (GtkWidget *widget, GtkAllocation *allocation) static void e_day_view_recalc_cell_sizes (EDayView *day_view) { + /* An array of dates, one for each month in the year 2000. They must + all be Sundays. */ + static const int days[12] = { 23, 20, 19, 23, 21, 18, + 23, 20, 17, 22, 19, 24 }; gfloat width, offset; - gint day; + gint day, max_width; + struct tm date_tm; + GdkFont *font; + char buffer[128]; + + g_return_if_fail (((GtkWidget*)day_view)->style != NULL); + font = GTK_WIDGET (day_view)->style->font; /* Calculate the column sizes, using floating point so that pixels get divided evenly. Note that we use one more element than the @@ -1109,11 +1153,53 @@ e_day_view_recalc_cell_sizes (EDayView *day_view) day_view->day_widths[day] = day_view->day_offsets[day + 1] - day_view->day_offsets[day]; } - /* Determine which date format to use, based on the column widths. */ - if (day_view->day_widths[0] > day_view->long_format_width) + /* Determine which date format to use, based on the column widths. + We want to check the widths using the longest full or abbreviated + month name and the longest full or abbreviated weekday name, as + appropriate. */ + max_width = day_view->day_widths[0]; + + memset (&date_tm, 0, sizeof (date_tm)); + date_tm.tm_year = 100; + + /* Try "Thursday 21 January". */ + date_tm.tm_mon = day_view->longest_month_name; + date_tm.tm_mday = days[date_tm.tm_mon] + + day_view->longest_weekday_name; + date_tm.tm_wday = day_view->longest_weekday_name; + date_tm.tm_isdst = -1; + /* strftime format %A = full weekday name, %d = day of month, + %B = full month name. Don't use any other specifiers. */ + strftime (buffer, sizeof (buffer), _("%A %d %B"), &date_tm); + if (gdk_string_width (font, buffer) < max_width) { day_view->date_format = E_DAY_VIEW_DATE_FULL; - else if (day_view->day_widths[0] > day_view->abbreviated_format_width) + return; + } + + /* Try "Thu 21 Jan". */ + date_tm.tm_mon = day_view->longest_abbreviated_month_name; + date_tm.tm_mday = days[date_tm.tm_mon] + + day_view->longest_abbreviated_weekday_name; + date_tm.tm_wday = day_view->longest_abbreviated_weekday_name; + date_tm.tm_isdst = -1; + /* strftime format %a = abbreviated weekday name, %d = day of month, + %b = abbreviated month name. Don't use any other specifiers. */ + strftime (buffer, sizeof (buffer), _("%a %d %b"), &date_tm); + if (gdk_string_width (font, buffer) < max_width) { day_view->date_format = E_DAY_VIEW_DATE_ABBREVIATED; + return; + } + + /* Try "23 Jan". */ + date_tm.tm_mon = day_view->longest_abbreviated_month_name; + date_tm.tm_mday = 23; + date_tm.tm_wday = 0; + date_tm.tm_isdst = -1; + /* strftime format %d = day of month, %b = abbreviated month name. + Don't use any other specifiers. */ + strftime (buffer, sizeof (buffer), _("%d %b"), &date_tm); + if (gdk_string_width (font, buffer) < max_width) + day_view->date_format = E_DAY_VIEW_DATE_NO_WEEKDAY; else day_view->date_format = E_DAY_VIEW_DATE_SHORT; } diff --git a/calendar/gui/e-day-view.h b/calendar/gui/e-day-view.h index cfd11b057c..fda44c1289 100644 --- a/calendar/gui/e-day-view.h +++ b/calendar/gui/e-day-view.h @@ -118,13 +118,15 @@ typedef enum } EDayViewBusyType; /* This is used to specify the format used when displaying the dates. - The full format is like 'September 12'. The abbreviated format is like - 'Sep 12'. The short format is like '12'. The actual format used is - determined in style_set(), once we know the font being used. */ + The full format is like 'Thursday 12 September'. The abbreviated format is + like 'Thu 12 Sep'. The no weekday format is like '12 Sep'. The short format + is like '12'. The actual format used is determined in + e_day_view_recalc_cell_sizes(), once we know the font being used. */ typedef enum { E_DAY_VIEW_DATE_FULL, E_DAY_VIEW_DATE_ABBREVIATED, + E_DAY_VIEW_DATE_NO_WEEKDAY, E_DAY_VIEW_DATE_SHORT } EDayViewDateFormat; @@ -301,9 +303,12 @@ struct _EDayView /* This specifies how we are displaying the dates at the top. */ EDayViewDateFormat date_format; - /* These are the maximum widths of the different types of dates. */ - gint long_format_width; - gint abbreviated_format_width; + /* These are the longest month & weekday names in the current font. + Months are 0 to 11. Weekdays are 0 (Sun) to 6 (Sat). */ + gint longest_month_name; + gint longest_abbreviated_month_name; + gint longest_weekday_name; + gint longest_abbreviated_weekday_name; /* The large font use to display the hours. I don't think we need a fontset since we only display numbers. */ diff --git a/calendar/gui/e-week-view-main-item.c b/calendar/gui/e-week-view-main-item.c index d30404305d..10990324ff 100644 --- a/calendar/gui/e-week-view-main-item.c +++ b/calendar/gui/e-week-view-main-item.c @@ -315,22 +315,41 @@ e_week_view_main_item_draw_day (EWeekViewMainItem *wvmitem, max_width = width - 4; format_string = NULL; if (show_day_name) { - if (week_view->max_abbr_day_width + - week_view->digit_width * 2 + week_view->space_width * 2 + if (week_view->max_day_width + week_view->digit_width * 2 + + week_view->space_width * 2 + week_view->month_widths[month - 1] < max_width) - format_string = "%a %d %B"; + /* strftime format %A = full weekday name, %d = day of + month, %B = full month name. You can change the + order but don't change the specifiers or add + anything. */ + format_string = _("%A %d %B"); + else if (week_view->max_abbr_day_width + + week_view->digit_width * 2 + + week_view->space_width * 2 + + week_view->abbr_month_widths[month - 1] < max_width) + /* strftime format %a = abbreviated weekday name, + %d = day of month, %b = abbreviated month name. + You can change the order but don't change the + specifiers or add anything. */ + format_string = _("%a %d %b"); } if (!format_string && show_month_name) { if (week_view->digit_width * 2 + week_view->space_width + week_view->month_widths[month - 1] < max_width) - format_string = "%d %B"; + /* strftime format %d = day of month, %B = full + month name. You can change the order but don't + change the specifiers or add anything. */ + format_string = _("%d %B"); else if (week_view->digit_width * 2 + week_view->space_width + week_view->abbr_month_widths[month - 1] < max_width) - format_string = "%d %b"; + /* strftime format %d = day of month, %b = abbreviated + month name. You can change the order but don't + change the specifiers or add anything. */ + format_string = _("%d %b"); } - g_date_strftime (buffer, 128, format_string ? format_string : "%d", - date); + g_date_strftime (buffer, sizeof (buffer), + format_string ? format_string : "%d", date); date_width = gdk_string_width (font, buffer); date_x = x + width - date_width - E_WEEK_VIEW_DATE_R_PAD; date_x = MAX (date_x, x + 1); |