View | Details | Raw Unified | Return to bug 236463
Collapse All | Expand All

(-)configure.in (+37 lines)
Lines 84-89 Link Here
84
dnl ==============================================
84
dnl ==============================================
85
85
86
dnl ==============================================
86
dnl ==============================================
87
dnl Check strftime for %l and %k support
88
dnl ==============================================
89
90
AC_MSG_CHECKING(for %l and %k support in strftime)
91
AC_TRY_RUN([
92
#include <string.h>
93
#include <time.h>
94
95
int main(int argc, char **argv)
96
{
97
	char buf[10];
98
	time_t rawtime;
99
	struct tm *timeinfo;
100
101
	time(&rawtime);
102
	timeinfo=localtime(&rawtime);
103
	buf[0] = '\0';
104
	strftime(buf, 10, "%lx%k", timeinfo);
105
106
	if (buf[0] == '\0' || buf[0] == 'x' || strstr(buf, "l") || strstr(buf, "k"))
107
		exit(1);
108
	else
109
		exit(0);
110
}],[
111
AC_DEFINE(HAVE_LKSTRFTIME, 1, [strftime supports use of l and k])
112
ac_cv_lkstrftime=yes
113
],ac_cv_lkstrftime=no,ac_cv_lkstrftime=no,[
114
AC_DEFINE(HAVE_LKSTRFTIME, 1, [strftime supports use of l and k])
115
ac_cv_lkstrftime=yes
116
])
117
AC_MSG_RESULT($ac_cv_lkstrftime)
118
119
dnl ==============================================
120
dnl End: strftime
121
dnl ==============================================
122
123
dnl ==============================================
87
dnl Nautilus Extension
124
dnl Nautilus Extension
88
dnl ==============================================
125
dnl ==============================================
89
126
(-)ChangeLog (+10 lines)
Lines 1-3 Link Here
1
2007-01-22  JP Rosevear  <jpr@novell.com>
2
3
	* configure.in: check for format support in strftime
4
5
	* libslab/document-tile.c (document_tile_new): use new
6
	create_subheader_string to show last modified strings in a more
7
	precise manner
8
	(create_subheader_string): create a more precise string for a
9
	relative date, mostly code from evolution
10
1
2007-01-19  Scott Reeves  <sreeves@novell.com>
11
2007-01-19  Scott Reeves  <sreeves@novell.com>
2
	* control-center/src/control-center.c
12
	* control-center/src/control-center.c
3
	* libslab/app-shell.c:
13
	* libslab/app-shell.c:
(-)libslab/document-tile.c (-10 / +219 lines)
Lines 47-52 Link Here
47
static void load_image (DocumentTile *);
47
static void load_image (DocumentTile *);
48
48
49
static GtkWidget *create_header (const gchar *);
49
static GtkWidget *create_header (const gchar *);
50
51
static char      *create_subheader_string (time_t date);
50
static GtkWidget *create_subheader (const gchar *);
52
static GtkWidget *create_subheader (const gchar *);
51
53
52
static void header_size_allocate_cb (GtkWidget *, GtkAllocation *, gpointer);
54
static void header_size_allocate_cb (GtkWidget *, GtkAllocation *, gpointer);
Lines 117-123 Link Here
117
119
118
	gchar *basename;
120
	gchar *basename;
119
121
120
	GDate *time_stamp;
121
	gchar *time_str;
122
	gchar *time_str;
122
123
123
	gchar *markup;
124
	gchar *markup;
Lines 137-152 Link Here
137
138
138
	header = create_header (basename);
139
	header = create_header (basename);
139
140
140
	time_stamp = g_date_new ();
141
	time_str = create_subheader_string (modified);
141
	g_date_set_time (time_stamp, modified);
142
143
	time_str = g_new0 (gchar, 256);
144
145
	g_date_strftime (time_str, 256, _("Edited %m/%d/%Y"), time_stamp);
146
	g_date_free (time_stamp);
147
148
	subheader = create_subheader (time_str);
142
	subheader = create_subheader (time_str);
149
143
	
150
	filename = g_filename_from_uri (uri, NULL, NULL);
