Beispiel #1
0
pointer foreign_time(scheme *sc, pointer args)
{
  time_t now;
  struct tm *now_tm;
  pointer ret;

  if (args != sc->NIL)
    return sc->F;

#if 1
  time(&now);
  now_tm = localtime(&now);
#else
GTime time;
GDate date;

  g_date_set_time(&date, &now);
  g_date_to_struct_tm(&now, &now_tm);
#endif

  ret = sc->vptr->cons(sc, sc->vptr->mk_integer(sc,(long) now_tm->tm_year),
         sc->vptr->cons(sc, sc->vptr->mk_integer(sc,(long) now_tm->tm_mon),
          sc->vptr->cons(sc, sc->vptr->mk_integer(sc,(long) now_tm->tm_mday),
           sc->vptr->cons(sc, sc->vptr->mk_integer(sc,(long) now_tm->tm_hour),
            sc->vptr->cons(sc, sc->vptr->mk_integer(sc,(long) now_tm->tm_min),
             sc->vptr->cons(sc, sc->vptr->mk_integer(sc,(long) now_tm->tm_sec),sc->NIL))))));

  return ret;
}
/**
 * Update start date... right now we always base this off the transaction
 * start date, but ideally we want to respect what the user has in the field,
 * somehow.
 **/
static void
sxftd_freq_combo_changed( GtkWidget *w, gpointer user_data )
{
    SXFromTransInfo *sxfti = (SXFromTransInfo*)user_data;
    GDate date, nextDate;
    time_t tmp_tt;
    struct tm *tmpTm;
    GList *schedule = NULL;

    tmp_tt = xaccTransGetDate( sxfti->trans );
    g_date_set_time_t( &date, tmp_tt );

    g_date_clear(&nextDate, 1);
    sxftd_update_schedule(sxfti, &date, &schedule);
    recurrenceListNextInstance(schedule, &date, &nextDate);

    tmpTm = g_new0( struct tm, 1 );
    g_date_to_struct_tm( &nextDate, tmpTm );
    tmp_tt = mktime( tmpTm );
    g_free( tmpTm );
    gnc_date_edit_set_time( sxfti->startDateGDE, tmp_tt );

    recurrenceListFree(&schedule);
    sxftd_update_example_cal( sxfti );
}
Beispiel #3
0
gsize     
g_date_strftime (gchar       *s, 
                 gsize        slen, 
                 const gchar *format, 
                 GDate       *d)
{
  struct tm tm;
  gsize retval;
  
  g_return_val_if_fail (d != NULL, 0);
  g_return_val_if_fail (g_date_valid (d), 0);
  g_return_val_if_fail (slen > 0, 0); 
  g_return_val_if_fail (format != 0, 0);
  g_return_val_if_fail (s != 0, 0);
  
  g_date_to_struct_tm (d, &tm);
  
  retval = strftime (s, slen, format, &tm);
  if (retval == 0)
    {
      /* If retval == 0, the contents of s are undefined.  We define
       *  them. 
       */
      s[0] = '\0';
    }
  return retval;
}
Beispiel #4
0
void
gnc_date_edit_set_gdate (GNCDateEdit *gde, const GDate *date)
{
    struct tm mytm;
    time64 t;

    g_return_if_fail(gde && GNC_IS_DATE_EDIT(gde) &&
                     date && g_date_valid(date));
    g_date_to_struct_tm(date, &mytm);
    t = gnc_mktime(&mytm);
    gnc_date_edit_set_time(gde, t);
}
Beispiel #5
0
time64
gnc_time64_get_day_start_gdate (const GDate *date)
{
    struct tm stm;
    time64 secs;

    /* First convert to a 'struct tm' */
    g_date_to_struct_tm (date, &stm);

    /* Then convert to number of seconds */
    secs = gnc_mktime (&stm);
    return secs;
}
Beispiel #6
0
gboolean
gth_datetime_to_struct_tm (GthDateTime *dt,
		           struct tm   *tm)
{
	if (! gth_datetime_valid (dt))
		return FALSE;

	g_date_to_struct_tm (dt->date, tm);
	tm->tm_hour = dt->time->hour;
	tm->tm_min = dt->time->min;
	tm->tm_sec = dt->time->sec;

