Default date format to the users locale. Date widgets now accept a

single number as the day, or two numbers as day and month (ordered
according to the users date preference).


git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/trunk@6822 57a11ea4-9604-0410-9ed3-97b8803252fd
This commit is contained in:
David Hampton 2002-04-27 21:43:25 +00:00
parent f9910405c2
commit b820a5006c
8 changed files with 169 additions and 21 deletions

View File

@ -1,3 +1,27 @@
2002-04-27 David Hampton <hampton@employees.org>
* src/app-utils/prefs.scm:
* src/engine/date.c:
* src/gnome/top-level.c (gnc_configure_date_format): Change the
default date format to be the user's LOCALE setting.
* src/engine/date.c (scanDate): Totally work over this routine to
support a user entering one, two, or three numbers. If one, assume
day. If two assume day/month, ordering from locale. Three is
day/month/year, ordering from locale. Also protect against an old
date string being supplied to the routine after the date format
has been changed.
* src/register/register-gnome/datecell-gnome.c
(gnc_date_cell_leave): Reprint the time when leaving a date_cell
field.
* src/gnome-utils/gnc-date-edit.c (date_focus_out_event): New
routine to reprint the time when tabbing out of a date_entry cell.
(create_children): Tie in new routine.
(gnc_date_editable_enters): New helper routine for setting
gnome_dialog_editable_enters on a date_entry widget.
2002-04-23 David Hampton <hampton@employees.org>
* src/app-utils/gnc-component-manager.h: Change

View File

