Bug #205137 - Configurable date formats in components
This commit is contained in:
committed by
Matthew Barnes
parent
cd6f86108b
commit
50302d03b3
@ -26,6 +26,7 @@
|
||||
#include <glib/gi18n.h>
|
||||
#include <table/e-table-scrolled.h>
|
||||
#include <table/e-table-model.h>
|
||||
#include <table/e-cell-date.h>
|
||||
#include <misc/e-gui-utils.h>
|
||||
#include <widgets/menus/gal-view-factory-etable.h>
|
||||
#include <filter/rule-editor.h>
|
||||
@ -267,19 +268,27 @@ static void
|
||||
addressbook_view_create_table_view (EAddressbookView *view)
|
||||
{
|
||||
ETableModel *adapter;
|
||||
ETableExtras *extras;
|
||||
ECell *cell;
|
||||
ETable *table;
|
||||
GtkWidget *widget;
|
||||
gchar *etspecfile;
|
||||
|
||||
adapter = eab_table_adapter_new (view->priv->model);
|
||||
|
||||
extras = e_table_extras_new ();
|
||||
|
||||
/* Set proper format component for a default 'date' cell renderer. */
|
||||
cell = e_table_extras_get_cell (extras, "date");
|
||||
e_cell_date_set_format_component (E_CELL_DATE (cell), "addressbook");
|
||||
|
||||
/* Here we create the table. We give it the three pieces of
|
||||
the table we've created, the header, the model, and the
|
||||
initial layout. It does the rest. */
|
||||
etspecfile = g_build_filename (
|
||||
EVOLUTION_ETSPECDIR, "e-addressbook-view.etspec", NULL);
|
||||
widget = e_table_scrolled_new_from_spec_file (
|
||||
adapter, NULL, etspecfile, NULL);
|
||||
adapter, extras, etspecfile, NULL);
|
||||
table = E_TABLE (E_TABLE_SCROLLED (widget)->table);
|
||||
g_free (etspecfile);
|
||||
|
||||
|
||||
@ -32,6 +32,7 @@
|
||||
#include "cal-prefs-dialog.h"
|
||||
#include <widgets/misc/e-dateedit.h>
|
||||
#include <e-util/e-binding.h>
|
||||
#include <e-util/e-datetime-format.h>
|
||||
#include <e-util/e-dialog-widgets.h>
|
||||
#include <e-util/e-util-private.h>
|
||||
#include <glib/gi18n.h>
|
||||
@ -581,6 +582,7 @@ calendar_prefs_dialog_construct (CalendarPrefsDialog *prefs,
|
||||
gint i;
|
||||
GtkWidget *toplevel;
|
||||
GtkWidget *widget;
|
||||
GtkWidget *table;
|
||||
GSList *l;
|
||||
gchar *gladefile;
|
||||
|
||||
@ -769,6 +771,11 @@ calendar_prefs_dialog_construct (CalendarPrefsDialog *prefs,
|
||||
toplevel = e_config_create_widget ((EConfig *)ec);
|
||||
gtk_container_add (GTK_CONTAINER (prefs), toplevel);
|
||||
|
||||
/* date/time format */
|
||||
table = glade_xml_get_widget (gui, "datetime_format_table");
|
||||
e_datetime_format_add_setup_widget (table, 0, "calendar", "table", DTFormatKindDateTime, _("Time and date:"));
|
||||
e_datetime_format_add_setup_widget (table, 1, "calendar", "table", DTFormatKindDate, _("Date only:"));
|
||||
|
||||
show_config (prefs);
|
||||
/* FIXME: weakref? */
|
||||
setup_changes (prefs);
|
||||
|
||||
@ -1024,6 +1024,85 @@ Days</property>
|
||||
<property name="position">3</property>
|
||||
</packing>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<widget class="GtkLabel" id="label65">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes"><span weight="bold">Date/Time Format</span></property>
|
||||
<property name="use_underline">False</property>
|
||||
<property name="use_markup">True</property>
|
||||
<property name="justify">GTK_JUSTIFY_LEFT</property>
|
||||
<property name="wrap">False</property>
|
||||
<property name="selectable">False</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="yalign">0.5</property>
|
||||
<property name="xpad">0</property>
|
||||
<property name="ypad">0</property>
|
||||
<property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
|
||||
<property name="width_chars">-1</property>
|
||||
<property name="single_line_mode">False</property>
|
||||
<property name="angle">0</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="padding">0</property>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<widget class="GtkHBox" id="hbox27">
|
||||
<property name="visible">True</property>
|
||||
<property name="homogeneous">False</property>
|
||||
<property name="spacing">12</property>
|
||||
|
||||
<child>
|
||||
<widget class="GtkLabel" id="label66">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes"></property>
|
||||
<property name="use_underline">False</property>
|
||||
<property name="use_markup">False</property>
|
||||
<property name="justify">GTK_JUSTIFY_LEFT</property>
|
||||
<property name="wrap">False</property>
|
||||
<property name="selectable">False</property>
|
||||
<property name="xalign">0.5</property>
|
||||
<property name="yalign">0.5</property>
|
||||
<property name="xpad">0</property>
|
||||
<property name="ypad">0</property>
|
||||
<property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
|
||||
<property name="width_chars">-1</property>
|
||||
<property name="single_line_mode">False</property>
|
||||
<property name="angle">0</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="padding">0</property>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<widget class="GtkTable" id="datetime_format_table">
|
||||
<property name="visible">True</property>
|
||||
<property name="n_rows">1</property>
|
||||
<property name="n_columns">3</property>
|
||||
<property name="homogeneous">False</property>
|
||||
<property name="row_spacing">0</property>
|
||||
<property name="column_spacing">0</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="padding">0</property>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="padding">0</property>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="position">1</property>
|
||||
|
||||
@ -41,6 +41,7 @@
|
||||
#include <table/e-cell-toggle.h>
|
||||
#include <table/e-cell-text.h>
|
||||
#include <table/e-cell-combo.h>
|
||||
#include <table/e-cell-date.h>
|
||||
#include <misc/e-popup-menu.h>
|
||||
#include <table/e-cell-date-edit.h>
|
||||
#include <e-util/e-categories-config.h>
|
||||
@ -269,6 +270,11 @@ setup_e_table (ECalListView *cal_list_view)
|
||||
e_table_extras_add_compare (extras, "date-compare",
|
||||
date_compare_cb);
|
||||
|
||||
|
||||
/* set proper format component for a default 'date' cell renderer */
|
||||
cell = e_table_extras_get_cell (extras, "date");
|
||||
e_cell_date_set_format_component (E_CELL_DATE (cell), "calendar");
|
||||
|
||||
/* Create table view */
|
||||
|
||||
etspecfile = g_build_filename (EVOLUTION_ETSPECDIR,
|
||||
|
||||
@ -41,6 +41,7 @@
|
||||
#include <table/e-cell-toggle.h>
|
||||
#include <table/e-cell-text.h>
|
||||
#include <table/e-cell-combo.h>
|
||||
#include <table/e-cell-date.h>
|
||||
#include <e-util/e-dialog-utils.h>
|
||||
#include <e-util/e-util-private.h>
|
||||
#include <table/e-cell-date-edit.h>
|
||||
@ -826,6 +827,10 @@ calendar_table_constructed (GObject *object)
|
||||
e_table_extras_add_pixbuf(extras, "complete", pixbuf);
|
||||
g_object_unref(pixbuf);
|
||||
|
||||
/* set proper format component for a default 'date' cell renderer */
|
||||
cell = e_table_extras_get_cell (extras, "date");
|
||||
e_cell_date_set_format_component (E_CELL_DATE (cell), "calendar");
|
||||
|
||||
/* Create the table */
|
||||
|
||||
etspecfile = g_build_filename (
|
||||
|
||||
@ -33,6 +33,7 @@
|
||||
#include <libedataserver/e-time-utils.h>
|
||||
#include <e-util/e-util.h>
|
||||
#include <e-util/e-error.h>
|
||||
#include <e-util/e-datetime-format.h>
|
||||
#include <e-util/e-dialog-utils.h>
|
||||
#include <e-util/e-icon-factory.h>
|
||||
#include <libecal/e-cal-time-util.h>
|
||||
@ -2044,16 +2045,11 @@ tooltip_grab (GtkWidget *tooltip, GdkEventKey *event, ECalendarView *view)
|
||||
static gchar *
|
||||
get_label (struct icaltimetype *tt, icaltimezone *f_zone, icaltimezone *t_zone)
|
||||
{
|
||||
gchar buffer[1000];
|
||||
struct tm tmp_tm;
|
||||
|
||||
tmp_tm = icaltimetype_to_tm_with_zone (tt, f_zone, t_zone);
|
||||
e_time_format_date_and_time (&tmp_tm,
|
||||
calendar_config_get_24_hour_format (),
|
||||
FALSE, FALSE,
|
||||
buffer, 1000);
|
||||
|
||||
return g_strdup (buffer);
|
||||
return e_datetime_format_format_tm ("calendar", "table", DTFormatKindDateTime, &tmp_tm);
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@ -33,6 +33,7 @@
|
||||
#include <libedataserver/e-time-utils.h>
|
||||
#include <libedataserver/e-data-server-util.h>
|
||||
#include <e-util/e-util.h>
|
||||
#include <e-util/e-datetime-format.h>
|
||||
#include <libecal/e-cal-time-util.h>
|
||||
|
||||
#include "e-cell-date-edit-text.h"
|
||||
@ -117,7 +118,6 @@ cell_date_edit_text_get_text (ECellText *cell,
|
||||
gboolean use_24_hour_format;
|
||||
icaltimezone *timezone;
|
||||
struct tm tmp_tm;
|
||||
gchar buffer[64];
|
||||
|
||||
if (!dv)
|
||||
return g_strdup ("");
|
||||
@ -131,10 +131,9 @@ cell_date_edit_text_get_text (ECellText *cell,
|
||||
it will be set to the current timezone. See set_value(). */
|
||||
tmp_tm = icaltimetype_to_tm_with_zone (&dv->tt, dv->zone, timezone);
|
||||
|
||||
e_time_format_date_and_time (&tmp_tm, use_24_hour_format,
|
||||
!dv->tt.is_date, FALSE,
|
||||
buffer, sizeof (buffer));
|
||||
return g_strdup (buffer);
|
||||
return e_datetime_format_format_tm (
|
||||
"calendar", "table", dv->tt.is_date ?
|
||||
DTFormatKindDate : DTFormatKindDateTime, &tmp_tm);
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
@ -41,6 +41,7 @@
|
||||
#include <table/e-cell-toggle.h>
|
||||
#include <table/e-cell-text.h>
|
||||
#include <table/e-cell-combo.h>
|
||||
#include <table/e-cell-date.h>
|
||||
#include <e-util/e-dialog-utils.h>
|
||||
#include <e-util/e-util-private.h>
|
||||
#include <table/e-cell-date-edit.h>
|
||||
@ -606,6 +607,10 @@ memo_table_constructed (GObject *object)
|
||||
e_table_extras_add_cell (extras, "icon", cell);
|
||||
e_table_extras_add_pixbuf (extras, "icon", icon_pixbufs[0]);
|
||||
|
||||
/* set proper format component for a default 'date' cell renderer */
|
||||
cell = e_table_extras_get_cell (extras, "date");
|
||||
e_cell_date_set_format_component (E_CELL_DATE (cell), "calendar");
|
||||
|
||||
/* Create the table */
|
||||
|
||||
etspecfile = g_build_filename (
|
||||
|
||||
@ -45,6 +45,7 @@ eutilinclude_HEADERS = \
|
||||
e-charset.h \
|
||||
e-config.h \
|
||||
e-cursor.h \
|
||||
e-datetime-format.h \
|
||||
e-dialog-utils.h \
|
||||
e-dialog-widgets.h \
|
||||
e-error.h \
|
||||
@ -88,6 +89,7 @@ libeutil_la_SOURCES = \
|
||||
e-charset.c \
|
||||
e-config.c \
|
||||
e-cursor.c \
|
||||
e-datetime-format.c \
|
||||
e-dialog-utils.c \
|
||||
e-dialog-widgets.c \
|
||||
e-error.c \
|
||||
|
||||
571
e-util/e-datetime-format.c
Normal file
571
e-util/e-datetime-format.c
Normal file
@ -0,0 +1,571 @@
|
||||
/*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with the program; if not, see <http://www.gnu.org/licenses/>
|
||||
*
|
||||
*
|
||||
* Copyright (C) 1999-2009 Novell, Inc. (www.novell.com)
|
||||
*
|
||||
*/
|
||||
|
||||
#include <glib.h>
|
||||
#include <glib/gi18n.h>
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#include "e-datetime-format.h"
|
||||
#include "e-util.h"
|
||||
|
||||
#define KEYS_FILENAME "datetime-formats"
|
||||
#define KEYS_GROUPNAME "formats"
|
||||
|
||||
#ifdef G_OS_WIN32
|
||||
/* The localtime() in Microsoft's C library *is* thread-safe */
|
||||
#define localtime_r(timep, result) (localtime (timep) ? memcpy ((result), localtime (timep), sizeof (*(result))) : 0)
|
||||
#endif
|
||||
|
||||
static GHashTable *key2fmt = NULL;
|
||||
|
||||
static GKeyFile *setup_keyfile = NULL; /* used on the combo */
|
||||
static gint setup_keyfile_instances = 0;
|
||||
|
||||
static void
|
||||
save_keyfile (GKeyFile *keyfile)
|
||||
{
|
||||
gchar *contents;
|
||||
gchar *filename;
|
||||
gsize length;
|
||||
GError *error = NULL;
|
||||
|
||||
g_return_if_fail (keyfile != NULL);
|
||||
|
||||
filename = g_build_filename (e_get_user_data_dir (), KEYS_FILENAME, NULL);
|
||||
contents = g_key_file_to_data (keyfile, &length, NULL);
|
||||
|
||||
g_file_set_contents (filename, contents, length, &error);
|
||||
|
||||
if (error != NULL) {
|
||||
g_warning ("%s", error->message);
|
||||
g_error_free (error);
|
||||
}
|
||||
|
||||
g_free (contents);
|
||||
g_free (filename);
|
||||
}
|
||||
|
||||
static void
|
||||
ensure_loaded (void)
|
||||
{
|
||||
GKeyFile *keyfile;
|
||||
gchar *str, **keys;
|
||||
gint i;
|
||||
|
||||
if (key2fmt)
|
||||
return;
|
||||
|
||||
key2fmt = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
|
||||
keyfile = g_key_file_new ();
|
||||
|
||||
str = g_build_filename (e_get_user_data_dir (), KEYS_FILENAME, NULL);
|
||||
g_key_file_load_from_file (keyfile, str, G_KEY_FILE_NONE, NULL);
|
||||
g_free (str);
|
||||
|
||||
keys = g_key_file_get_keys (keyfile, KEYS_GROUPNAME, NULL, NULL);
|
||||
|
||||
if (keys) {
|
||||
for (i = 0; keys [i]; i++) {
|
||||
str = g_key_file_get_string (keyfile, KEYS_GROUPNAME, keys [i], NULL);
|
||||
if (str)
|
||||
g_hash_table_insert (key2fmt, g_strdup (keys [i]), str);
|
||||
}
|
||||
|
||||
g_strfreev (keys);
|
||||
}
|
||||
|
||||
g_key_file_free (keyfile);
|
||||
}
|
||||
|
||||
static const gchar *
|
||||
get_default_format (DTFormatKind kind, const gchar *key)
|
||||
{
|
||||
const gchar *res = NULL;
|
||||
|
||||
ensure_loaded ();
|
||||
|
||||
switch (kind) {
|
||||
case DTFormatKindDate:
|
||||
res = g_hash_table_lookup (key2fmt, "Default-Date");
|
||||
if (!res)
|
||||
res = "%x";
|
||||
break;
|
||||
case DTFormatKindTime:
|
||||
res = g_hash_table_lookup (key2fmt, "Default-Time");
|
||||
if (!res)
|
||||
res = "%X";
|
||||
break;
|
||||
case DTFormatKindDateTime:
|
||||
res = g_hash_table_lookup (key2fmt, "Default-DateTime");
|
||||
if (!res && key && g_str_has_prefix (key, "mail-table"))
|
||||
res = "%ad %H:%M";
|
||||
if (!res)
|
||||
res = "%x %X"; /* %c is also possible, but it doesn't play well with time zone identifiers */
|
||||
break;
|
||||
case DTFormatKindShortDate:
|
||||
res = g_hash_table_lookup (key2fmt, "Default-ShortDate");
|
||||
if (!res)
|
||||
res = "%A, %B %d";
|
||||
break;
|
||||
}
|
||||
|
||||
if (!res)
|
||||
res = "%x %X";
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static const gchar *
|
||||
get_format_internal (const gchar *key, DTFormatKind kind)
|
||||
{
|
||||
const gchar *res;
|
||||
|
||||
ensure_loaded ();
|
||||
|
||||
g_return_val_if_fail (key != NULL, NULL);
|
||||
g_return_val_if_fail (key2fmt != NULL, NULL);
|
||||
|
||||
res = g_hash_table_lookup (key2fmt, key);
|
||||
if (!res)
|
||||
res = get_default_format (kind, key);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static void
|
||||
set_format_internal (const gchar *key, const gchar *fmt, GKeyFile *keyfile)
|
||||
{
|
||||
ensure_loaded ();
|
||||
|
||||
g_return_if_fail (key != NULL);
|
||||
g_return_if_fail (key2fmt != NULL);
|
||||
g_return_if_fail (keyfile != NULL);
|
||||
|
||||
if (!fmt || !*fmt) {
|
||||
g_hash_table_remove (key2fmt, key);
|
||||
g_key_file_remove_key (keyfile, KEYS_GROUPNAME, key, NULL);
|
||||
} else {
|
||||
g_hash_table_insert (key2fmt, g_strdup (key), g_strdup (fmt));
|
||||
g_key_file_set_string (keyfile, KEYS_GROUPNAME, key, fmt);
|
||||
}
|
||||
}
|
||||
|
||||
static gchar *
|
||||
format_relative_date (time_t tvalue, time_t ttoday, const struct tm *value, const struct tm *today)
|
||||
{
|
||||
gchar *res = g_strdup (get_default_format (DTFormatKindDate, NULL));
|
||||
|
||||
g_return_val_if_fail (value != NULL, res);
|
||||
g_return_val_if_fail (today != NULL, res);
|
||||
|
||||
/* if it's more than a week, use the default date format */
|
||||
if (ttoday - tvalue > 7 * 24 * 60 * 60 ||
|
||||
tvalue - ttoday > 7 * 24 * 60 * 60)
|
||||
return res;
|
||||
|
||||
g_free (res);
|
||||
|
||||
if (value->tm_year == today->tm_year &&
|
||||
value->tm_mon == today->tm_mon &&
|
||||
value->tm_mday == today->tm_mday) {
|
||||
res = g_strdup (_("Today"));
|
||||
} else {
|
||||
gint diff = (gint) (tvalue - ttoday);
|
||||
gint since_midnight = today->tm_sec + (60 * today->tm_min) + (60 * 60 * today->tm_hour);
|
||||
gboolean future = (diff > 0);
|
||||
|
||||
if (!future)
|
||||
diff *= -1;
|
||||
|
||||
diff = (diff - since_midnight) / (24 * 60 * 60);
|
||||
if (diff <= 1) {
|
||||
if (future)
|
||||
res = g_strdup (_("Tomorrow"));
|
||||
else
|
||||
res = g_strdup (_("Yesterday"));
|
||||
} else {
|
||||
if (future)
|
||||
res = g_strdup_printf (_("%d days from now"), diff);
|
||||
else
|
||||
res = g_strdup_printf (_("%d days ago"), diff);
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static gchar *
|
||||
format_internal (const gchar *key, DTFormatKind kind, time_t tvalue, struct tm *tm_value)
|
||||
{
|
||||
const gchar *fmt;
|
||||
gchar buff[129];
|
||||
GString *use_fmt = NULL;
|
||||
gint i, last = 0;
|
||||
struct tm today, value;
|
||||
time_t ttoday;
|
||||
|
||||
tzset();
|
||||
if (!tm_value) {
|
||||
localtime_r (&tvalue, &value);
|
||||
tm_value = &value;
|
||||
} else {
|
||||
/* recalculate tvalue to local (system) timezone */
|
||||
tvalue = mktime (tm_value);
|
||||
localtime_r (&tvalue, &value);
|
||||
}
|
||||
|
||||
fmt = get_format_internal (key, kind);
|
||||
for (i = 0; fmt [i]; i++) {
|
||||
if (fmt [i] == '%') {
|
||||
if (fmt [i + 1] == '%') {
|
||||
i++;
|
||||
} else if (fmt [i + 1] == 'a' && fmt [i + 2] == 'd' && (fmt [i + 3] == 0 || !g_ascii_isalpha (fmt [i + 3]))) {
|
||||
gchar *ad;
|
||||
|
||||
/* "%ad" for abbreviated date */
|
||||
if (!use_fmt) {
|
||||
use_fmt = g_string_new ("");
|
||||
|
||||
ttoday = time (NULL);
|
||||
localtime_r (&ttoday, &today);
|
||||
}
|
||||
|
||||
g_string_append_len (use_fmt, fmt + last, i - last);
|
||||
last = i + 3;
|
||||
i += 2;
|
||||
|
||||
ad = format_relative_date (tvalue, ttoday, &value, &today);
|
||||
if (ad)
|
||||
g_string_append (use_fmt, ad);
|
||||
else if (g_ascii_isspace (fmt [i + 3]))
|
||||
i++;
|
||||
|
||||
g_free (ad);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (use_fmt && last < i) {
|
||||
g_string_append_len (use_fmt, fmt + last, i - last);
|
||||
}
|
||||
|
||||
e_utf8_strftime_fix_am_pm (buff, sizeof (buff) - 1, use_fmt ? use_fmt->str : fmt, tm_value);
|
||||
|
||||
if (use_fmt)
|
||||
g_string_free (use_fmt, TRUE);
|
||||
|
||||
return g_strstrip (g_strdup (buff));
|
||||
}
|
||||
|
||||
static void
|
||||
fill_combo_formats (GtkWidget *combo, const gchar *key, DTFormatKind kind)
|
||||
{
|
||||
const gchar *date_items [] = {
|
||||
N_ ("Use locale default"),
|
||||
"%m/%d/%y", /* American style */
|
||||
"%m/%d/%Y", /* American style, full year */
|
||||
"%d.%m.%y", /* non-American style */
|
||||
"%d.%m.%Y", /* non-American style, full year */
|
||||
"%ad", /* abbreviated date, like "Today" */
|
||||
NULL
|
||||
};
|
||||
|
||||
const gchar *time_items [] = {
|
||||
N_ ("Use locale default"),
|
||||
"%I:%M:%S %p", /* 12hours style */
|
||||
"%I:%M %p", /* 12hours style, without seconds */
|
||||
"%H:%M:%S", /* 24hours style */
|
||||
"%H:%M", /* 24hours style, without seconds */
|
||||
NULL
|
||||
};
|
||||
|
||||
const gchar *datetime_items [] = {
|
||||
N_ ("Use locale default"),
|
||||
"%m/%d/%y %I:%M:%S %p", /* American style */
|
||||
"%m/%d/%Y %I:%M:%S %p", /* American style, full year */
|
||||
"%m/%d/%y %I:%M %p", /* American style, without seconds */
|
||||
"%m/%d/%Y %I:%M %p", /* American style, without seconds, full year */
|
||||
"%ad %I:%M:%S %p", /* %ad is an abbreviated date, like "Today" */
|
||||
"%ad %I:%M %p", /* %ad is an abbreviated date, like "Today", without seconds */
|
||||
"%d.%m.%y %H:%M:%S", /* non-American style */
|
||||
"%d.%m.%Y %H:%M:%S", /* non-American style, full year */
|
||||
"%d.%m.%y %H:%M", /* non-American style, without seconds */
|
||||
"%d.%m.%Y %H:%M", /* non-American style, without seconds, full year */
|
||||
"%ad %H:%M:%S",
|
||||
"%ad %H:%M", /* without seconds */
|
||||
NULL
|
||||
};
|
||||
|
||||
const gchar *shortdate_items [] = {
|
||||
"%A, %B %d",
|
||||
"%A, %d %B",
|
||||
"%a, %b %d",
|
||||
"%a, %d %b",
|
||||
NULL
|
||||
};
|
||||
|
||||
const gchar **items = NULL;
|
||||
int i, idx = 0;
|
||||
const gchar *fmt;
|
||||
|
||||
g_return_if_fail (GTK_IS_COMBO_BOX_ENTRY (combo));
|
||||
|
||||
switch (kind) {
|
||||
case DTFormatKindDate:
|
||||
items = date_items;
|
||||
break;
|
||||
case DTFormatKindTime:
|
||||
items = time_items;
|
||||
break;
|
||||
case DTFormatKindDateTime:
|
||||
items = datetime_items;
|
||||
break;
|
||||
case DTFormatKindShortDate:
|
||||
items = shortdate_items;
|
||||
break;
|
||||
}
|
||||
|
||||
g_return_if_fail (items != NULL);
|
||||
|
||||
fmt = get_format_internal (key, kind);
|
||||
|
||||
for (i = 0; items [i]; i++) {
|
||||
if (i == 0) {
|
||||
gtk_combo_box_append_text ((GtkComboBox *) combo, _(items[i]));
|
||||
} else {
|
||||
gtk_combo_box_append_text ((GtkComboBox *) combo, items[i]);
|
||||
if (!idx && fmt && g_str_equal (fmt, items[i]))
|
||||
idx = i;
|
||||
}
|
||||
}
|
||||
|
||||
if (idx == 0 && fmt && !g_str_equal (fmt, get_default_format (kind, key))) {
|
||||
gtk_combo_box_append_text ((GtkComboBox *) combo, fmt);
|
||||
idx = i;
|
||||
}
|
||||
|
||||
gtk_combo_box_set_active ((GtkComboBox *) combo, idx);
|
||||
}
|
||||
|
||||
static void
|
||||
update_preview_widget (GtkWidget *combo)
|
||||
{
|
||||
GtkWidget *preview;
|
||||
const gchar *key;
|
||||
gchar *value;
|
||||
time_t now;
|
||||
|
||||
g_return_if_fail (combo != NULL);
|
||||
g_return_if_fail (GTK_IS_COMBO_BOX_ENTRY (combo));
|
||||
|
||||
preview = g_object_get_data (G_OBJECT (combo), "preview-label");
|
||||
g_return_if_fail (preview != NULL);
|
||||
g_return_if_fail (GTK_IS_LABEL (preview));
|
||||
|
||||
key = g_object_get_data (G_OBJECT (combo), "format-key");
|
||||
g_return_if_fail (key != NULL);
|
||||
|
||||
time (&now);
|
||||
|
||||
value = format_internal (key, GPOINTER_TO_INT (g_object_get_data (G_OBJECT (combo), "format-kind")), now, NULL);
|
||||
gtk_label_set_text (GTK_LABEL (preview), value ? value : "");
|
||||
g_free (value);
|
||||
}
|
||||
|
||||
static void
|
||||
format_combo_changed_cb (GtkWidget *combo, gpointer user_data)
|
||||
{
|
||||
const gchar *key;
|
||||
DTFormatKind kind;
|
||||
GKeyFile *keyfile;
|
||||
|
||||
g_return_if_fail (combo != NULL);
|
||||
g_return_if_fail (GTK_IS_COMBO_BOX_ENTRY (combo));
|
||||
|
||||
key = g_object_get_data (G_OBJECT (combo), "format-key");
|
||||
g_return_if_fail (key != NULL);
|
||||
|
||||
kind = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (combo), "format-kind"));
|
||||
keyfile = g_object_get_data (G_OBJECT (combo), "setup-key-file");
|
||||
|
||||
if (kind != DTFormatKindShortDate && gtk_combo_box_get_active (GTK_COMBO_BOX (combo)) == 0) {
|
||||
/* use locale default */
|
||||
set_format_internal (key, NULL, keyfile);
|
||||
} else {
|
||||
gchar *text;
|
||||
|
||||
text = gtk_combo_box_get_active_text (GTK_COMBO_BOX (combo));
|
||||
set_format_internal (key, text, keyfile);
|
||||
g_free (text);
|
||||
}
|
||||
|
||||
update_preview_widget (combo);
|
||||
|
||||
/* save on every change only because 'unref_setup_keyfile' is never called :(
|
||||
how about in kill-bonobo? */
|
||||
save_keyfile (keyfile);
|
||||
}
|
||||
|
||||
static gchar *
|
||||
gen_key (const gchar *component, const gchar *part, DTFormatKind kind)
|
||||
{
|
||||
const gchar *kind_str = NULL;
|
||||
|
||||
g_return_val_if_fail (component != NULL, NULL);
|
||||
g_return_val_if_fail (*component != 0, NULL);
|
||||
|
||||
|
||||
switch (kind) {
|
||||
case DTFormatKindDate:
|
||||
kind_str = "Date";
|
||||
break;
|
||||
case DTFormatKindTime:
|
||||
kind_str = "Time";
|
||||
break;
|
||||
case DTFormatKindDateTime:
|
||||
kind_str = "DateTime";
|
||||
break;
|
||||
case DTFormatKindShortDate:
|
||||
kind_str = "ShortDate";
|
||||
break;
|
||||
}
|
||||
|
||||
return g_strconcat (component, (part && *part) ? "-" : "", part && *part ? part : "", "-", kind_str, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
unref_setup_keyfile (gpointer ptr)
|
||||
{
|
||||
g_return_if_fail (ptr == setup_keyfile);
|
||||
g_return_if_fail (setup_keyfile != NULL);
|
||||
g_return_if_fail (setup_keyfile_instances > 0);
|
||||
|
||||
/* this is never called :( */
|
||||
setup_keyfile_instances--;
|
||||
if (setup_keyfile_instances == 0) {
|
||||
save_keyfile (setup_keyfile);
|
||||
g_key_file_free (setup_keyfile);
|
||||
setup_keyfile = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* e_datetime_format_add_setup_widget:
|
||||
* @table: Where to attach widgets. Requires 3 columns.
|
||||
* @row: On which row to attach.
|
||||
* @component: Component identifier for the format. Cannot be empty nor NULL.
|
||||
* @part: Part in the component, can be NULL or empty string.
|
||||
* @kind: Kind of the format for the component/part.
|
||||
* @caption: Caption for the widget, can be NULL, then the "Format:" is used.
|
||||
*
|
||||
* Adds a setup widget for a component and part. The table should have 3 columns.
|
||||
* All the work related to loading and saving the value is done automatically,
|
||||
* on user's changes.
|
||||
**/
|
||||
void
|
||||
e_datetime_format_add_setup_widget (GtkWidget *table, gint row, const gchar *component, const gchar *part, DTFormatKind kind, const gchar *caption)
|
||||
{
|
||||
GtkWidget *label, *combo, *preview, *align;
|
||||
gchar *key;
|
||||
|
||||
g_return_if_fail (table != NULL);
|
||||
g_return_if_fail (row >= 0);
|
||||
g_return_if_fail (component != NULL);
|
||||
g_return_if_fail (*component != 0);
|
||||
|
||||
key = gen_key (component, part, kind);
|
||||
|
||||
label = gtk_label_new_with_mnemonic (caption ? caption : _("Format:"));
|
||||
combo = gtk_combo_box_entry_new_text ();
|
||||
|
||||
fill_combo_formats (combo, key, kind);
|
||||
gtk_label_set_mnemonic_widget ((GtkLabel *)label, combo);
|
||||
|
||||
align = gtk_alignment_new (0.0, 0.5, 0.0, 0.0);
|
||||
gtk_container_add (GTK_CONTAINER (align), combo);
|
||||
|
||||
gtk_table_attach ((GtkTable *) table, label, 0, 1, row, row + 1, 0, 0, 2, 0);
|
||||
gtk_table_attach ((GtkTable *) table, align, 1, 2, row, row + 1, 0, 0, 2, 0);
|
||||
|
||||
preview = gtk_label_new ("");
|
||||
gtk_misc_set_alignment (GTK_MISC (preview), 0.0, 0.5);
|
||||
gtk_label_set_ellipsize (GTK_LABEL (preview), PANGO_ELLIPSIZE_END);
|
||||
gtk_table_attach ((GtkTable *) table, preview, 2, 3, row, row + 1, GTK_EXPAND | GTK_FILL, 0, 2, 0);
|
||||
|
||||
if (!setup_keyfile) {
|
||||
gchar *filename;
|
||||
|
||||
filename = g_build_filename (e_get_user_data_dir (), KEYS_FILENAME, NULL);
|
||||
setup_keyfile = g_key_file_new ();
|
||||
g_key_file_load_from_file (setup_keyfile, filename, G_KEY_FILE_NONE, NULL);
|
||||
g_free (filename);
|
||||
|
||||
setup_keyfile_instances = 1;
|
||||
} else {
|
||||
setup_keyfile_instances++;
|
||||
}
|
||||
|
||||
g_object_set_data (G_OBJECT (combo), "preview-label", preview);
|
||||
g_object_set_data (G_OBJECT (combo), "format-kind", GINT_TO_POINTER (kind));
|
||||
g_object_set_data_full (G_OBJECT (combo), "format-key", key, g_free);
|
||||
g_object_set_data_full (G_OBJECT (combo), "setup-key-file", setup_keyfile, unref_setup_keyfile);
|
||||
g_signal_connect (combo, "changed", G_CALLBACK (format_combo_changed_cb), NULL);
|
||||
|
||||
update_preview_widget (combo);
|
||||
|
||||
gtk_widget_show_all (table);
|
||||
}
|
||||
|
||||
gchar *
|
||||
e_datetime_format_format (const gchar *component, const gchar *part, DTFormatKind kind, time_t value)
|
||||
{
|
||||
gchar *key, *res;
|
||||
|
||||
g_return_val_if_fail (component != NULL, NULL);
|
||||
g_return_val_if_fail (*component != 0, NULL);
|
||||
|
||||
key = gen_key (component, part, kind);
|
||||
g_return_val_if_fail (key != NULL, NULL);
|
||||
|
||||
res = format_internal (key, kind, value, NULL);
|
||||
|
||||
g_free (key);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
gchar *
|
||||
e_datetime_format_format_tm (const gchar *component, const gchar *part, DTFormatKind kind, struct tm *tm_time)
|
||||
{
|
||||
gchar *key, *res;
|
||||
|
||||
g_return_val_if_fail (component != NULL, NULL);
|
||||
g_return_val_if_fail (*component != 0, NULL);
|
||||
g_return_val_if_fail (tm_time != NULL, NULL);
|
||||
|
||||
key = gen_key (component, part, kind);
|
||||
g_return_val_if_fail (key != NULL, NULL);
|
||||
|
||||
res = format_internal (key, kind, 0, tm_time);
|
||||
|
||||
g_free (key);
|
||||
|
||||
return res;
|
||||
}
|
||||
46
e-util/e-datetime-format.h
Normal file
46
e-util/e-datetime-format.h
Normal file
@ -0,0 +1,46 @@
|
||||
/*
|
||||
*
|
||||
* Customizable date/time formatting in Evolution
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with the program; if not, see <http://www.gnu.org/licenses/>
|
||||
*
|
||||
*
|
||||
* Copyright (C) 1999-2009 Novell, Inc. (www.novell.com)
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __E_DATETIME_FORMAT__
|
||||
#define __E_DATETIME_FORMAT__
|
||||
|
||||
#include <time.h>
|
||||
#include <glib.h>
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
typedef enum _DTFormatKind {
|
||||
DTFormatKindDate,
|
||||
DTFormatKindTime,
|
||||
DTFormatKindDateTime,
|
||||
DTFormatKindShortDate
|
||||
} DTFormatKind;
|
||||
|
||||
void e_datetime_format_add_setup_widget (GtkWidget *table, gint row, const gchar *component, const gchar *part, DTFormatKind kind, const gchar *caption);
|
||||
|
||||
gchar *e_datetime_format_format (const gchar *component, const gchar *part, DTFormatKind kind, time_t value);
|
||||
gchar *e_datetime_format_format_tm (const gchar *component, const gchar *part, DTFormatKind kind, struct tm *tm_time);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif
|
||||
@ -63,6 +63,7 @@
|
||||
#include <e-util/e-util-private.h>
|
||||
|
||||
#include <libedataserver/e-msgport.h>
|
||||
#include "e-util/e-datetime-format.h"
|
||||
#include <e-util/e-dialog-utils.h>
|
||||
#include <e-util/e-icon-factory.h>
|
||||
|
||||
@ -81,16 +82,6 @@
|
||||
#include "widgets/misc/e-attachment-button.h"
|
||||
#include "widgets/misc/e-attachment-view.h"
|
||||
|
||||
#ifdef G_OS_WIN32
|
||||
/* Undefine the similar macro from <pthread.h>,it doesn't check if
|
||||
* localtime() returns NULL.
|
||||
*/
|
||||
#undef localtime_r
|
||||
|
||||
/* The localtime() in Microsoft's C library is MT-safe */
|
||||
#define localtime_r(tp,tmp) (localtime(tp)?(*(tmp)=*localtime(tp),(tmp)):0)
|
||||
#endif
|
||||
|
||||
#define d(x)
|
||||
|
||||
#define EM_FORMAT_HTML_DISPLAY_GET_PRIVATE(obj) \
|
||||
@ -768,9 +759,7 @@ efhd_message_prefix(EMFormat *emf, CamelStream *stream, CamelMimePart *part, EMF
|
||||
{
|
||||
const gchar *flag, *comp, *due;
|
||||
time_t date;
|
||||
gchar due_date[128];
|
||||
struct tm due_tm;
|
||||
gchar *iconpath;
|
||||
gchar *iconpath, *due_date_str;
|
||||
|
||||
if (emf->folder == NULL || emf->uid == NULL
|
||||
|| (flag = camel_folder_get_message_user_tag(emf->folder, emf->uid, "follow-up")) == NULL
|
||||
@ -801,10 +790,10 @@ efhd_message_prefix(EMFormat *emf, CamelStream *stream, CamelMimePart *part, EMF
|
||||
camel_stream_printf(stream, "<td align=\"left\" width=\"100%%\">");
|
||||
|
||||
if (comp && comp[0]) {
|
||||
date = camel_header_decode_date(comp, NULL);
|
||||
localtime_r(&date, &due_tm);
|
||||
e_utf8_strftime_fix_am_pm(due_date, sizeof (due_date), _("Completed on %B %d, %Y, %l:%M %p"), &due_tm);
|
||||
camel_stream_printf(stream, "%s, %s", flag, due_date);
|
||||
date = camel_header_decode_date (comp, NULL);
|
||||
due_date_str = e_datetime_format_format ("mail", "header", DTFormatKindDateTime, date);
|
||||
camel_stream_printf (stream, "%s, %s %s", flag, _("Completed on"), due_date_str ? due_date_str : "???");
|
||||
g_free (due_date_str);
|
||||
} else if ((due = camel_folder_get_message_user_tag(emf->folder, emf->uid, "due-by")) != NULL && due[0]) {
|
||||
time_t now;
|
||||
|
||||
@ -813,9 +802,9 @@ efhd_message_prefix(EMFormat *emf, CamelStream *stream, CamelMimePart *part, EMF
|
||||
if (now > date)
|
||||
camel_stream_printf(stream, "<b>%s</b> ", _("Overdue:"));
|
||||
|
||||
localtime_r(&date, &due_tm);
|
||||
e_utf8_strftime_fix_am_pm(due_date, sizeof (due_date), _("by %B %d, %Y, %l:%M %p"), &due_tm);
|
||||
camel_stream_printf(stream, "%s %s", flag, due_date);
|
||||
due_date_str = e_datetime_format_format ("mail", "header", DTFormatKindDateTime, date);
|
||||
/* To Translators: the "by" is part of the string, like "Follow-up by Tuesday, January 13, 2009" */
|
||||
camel_stream_printf (stream, "%s %s %s", flag, _("by"), due_date_str ? due_date_str : "???");
|
||||
} else {
|
||||
camel_stream_printf(stream, "%s", flag);
|
||||
}
|
||||
|
||||
@ -43,6 +43,7 @@
|
||||
|
||||
#include <libedataserver/e-data-server-util.h> /* for e_utf8_strftime, what about e_time_format_time? */
|
||||
#include <libedataserver/e-time-utils.h>
|
||||
#include "e-util/e-datetime-format.h"
|
||||
#include "e-util/e-icon-factory.h"
|
||||
#include "e-util/e-util-private.h"
|
||||
#include "e-util/e-util.h"
|
||||
@ -2321,14 +2322,16 @@ efh_format_header(EMFormat *emf, CamelStream *stream, CamelMedium *part, struct
|
||||
gint msg_offset, local_tz;
|
||||
time_t msg_date;
|
||||
struct tm local;
|
||||
gchar *date_str;
|
||||
|
||||
txt = header->value;
|
||||
while (*txt == ' ' || *txt == '\t')
|
||||
txt++;
|
||||
|
||||
/* Show the local timezone equivalent in brackets if the sender is remote */
|
||||
msg_date = camel_header_decode_date(txt, &msg_offset);
|
||||
e_localtime_with_offset(msg_date, &local, &local_tz);
|
||||
e_localtime_with_offset (msg_date, &local, &local_tz);
|
||||
|
||||
date_str = e_datetime_format_format ("mail", "header", DTFormatKindDateTime, msg_date);
|
||||
|
||||
/* Convert message offset to minutes (e.g. -0400 --> -240) */
|
||||
msg_offset = ((msg_offset / 100) * 60) + (msg_offset % 100);
|
||||
@ -2336,25 +2339,18 @@ efh_format_header(EMFormat *emf, CamelStream *stream, CamelMedium *part, struct
|
||||
msg_offset -= local_tz / 60;
|
||||
|
||||
if (msg_offset) {
|
||||
gchar buf[256], *html;
|
||||
gchar *html;
|
||||
|
||||
msg_offset += (local.tm_hour * 60) + local.tm_min;
|
||||
if (msg_offset >= (24 * 60) || msg_offset < 0) {
|
||||
/* translators: strftime format for local time equivalent in Date header display, with day */
|
||||
gchar *msg = g_strdup_printf("<I>%s</I>", _(" (%a, %R %Z)"));
|
||||
e_utf8_strftime(buf, sizeof(buf), msg, &local);
|
||||
g_free(msg);
|
||||
} else {
|
||||
/* translators: strftime format for local time equivalent in Date header display, without day */
|
||||
gchar *msg = g_strdup_printf("<I>%s</I>", _(" (%R %Z)"));
|
||||
e_utf8_strftime(buf, sizeof(buf), msg, &local);
|
||||
g_free(msg);
|
||||
}
|
||||
html = camel_text_to_html (txt, efh->text_html_flags, 0);
|
||||
txt = value = g_strdup_printf ("%s (<I>%s</I>)", date_str, html);
|
||||
|
||||
g_free (html);
|
||||
g_free (date_str);
|
||||
|
||||
html = camel_text_to_html(txt, efh->text_html_flags, 0);
|
||||
txt = value = g_strdup_printf("%s %s", html, buf);
|
||||
g_free(html);
|
||||
flags |= EM_FORMAT_HTML_HEADER_HTML;
|
||||
} else {
|
||||
/* date_str will be freed at the end */
|
||||
txt = value = date_str;
|
||||
}
|
||||
|
||||
flags |= EM_FORMAT_HEADER_BOLD;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -1811,7 +1811,8 @@ static ECell * create_composite_cell (gint col)
|
||||
images [i] = states_pixmaps [i + 6].pixbuf;
|
||||
cell_attach = e_cell_toggle_new (0, 2, images);
|
||||
|
||||
cell_date = e_cell_date_new(NULL, GTK_JUSTIFY_RIGHT);
|
||||
cell_date = e_cell_date_new (NULL, GTK_JUSTIFY_RIGHT);
|
||||
e_cell_date_set_format_component (E_CELL_DATE (cell_date), "mail");
|
||||
g_object_set (G_OBJECT (cell_date),
|
||||
"bold_column", COL_UNREAD,
|
||||
"color_column", COL_COLOUR,
|
||||
@ -1894,6 +1895,7 @@ message_list_create_extras (void)
|
||||
|
||||
/* date cell */
|
||||
cell = e_cell_date_new (NULL, GTK_JUSTIFY_LEFT);
|
||||
e_cell_date_set_format_component (E_CELL_DATE (cell), "mail");
|
||||
g_object_set (G_OBJECT (cell),
|
||||
"bold_column", COL_UNREAD,
|
||||
"color_column", COL_COLOUR,
|
||||
@ -1927,6 +1929,10 @@ message_list_create_extras (void)
|
||||
cell = create_composite_cell (COL_TO);
|
||||
e_table_extras_add_cell (extras, "render_composite_to", cell);
|
||||
|
||||
/* set proper format component for a default 'date' cell renderer */
|
||||
cell = e_table_extras_get_cell (extras, "date");
|
||||
e_cell_date_set_format_component (E_CELL_DATE (cell), "mail");
|
||||
|
||||
return extras;
|
||||
}
|
||||
|
||||
|
||||
@ -30,6 +30,7 @@
|
||||
#include <libedataserverui/e-source-selector.h>
|
||||
#include <libedataserverui/e-name-selector-entry.h>
|
||||
|
||||
#include "e-util/e-datetime-format.h"
|
||||
#include "widgets/misc/e-preferences-window.h"
|
||||
|
||||
static void
|
||||
@ -129,9 +130,9 @@ autocompletion_config_init (EShell *shell)
|
||||
|
||||
e_preferences_window_add_page (
|
||||
E_PREFERENCES_WINDOW (preferences_window),
|
||||
"autocompletion",
|
||||
"contacts",
|
||||
"preferences-autocompletion",
|
||||
_("Autocompletion"),
|
||||
_("Contacts"),
|
||||
scrolled_window,
|
||||
200);
|
||||
}
|
||||
|
||||
@ -41,6 +41,7 @@
|
||||
#include "libedataserverui/e-cell-renderer-color.h"
|
||||
|
||||
#include "e-util/e-binding.h"
|
||||
#include "e-util/e-datetime-format.h"
|
||||
#include "e-util/e-util-private.h"
|
||||
#include "widgets/misc/e-charset-combo-box.h"
|
||||
|
||||
@ -811,6 +812,7 @@ em_mailer_prefs_construct (EMMailerPrefs *prefs,
|
||||
GHashTable *default_header_hash;
|
||||
GtkWidget *toplevel;
|
||||
GtkWidget *container;
|
||||
GtkWidget *table;
|
||||
GtkWidget *widget;
|
||||
GtkTreeSelection *selection;
|
||||
GtkCellRenderer *renderer;
|
||||
@ -1133,6 +1135,11 @@ em_mailer_prefs_construct (EMMailerPrefs *prefs,
|
||||
|
||||
g_slist_free (header_add_list);
|
||||
|
||||
/* date/time format */
|
||||
table = glade_xml_get_widget (gui, "datetime_format_table");
|
||||
e_datetime_format_add_setup_widget (table, 0, "mail", "header", DTFormatKindDateTime, _("Date header:"));
|
||||
e_datetime_format_add_setup_widget (table, 1, "mail", "table", DTFormatKindDateTime, _("Table column:"));
|
||||
|
||||
/* Junk prefs */
|
||||
widget = glade_xml_get_widget (gui, "chkCheckIncomingMail");
|
||||
e_mutual_binding_new (
|
||||
|
||||
@ -147,6 +147,7 @@ data/evolution.desktop.in.in
|
||||
data/evolution.keys.in.in
|
||||
e-util/e-categories-config.c
|
||||
e-util/e-charset.c
|
||||
e-util/e-datetime-format.c
|
||||
e-util/e-dialog-utils.c
|
||||
e-util/e-error.c
|
||||
e-util/e-logger.c
|
||||
|
||||
@ -30,84 +30,28 @@
|
||||
#include <glib/gi18n.h>
|
||||
#include "e-util/e-util.h"
|
||||
#include "e-util/e-unicode.h"
|
||||
#include "e-util/e-datetime-format.h"
|
||||
|
||||
#include "e-cell-date.h"
|
||||
|
||||
G_DEFINE_TYPE (ECellDate, e_cell_date, E_CELL_TEXT_TYPE)
|
||||
|
||||
#ifdef G_OS_WIN32
|
||||
/* The localtime() in Microsoft's C library *is* thread-safe */
|
||||
#define localtime_r(timep, result) (localtime (timep) ? memcpy ((result), localtime (timep), sizeof (*(result))) : 0)
|
||||
#endif
|
||||
|
||||
static gchar *
|
||||
ecd_get_text(ECellText *cell, ETableModel *model, gint col, gint row)
|
||||
{
|
||||
time_t date = GPOINTER_TO_INT (e_table_model_value_at(model, col, row));
|
||||
time_t nowdate = time(NULL);
|
||||
time_t yesdate;
|
||||
struct tm then, now, yesterday;
|
||||
gchar buf[100];
|
||||
gchar *temp;
|
||||
gboolean done = FALSE;
|
||||
const gchar *fmt_component, *fmt_part = NULL;
|
||||
|
||||
if (date == 0) {
|
||||
return g_strdup (_("?"));
|
||||
}
|
||||
|
||||
tzset ();
|
||||
localtime_r (&date, &then);
|
||||
localtime_r (&nowdate, &now);
|
||||
|
||||
if (nowdate - date < 60 * 60 * 8 && nowdate > date) {
|
||||
e_utf8_strftime_fix_am_pm (buf, 100, _("%l:%M %p"), &then);
|
||||
done = TRUE;
|
||||
}
|
||||
|
||||
if (!done) {
|
||||
if (then.tm_mday == now.tm_mday &&
|
||||
then.tm_mon == now.tm_mon &&
|
||||
then.tm_year == now.tm_year) {
|
||||
e_utf8_strftime_fix_am_pm (buf, 100, _("Today %l:%M %p"), &then);
|
||||
done = TRUE;
|
||||
}
|
||||
}
|
||||
if (!done) {
|
||||
yesdate = nowdate - 60 * 60 * 24;
|
||||
localtime_r (&yesdate, &yesterday);
|
||||
if (then.tm_mday == yesterday.tm_mday &&
|
||||
then.tm_mon == yesterday.tm_mon &&
|
||||
then.tm_year == yesterday.tm_year) {
|
||||
e_utf8_strftime_fix_am_pm (buf, 100, _("Yesterday %l:%M %p"), &then);
|
||||
done = TRUE;
|
||||
}
|
||||
}
|
||||
if (!done) {
|
||||
gint i;
|
||||
for (i = 2; i < 7; i++) {
|
||||
yesdate = nowdate - 60 * 60 * 24 * i;
|
||||
localtime_r (&yesdate, &yesterday);
|
||||
if (then.tm_mday == yesterday.tm_mday &&
|
||||
then.tm_mon == yesterday.tm_mon &&
|
||||
then.tm_year == yesterday.tm_year) {
|
||||
e_utf8_strftime_fix_am_pm (buf, 100, _("%a %l:%M %p"), &then);
|
||||
done = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!done) {
|
||||
if (then.tm_year == now.tm_year) {
|
||||
e_utf8_strftime_fix_am_pm (buf, 100, _("%b %d %l:%M %p"), &then);
|
||||
} else {
|
||||
e_utf8_strftime_fix_am_pm (buf, 100, _("%b %d %Y"), &then);
|
||||
}
|
||||
}
|
||||
temp = buf;
|
||||
while ((temp = strstr (temp, " "))) {
|
||||
memmove (temp, temp + 1, strlen (temp));
|
||||
}
|
||||
return g_strstrip (g_strdup (buf));
|
||||
fmt_component = g_object_get_data ((GObject *) cell, "fmt-component");
|
||||
if (!fmt_component || !*fmt_component)
|
||||
fmt_component = "Default";
|
||||
else
|
||||
fmt_part = "table";
|
||||
return e_datetime_format_format (fmt_component, fmt_part, DTFormatKindDateTime, date);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -165,3 +109,10 @@ e_cell_date_new (const gchar *fontname, GtkJustification justify)
|
||||
return (ECell *) ecd;
|
||||
}
|
||||
|
||||
void
|
||||
e_cell_date_set_format_component (ECellDate *ecd, const gchar *fmt_component)
|
||||
{
|
||||
g_return_if_fail (ecd != NULL);
|
||||
|
||||
g_object_set_data_full ((GObject *)ecd, "fmt-component", g_strdup (fmt_component), g_free);
|
||||
}
|
||||
|
||||
@ -44,6 +44,7 @@ typedef struct {
|
||||
|
||||
GType e_cell_date_get_type (void);
|
||||
ECell *e_cell_date_new (const gchar *fontname, GtkJustification justify);
|
||||
void e_cell_date_set_format_component (ECellDate *ecd, const gchar *fmt_component);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
||||
Reference in New Issue
Block a user