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> 2002-04-23 David Hampton <hampton@employees.org>
* src/app-utils/gnc-component-manager.h: Change * src/app-utils/gnc-component-manager.h: Change

View File

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

View File

@ -55,7 +55,8 @@
#endif #endif
/* This is now user configured through the gnome options system() */ /* 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. */ /* This static indicates the debugging module that this .o belongs to. */
static short module = MOD_ENGINE; static short module = MOD_ENGINE;
@ -176,6 +177,7 @@ void setDateFormat(DateFormat df)
{ {
if(df >= DATE_FORMAT_FIRST && df <= DATE_FORMAT_LAST) if(df >= DATE_FORMAT_FIRST && df <= DATE_FORMAT_LAST)
{ {
prevDateFormat = dateFormat;
dateFormat = df; dateFormat = df;
} }
else else
@ -289,6 +291,12 @@ gnc_print_date (Timespec ts)
* Convert a string into day / month / year integers according to * Convert a string into day / month / year integers according to
* the current dateFormat value. * 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 * Args: buff - pointer to date string
* day - will store day of the month as 1 ... 31 * day - will store day of the month as 1 ... 31
* month - will store month of the year as 1 ... 12 * month - will store month of the year as 1 ... 12
@ -298,15 +306,16 @@ gnc_print_date (Timespec ts)
* *
* Globals: global dateFormat value * Globals: global dateFormat value
*/ */
void static gboolean
scanDate (const char *buff, int *day, int *month, int *year) scanDateInternal (const char *buff, int *day, int *month, int *year,
DateFormat which_format)
{ {
char *dupe, *tmp, *first_field, *second_field, *third_field; char *dupe, *tmp, *first_field, *second_field, *third_field;
int iday, imonth, iyear; int iday, imonth, iyear;
struct tm *now; struct tm *now;
time_t secs; time_t secs;
if (!buff) return; if (!buff) return(FALSE);
dupe = g_strdup (buff); dupe = g_strdup (buff);
@ -334,41 +343,102 @@ scanDate (const char *buff, int *day, int *month, int *year)
iyear = now->tm_year+1900; iyear = now->tm_year+1900;
/* get numeric values */ /* get numeric values */
switch (dateFormat) switch (which_format)
{ {
case DATE_FORMAT_LOCALE: case DATE_FORMAT_LOCALE:
if (buff[0] != '\0') if (buff[0] != '\0')
{ {
struct tm thetime; struct tm thetime;
/* Parse time string. */
memset(&thetime, -1, sizeof(struct tm));
strptime (buff, GNC_D_FMT, &thetime); strptime (buff, GNC_D_FMT, &thetime);
iday = thetime.tm_mday; if (third_field) {
imonth = thetime.tm_mon + 1; /* Easy. All three values were parsed. */
iyear = thetime.tm_year + 1900; 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; break;
case DATE_FORMAT_UK: case DATE_FORMAT_UK:
case DATE_FORMAT_CE: case DATE_FORMAT_CE:
if (first_field) iday = atoi (first_field); if (third_field) {
if (second_field) imonth = atoi (second_field); iday = atoi(first_field);
if (third_field) iyear = atoi (third_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; break;
case DATE_FORMAT_ISO: case DATE_FORMAT_ISO:
if (first_field) iyear = atoi (first_field); if (third_field) {
if (second_field) imonth = atoi (second_field); iyear = atoi(first_field);
if (third_field) iday = atoi (third_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; break;
case DATE_FORMAT_US: case DATE_FORMAT_US:
default: default:
if (first_field) imonth = atoi (first_field); if (third_field) {
if (second_field) iday = atoi (second_field); imonth = atoi(first_field);
if (third_field) iyear = atoi (third_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; break;
} }
g_free (dupe); 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 /* if the year entered is smaller than 100, assume we mean the current
century (and are not revising some roman emperor's books) */ century (and are not revising some roman emperor's books) */
if (iyear < 100) if (iyear < 100)
@ -377,6 +447,13 @@ scanDate (const char *buff, int *day, int *month, int *year)
if (year) *year=iyear; if (year) *year=iyear;
if (month) *month=imonth; if (month) *month=imonth;
if (day) *day=iday; 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; 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 static void
create_children (GNCDateEdit *gde) create_children (GNCDateEdit *gde)
{ {
@ -585,6 +601,8 @@ create_children (GNCDateEdit *gde)
gtk_widget_show (gde->date_entry); gtk_widget_show (gde->date_entry);
gtk_signal_connect (GTK_OBJECT (gde->date_entry), "key_press_event", gtk_signal_connect (GTK_OBJECT (gde->date_entry), "key_press_event",
GTK_SIGNAL_FUNC(date_accel_key_press), gde); 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 (); gde->date_button = gtk_button_new ();
gtk_signal_connect (GTK_OBJECT (gde->date_button), "clicked", gtk_signal_connect (GTK_OBJECT (gde->date_button), "clicked",
@ -930,6 +948,26 @@ gnc_date_edit_get_flags (GNCDateEdit *gde)
return gde->flags; 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: Local Variables:
c-basic-offset: 8 c-basic-offset: 8

View File

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

View File

@ -485,7 +485,7 @@ gnc_configure_date_format (void)
{ {
char *format_code = gnc_lookup_multichoice_option("International", char *format_code = gnc_lookup_multichoice_option("International",
"Date Format", "Date Format",
"us"); "locale");
DateFormat df; 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 */ /* need to get a callback on date changes to update the recn balance */
gtk_signal_connect ( GTK_OBJECT (date_value), "date_changed", gtk_signal_connect ( GTK_OBJECT (date_value), "date_changed",
GTK_SIGNAL_FUNC (gnc_start_recn_date_changed), (gpointer) &data ); 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; print_info.use_symbol = 0;
gnc_amount_edit_set_print_info (GNC_AMOUNT_EDIT (end_value), print_info); 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 static void
gnc_date_cell_leave (BasicCell *bcell) gnc_date_cell_leave (BasicCell *bcell)
{ {
Timespec ts;
PopBox *box = bcell->gui_private; PopBox *box = bcell->gui_private;
date_picker_disconnect_signals ((DateCell *) bcell); date_picker_disconnect_signals ((DateCell *) bcell);
@ -645,6 +646,10 @@ gnc_date_cell_leave (BasicCell *bcell)
NULL, NULL, NULL, NULL, NULL); NULL, NULL, NULL, NULL, NULL);
box->calendar_popped = FALSE; 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 void