	return TRUE;
}
Beispiel #7
0
gchar* property_format_value (Property *property, const gchar *value)
{
    gchar *ret;
    GDate *d;
    struct tm tm;
    GRegex *subject_format;
    gboolean subject_already_formatted;

    ret = NULL;

    switch (property_get_datatype (property)) {
        case PROPERTY_TYPE_STRING:
            ret = g_strdup_printf ("\"%s\"", value);
            break;

        case PROPERTY_TYPE_DATETIME:
            d = g_date_new ();
            g_date_set_parse (d, value);

            if (g_date_valid (d) == TRUE) {
                g_date_to_struct_tm (d, &tm);
                ret = g_strdup_printf ("\"%04d-%02d-%02dT%02d:%02d:%02dZ\"",
                                       tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
                                       tm.tm_hour, tm.tm_min, tm.tm_sec);
            }

            g_date_free (d);
            break;

        case PROPERTY_TYPE_RESOURCE:
	    subject_format = g_regex_new ("<.*>", 0, 0, NULL);
	    subject_already_formatted = g_regex_match(subject_format, value, 0, NULL);
	    if(!subject_already_formatted)
              ret = g_strdup_printf ("<%s>", value);
	    else
	      ret = g_strdup (value);
	    g_regex_unref (subject_format);
	    break;

        case PROPERTY_TYPE_BOOLEAN:
        case PROPERTY_TYPE_INTEGER:
        case PROPERTY_TYPE_DOUBLE:
        default:
            ret = g_strdup (value);
            break;
    }

    return ret;
}
gchar *
gnc_tree_util_split_reg_get_date_help (GDate *date)
{
    char string[1024];

    if (g_date_valid (date))
    {
        struct tm tm;
        memset (&tm, 0, sizeof (tm));
        g_date_to_struct_tm (date, &tm);
        qof_strftime (string, sizeof (string), _("%A %d %B %Y"), &tm);
        return g_strdup (string);
    }
    else
        return g_strdup (" ");
}
Beispiel #9
0
gchar *
get_markup_date (PopplerAnnotMarkup *poppler_annot)
{
    GDate *date;
    struct tm t;
    time_t timet;

    date = poppler_annot_markup_get_date (poppler_annot);
    if (!date)
	    return NULL;

    g_date_to_struct_tm (date, &t);
    g_date_free (date);

    timet = mktime (&t);
    return timet == (time_t) - 1 ? NULL : pgd_format_date (timet);
}
Beispiel #10
0
/**
 * _calculate_wday_yday:
 * @tm: A struct tm that should be updated.
 *
 * Ensure tm_wday and tm_yday are set correctly in a struct tm.
 * The other date (dmy) values must have been set already.
 **/