144
	filename = g_filename_from_uri (uri, NULL, NULL);
151
145
152
  	if (filename)
146
  	if (filename)
Lines 445-450 Link Here
445
		g_free (icon_id);
439
		g_free (icon_id);
446
}
440
}
447
441
442
/* Next function taken from e-data-server-util.c in evolution-data-server */
443
/** 
444
 * e_strftime:
445
 * @s: The string array to store the result in.
446
 * @max: The size of array @s.
447
 * @fmt: The formatting to use on @tm.
448
 * @tm: The time value to format.
449
 *
450
 * This function is a wrapper around the strftime(3) function, which
451
 * converts the &percnt;l and &percnt;k (12h and 24h) format variables if necessary.
452
 *
453
 * Returns: The number of characters placed in @s.
454
 **/
455
static size_t
456
e_strftime(char *s, size_t max, const char *fmt, const struct tm *tm)
457
{
458
#ifdef HAVE_LKSTRFTIME
459
	return strftime(s, max, fmt, tm);
460
#else
461
	char *c, *ffmt, *ff;
462
	size_t ret;
463
464
	ffmt = g_strdup(fmt);
465
	ff = ffmt;
466
	while ((c = strstr(ff, "%l")) != NULL) {
467
		c[1] = 'I';
468
		ff = c;
469
	}
470
471
	ff = ffmt;
472
	while ((c = strstr(ff, "%k")) != NULL) {
473
		c[1] = 'H';
474
		ff = c;
475
	}
476
477
#ifdef G_OS_WIN32
478
	/* The Microsoft strftime() doesn't have %e either */
479
	ff = ffmt;
480
	while ((c = strstr(ff, "%e")) != NULL) {
481
		c[1] = 'd';
482
		ff = c;
483
	}
484
#endif
485
486
	ret = strftime(s, max, ffmt, tm);
487
	g_free(ffmt);
488
	return ret;
489
#endif
490
}
491
492
/* Next two functions taken from e-util.c in evolution */
493
/**
494
 * Function to do a last minute fixup of the AM/PM stuff if the locale
495
 * and gettext haven't done it right. Most English speaking countries
496
 * except the USA use the 24 hour clock (UK, Australia etc). However
497
 * since they are English nobody bothers to write a language
498
 * translation (gettext) file. So the locale turns off the AM/PM, but
499
 * gettext does not turn on the 24 hour clock. Leaving a mess.
500
 *
501
 * This routine checks if AM/PM are defined in the locale, if not it
502
 * forces the use of the 24 hour clock.
503
 *
504
 * The function itself is a front end on strftime and takes exactly
505
 * the same arguments.
506
 *
507
 * TODO: Actually remove the '%p' from the fixed up string so that
508
 * there isn't a stray space.
509
 **/