@ -141,7 +141,7 @@
(gnc:register-configuration-option
(gnc:make-multichoice-option
(N_ "International") (N_ "Date Format")
"a" (N_ "Date Format Display") 'us
"a" (N_ "Date Format Display") 'locale
(list (list->vector (list 'us
(N_ "US")
(N_ "US-style: mm/dd/yyyy")))

View File

@ -55,7 +55,8 @@
#endif
/* This is now user configured through the gnome options system() */
static DateFormat dateFormat = DATE_FORMAT_US;
static DateFormat dateFormat = DATE_FORMAT_LOCALE;
static DateFormat prevDateFormat = DATE_FORMAT_LOCALE;
/* This static indicates the debugging module that this .o belongs to. */
static short module = MOD_ENGINE;
@ -176,6 +177,7 @@ void setDateFormat(DateFormat df)
{
if(df >= DATE_FORMAT_FIRST && df <= DATE_FORMAT_LAST)
{
prevDateFormat = dateFormat;
dateFormat = df;
}
else
@ -289,6 +291,12 @@ gnc_print_date (Timespec ts)
* Convert a string into day / month / year integers according to
* the current dateFormat value.
*
* This function will always parse a single number as the day of
* the month, regardless of the ordering of the dateFormat value.
* Two numbers will always be parsed as the day and the month, in
* the same order that they appear in the dateFormat value. Three
* numbers are parsed exactly as specified in the dateFormat field.
*
* Args: buff - pointer to date string
* day - will store day of the month as 1 ... 31
* month - will store month of the year as 1 ... 12
@ -298,15 +306,16 @@ gnc_print_date (Timespec ts)
*
* Globals: global dateFormat value
*/
void
scanDate (const char *buff, int *day, int *month, int *year)
static gboolean
scanDateInternal (const char *buff, int *day, int *month, int *year,
DateFormat which_format)
{
char *dupe, *tmp, *first_field, *second_field, *third_field;
int iday, imonth, iyear;
struct tm *now;
time_t secs;
if (!buff) return;
if (!buff) return(FALSE);
dupe = g_strdup (buff);
@ -334,41 +343,102 @@ scanDate (const char *buff, int *day, int *month, int *year)
iyear = now->tm_year+1900;
/* get numeric values */
switch (dateFormat)
switch (which_format)
{
case DATE_FORMAT_LOCALE:
if (buff[0] != '\0')
{
struct tm thetime;
/* Parse time string. */
memset(&thetime, -1, sizeof(struct tm));
strptime (buff, GNC_D_FMT, &thetime);
iday = thetime.tm_mday;
imonth = thetime.tm_mon + 1;
iyear = thetime.tm_year + 1900;
if (third_field) {
/* Easy. All three values were parsed. */
iyear = thetime.tm_year + 1900;
iday = thetime.tm_mday;
imonth = thetime.tm_mon + 1;
} else if (second_field) {
/* Hard. Two values parsed. Figure out the ordering. */
if (thetime.tm_year == -1) {
/* %m-%d or %d-%m. Don't care. Already parsed correctly. */
iday = thetime.tm_mday;
imonth = thetime.tm_mon + 1;
} else if (thetime.tm_mon != -1) {
/* Must be %Y-%m-%d. Reparse as %m-%d.*/
imonth = atoi(first_field);
iday = atoi(second_field);
} else {
/* Must be %Y-%d-%m. Reparse as %d-%m. */
iday = atoi(first_field);
imonth = atoi(second_field);
}
} else if (first_field) {
iday = atoi(first_field);
}
}
break;
case DATE_FORMAT_UK:
case DATE_FORMAT_CE:
if (first_field) iday = atoi (first_field);
if (second_field) imonth = atoi (second_field);
if (third_field) iyear = atoi (third_field);
if (third_field) {
iday = atoi(first_field);
imonth = atoi(second_field);
iyear = atoi(third_field);
} else if (second_field) {
iday = atoi(first_field);
imonth = atoi(second_field);
} else if (first_field) {
iday = atoi(first_field);
}
break;
case DATE_FORMAT_ISO:
if (first_field) iyear = atoi (first_field);
if (second_field) imonth = atoi (second_field);
if (third_field) iday = atoi (third_field);
if (third_field) {
iyear = atoi(first_field);
imonth = atoi(second_field);
iday = atoi(third_field);
} else if (second_field) {
imonth = atoi(first_field);
iday = atoi(second_field);
} else if (first_field) {
iday = atoi(first_field);
}
break;
case DATE_FORMAT_US:
default:
if (first_field) imonth = atoi (first_field);
if (second_field) iday = atoi (second_field);
if (third_field) iyear = atoi (third_field);
case DATE_FORMAT_US:
default:
if (third_field) {
imonth = atoi(first_field);
iday = atoi(second_field);
iyear = atoi(third_field);
} else if (second_field) {
imonth = atoi(first_field);
iday = atoi(second_field);
} else if (first_field) {
iday = atoi(first_field);
}
break;
}
g_free (dupe);
if (imonth > 12 || iday > 31) {
/*
* Ack! Thppfft! Someone just fed this routine a string in the
* wrong date format. This is known to happen if a register
* window is open when changing the date format. Try the
* previous date format. If that doesn't work, bail and give the
* caller what they asked for (garbage) parsed in the new format.
*
* Note: This test cannot detect any format change that only
* swaps month and day field, if the day is 12 or less. This is
* deemed acceptable given the obscurity of this bug.
*/
if (which_format == prevDateFormat)
return(FALSE);
if (scanDateInternal(buff, day, month, year, prevDateFormat))
return(TRUE);
}
/* if the year entered is smaller than 100, assume we mean the current
century (and are not revising some roman emperor's books) */
if (iyear < 100)
@ -377,6 +447,13 @@ scanDate (const char *buff, int *day, int *month, int *year)
if (year) *year=iyear;
if (month) *month=imonth;
if (day) *day=iday;
return(TRUE);
}
void
scanDate (const char *buff, int *day, int *month, int *year)
{
scanDateInternal(buff, day, month, year, dateFormat);
}
/**

View File

@ -572,6 +572,22 @@ date_accel_key_press(GtkWidget *widget, GdkEventKey *event, gpointer data)
return TRUE;
}
static int
date_focus_out_event(GtkWidget *widget, GdkEventKey *event, gpointer data)
{
GNCDateEdit *gde = data;
struct tm tm;
tm = gnc_date_edit_get_date_internal (gde);
gnc_date_edit_set_time (gde, mktime (&tm));
gtk_calendar_select_month (GTK_CALENDAR (gde->calendar), tm.tm_mon,
1900 + tm.tm_year);
gtk_calendar_select_day (GTK_CALENDAR (gde->calendar), tm.tm_mday);
return TRUE;
}
static void
create_children (GNCDateEdit *gde)
{
@ -585,6 +601,8 @@ create_children (GNCDateEdit *gde)
gtk_widget_show (gde->date_entry);
gtk_signal_connect (GTK_OBJECT (gde->date_entry), "key_press_event",
GTK_SIGNAL_FUNC(date_accel_key_press), gde);
gtk_signal_connect (GTK_OBJECT (gde->date_entry), "focus_out_event",
GTK_SIGNAL_FUNC(date_focus_out_event), gde);
gde->date_button = gtk_button_new ();
gtk_signal_connect (GTK_OBJECT (gde->date_button), "clicked",
@ -930,6 +948,26 @@ gnc_date_edit_get_flags (GNCDateEdit *gde)
return gde->flags;
}
/**
* gnc_date_editable_enters:
* @dialog: The gnome dialog this date editor lives in
* @gde: The date editor to modity
*
* Extracts the editable field from a GNCDateEdit widget, and sets it
* up so that pressing the Enter key in this field as the same as
* clicking the button that has the default.
**/
void
gnc_date_editable_enters (GnomeDialog *dialog, GNCDateEdit *gde)
{
if (!dialog || !gde)
return;
gnome_dialog_editable_enters(GNOME_DIALOG(dialog),
GTK_EDITABLE(gde->date_entry));
}
/*
Local Variables:
c-basic-offset: 8

View File

@ -108,6 +108,9 @@ void gnc_date_edit_set_flags (GNCDateEdit *gde,
GNCDateEditFlags flags);
int gnc_date_edit_get_flags (GNCDateEdit *gde);
void gnc_date_editable_enters (GnomeDialog *dialog,
GNCDateEdit *gde);
END_GNOME_DECLS

View File

@ -485,7 +485,7 @@ gnc_configure_date_format (void)
{
char *format_code = gnc_lookup_multichoice_option("International",
"Date Format",
"us");
"locale");
DateFormat df;

View File

@ -637,6 +637,7 @@ startRecnWindow(GtkWidget *parent, Account *account,
/* need to get a callback on date changes to update the recn balance */
gtk_signal_connect ( GTK_OBJECT (date_value), "date_changed",
GTK_SIGNAL_FUNC (gnc_start_recn_date_changed), (gpointer) &data );
gnc_date_editable_enters(GNOME_DIALOG(dialog), GNC_DATE_EDIT(date_value));
print_info.use_symbol = 0;
gnc_amount_edit_set_print_info (GNC_AMOUNT_EDIT (end_value), print_info);

View File

@ -637,6 +637,7 @@ gnc_date_cell_enter (BasicCell *bcell,
static void
gnc_date_cell_leave (BasicCell *bcell)
{
Timespec ts;
PopBox *box = bcell->gui_private;
date_picker_disconnect_signals ((DateCell *) bcell);
@ -645,6 +646,10 @@ gnc_date_cell_leave (BasicCell *bcell)
NULL, NULL, NULL, NULL, NULL);
box->calendar_popped = FALSE;
/* Refresh the date to expand any shortcuts. */
gnc_date_cell_get_date ((DateCell *)bcell, &ts);
gnc_date_cell_set_value_secs ((DateCell *)bcell, ts.tv_sec);
}
void