static void
_calculate_wday_yday (struct tm *tm)
{
	GDate *exif_date;
	struct tm tmp_tm;

	exif_date = g_date_new_dmy (tm->tm_mday,
				    tm->tm_mon+1,
				    tm->tm_year+1900);

	g_return_if_fail (exif_date != NULL && g_date_valid (exif_date));

	// Use this to get GLib <-> libc corrected values
	g_date_to_struct_tm (exif_date, &tmp_tm);
	g_date_free (exif_date);

	tm->tm_wday = tmp_tm.tm_wday;
	tm->tm_yday = tmp_tm.tm_yday;
}
Beispiel #11
0
time64
gnc_time64_get_day_end_gdate (const GDate *date)
{
    struct tm stm;
    time64 secs;

    /* First convert to a 'struct tm' */
    g_date_to_struct_tm(date, &stm);

    /* Force to th last second of the day */
    stm.tm_hour = 23;
    stm.tm_min = 59;
    stm.tm_sec = 59;
    stm.tm_isdst = -1;

    /* Then convert to number of seconds */
    secs = gnc_mktime (&stm);
    return secs;
}
Beispiel #12
0
int
main (int argc, char **argv)
{
    WeatherInfo     info;
    GOptionContext* context;
    GError*         error = NULL;
    gdouble         latitude, longitude;
    WeatherLocation location;
    gchar*          gtime = NULL;
    GDate           gdate;
    struct tm       tm;
    gboolean        bsun, bmoon;
    time_t          phases[4];
    const GOptionEntry entries[] = {
	{ "latitude", 0, 0, G_OPTION_ARG_DOUBLE, &latitude,
	  "observer's latitude in degrees north", NULL },
	{ "longitude", 0, 0,  G_OPTION_ARG_DOUBLE, &longitude,
	  "observer's longitude in degrees east", NULL },
	{ "time", 0, 0, G_OPTION_ARG_STRING, &gtime,
	  "time in seconds from Unix epoch", NULL },
	{ NULL }
    };

    memset(&location, 0, sizeof(WeatherLocation));
    memset(&info, 0, sizeof(WeatherInfo));

    context = g_option_context_new ("- test libmateweather sun/moon calculations");
    g_option_context_add_main_entries (context, entries, NULL);
    g_option_context_parse (context, &argc, &argv, &error);

    if (error) {
	perror (error->message);
	return error->code;
    }
    else if (latitude < -90. || latitude > 90.) {
	perror ("invalid latitude: should be [-90 .. 90]");
	return -1;
    } else if (longitude < -180. || longitude > 180.) {
	perror ("invalid longitude: should be [-180 .. 180]");
	return -1;
    }

    location.latitude = DEGREES_TO_RADIANS(latitude);
    location.longitude = DEGREES_TO_RADIANS(longitude);
    location.latlon_valid = TRUE;
    info.location = &location;
    info.valid = TRUE;

    if (gtime != NULL) {
	//	printf(" gtime=%s\n", gtime);
	g_date_set_parse(&gdate, gtime);
	g_date_to_struct_tm(&gdate, &tm);
	info.update = mktime(&tm);
    } else {
	info.update = time(NULL);
    }

    bsun = calc_sun_time(&info, info.update);
    bmoon = calc_moon(&info);

    printf ("  Latitude %7.3f %c  Longitude %7.3f %c for %s  All times UTC\n",
	    fabs(latitude), (latitude >= 0. ? 'N' : 'S'),
	    fabs(longitude), (longitude >= 0. ? 'E' : 'W'),
	    asctime(gmtime(&info.update)));
    printf("sunrise:   %s",
	   (info.sunriseValid ? ctime(&info.sunrise) : "(invalid)\n"));
    printf("sunset:    %s",
	   (info.sunsetValid ? ctime(&info.sunset)  : "(invalid)\n"));
    if (bmoon) {
	printf("moonphase: %g\n", info.moonphase);
	printf("moonlat:   %g\n", info.moonlatitude);

	if (calc_moon_phases(&info, phases)) {
	    printf("    New:   %s", asctime(gmtime(&phases[0])));
	    printf("    1stQ:  %s", asctime(gmtime(&phases[1])));
	    printf("    Full:  %s", asctime(gmtime(&phases[2])));
	    printf("    3rdQ:  %s", asctime(gmtime(&phases[3])));
	}
    }
    return 0;
}
Beispiel #13
0
gsize     
g_date_strftime (gchar       *s, 
                 gsize        slen, 
                 const gchar *format, 
                 const GDate *d)
{
  struct tm tm;
#ifndef G_OS_WIN32
  gsize locale_format_len = 0;
  gchar *locale_format;
  gsize tmplen;
  gchar *tmpbuf;
  gsize tmpbufsize;
  gsize convlen = 0;
  gchar *convbuf;
  GError *error = NULL;
  gsize retval;
#endif

  g_return_val_if_fail (g_date_valid (d), 0);
  g_return_val_if_fail (slen > 0, 0); 
  g_return_val_if_fail (format != NULL, 0);
  g_return_val_if_fail (s != NULL, 0);

  g_date_to_struct_tm (d, &tm);

#ifdef G_OS_WIN32
  if (!g_utf8_validate (format, -1, NULL))
    {
      s[0] = '\0';
      return 0;
    }
  return win32_strftime_helper (d, format, &tm, s, slen);
#else

  locale_format = g_locale_from_utf8 (format, -1, NULL, &locale_format_len, &error);

  if (error)
    {
      g_warning (G_STRLOC "Error converting format to locale encoding: %s\n", error->message);
      g_error_free (error);

      s[0] = '\0';
      return 0;
    }

  tmpbufsize = MAX (128, locale_format_len * 2);
  while (TRUE)
    {
      tmpbuf = g_malloc (tmpbufsize);

      /* Set the first byte to something other than '\0', to be able to
       * recognize whether strftime actually failed or just returned "".
       */
      tmpbuf[0] = '\1';
      tmplen = strftime (tmpbuf, tmpbufsize, locale_format, &tm);

      if (tmplen == 0 && tmpbuf[0] != '\0')
        {
          g_free (tmpbuf);
          tmpbufsize *= 2;

          if (tmpbufsize > 65536)
            {
              g_warning (G_STRLOC "Maximum buffer size for g_date_strftime exceeded: giving up\n");
              g_free (locale_format);

              s[0] = '\0';
              return 0;
            }
        }
      else
        break;
    }
  g_free (locale_format);

  convbuf = g_locale_to_utf8 (tmpbuf, tmplen, NULL, &convlen, &error);
  g_free (tmpbuf);

  if (error)
    {
      g_warning (G_STRLOC "Error converting results of strftime to UTF-8: %s\n", error->message);
      g_error_free (error);

      s[0] = '\0';
      return 0;
    }

  if (slen <= convlen)
    {
      /* Ensure only whole characters are copied into the buffer.
       */
      gchar *end = g_utf8_find_prev_char (convbuf, convbuf + slen);
      g_assert (end != NULL);
      convlen = end - convbuf;

      /* Return 0 because the buffer isn't large enough.
       */
      retval = 0;
    }
  else
    retval = convlen;

  memcpy (s, convbuf, convlen);
  s[convlen] = '\0';
  g_free (convbuf);

  return retval;
#endif
}
Beispiel #14
0
/*  BBBBB.BBBBBBBB] - Epoch Time -- 2-digit year, followed by 3-digit sequential
                      day of the year, followed by the time represented as the
                      fractional portion of one day, but...

    we now have the converted fields, tle->epoch_year, tle->epoch_day and tle->epoch_fod
                
*/
static gchar   *epoch_to_str(sat_t * sat)
{
    GDate          *epd;
    guint           h, m, s, sec;
    gchar          *buff;
    gchar          *fmt;
    struct tm       tms;
    time_t          t;
    guint           size;

    /* http://celestrak.com/columns/v04n03/#FAQ02
       ... While talking about the epoch, this is perhaps a good place to answer
       the other time-related questions. First, how is the epoch time format
       interpreted? This question is best answered by using an example. An epoch
       of 98001.00000000 corresponds to 0000 UT on 1998 January 01st in other
       words, midnight between 1997 December 31 and 1998 January 01. An epoch of
       98000.00000000 would actually correspond to the beginning of 1997 December
       31st strange as that might seem. Note that the epoch day starts at UT
       midnight (not noon) and that all times are measured mean solar rather than
       sidereal time units (the answer to our third question).
     */
    epd = g_date_new_dmy(1, 1, sat->tle.epoch_year);
    g_date_add_days(epd, sat->tle.epoch_day - 1);

    /* convert date to struct tm */
    g_date_to_struct_tm(epd, &tms);

    /* add HMS */
    sec = (guint) floor(sat->tle.epoch_fod * 86400);    /* fraction of day in seconds */

    /* hour */
    h = (guint) floor(sec / 3600);
    tms.tm_hour = h;

    /* minutes */
    m = (guint) floor((sec - (h * 3600)) / 60);
    tms.tm_min = m;

    s = (guint) floor(sec - (h * 3600) - (m * 60));
    tms.tm_sec = s;

    /* get format string */
    fmt = sat_cfg_get_str(SAT_CFG_STR_TIME_FORMAT);

    /* format either local time or UTC depending on check box */
    t = mktime(&tms);
    buff = g_try_malloc(51);

    if (sat_cfg_get_bool(SAT_CFG_BOOL_USE_LOCAL_TIME))
        size = strftime(buff, 50, fmt, localtime(&t));
    else
        size = strftime(buff, 50, fmt, gmtime(&t));

    if (size < 50)
        buff[size] = '\0';
    else
        buff[50] = '\0';

    g_date_free(epd);
    g_free(fmt);

    return buff;
}
/* utility functions shared between all contact importers */
static void
preview_contact (EWebViewPreview *preview,
                 EContact *contact)
{
	gint idx;
	gboolean had_value = FALSE;

	const gint fields[] = {
		E_CONTACT_FILE_AS,
		E_CONTACT_CATEGORIES,

		E_CONTACT_IS_LIST,
		E_CONTACT_LIST_SHOW_ADDRESSES,
		E_CONTACT_WANTS_HTML,

		E_CONTACT_FULL_NAME,
		E_CONTACT_GIVEN_NAME,
		E_CONTACT_FAMILY_NAME,
		E_CONTACT_NICKNAME,
		E_CONTACT_SPOUSE,
		E_CONTACT_BIRTH_DATE,
		E_CONTACT_ANNIVERSARY,
		E_CONTACT_MAILER,
		E_CONTACT_EMAIL,

		-1,

		E_CONTACT_ORG,
		E_CONTACT_ORG_UNIT,
		E_CONTACT_OFFICE,
		E_CONTACT_TITLE,
		E_CONTACT_ROLE,
		E_CONTACT_MANAGER,
		E_CONTACT_ASSISTANT,

		-1,

		E_CONTACT_PHONE_ASSISTANT,
		E_CONTACT_PHONE_BUSINESS,
		E_CONTACT_PHONE_BUSINESS_2,
		E_CONTACT_PHONE_BUSINESS_FAX,
		E_CONTACT_PHONE_CALLBACK,
		E_CONTACT_PHONE_CAR,
		E_CONTACT_PHONE_COMPANY,
		E_CONTACT_PHONE_HOME,
		E_CONTACT_PHONE_HOME_2,
		E_CONTACT_PHONE_HOME_FAX,
		E_CONTACT_PHONE_ISDN,
		E_CONTACT_PHONE_MOBILE,
		E_CONTACT_PHONE_OTHER,
		E_CONTACT_PHONE_OTHER_FAX,
		E_CONTACT_PHONE_PAGER,
		E_CONTACT_PHONE_PRIMARY,
		E_CONTACT_PHONE_RADIO,
		E_CONTACT_PHONE_TELEX,
		E_CONTACT_PHONE_TTYTDD,

		-1,

		E_CONTACT_ADDRESS_HOME,
		E_CONTACT_ADDRESS_WORK,
		E_CONTACT_ADDRESS_OTHER,

		-1,

		E_CONTACT_HOMEPAGE_URL,
		E_CONTACT_BLOG_URL,
		E_CONTACT_CALENDAR_URI,
		E_CONTACT_FREEBUSY_URL,
		E_CONTACT_ICS_CALENDAR,
		E_CONTACT_VIDEO_URL,

		-1,

		E_CONTACT_IM_AIM,
		E_CONTACT_IM_GROUPWISE,
		E_CONTACT_IM_JABBER,
		E_CONTACT_IM_YAHOO,
		E_CONTACT_IM_MSN,
		E_CONTACT_IM_ICQ,
		E_CONTACT_IM_GADUGADU,
		E_CONTACT_IM_SKYPE,

		-1,

		E_CONTACT_NOTE
	};

	g_return_if_fail (preview != NULL);
	g_return_if_fail (contact != NULL);

	for (idx = 0; idx < G_N_ELEMENTS (fields); idx++) {
		EContactField field;

		if (fields[idx] == -1) {
			if (had_value)
				e_web_view_preview_add_empty_line (preview);
			had_value = FALSE;
			continue;
		}

		field = fields[idx];

		if (field == E_CONTACT_BIRTH_DATE || field == E_CONTACT_ANNIVERSARY) {
			EContactDate *dt = e_contact_get (contact, field);
			if (dt) {
				GDate gd = { 0 };
				struct tm tm;
				gchar *value;

				g_date_set_dmy (&gd, dt->day, dt->month, dt->year);
				g_date_to_struct_tm (&gd, &tm);

				value = e_datetime_format_format_tm (
					"addressbook", "table",
					DTFormatKindDate, &tm);
				if (value) {
					e_web_view_preview_add_section (
						preview,
						e_contact_pretty_name (field),
						value);
					had_value = TRUE;
				}

				g_free (value);
				e_contact_date_free (dt);
			}
		} else if (field == E_CONTACT_IS_LIST ||
			   field == E_CONTACT_WANTS_HTML ||
			   field == E_CONTACT_LIST_SHOW_ADDRESSES) {
			if (e_contact_get (contact, field)) {
				e_web_view_preview_add_text (
					preview, e_contact_pretty_name (field));
				had_value = TRUE;
			}
		} else if (field == E_CONTACT_ADDRESS_HOME ||
			   field == E_CONTACT_ADDRESS_WORK ||
			   field == E_CONTACT_ADDRESS_OTHER) {
			EContactAddress *addr = e_contact_get (contact, field);
			if (addr) {
				gboolean have = FALSE;

				#define add_it(_what)	\
					if (addr->_what && *addr->_what) {	\
						e_web_view_preview_add_section ( \
							preview, have ? NULL : \
							e_contact_pretty_name (field), addr->_what);	\
						have = TRUE;	\
						had_value = TRUE;	\
					}

				add_it (po);
				add_it (ext);
				add_it (street);
				add_it (locality);
				add_it (region);
				add_it (code);
				add_it (country);

				#undef add_it

				e_contact_address_free (addr);
			}
		} else if (field == E_CONTACT_IM_AIM ||
			   field == E_CONTACT_IM_GROUPWISE ||
			   field == E_CONTACT_IM_JABBER ||
			   field == E_CONTACT_IM_YAHOO ||
			   field == E_CONTACT_IM_MSN ||
			   field == E_CONTACT_IM_ICQ ||
			   field == E_CONTACT_IM_GADUGADU ||
			   field == E_CONTACT_IM_SKYPE ||
			   field == E_CONTACT_EMAIL) {
			GList *attrs, *a;
			gboolean have = FALSE;
			const gchar *pretty_name;

			pretty_name = e_contact_pretty_name (field);

			attrs = e_contact_get_attributes (contact, field);
			for (a = attrs; a; a = a->next) {
				EVCardAttribute *attr = a->data;
				GList *value;

				if (!attr)
					continue;

				value = e_vcard_attribute_get_values (attr);

				while (value != NULL) {
					const gchar *str = value->data;

					if (str && *str) {
						e_web_view_preview_add_section (
							preview, have ? NULL :
							pretty_name, str);
						have = TRUE;
						had_value = TRUE;
					}

					value = value->next;
				}

				e_vcard_attribute_free (attr);
			}

			g_list_free (attrs);

		} else if (field == E_CONTACT_CATEGORIES) {
			const gchar *pretty_name;
			const gchar *value;

			pretty_name = e_contact_pretty_name (field);
			value = e_contact_get_const (contact, field);

			if (value != NULL && *value != '\0') {
				e_web_view_preview_add_section (
					preview, pretty_name, value);
				had_value = TRUE;
			}

		} else {
			const gchar *pretty_name;
			const gchar *value;

			pretty_name = e_contact_pretty_name (field);
			value = e_contact_get_const (contact, field);

			if (value != NULL && *value != '\0') {
				e_web_view_preview_add_section (
					preview, pretty_name, value);
				had_value = TRUE;
			}
		}
	}
}
Beispiel #16
0
gboolean
gnc_handle_date_accelerator (GdkEventKey *event,
                             struct tm *tm,
                             const char *date_str)
{
    GDate gdate;

    g_return_val_if_fail (event != NULL, FALSE);
    g_return_val_if_fail (tm != NULL, FALSE);
    g_return_val_if_fail (date_str != NULL, FALSE);

    if (event->type != GDK_KEY_PRESS)
        return FALSE;

    if ((tm->tm_mday <= 0) || (tm->tm_mon == -1) || (tm->tm_year == -1))
        return FALSE;

    // Make sure we have a valid date before we proceed
    if (!g_date_valid_dmy (tm->tm_mday, tm->tm_mon + 1, tm->tm_year + 1900))
        return FALSE;

    g_date_set_dmy (&gdate,
                    tm->tm_mday,
                    tm->tm_mon + 1,
                    tm->tm_year + 1900);

    /*
     * Check those keys where the code does different things depending
     * upon the modifiers.
     */
    switch (event->keyval)
    {
    case GDK_KEY_KP_Add:
    case GDK_KEY_plus:
    case GDK_KEY_equal:
        if (event->state & GDK_SHIFT_MASK)
            g_date_add_days (&gdate, 7);
        else if (event->state & GDK_MOD1_MASK)
            g_date_add_months (&gdate, 1);
        else if (event->state & GDK_CONTROL_MASK)
            g_date_add_years (&gdate, 1);
        else
            g_date_add_days (&gdate, 1);
        g_date_to_struct_tm (&gdate, tm);
        return TRUE;

    case GDK_KEY_minus:
    case GDK_KEY_KP_Subtract:
    case GDK_KEY_underscore:
        if ((strlen (date_str) != 0) && (dateSeparator () == '-'))
        {
            const char *c;
            gunichar uc;
            int count = 0;

            /* rough check for existing date */
            c = date_str;
            while (*c)
            {
                uc = g_utf8_get_char (c);
                if (uc == '-')
                    count++;
                c = g_utf8_next_char (c);
            }

            if (count < 2)
                return FALSE;
        }

        if (event->state & GDK_SHIFT_MASK)
            g_date_subtract_days (&gdate, 7);
        else if (event->state & GDK_MOD1_MASK)
            g_date_subtract_months (&gdate, 1);
        else if (event->state & GDK_CONTROL_MASK)
            g_date_subtract_years (&gdate, 1);
        else
            g_date_subtract_days (&gdate, 1);
        g_date_to_struct_tm (&gdate, tm);
        return TRUE;

    default:
        break;
    }

    /*
     * Control and Alt key combinations should be ignored by this
     * routine so that the menu system gets to handle them.  This
     * prevents weird behavior of the menu accelerators (i.e. work in
     * some widgets but not others.)
     */
    if (event->state & (GDK_CONTROL_MASK | GDK_MOD1_MASK))
        return FALSE;

    /* Now check for the remaining keystrokes. */
    switch (event->keyval)
    {
    case GDK_KEY_braceright:
    case GDK_KEY_bracketright:
        /* increment month */
        g_date_add_months (&gdate, 1);
        break;

    case GDK_KEY_braceleft:
    case GDK_KEY_bracketleft:
        /* decrement month */
        g_date_subtract_months (&gdate, 1);
        break;

    case GDK_KEY_M:
    case GDK_KEY_m:
        /* beginning of month */
        g_date_set_day (&gdate, 1);
        break;

    case GDK_KEY_H:
    case GDK_KEY_h:
        /* end of month */
        g_date_set_day (&gdate, 1);
        g_date_add_months (&gdate, 1);
        g_date_subtract_days (&gdate, 1);
        break;

    case GDK_KEY_Y:
    case GDK_KEY_y:
        /* beginning of year */
        g_date_set_day (&gdate, 1);
        g_date_set_month (&gdate, 1);
        break;

    case GDK_KEY_R:
    case GDK_KEY_r:
        /* end of year */
        g_date_set_day (&gdate, 1);
        g_date_set_month (&gdate, 1);
        g_date_add_years (&gdate, 1);
        g_date_subtract_days (&gdate, 1);
        break;

    case GDK_KEY_T:
    case GDK_KEY_t:
        /* today */
        gnc_gdate_set_today (&gdate);
        break;

    default:
        return FALSE;
    }

    g_date_to_struct_tm (&gdate, tm);

    return TRUE;
}
static gint
sxftd_init( SXFromTransInfo *sxfti )
{
    GtkWidget *w;
    const char *transName;
    gint pos;
    GList *schedule = NULL;
    time_t start_tt;
    struct tm *tmpTm;
    GDate date, nextDate;

    if ( ! sxfti->sx )
    {
        return -1;
    }
    if ( ! sxfti->trans )
    {
        return -2;
    }
    if ( xaccTransIsOpen( sxfti->trans ) )
    {
        return SXFTD_ERRNO_OPEN_XACTION;
    }

    sxfti_attach_callbacks(sxfti);

    /* Setup the example calendar and related data structures. */
    {
        int num_marks = SXFTD_EXCAL_NUM_MONTHS * 31;

        w = GTK_WIDGET(glade_xml_get_widget( sxfti->gxml, SXFTD_EX_CAL_FRAME ));
        sxfti->dense_cal_model = gnc_dense_cal_store_new(num_marks);
        sxfti->example_cal = GNC_DENSE_CAL(gnc_dense_cal_new_with_model(GNC_DENSE_CAL_MODEL(sxfti->dense_cal_model)));
        g_object_ref_sink(sxfti->example_cal);

        g_assert(sxfti->example_cal);
        gnc_dense_cal_set_num_months( sxfti->example_cal, SXFTD_EXCAL_NUM_MONTHS );
        gnc_dense_cal_set_months_per_col( sxfti->example_cal, SXFTD_EXCAL_MONTHS_PER_COL );
        gtk_container_add( GTK_CONTAINER(w), GTK_WIDGET(sxfti->example_cal) );
    }

    /* Setup the start and end dates as GNCDateEdits */
    {
        GtkWidget *paramTable = glade_xml_get_widget( sxfti->gxml,
                                SXFTD_PARAM_TABLE );
        sxfti->startDateGDE =
            GNC_DATE_EDIT( gnc_date_edit_new( time( NULL ),
                                              FALSE, FALSE ) );
        gtk_table_attach( GTK_TABLE(paramTable),
                          GTK_WIDGET( sxfti->startDateGDE ),
                          1, 2, 2, 3,
                          (GTK_EXPAND | GTK_FILL),
                          GTK_FILL,
                          0, 0 );
        g_signal_connect( sxfti->startDateGDE, "date-changed",
                          G_CALLBACK( sxftd_update_excal_adapt ),
                          sxfti );
    }
    {
        GtkWidget *endDateBox = glade_xml_get_widget( sxfti->gxml,
                                SXFTD_END_DATE_BOX );
        sxfti->endDateGDE =
            GNC_DATE_EDIT( gnc_date_edit_new( time( NULL ),
                                              FALSE, FALSE ) );
        gtk_box_pack_start( GTK_BOX( endDateBox ),
                            GTK_WIDGET( sxfti->endDateGDE ),
                            FALSE, TRUE, 0 );
        g_signal_connect( sxfti->endDateGDE, "date-changed",
                          G_CALLBACK( sxftd_update_excal_adapt ),
                          sxfti );
    }

    /* Get the name from the transaction, try that as the initial SX name. */
    transName = xaccTransGetDescription( sxfti->trans );
    xaccSchedXactionSetName( sxfti->sx, transName );

    /* Setup the initial start date for user display/confirmation */
    /* compute good initial date. */
    start_tt = xaccTransGetDate( sxfti->trans );
    g_date_set_time_t( &date, start_tt );
    w = glade_xml_get_widget(sxfti->gxml,
                             SXFTD_FREQ_COMBO_BOX);
    gtk_combo_box_set_active(GTK_COMBO_BOX(w), 0);
    g_signal_connect( w, "changed",
                      G_CALLBACK(sxftd_freq_combo_changed),
                      sxfti );
    sxftd_update_schedule( sxfti, &date, &schedule);
    recurrenceListNextInstance(schedule, &date, &nextDate);
    recurrenceListFree(&schedule);

    tmpTm = g_new0( struct tm, 1 );
    g_date_to_struct_tm( &nextDate, tmpTm );
    start_tt = mktime( tmpTm );
    g_free( tmpTm );
    gnc_date_edit_set_time( sxfti->startDateGDE, start_tt );

    w = glade_xml_get_widget( sxfti->gxml, SXFTD_NAME_ENTRY );
    pos = 0;
    gtk_editable_insert_text( GTK_EDITABLE(w), transName,
                              (strlen(transName) * sizeof(char)), &pos );

    g_signal_connect( GTK_OBJECT(w), "destroy",
                      G_CALLBACK(sxftd_destroy),
                      sxfti );

    sxftd_update_example_cal( sxfti );

    return 0;
}