510
511
static size_t
512
e_strftime_fix_am_pm(char *s, size_t max, const char *fmt, const struct tm *tm)
513
{
514
	char buf[10];
515
	char *sp;
516
	char *ffmt;
517
	size_t ret;
518
519
	if (strstr(fmt, "%p")==NULL && strstr(fmt, "%P")==NULL) {
520
		/* No AM/PM involved - can use the fmt string directly */
521
		ret=e_strftime(s, max, fmt, tm);
522
	} else {
523
		/* Get the AM/PM symbol from the locale */
524
		e_strftime (buf, 10, "%p", tm);
525
526
		if (buf[0]) {
527
			/**
528
			 * AM/PM have been defined in the locale
529
			 * so we can use the fmt string directly
530
			 **/
531
			ret=e_strftime(s, max, fmt, tm);
532
		} else {
533
			/**
534
			 * No AM/PM defined by locale
535
			 * must change to 24 hour clock
536
			 **/
537
			ffmt=g_strdup(fmt);
538
			for (sp=ffmt; (sp=strstr(sp, "%l")); sp++) {
539
				/**
540
				 * Maybe this should be 'k', but I have never
541
				 * seen a 24 clock actually use that format
542
				 **/
543
				sp[1]='H';
544
			}
545
			for (sp=ffmt; (sp=strstr(sp, "%I")); sp++) {
546
				sp[1]='H';
547
			}
548
			ret=e_strftime(s, max, ffmt, tm);
549
			g_free(ffmt);
550
		}
551
	}
552
553
	return(ret);
554
}
555
556
static size_t 
557
e_utf8_strftime_fix_am_pm(char *s, size_t max, const char *fmt, const struct tm *tm)
558
{
559
	size_t sz, ret;
560
	char *locale_fmt, *buf;
561
562
	locale_fmt = g_locale_from_utf8(fmt, -1, NULL, &sz, NULL);
563
	if (!locale_fmt)
564
		return 0;
565
566
	ret = e_strftime_fix_am_pm(s, max, locale_fmt, tm);
567
	if (!ret) {
568
		g_free (locale_fmt);
569
		return 0;
570
	}
571
572
	buf = g_locale_to_utf8(s, ret, NULL, &sz, NULL);
573
	if (!buf) {
574
		g_free (locale_fmt);
575
		return 0;
576
	}
577
578
	if (sz >= max) {
579
		char *tmp = buf + max - 1;
580
		tmp = g_utf8_find_prev_char(buf, tmp);
581
		if (tmp)
582
			sz = tmp - buf;
583
		else
584
			sz = 0;
585
	}
586
	memcpy(s, buf, sz);
587
	s[sz] = '\0';
588
	g_free(locale_fmt);
589
	g_free(buf);
590
	return sz;
591
}
592
593
static char *
594
create_subheader_string (time_t date)
595
{
596
	time_t nowdate = time(NULL);
597
	time_t yesdate;
598
	struct tm then, now, yesterday;
599
	char buf[100];
600
	gboolean done = FALSE;
601
602
	if (date == 0) {
603
		return g_strdup (_("?"));
604
	}
605
606
	localtime_r (&date, &then);
607
	localtime_r (&nowdate, &now);
608
609
	if (nowdate - date < 60 * 60 * 8 && nowdate > date) {
610
		e_utf8_strftime_fix_am_pm (buf, 100, _("%l:%M %p"), &then);
611
		done = TRUE;
612
	}
613
614
	if (!done) {
615
		if (then.tm_mday == now.tm_mday &&
616
		    then.tm_mon == now.tm_mon &&
617
		    then.tm_year == now.tm_year) {
618
			e_utf8_strftime_fix_am_pm (buf, 100, _("Today %l:%M %p"), &then);
619
			done = TRUE;
620
		}
621
	}
622
	if (!done) {
623
		yesdate = nowdate - 60 * 60 * 24;
624
		localtime_r (&yesdate, &yesterday);
625
		if (then.tm_mday == yesterday.tm_mday &&
626
		    then.tm_mon == yesterday.tm_mon &&
627
		    then.tm_year == yesterday.tm_year) {
628
			e_utf8_strftime_fix_am_pm (buf, 100, _("Yesterday %l:%M %p"), &then);
629
			done = TRUE;
630
		}
631
	}
632
	if (!done) {
633
		int i;
634
		for (i = 2; i < 7; i++) {
635
			yesdate = nowdate - 60 * 60 * 24 * i;
636
			localtime_r (&yesdate, &yesterday);
637
			if (then.tm_mday == yesterday.tm_mday &&
638
			    then.tm_mon == yesterday.tm_mon &&
639
			    then.tm_year == yesterday.tm_year) {
640
				e_utf8_strftime_fix_am_pm (buf, 100, _("%a %l:%M %p"), &then);
641
				done = TRUE;
642
				break;
643
			}
644
		}
645
	}
646
	if (!done) {
647
		if (then.tm_year == now.tm_year) {
648
			e_utf8_strftime_fix_am_pm (buf, 100, _("%b %d %l:%M %p"), &then);
649
		} else {
650
			e_utf8_strftime_fix_am_pm (buf, 100, _("%b %d %Y"), &then);
651
		}
652
	}
653
654
	return g_strdup (g_strstrip (buf));
655
}
656
448
static GtkWidget *
657
static GtkWidget *
449
create_header (const gchar *name)
658
create_header (const gchar *name)
450
{
659
{

Return to bug 236463