Commit c1e840df authored by John Sullivan's avatar John Sullivan

Better text for date column in list view.

parent 961f18d6
2000-01-25 John Sullivan <sullivan@eazel.com>
Better text for displayed file dates. This is currently used only
in the list view date column, but will be used later in icon view
when we get multiple lines of text per icon working.
* libnautilus/nautilus-glib-extensions.c:
* libnautilus/nautilus-glib-extensions.h:
New files, intended to hold nautilus code that logically belongs
in glib. Now contains a g_date constructor that takes a struct tm,
and a strdup_strftime function that returns a new string of exactly
the right size.
* libnautilus/Makefile.am: Build and install these two new files.
* libnautilus/nautilus-lib-self-check-functions.h: include the
new self-check function for nautilus-glib-extensions.
* libnautilus/nautilus-directory.c:
#include nautilus-glib-extensions.h
(nautilus_file_get_date_as_string): Replaced simple ctime version
with fancy version that uses shorter date format, the words
"today" and "yesterday" when appropriate, and the weekday name if
the date is in the last week (other than today or yesterday).
2000-01-25 Andy Hertzfeld <andy@eazel.com>
* libnautilus/nautilus-icons-view-icon-item.c,h:
......
......@@ -34,6 +34,7 @@ libnautilusinclude_HEADERS= \
nautilus-debug.h \
nautilus-directory.h \
nautilus-file-utilities.h \
nautilus-glib-extensions.h \
nautilus-gtk-extensions.h \
nautilus-icons-controller.h \
nautilus-icons-view-icon-item.h \
......@@ -55,6 +56,7 @@ libnautilus_la_SOURCES=$(nautilus_idl_sources) \
nautilus-debug.c \
nautilus-directory.c \
nautilus-file-utilities.c \
nautilus-glib-extensions.c \
nautilus-gtk-extensions.c \
nautilus-icons-controller.c \
nautilus-icons-view-icon-item.c \
......
......@@ -43,6 +43,7 @@
#include <gnome-xml/tree.h>
#include <gnome-xml/xmlmemory.h>
#include "nautilus-glib-extensions.h"
#include "nautilus-gtk-macros.h"
#include "nautilus-lib-self-check-functions.h"
#include "nautilus-string.h"
......@@ -845,20 +846,72 @@ nautilus_file_get_uri (NautilusFile *file)
gchar *
nautilus_file_get_date_as_string (NautilusFile *file)
{
/* Note: There's also accessed time and changed time.
* Accessed time doesn't seem worth showing to the user.
time_t now_secs;
struct tm *now;
struct tm *file_time;
GDate *today;
GDate *file_date;
gchar *result;
guint32 file_date_age;
/* Note: This uses modified time. There's also accessed time and
* changed time. Accessed time doesn't seem worth showing to the user.
* Changed time is only subtly different from modified time
* (changed time includes "metadata" changes like file permissions).
* We should not display both, but we might change our minds as to
* which one is better.
*/
g_return_val_if_fail (file != NULL, NULL);
/* Note that ctime is a funky function that returns a
* string that you're not supposed to free.
/* Each call to localtime clobbers a static variable. So to compare two
* time structures, one of the calls needs to use localtime_r to
* fill in a locally created time structure. This call still clobbers
* the static variable, so the other localtime call must be later.
*/
file_time = g_new0 (struct tm, 1);
localtime_r (&file->info->mtime, file_time);
file_date = nautilus_g_date_new_tm (file_time);
now_secs = time (NULL);
now = localtime (&now_secs);
today = nautilus_g_date_new_tm (now);
file_date_age = g_date_julian (today) - g_date_julian (file_date);
g_date_free (file_date);
g_date_free (today);
/* Format varies depending on how old the date is. This minimizes
* the length (and thus clutter & complication) of typical dates
* while providing sufficient detail for recent dates to make
* them maximally understandable at a glance. Keep all format
* strings separate rather than combining bits & pieces for
* internationalization's sake.
*/
return g_strdup (ctime (&file->info->mtime));
if (file_date_age == 0)
{
/* today, use special word */
result = nautilus_strdup_strftime (_("today %-I:%M %p"), file_time);
}
else if (file_date_age == 1)
{
/* yesterday, use special word */
result = nautilus_strdup_strftime (_("yesterday %-I:%M %p"), file_time);
}
else if (file_date_age < 7)
{
/* current week, include day of week */
result = nautilus_strdup_strftime (_("%A %-m/%-d/%y %-I:%M %p"), file_time);
}
else
{
result = nautilus_strdup_strftime (_("%-m/%-d/%y %-I:%M %p"), file_time);
}
g_free (file_time);
return result;
}
/**
......@@ -1015,7 +1068,7 @@ nautilus_self_check_directory (void)
directory = nautilus_directory_get ("file:///etc");
g_assert (g_hash_table_size (directory_objects) == 1);
NAUTILUS_CHECK_INTEGER_RESULT (g_hash_table_size (directory_objects), 1);
file_count = 0;
nautilus_directory_get_files (directory, get_files_cb, &data_dummy);
......@@ -1025,11 +1078,11 @@ nautilus_self_check_directory (void)
gtk_object_unref (GTK_OBJECT (directory));
g_assert (g_hash_table_size (directory_objects) == 0);
NAUTILUS_CHECK_INTEGER_RESULT (g_hash_table_size (directory_objects), 0);
directory = nautilus_directory_get ("file:///etc");
g_assert (g_hash_table_size (directory_objects) == 1);
NAUTILUS_CHECK_INTEGER_RESULT (g_hash_table_size (directory_objects), 1);
NAUTILUS_CHECK_STRING_RESULT (nautilus_directory_get_metadata (directory, "TEST", "default"), "value");
......
/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
/* nautilus-glib-extensions.c - implementation of new functions that conceptually
belong in glib. Perhaps some of these will be
actually rolled into glib someday.
Copyright (C) 2000 Eazel, Inc.
The Gnome Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
The Gnome Library 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
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with the Gnome Library; see the file COPYING.LIB. If not,
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA.
Authors: John Sullivan <sullivan@eazel.com>
*/
#include "nautilus-glib-extensions.h"
#include "nautilus-lib-self-check-functions.h"
/**
* nautilus_g_date_new_tm:
*
* Get a new GDate * for the date represented by a tm struct.
* The caller is responsible for g_free-ing the result.
* @time_pieces: Pointer to a tm struct representing the date to be converted.
*
* Returns: Newly allocated date.
*
**/
GDate *
nautilus_g_date_new_tm (struct tm *time_pieces)
{
/* tm uses 0-based months; GDate uses 1-based months.
* tm_year needs 1900 added to get the full year.
*/
return g_date_new_dmy (time_pieces->tm_mday,
time_pieces->tm_mon + 1,
time_pieces->tm_year + 1900);
}
/**
* nautilus_strdup_strftime:
*
* Cover for standard date-and-time-formatting routine strftime that returns
* a newly-allocated string of the correct size. The caller is responsible
* for g_free-ing the returned string.
* @format: format string to pass to strftime. See strftime documentation
* for details.
* @time_pieces: date/time, in struct format.
*
* Return value: Newly allocated string containing the formatted time.
**/
char *
nautilus_strdup_strftime (const char *format, struct tm *time_pieces)
{
char *result;
size_t string_length;
string_length = strftime (NULL, UINT_MAX, format, time_pieces);
result = g_malloc (string_length + 1);
strftime (result, string_length + 1, format, time_pieces);
return result;
}
#if !defined (NAUTILUS_OMIT_SELF_CHECK)
static void
check_tm_to_g_date (time_t time)
{
struct tm *before_conversion;
struct tm *after_conversion;
GDate *date;
before_conversion = localtime (&time);
date = nautilus_g_date_new_tm (before_conversion);
after_conversion = g_new0 (struct tm, 1);
g_date_to_struct_tm (date, after_conversion);
NAUTILUS_CHECK_INTEGER_RESULT (after_conversion->tm_mday,
before_conversion->tm_mday);
NAUTILUS_CHECK_INTEGER_RESULT (after_conversion->tm_mon,
before_conversion->tm_mon);
NAUTILUS_CHECK_INTEGER_RESULT (after_conversion->tm_year,
before_conversion->tm_year);
g_free (after_conversion);
}
void
nautilus_self_check_glib_extensions (void)
{
check_tm_to_g_date (0); /* lower limit */
check_tm_to_g_date ((time_t) -1); /* upper limit */
check_tm_to_g_date (time (NULL)); /* current time */
}
#endif /* !NAUTILUS_OMIT_SELF_CHECK */
/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
/* nautilus-glib-extensions.h - interface for new functions that conceptually
belong in glib. Perhaps some of these will be
actually rolled into glib someday.
Copyright (C) 2000 Eazel, Inc.
The Gnome Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
The Gnome Library 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
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with the Gnome Library; see the file COPYING.LIB. If not,
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA.
Authors: John Sullivan <sullivan@eazel.com>
*/
#ifndef NAUTILUS_GLIB_EXTENSIONS_H
#define NAUTILUS_GLIB_EXTENSIONS_H 1
#include <time.h>
#include <glib.h>
/* Date & time functions */
GDate * nautilus_g_date_new_tm (struct tm *time_pieces);
char * nautilus_strdup_strftime (const char *format,
struct tm *time_pieces);
#endif /* NAUTILUS_GLIB_EXTENSIONS_H */
......@@ -42,6 +42,7 @@ void nautilus_run_lib_self_checks (void);
macro(nautilus_self_check_background) \
macro(nautilus_self_check_directory) \
macro(nautilus_self_check_gdk_extensions) \
macro(nautilus_self_check_glib_extensions) \
/* Add new self-check functions to the list above this line. */
/* Generate prototypes for all the functions. */
......
......@@ -34,6 +34,7 @@ libnautilusinclude_HEADERS= \
nautilus-debug.h \
nautilus-directory.h \
nautilus-file-utilities.h \
nautilus-glib-extensions.h \
nautilus-gtk-extensions.h \
nautilus-icons-controller.h \
nautilus-icons-view-icon-item.h \
......@@ -55,6 +56,7 @@ libnautilus_la_SOURCES=$(nautilus_idl_sources) \
nautilus-debug.c \
nautilus-directory.c \
nautilus-file-utilities.c \
nautilus-glib-extensions.c \
nautilus-gtk-extensions.c \
nautilus-icons-controller.c \
nautilus-icons-view-icon-item.c \
......
......@@ -43,6 +43,7 @@
#include <gnome-xml/tree.h>
#include <gnome-xml/xmlmemory.h>
#include "nautilus-glib-extensions.h"
#include "nautilus-gtk-macros.h"
#include "nautilus-lib-self-check-functions.h"
#include "nautilus-string.h"
......@@ -845,20 +846,72 @@ nautilus_file_get_uri (NautilusFile *file)
gchar *
nautilus_file_get_date_as_string (NautilusFile *file)
{
/* Note: There's also accessed time and changed time.
* Accessed time doesn't seem worth showing to the user.
time_t now_secs;
struct tm *now;
struct tm *file_time;
GDate *today;
GDate *file_date;
gchar *result;
guint32 file_date_age;
/* Note: This uses modified time. There's also accessed time and
* changed time. Accessed time doesn't seem worth showing to the user.
* Changed time is only subtly different from modified time
* (changed time includes "metadata" changes like file permissions).
* We should not display both, but we might change our minds as to
* which one is better.
*/
g_return_val_if_fail (file != NULL, NULL);
/* Note that ctime is a funky function that returns a
* string that you're not supposed to free.
/* Each call to localtime clobbers a static variable. So to compare two
* time structures, one of the calls needs to use localtime_r to
* fill in a locally created time structure. This call still clobbers
* the static variable, so the other localtime call must be later.
*/
file_time = g_new0 (struct tm, 1);
localtime_r (&file->info->mtime, file_time);
file_date = nautilus_g_date_new_tm (file_time);
now_secs = time (NULL);
now = localtime (&now_secs);
today = nautilus_g_date_new_tm (now);
file_date_age = g_date_julian (today) - g_date_julian (file_date);
g_date_free (file_date);
g_date_free (today);
/* Format varies depending on how old the date is. This minimizes
* the length (and thus clutter & complication) of typical dates
* while providing sufficient detail for recent dates to make
* them maximally understandable at a glance. Keep all format
* strings separate rather than combining bits & pieces for
* internationalization's sake.
*/
return g_strdup (ctime (&file->info->mtime));
if (file_date_age == 0)
{
/* today, use special word */
result = nautilus_strdup_strftime (_("today %-I:%M %p"), file_time);
}
else if (file_date_age == 1)
{
/* yesterday, use special word */
result = nautilus_strdup_strftime (_("yesterday %-I:%M %p"), file_time);
}
else if (file_date_age < 7)
{
/* current week, include day of week */
result = nautilus_strdup_strftime (_("%A %-m/%-d/%y %-I:%M %p"), file_time);
}
else
{
result = nautilus_strdup_strftime (_("%-m/%-d/%y %-I:%M %p"), file_time);
}
g_free (file_time);
return result;
}
/**
......@@ -1015,7 +1068,7 @@ nautilus_self_check_directory (void)
directory = nautilus_directory_get ("file:///etc");
g_assert (g_hash_table_size (directory_objects) == 1);
NAUTILUS_CHECK_INTEGER_RESULT (g_hash_table_size (directory_objects), 1);
file_count = 0;
nautilus_directory_get_files (directory, get_files_cb, &data_dummy);
......@@ -1025,11 +1078,11 @@ nautilus_self_check_directory (void)
gtk_object_unref (GTK_OBJECT (directory));
g_assert (g_hash_table_size (directory_objects) == 0);
NAUTILUS_CHECK_INTEGER_RESULT (g_hash_table_size (directory_objects), 0);
directory = nautilus_directory_get ("file:///etc");
g_assert (g_hash_table_size (directory_objects) == 1);
NAUTILUS_CHECK_INTEGER_RESULT (g_hash_table_size (directory_objects), 1);
NAUTILUS_CHECK_STRING_RESULT (nautilus_directory_get_metadata (directory, "TEST", "default"), "value");
......
/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
/* nautilus-glib-extensions.c - implementation of new functions that conceptually
belong in glib. Perhaps some of these will be
actually rolled into glib someday.
Copyright (C) 2000 Eazel, Inc.
The Gnome Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
The Gnome Library 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
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with the Gnome Library; see the file COPYING.LIB. If not,
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA.
Authors: John Sullivan <sullivan@eazel.com>
*/
#include "nautilus-glib-extensions.h"
#include "nautilus-lib-self-check-functions.h"
/**
* nautilus_g_date_new_tm:
*
* Get a new GDate * for the date represented by a tm struct.
* The caller is responsible for g_free-ing the result.
* @time_pieces: Pointer to a tm struct representing the date to be converted.
*
* Returns: Newly allocated date.
*
**/
GDate *
nautilus_g_date_new_tm (struct tm *time_pieces)
{
/* tm uses 0-based months; GDate uses 1-based months.
* tm_year needs 1900 added to get the full year.
*/
return g_date_new_dmy (time_pieces->tm_mday,
time_pieces->tm_mon + 1,
time_pieces->tm_year + 1900);
}
/**
* nautilus_strdup_strftime:
*
* Cover for standard date-and-time-formatting routine strftime that returns
* a newly-allocated string of the correct size. The caller is responsible
* for g_free-ing the returned string.
* @format: format string to pass to strftime. See strftime documentation
* for details.
* @time_pieces: date/time, in struct format.
*
* Return value: Newly allocated string containing the formatted time.
**/
char *
nautilus_strdup_strftime (const char *format, struct tm *time_pieces)
{
char *result;
size_t string_length;
string_length = strftime (NULL, UINT_MAX, format, time_pieces);
result = g_malloc (string_length + 1);
strftime (result, string_length + 1, format, time_pieces);
return result;
}
#if !defined (NAUTILUS_OMIT_SELF_CHECK)
static void
check_tm_to_g_date (time_t time)
{
struct tm *before_conversion;
struct tm *after_conversion;
GDate *date;
before_conversion = localtime (&time);
date = nautilus_g_date_new_tm (before_conversion);
after_conversion = g_new0 (struct tm, 1);
g_date_to_struct_tm (date, after_conversion);
NAUTILUS_CHECK_INTEGER_RESULT (after_conversion->tm_mday,
before_conversion->tm_mday);
NAUTILUS_CHECK_INTEGER_RESULT (after_conversion->tm_mon,
before_conversion->tm_mon);
NAUTILUS_CHECK_INTEGER_RESULT (after_conversion->tm_year,
before_conversion->tm_year);
g_free (after_conversion);
}
void
nautilus_self_check_glib_extensions (void)
{
check_tm_to_g_date (0); /* lower limit */
check_tm_to_g_date ((time_t) -1); /* upper limit */
check_tm_to_g_date (time (NULL)); /* current time */
}
#endif /* !NAUTILUS_OMIT_SELF_CHECK */
/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
/* nautilus-glib-extensions.h - interface for new functions that conceptually
belong in glib. Perhaps some of these will be
actually rolled into glib someday.
Copyright (C) 2000 Eazel, Inc.
The Gnome Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
The Gnome Library 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
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with the Gnome Library; see the file COPYING.LIB. If not,
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA.
Authors: John Sullivan <sullivan@eazel.com>
*/
#ifndef NAUTILUS_GLIB_EXTENSIONS_H
#define NAUTILUS_GLIB_EXTENSIONS_H 1
#include <time.h>
#include <glib.h>
/* Date & time functions */
GDate * nautilus_g_date_new_tm (struct tm *time_pieces);
char * nautilus_strdup_strftime (const char *format,
struct tm *time_pieces);
#endif /* NAUTILUS_GLIB_EXTENSIONS_H */
......@@ -42,6 +42,7 @@ void nautilus_run_lib_self_checks (void);
macro(nautilus_self_check_background) \
macro(nautilus_self_check_directory) \
macro(nautilus_self_check_gdk_extensions) \
macro(nautilus_self_check_glib_extensions) \
/* Add new self-check functions to the list above this line. */
/* Generate prototypes for all the functions. */
......
......@@ -34,6 +34,7 @@ libnautilusinclude_HEADERS= \
nautilus-debug.h \
nautilus-directory.h \
nautilus-file-utilities.h \
nautilus-glib-extensions.h \
nautilus-gtk-extensions.h \
nautilus-icons-controller.h \
nautilus-icons-view-icon-item.h \
......@@ -55,6 +56,7 @@ libnautilus_la_SOURCES=$(nautilus_idl_sources) \
nautilus-debug.c \
nautilus-directory.c \
nautilus-file-utilities.c \
nautilus-glib-extensions.c \
nautilus-gtk-extensions.c \
nautilus-icons-controller.c \
nautilus-icons-view-icon-item.c \
......
......@@ -43,6 +43,7 @@
#include <gnome-xml/tree.h>
#include <gnome-xml/xmlmemory.h>
#include "nautilus-glib-extensions.h"
#include "nautilus-gtk-macros.h"
#include "nautilus-lib-self-check-functions.h"
#include "nautilus-string.h"
......@@ -845,20 +846,72 @@ nautilus_file_get_uri (NautilusFile *file)
gchar *
nautilus_file_get_date_as_string (NautilusFile *file)
{
/* Note: There's also accessed time and changed time.
* Accessed time doesn't seem worth showing to the user.
time_t now_secs;
struct tm *now;
struct tm *file_time;
GDate *today;
GDate *file_date;
gchar *result;
guint32 file_date_age;
/* Note: This uses modified time. There's also accessed time and
* changed time. Accessed time doesn't seem worth showing to the user.
* Changed time is only subtly different from modified time
* (changed time includes "metadata" changes like file permissions).
* We should not display both, but we might change our minds as to
* which one is better.
*/
g_return_val_if_fail (file != NULL, NULL);
/* Note that ctime is a funky function that returns a
* string that you're not supposed to free.
/* Each call to localtime clobbers a static variable. So to compare two
* time structures, one of the calls needs to use localtime_r to
* fill in a locally created time structure. This call still clobbers
* the static variable, so the other localtime call must be later.
*/
file_time = g_new0 (struct tm, 1);
localtime_r (&file->info->mtime, file_time);
file_date = nautilus_g_date_new_tm (file_time);
now_secs = time (NULL);
now = localtime (&now_secs);
today = nautilus_g_date_new_tm (now);
file_date_age = g_date_julian (today) - g_date_julian (file_date);
g_date_free (file_date);
g_date_free (today);
/* Format varies depending on how old the date is. This minimizes
* the length (and thus clutter & complication) of typical dates
* while providing sufficient detail for recent dates to make
* them maximally understandable at a glance. Keep all format
* strings separate rather than combining bits & pieces for
* internationalization's sake.
*/
return g_strdup (ctime (&file->info->mtime));
if (file_date_age == 0)
{
/* today, use special word */
result = nautilus_strdup_strftime (_("today %-I:%M %p"), file_time);
}
else if (file_date_age == 1)
{
/* yesterday, use special word */
result = nautilus_strdup_strftime (_("yesterday %-I:%M %p"), file_time);
}
else if (file_date_age < 7)
{
/* current week, include day of week */
result = nautilus_strdup_strftime (_("%A %-m/%-d/%y %-I:%M %p"), file_time);
}
else
{
result = nautilus_strdup_strftime (_("%-m/%-d/%y %-I:%M %p"), file_time);
}
g_free (file_time);
return result;
}
/**
......@@ -1015,7 +1068,7 @@ nautilus_self_check_directory (void)
directory = nautilus_directory_get ("file:///etc");
g_assert (g_hash_table_size (directory_objects) == 1);
NAUTILUS_CHECK_INTEGER_RESULT (g_hash_table_size (directory_objects), 1);
file_count = 0;
nautilus_directory_get_files (directory, get_files_cb, &data_dummy);
......@@ -1025,11 +1078,11 @@ nautilus_self_check_directory (void)
gtk_object_unref (GTK_OBJECT (directory));
g_assert (g_hash_table_size (directory_objects) == 0);
NAUTILUS_CHECK_INTEGER_RESULT (g_hash_table_size (directory_objects), 0);
directory = nautilus_directory_get ("file:///etc");