Commit 00073501 authored by John Sullivan's avatar John Sullivan

Finished first decent UI for icon-text choosing.

parent c7d4a5ba
2000-02-08 John Sullivan <sullivan@eazel.com>
Completed first cut at icon-text-choosing UI.
Choose "Customize Icon Text..." from context menu in icon view to try.
Still doesn't save global setting across sessions; awaiting
more of a Preferences framework for that.
* src/file-manager/fm-signaller.h: New file.
* src/file-manager/fm-signaller.c: New file, manages object that acts
as a central place for file manager objects to register with and
broadcast signals, without having to wire specific objects together.
* src/file-manager/Makefile.am: Added these two new files to the build.
* src/file-manager/fm-directory-view-icons.h:
(fm_directory_view_icons_set_full_icon_text_attribute_names): Removed the
set_default parameter; for now at least, the text beneath icons is only
changeable on a global basis.
* src/file-manager/fm-directory-view-icons.c:
(icon_text_changed_cb): New function, tells GnomeIconContainer to
update all its icons.
(fm_directory_view_icons_initialize): Connect with FMSignaller's
"icon_text_changed" signal, so all windows will be updated.
(fm_directory_view_icons_set_full_icon_text_attribute_names):
Removed the set_default parameter; also tell FMSignaller to emit
"icon_text_changed".
* src/file-manager/fm-icon-text-window.c:
Completely reworked. Window used to contain three radio buttons for
pre-defined orderings of size/type/date_modified. Now window contains
three option menus, each with all available text attributes (except
name, which is hardwired to always go first). Selecting from any of
the option menus instantly updates all directory views.
* libnautilus/nautilus-directory.c:
defined private typedef enum NautilusDateType.
(nautilus_file_get_date_as_string): Added NautilusDateType parameter,
which chooses between the three available file dates (modified, changed,
accessed).
(nautilus_file_get_string_attribute): Now handles all three date types.
2000-02-08 John Sullivan <sullivan@eazel.com>
* configure.in: turned -Werror back on. It had been turned off a
......
......@@ -65,6 +65,12 @@
#define DIRECTORY_LOAD_ITEMS_PER_CB 1
typedef enum {
NAUTILUS_DATE_TYPE_MODIFIED,
NAUTILUS_DATE_TYPE_CHANGED,
NAUTILUS_DATE_TYPE_ACCESSED
} NautilusDateType;
enum
{
FILES_ADDED,
......@@ -90,7 +96,8 @@ static int nautilus_file_compare_for_sort_internal (NautilusFile *file_1,
NautilusFileSortType sort_type,
gboolean reversed);
static char * nautilus_file_get_date_as_string (NautilusFile *file);
static char * nautilus_file_get_date_as_string (NautilusFile *file,
NautilusDateType date_type);
static char * nautilus_file_get_size_as_string (NautilusFile *file);
static char * nautilus_file_get_type_as_string (NautilusFile *file);
static void nautilus_directory_load_cb (GnomeVFSAsyncHandle *handle,
......@@ -1332,16 +1339,8 @@ nautilus_file_get_uri (NautilusFile *file)
*
**/
static char *
nautilus_file_get_date_as_string (NautilusFile *file)
{
/* 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.
*/
nautilus_file_get_date_as_string (NautilusFile *file, NautilusDateType date_type)
{
struct tm *file_time;
const char *format;
GDate *today;
......@@ -1350,7 +1349,20 @@ nautilus_file_get_date_as_string (NautilusFile *file)
g_return_val_if_fail (file != NULL, NULL);
file_time = localtime(&file->info->mtime);
switch (date_type)
{
case NAUTILUS_DATE_TYPE_CHANGED:
file_time = localtime(&file->info->ctime);
break;
case NAUTILUS_DATE_TYPE_ACCESSED:
file_time = localtime(&file->info->atime);
break;
case NAUTILUS_DATE_TYPE_MODIFIED:
file_time = localtime(&file->info->mtime);
break;
default:
g_assert_not_reached ();
}
file_date = nautilus_g_date_new_tm (file_time);
today = g_date_new ();
......@@ -1439,7 +1451,8 @@ nautilus_file_get_size_as_string (NautilusFile *file)
*
* @file: NautilusFile representing the file in question.
* @attribute_name: The name of the desired attribute. The currently supported
* set includes "name", "type", "size", and "date modified".
* set includes "name", "type", "size", "date_modified", "date_changed", and
* "date_accessed".
*
* Returns: Newly allocated string ready to display to the user, or NULL
* if @attribute_name is not supported.
......@@ -1458,7 +1471,16 @@ nautilus_file_get_string_attribute (NautilusFile *file, const char *attribute_na
return nautilus_file_get_size_as_string (file);
if (strcmp (attribute_name, "date_modified") == 0)
return nautilus_file_get_date_as_string (file);
return nautilus_file_get_date_as_string (file,
NAUTILUS_DATE_TYPE_MODIFIED);
if (strcmp (attribute_name, "date_changed") == 0)
return nautilus_file_get_date_as_string (file,
NAUTILUS_DATE_TYPE_CHANGED);
if (strcmp (attribute_name, "date_accessed") == 0)
return nautilus_file_get_date_as_string (file,
NAUTILUS_DATE_TYPE_ACCESSED);
return NULL;
}
......
......@@ -65,6 +65,12 @@
#define DIRECTORY_LOAD_ITEMS_PER_CB 1
typedef enum {
NAUTILUS_DATE_TYPE_MODIFIED,
NAUTILUS_DATE_TYPE_CHANGED,
NAUTILUS_DATE_TYPE_ACCESSED
} NautilusDateType;
enum
{
FILES_ADDED,
......@@ -90,7 +96,8 @@ static int nautilus_file_compare_for_sort_internal (NautilusFile *file_1,
NautilusFileSortType sort_type,
gboolean reversed);
static char * nautilus_file_get_date_as_string (NautilusFile *file);
static char * nautilus_file_get_date_as_string (NautilusFile *file,
NautilusDateType date_type);
static char * nautilus_file_get_size_as_string (NautilusFile *file);
static char * nautilus_file_get_type_as_string (NautilusFile *file);
static void nautilus_directory_load_cb (GnomeVFSAsyncHandle *handle,
......@@ -1332,16 +1339,8 @@ nautilus_file_get_uri (NautilusFile *file)
*
**/
static char *
nautilus_file_get_date_as_string (NautilusFile *file)
{
/* 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.
*/
nautilus_file_get_date_as_string (NautilusFile *file, NautilusDateType date_type)
{
struct tm *file_time;
const char *format;
GDate *today;
......@@ -1350,7 +1349,20 @@ nautilus_file_get_date_as_string (NautilusFile *file)
g_return_val_if_fail (file != NULL, NULL);
file_time = localtime(&file->info->mtime);
switch (date_type)
{
case NAUTILUS_DATE_TYPE_CHANGED:
file_time = localtime(&file->info->ctime);
break;
case NAUTILUS_DATE_TYPE_ACCESSED:
file_time = localtime(&file->info->atime);
break;
case NAUTILUS_DATE_TYPE_MODIFIED:
file_time = localtime(&file->info->mtime);
break;
default:
g_assert_not_reached ();
}
file_date = nautilus_g_date_new_tm (file_time);
today = g_date_new ();
......@@ -1439,7 +1451,8 @@ nautilus_file_get_size_as_string (NautilusFile *file)
*
* @file: NautilusFile representing the file in question.
* @attribute_name: The name of the desired attribute. The currently supported
* set includes "name", "type", "size", and "date modified".
* set includes "name", "type", "size", "date_modified", "date_changed", and
* "date_accessed".
*
* Returns: Newly allocated string ready to display to the user, or NULL
* if @attribute_name is not supported.
......@@ -1458,7 +1471,16 @@ nautilus_file_get_string_attribute (NautilusFile *file, const char *attribute_na
return nautilus_file_get_size_as_string (file);
if (strcmp (attribute_name, "date_modified") == 0)
return nautilus_file_get_date_as_string (file);
return nautilus_file_get_date_as_string (file,
NAUTILUS_DATE_TYPE_MODIFIED);
if (strcmp (attribute_name, "date_changed") == 0)
return nautilus_file_get_date_as_string (file,
NAUTILUS_DATE_TYPE_CHANGED);
if (strcmp (attribute_name, "date_accessed") == 0)
return nautilus_file_get_date_as_string (file,
NAUTILUS_DATE_TYPE_ACCESSED);
return NULL;
}
......
......@@ -65,6 +65,12 @@
#define DIRECTORY_LOAD_ITEMS_PER_CB 1
typedef enum {
NAUTILUS_DATE_TYPE_MODIFIED,
NAUTILUS_DATE_TYPE_CHANGED,
NAUTILUS_DATE_TYPE_ACCESSED
} NautilusDateType;
enum
{
FILES_ADDED,
......@@ -90,7 +96,8 @@ static int nautilus_file_compare_for_sort_internal (NautilusFile *file_1,
NautilusFileSortType sort_type,
gboolean reversed);
static char * nautilus_file_get_date_as_string (NautilusFile *file);
static char * nautilus_file_get_date_as_string (NautilusFile *file,
NautilusDateType date_type);
static char * nautilus_file_get_size_as_string (NautilusFile *file);
static char * nautilus_file_get_type_as_string (NautilusFile *file);
static void nautilus_directory_load_cb (GnomeVFSAsyncHandle *handle,
......@@ -1332,16 +1339,8 @@ nautilus_file_get_uri (NautilusFile *file)
*
**/
static char *
nautilus_file_get_date_as_string (NautilusFile *file)
{
/* 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.
*/
nautilus_file_get_date_as_string (NautilusFile *file, NautilusDateType date_type)
{
struct tm *file_time;
const char *format;
GDate *today;
......@@ -1350,7 +1349,20 @@ nautilus_file_get_date_as_string (NautilusFile *file)
g_return_val_if_fail (file != NULL, NULL);
file_time = localtime(&file->info->mtime);
switch (date_type)
{
case NAUTILUS_DATE_TYPE_CHANGED:
file_time = localtime(&file->info->ctime);
break;
case NAUTILUS_DATE_TYPE_ACCESSED:
file_time = localtime(&file->info->atime);
break;
case NAUTILUS_DATE_TYPE_MODIFIED:
file_time = localtime(&file->info->mtime);
break;
default:
g_assert_not_reached ();
}
file_date = nautilus_g_date_new_tm (file_time);
today = g_date_new ();
......@@ -1439,7 +1451,8 @@ nautilus_file_get_size_as_string (NautilusFile *file)
*
* @file: NautilusFile representing the file in question.
* @attribute_name: The name of the desired attribute. The currently supported
* set includes "name", "type", "size", and "date modified".
* set includes "name", "type", "size", "date_modified", "date_changed", and
* "date_accessed".
*
* Returns: Newly allocated string ready to display to the user, or NULL
* if @attribute_name is not supported.
......@@ -1458,7 +1471,16 @@ nautilus_file_get_string_attribute (NautilusFile *file, const char *attribute_na
return nautilus_file_get_size_as_string (file);
if (strcmp (attribute_name, "date_modified") == 0)
return nautilus_file_get_date_as_string (file);
return nautilus_file_get_date_as_string (file,
NAUTILUS_DATE_TYPE_MODIFIED);
if (strcmp (attribute_name, "date_changed") == 0)
return nautilus_file_get_date_as_string (file,
NAUTILUS_DATE_TYPE_CHANGED);
if (strcmp (attribute_name, "date_accessed") == 0)
return nautilus_file_get_date_as_string (file,
NAUTILUS_DATE_TYPE_ACCESSED);
return NULL;
}
......
......@@ -32,8 +32,9 @@ libntl_file_manager_la_SOURCES= \
fm-icon-text-window.c \
fm-icon-text-window.h \
fm-icons-controller.c \
fm-icons-controller.h
fm-icons-controller.h \
fm-signaller.c \
fm-signaller.h
# noinst_PROGRAMS=gnome-desktop
......
......@@ -27,6 +27,7 @@
#include "fm-icon-text-window.h"
#include "fm-icons-controller.h"
#include "fm-signaller.h"
#include <ctype.h>
#include <errno.h>
......@@ -97,6 +98,8 @@ static void icon_container_context_click_icon_cb (GnomeIconContainer *container,
FMDirectoryViewIcons *icon_view);
static void icon_container_context_click_background_cb (GnomeIconContainer *container,
FMDirectoryViewIcons *icon_view);
static void icon_text_changed_cb (FMSignaller *signaller,
FMDirectoryViewIcons *icon_view);
static char * default_icon_text_attribute_names = NULL;
......@@ -157,6 +160,12 @@ fm_directory_view_icons_initialize (FMDirectoryViewIcons *icon_view)
icon_view->details = g_new0 (FMDirectoryViewIconsDetails, 1);
icon_container = create_icon_container (icon_view);
gtk_signal_connect_while_alive (GTK_OBJECT (fm_signaller_get_current ()),
"icon_text_changed",
icon_text_changed_cb,
icon_view,
GTK_OBJECT (icon_view));
}
static void
......@@ -438,9 +447,9 @@ fm_directory_view_icons_can_zoom_out (FMDirectoryView *view)
* fm_directory_view_icons_get_icon_text_attribute_names:
*
* Get a string representing which text attributes should be displayed
* beneath an icon in this directory at the highest zoom level.
* beneath an icon at the highest zoom level.
* Use g_free to free the result.
* @view: FMDirectoryViewIcons to query.
* @view: Any FMDirectoryViewIcons object.
*
* Return value: A |-delimited string comprising attribute names, e.g. "name|size".
*
......@@ -448,6 +457,10 @@ fm_directory_view_icons_can_zoom_out (FMDirectoryView *view)
char *
fm_directory_view_icons_get_full_icon_text_attribute_names (FMDirectoryViewIcons *view)
{
/* For now at least, there's only a global setting, not a per-directory one.
* So this routine doesn't need the first parameter, but it's in there
* for consistency and possible future expansion.
*/
return g_strdup (default_icon_text_attribute_names);
}
......@@ -455,19 +468,21 @@ fm_directory_view_icons_get_full_icon_text_attribute_names (FMDirectoryViewIcons
* fm_directory_view_icons_set_icon_text_attribute_names:
*
* Sets the string representing which text attributes should be displayed
* beneath an icon in this directory at the highest zoom level.
* beneath an icon at the highest zoom level.
* @view: FMDirectoryViewIcons whose displayed text attributes should be changed.
* @new_names: The |-delimited set of names to display at the highest zoom level,
* e.g. "name|size|date_modified".
* @set_default: TRUE if @new_names should be used as the default for directories
* that don't have their own setting.
*
**/
void
fm_directory_view_icons_set_full_icon_text_attribute_names (FMDirectoryViewIcons *view,
char *new_names,
gboolean set_default)
char *new_names)
{
/* For now at least, there's only a global setting, not a per-directory one.
* So this routine doesn't need the first parameter, but it's in there
* for consistency and possible future expansion.
*/
if (strcmp (new_names, default_icon_text_attribute_names) == 0)
return;
......@@ -475,7 +490,10 @@ fm_directory_view_icons_set_full_icon_text_attribute_names (FMDirectoryViewIcons
default_icon_text_attribute_names = g_strdup (new_names);
/* FIXME: save new choice in global preferences */
gnome_icon_container_request_update_all (get_icon_container (view));
/* Send signal that will notify us and all other directory views to update */
gtk_signal_emit_by_name (GTK_OBJECT (fm_signaller_get_current ()),
"icon_text_changed");
}
/**
......@@ -586,6 +604,15 @@ icon_container_selection_changed_cb (GnomeIconContainer *container,
fm_directory_view_notify_selection_changed (FM_DIRECTORY_VIEW (icon_view));
}
static void
icon_text_changed_cb (FMSignaller *signaller,
FMDirectoryViewIcons *icon_view)
{
g_assert (FM_IS_DIRECTORY_VIEW_ICONS (icon_view));
gnome_icon_container_request_update_all (get_icon_container (icon_view));
}
static void
icon_container_context_click_icon_cb (GnomeIconContainer *container,
NautilusFile *file,
......
......@@ -55,8 +55,7 @@ GtkType fm_directory_view_icons_get_type (void);
char * fm_directory_view_icons_get_icon_text_attribute_names (FMDirectoryViewIcons *view);
char * fm_directory_view_icons_get_full_icon_text_attribute_names (FMDirectoryViewIcons *view);
void fm_directory_view_icons_set_full_icon_text_attribute_names (FMDirectoryViewIcons *view,
char *new_names,
gboolean set_default);
char *new_names);
/*
* FIXME: None of the following are currently used. Remove them eventually if
......
......@@ -26,8 +26,11 @@
#include <config.h>
#include "fm-icon-text-window.h"
#include <gtk/gtkbox.h>
#include <gtk/gtkhbox.h>
#include <gtk/gtkhseparator.h>
#include <gtk/gtklabel.h>
#include <gtk/gtkmenuitem.h>
#include <gtk/gtkoptionmenu.h>
#include <gtk/gtksignal.h>
#include <gtk/gtktext.h>
#include <gtk/gtkradiobutton.h>
......@@ -35,100 +38,161 @@
#include <libgnome/gnome-i18n.h>
#include <libgnomeui/gnome-uidefs.h>
/* Larger size initially; user can stretch or shrink (but not shrink below min) */
#define ICON_TEXT_WINDOW_INITIAL_WIDTH 500
#define ICON_TEXT_WINDOW_INITIAL_HEIGHT 200
static gboolean fm_icon_text_window_delete_event_cb (GtkWidget *widget,
GdkEvent *event,
gpointer user_data);
static FMDirectoryViewIcons *icon_view = NULL;
static GtkOptionMenu *option_menu_2nd_line = NULL;
static GtkOptionMenu *option_menu_3rd_line = NULL;
static GtkOptionMenu *option_menu_4th_line = NULL;
static char * attribute_names[] = {
"size",
"type",
"date_modified",
"date_changed",
"date_accessed",
NULL
};
static char * attribute_labels[] = {
_("size"),
_("type"),
_("date modified"),
_("date changed"),
_("date accessed"),
NULL
};
#define PIECES_COUNT 4
static char *
get_chosen_attribute_name (GtkOptionMenu *option_menu)
{
int attribute_index;
g_assert (GTK_IS_OPTION_MENU (option_menu));
attribute_index = GPOINTER_TO_INT (gtk_object_get_user_data (
GTK_OBJECT (option_menu->menu_item)));
return g_strdup (attribute_names[attribute_index]);
}
static void
toggled_radio_button (GtkToggleButton *button, gpointer user_data)
changed_attributes_option_menu_cb (GtkMenuItem *menu_item, gpointer user_data)
{
char * all_attribute_names;
char ** attribute_names_array;
char * attribute_names_string;
g_assert (FM_IS_DIRECTORY_VIEW_ICONS (icon_view));
if (!gtk_toggle_button_get_active (button))
return;
switch (GPOINTER_TO_INT (user_data))
attribute_names_array = g_new0 (gchar*, PIECES_COUNT + 1);
/* Always start with the name. */
attribute_names_array[0] = g_strdup ("name");
attribute_names_array[1] = get_chosen_attribute_name (option_menu_2nd_line);
attribute_names_array[2] = get_chosen_attribute_name (option_menu_3rd_line);
attribute_names_array[3] = get_chosen_attribute_name (option_menu_4th_line);
attribute_names_string = g_strjoinv ("|", attribute_names_array);
fm_directory_view_icons_set_full_icon_text_attribute_names (icon_view,
attribute_names_string);
g_free (attribute_names_string);
g_strfreev (attribute_names_array);
}
static GtkOptionMenu *
create_attributes_option_menu (void)
{
GtkWidget *option_menu;
GtkWidget *menu;
GtkWidget *menu_item;
int index;
option_menu = gtk_option_menu_new ();
gtk_widget_show (option_menu);
menu = gtk_menu_new ();
for (index = 0; attribute_names[index] != NULL; ++index)
{
case 0:
all_attribute_names = "name|size|date_modified|type";
break;
case 1:
all_attribute_names = "name|date_modified|type|size";
break;
case 2:
all_attribute_names = "name|type|size|date_modified";
break;
default:
g_assert_not_reached ();
menu_item = gtk_menu_item_new_with_label (_(attribute_labels[index]));
/* Store index in item as the way to get from item back to attribute name */
gtk_object_set_user_data (GTK_OBJECT (menu_item), GINT_TO_POINTER (index));
gtk_widget_show (menu_item);
gtk_menu_append (GTK_MENU (menu), menu_item);
/* Wire all the menu items to the same callback. If any item is
* changed, the attribute text will be recomputed from scratch.
*/
gtk_signal_connect (GTK_OBJECT (menu_item),
"activate",
changed_attributes_option_menu_cb,
NULL);
}
gtk_option_menu_set_menu (GTK_OPTION_MENU (option_menu), menu);
fm_directory_view_icons_set_full_icon_text_attribute_names (icon_view,
all_attribute_names,
TRUE);
return GTK_OPTION_MENU (option_menu);
}
static GtkWidget*
create_icon_text_window (void)
create_icon_text_window ()
{
GtkWidget *window;
GtkWidget *vbox1;
GtkWidget *prompt;
GtkWidget *vbox;
GSList *radio_group;
GtkWidget *default_1;
GtkWidget *default_2;
GtkWidget *custom;
radio_group = NULL;
GtkWidget *hseparator1;
GtkWidget *hbox1;
GtkWidget *vbox2;
GtkWidget *name_label;
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_container_set_border_width (GTK_CONTAINER (window), 8);
gtk_window_set_title (GTK_WINDOW (window), _("Nautilus: Icon Text"));
gtk_window_set_policy (GTK_WINDOW (window), FALSE, FALSE, FALSE);
gtk_container_set_border_width (GTK_CONTAINER (window), GNOME_PAD);
gtk_window_set_title (GTK_WINDOW (window), _("Nautilus: Icon Text (placeholder UI)"));
vbox = gtk_vbox_new (FALSE, 0);
gtk_widget_show (vbox);
gtk_container_add (GTK_CONTAINER (window), vbox);
prompt = gtk_label_new (_("Choose the order for information to appear beneath icons.\nMore information appears as you zoom in closer."));
gtk_label_set_justify (GTK_LABEL (prompt), GTK_JUSTIFY_LEFT);
gtk_widget_show (prompt);
gtk_box_pack_start (GTK_BOX (vbox), prompt, FALSE, FALSE, GNOME_PAD);
default_1 = gtk_radio_button_new_with_label (radio_group, _("name, size, date modified, type"));
radio_group = gtk_radio_button_group (GTK_RADIO_BUTTON (default_1));
gtk_widget_show (default_1);
gtk_box_pack_start (GTK_BOX (vbox), default_1, FALSE, FALSE, 0);
gtk_signal_connect (GTK_OBJECT (default_1),
"toggled",
toggled_radio_button,
GINT_TO_POINTER (0));
default_2 = gtk_radio_button_new_with_label (radio_group, _("name, date modified, type, size"));
radio_group = gtk_radio_button_group (GTK_RADIO_BUTTON (default_2));
gtk_widget_show (default_2);
gtk_box_pack_start (GTK_BOX (vbox), default_2, FALSE, FALSE, 0);
gtk_signal_connect (GTK_OBJECT (default_2),
"toggled",
toggled_radio_button,
GINT_TO_POINTER (1));
custom = gtk_radio_button_new_with_label (radio_group, _("name, type, size, date modified"));
radio_group = gtk_radio_button_group (GTK_RADIO_BUTTON (custom));
gtk_widget_show (custom);
gtk_box_pack_start (GTK_BOX (vbox), custom, FALSE, FALSE, 0);
gtk_signal_connect (GTK_OBJECT (custom),