Commit 771cbf47 authored by Darin Adler's avatar Darin Adler

Icon positions are now written out when you drag an icon,

	and read in when you visit a directory. But the code then
	immediately re-lays out the icons, so the position is lost!

	* src/file-manager/fm-directory-view-icons.c:
	(fm_directory_view_icons_icon_moved_cb):
	(fm_directory_view_icons_initialize): (add_container_icon): Save
	icon position when an icon is moved. Get icon position when an
	icon is first created.

	* libnautilus/nautilus-directory.c:
	(nautilus_directory_get_metadata_from_node):
	(nautilus_directory_get_metadata):
	(nautilus_directory_create_metafile_tree_root):
	(nautilus_directory_get_metadata):
	(nautilus_directory_set_metadata):
	(nautilus_directory_get_file_metadata):
	(nautilus_directory_set_file_metadata): Added the routines to get
	and set metadata for individual files.

	* libnautilus/nautilus-string.h: libnautilus/nautilus-string.c:
	(nautilus_eat_strcmp): (nautilus_string_to_int):
	(nautilus_eat_string_to_int): Made new string functions that free
	the existing strings, and a function to convert an int to a
	string.

	* libnautilus/gnome-icon-container.h:
	libnautilus/gnome-icon-container.c: (move_icon): (class_init):
	(handle_icon_button_press): Added context_click_background and
	icon_moved signals, and renamed context_click to
	context_click_icon.

	* configure.in: Turned -Wunused back on. I had to turn -W off,
	but I think it's worth it.
parent 8d1eba09
2000-01-19 Darin Adler <darin@eazel.com>
Icon positions are now written out when you drag an icon,
and read in when you visit a directory. But the code then
immediately re-lays out the icons, so the position is lost!
* src/file-manager/fm-directory-view-icons.c:
(fm_directory_view_icons_icon_moved_cb):
(fm_directory_view_icons_initialize): (add_container_icon): Save
icon position when an icon is moved. Get icon position when an
icon is first created.
* libnautilus/nautilus-directory.c:
(nautilus_directory_get_metadata_from_node):
(nautilus_directory_get_metadata):
(nautilus_directory_create_metafile_tree_root):
(nautilus_directory_get_metadata):
(nautilus_directory_set_metadata):
(nautilus_directory_get_file_metadata):
(nautilus_directory_set_file_metadata): Added the routines to get
and set metadata for individual files.
* libnautilus/nautilus-string.h: libnautilus/nautilus-string.c:
(nautilus_eat_strcmp): (nautilus_string_to_int):
(nautilus_eat_string_to_int): Made new string functions that free
the existing strings, and a function to convert an int to a
string.
* libnautilus/gnome-icon-container.h:
libnautilus/gnome-icon-container.c: (move_icon): (class_init):
(handle_icon_button_press): Added context_click_background and
icon_moved signals, and renamed context_click to
context_click_icon.
* configure.in: Turned -Wunused back on. I had to turn -W off,
but I think it's worth it.
2000-01-19 John Sullivan <sullivan@eazel.com>
* src/file-manager/fm-directory-view.c:
......
......@@ -28,7 +28,7 @@ set_more_warnings="$enableval", set_more_warnings=yes)
if test "$GCC" = "yes" -a "$set_more_warnings" != "no"; then
echo "enable compile warnings = $set_more_warnings"
CFLAGS="$CFLAGS \
-W -Wall -Wno-unused \
-Wall \
-Wchar-subscripts -Wmissing-declarations -Wmissing-prototypes \
-Wnested-externs -Wpointer-arith \
-Wno-sign-compare -Wsign-promo"
......
......@@ -68,7 +68,9 @@ enum _GnomeIconContainerSignalNumber {
SELECTION_CHANGED,
BUTTON_PRESS,
ACTIVATE,
CONTEXT_CLICK,
CONTEXT_CLICK_ICON,
CONTEXT_CLICK_BACKGROUND,
ICON_MOVED,
LAST_SIGNAL
};
typedef enum _GnomeIconContainerSignalNumber GnomeIconContainerSignalNumber;
......@@ -1162,6 +1164,9 @@ move_icon (GnomeIconContainer *container,
icon_grid_add (priv->grid, icon, new_grid_x + 1, new_grid_y + 1);
icon_position (icon, container, x, y);
gtk_signal_emit (GTK_OBJECT (container), signals[ICON_MOVED],
icon->text, icon->data, x, y);
}
static void
......@@ -1893,6 +1898,12 @@ button_press_event (GtkWidget *widget,
return TRUE;
}
if (event->button == 3) {
gtk_signal_emit (GTK_OBJECT (widget),
signals[CONTEXT_CLICK_BACKGROUND]);
return TRUE;
}
gtk_signal_emit (GTK_OBJECT (widget), signals[BUTTON_PRESS], event,
&return_value);
......@@ -2092,16 +2103,36 @@ class_init (GnomeIconContainerClass *class)
GTK_TYPE_NONE, 2,
GTK_TYPE_STRING,
GTK_TYPE_POINTER);
signals[CONTEXT_CLICK]
= gtk_signal_new ("context_click",
signals[CONTEXT_CLICK_ICON]
= gtk_signal_new ("context_click_icon",
GTK_RUN_LAST,
object_class->type,
GTK_SIGNAL_OFFSET (GnomeIconContainerClass,
activate),
context_click_icon),
gtk_marshal_NONE__POINTER_POINTER,
GTK_TYPE_NONE, 2,
GTK_TYPE_STRING,
GTK_TYPE_POINTER);
signals[CONTEXT_CLICK_BACKGROUND]
= gtk_signal_new ("context_click_background",
GTK_RUN_LAST,
object_class->type,
GTK_SIGNAL_OFFSET (GnomeIconContainerClass,
context_click_background),
gtk_marshal_NONE__NONE,
GTK_TYPE_NONE, 0);
signals[ICON_MOVED]
= gtk_signal_new ("icon_moved",
GTK_RUN_LAST,
object_class->type,
GTK_SIGNAL_OFFSET (GnomeIconContainerClass,
icon_moved),
gtk_marshal_NONE__POINTER_POINTER_INT_INT,
GTK_TYPE_NONE, 4,
GTK_TYPE_STRING,
GTK_TYPE_POINTER,
GTK_TYPE_INT,
GTK_TYPE_INT);
gtk_object_class_add_signals (object_class, signals, LAST_SIGNAL);
......@@ -2236,7 +2267,7 @@ handle_icon_button_press (GnomeIconContainer *container,
priv->drag_icon = NULL;
gtk_signal_emit (GTK_OBJECT (container),
signals[CONTEXT_CLICK],
signals[CONTEXT_CLICK_ICON],
icon->text, icon->data);
return TRUE;
......
......@@ -72,12 +72,19 @@ struct _GnomeIconContainerClass {
gint (* button_press) (GnomeIconContainer *container,
GdkEventButton *event);
void (* activate) (GnomeIconContainer *container,
const gchar *name,
gpointer data);
const gchar *icon_name,
gpointer icon_data);
void (* context_click) (GnomeIconContainer *container,
const gchar *name,
gpointer data);
void (* context_click_icon) (GnomeIconContainer *container,
const gchar *icon_name,
gpointer icon_data);
void (* context_click_background) (GnomeIconContainer *container);
void (* icon_moved) (GnomeIconContainer *container,
const gchar *icon_name,
gpointer icon_data,
int x, int y);
};
......
......@@ -521,25 +521,18 @@ nautilus_directory_get_files (NautilusDirectory *directory,
callback_data);
}
char *
nautilus_directory_get_metadata (NautilusDirectory *directory,
const char *tag,
const char *default_metadata)
static char *
nautilus_directory_get_metadata_from_node (xmlNode *node,
const char *tag,
const char *default_metadata)
{
xmlNode *root;
xmlChar *property;
char *result;
g_return_val_if_fail (tag, NULL);
g_return_val_if_fail (tag[0], NULL);
/* It's legal to call this on a NULL directory. */
if (directory == NULL)
return NULL;
g_return_val_if_fail (NAUTILUS_IS_DIRECTORY (directory), NULL);
root = xmlDocGetRootElement (directory->details->metafile_tree);
property = xmlGetProp (root, tag);
property = xmlGetProp (node, tag);
if (property == NULL)
result = g_strdup (default_metadata);
else
......@@ -549,6 +542,38 @@ nautilus_directory_get_metadata (NautilusDirectory *directory,
return result;
}
static xmlNode *
nautilus_directory_create_metafile_tree_root (NautilusDirectory *directory)
{
xmlNode *root;
if (directory->details->metafile_tree == NULL)
directory->details->metafile_tree = xmlNewDoc (METAFILE_XML_VERSION);
root = xmlDocGetRootElement (directory->details->metafile_tree);
if (root == NULL) {
root = xmlNewDocNode (directory->details->metafile_tree, NULL, "DIRECTORY", NULL);
xmlDocSetRootElement (directory->details->metafile_tree, root);
}
return root;
}
char *
nautilus_directory_get_metadata (NautilusDirectory *directory,
const char *tag,
const char *default_metadata)
{
/* It's legal to call this on a NULL directory. */
if (directory == NULL)
return NULL;
g_return_val_if_fail (NAUTILUS_IS_DIRECTORY (directory), NULL);
/* The root itself represents the directory. */
return nautilus_directory_get_metadata_from_node
(xmlDocGetRootElement (directory->details->metafile_tree),
tag, default_metadata);
}
void
nautilus_directory_set_metadata (NautilusDirectory *directory,
const char *tag,
......@@ -581,13 +606,7 @@ nautilus_directory_set_metadata (NautilusDirectory *directory,
value = metadata;
/* Get at the tree. */
if (directory->details->metafile_tree == NULL)
directory->details->metafile_tree = xmlNewDoc (METAFILE_XML_VERSION);
root = xmlDocGetRootElement (directory->details->metafile_tree);
if (root == NULL) {
root = xmlNewDocNode (directory->details->metafile_tree, NULL, "DIRECTORY", NULL);
xmlDocSetRootElement (directory->details->metafile_tree, root);
}
root = nautilus_directory_create_metafile_tree_root (directory);
/* Add or remove an attribute node. */
property_node = xmlSetProp (root, tag, value);
......@@ -598,6 +617,102 @@ nautilus_directory_set_metadata (NautilusDirectory *directory,
nautilus_directory_request_write_metafile (directory);
}
char *
nautilus_directory_get_file_metadata (NautilusDirectory *directory,
const char *file_name,
const char *tag,
const char *default_metadata)
{
xmlNode *root, *child;
xmlChar *property;
g_return_val_if_fail (NAUTILUS_IS_DIRECTORY (directory), NULL);
/* The root itself represents the directory. */
root = xmlDocGetRootElement (directory->details->metafile_tree);
/* The children represent the files.
This linear search is temporary.
Eventually, we'll have a pointer from the FMFile right to
the corresponding XML node, or we won't have the XML tree
in memory at all.
*/
for (child = root->childs; child != NULL; child = child->next)
if (strcmp (child->name, "FILE") == 0) {
property = xmlGetProp (child, "NAME");
if (nautilus_eat_strcmp (property, file_name) == 0)
break;
}
/* If we found a child, we can get the data from it. */
return nautilus_directory_get_metadata_from_node
(child, tag, default_metadata);
}
void
nautilus_directory_set_file_metadata (NautilusDirectory *directory,
const char *file_name,
const char *tag,
const char *default_metadata,
const char *metadata)
{
char *old_metadata;
gboolean old_metadata_matches;
xmlNode *root, *child;
const char *value;
xmlChar *property;
xmlAttr *property_node;
g_return_if_fail (NAUTILUS_IS_DIRECTORY (directory));
g_return_if_fail (tag);
g_return_if_fail (tag[0]);
/* If the data in the metafile is already correct, do nothing. */
old_metadata = nautilus_directory_get_file_metadata
(directory, file_name, tag, default_metadata);
old_metadata_matches = nautilus_strcmp (old_metadata, metadata) == 0;
g_free (old_metadata);
if (old_metadata_matches)
return;
/* Data that matches the default is represented in the tree by
the lack of an attribute.
*/
if (nautilus_strcmp (default_metadata, metadata) == 0)
value = NULL;
else
value = metadata;
/* The root itself represents the directory. */
root = nautilus_directory_create_metafile_tree_root (directory);
/* The children represent the files.
This linear search is temporary.
Eventually, we'll have a pointer from the FMFile right to
the corresponding XML node, or we won't have the XML tree
in memory at all.
*/
for (child = root->childs; child != NULL; child = child->next)
if (strcmp (child->name, "FILE") == 0) {
property = xmlGetProp (child, "NAME");
if (nautilus_eat_strcmp (property, file_name) == 0)
break;
}
if (child == NULL) {
g_assert (value != NULL);
child = xmlNewChild (root, NULL, "FILE", NULL);
xmlSetProp (child, "NAME", file_name);
}
/* Add or remove an attribute node. */
property_node = xmlSetProp (child, tag, value);
if (value == NULL)
xmlRemoveProp (property_node);
/* Since we changed the tree, arrange for it to be written. */
nautilus_directory_request_write_metafile (directory);
}
#if !defined (NAUTILUS_OMIT_SELF_CHECK)
static int data_dummy;
......
......@@ -28,6 +28,10 @@
#include "nautilus-string.h"
#include <ctype.h>
#include <errno.h>
#include <stdlib.h>
size_t
nautilus_strlen (const char *string_null_allowed)
{
......@@ -46,3 +50,52 @@ nautilus_strcmp (const char *string_a_null_allowed, const char *string_b_null_al
return strcmp (string_a_null_allowed == NULL ? "" : string_a_null_allowed,
string_b_null_allowed == NULL ? "" : string_b_null_allowed);
}
int
nautilus_eat_strcmp (char *string_a, const char *string_b)
{
int result;
result = nautilus_strcmp (string_a, string_b);
g_free (string_a);
return result;
}
gboolean
nautilus_string_to_int (const char *string, int *integer)
{
long result;
char *parse_end;
/* Check for the case of an empty string. */
if (string == NULL || *string == '\0')
return FALSE;
/* Call the standard library routine to do the conversion. */
result = strtol (string, &parse_end, 0);
/* Check that the result is in range. */
if ((result == LONG_MIN || result == LONG_MAX) && errno == ERANGE)
return FALSE;
if (result < INT_MIN || result > INT_MAX)
return FALSE;
/* Check that all the trailing characters are spaces. */
while (*parse_end != '\0')
if (!isspace (*parse_end++))
return FALSE;
/* Return the result. */
*integer = result;
return TRUE;
}
gboolean
nautilus_eat_string_to_int (char *string, int *integer)
{
gboolean result;
result = nautilus_string_to_int (string, integer);
g_free (string);
return result;
}
......@@ -25,13 +25,24 @@
#ifndef NAUTILUS_STRING_H
#define NAUTILUS_STRING_H
#include <glib.h>
#include <string.h>
/* Versions of basic string functions that allow NULL. */
size_t nautilus_strlen (const char *string_null_allowed);
char * nautilus_strchr (const char *haystack_null_allowed,
char needle);
int nautilus_strcmp (const char *string_a_null_allowed,
const char *string_b_null_allowed);
size_t nautilus_strlen (const char *string_null_allowed);
char * nautilus_strchr (const char *haystack_null_allowed,
char needle);
int nautilus_strcmp (const char *string_a_null_allowed,
const char *string_b_null_allowed);
/* Versions of basic string functions that free their parameters. */
int nautilus_eat_strcmp (char *string_a_null_allowed_gets_freed,
const char *string_b_null_allowed);
/* Conversions to and from strings. */
gboolean nautilus_string_to_int (const char *string,
int *integer);
gboolean nautilus_eat_string_to_int (char *string_gets_freed,
int *integer);
#endif /* NAUTILUS_STRING_H */
......@@ -68,7 +68,9 @@ enum _GnomeIconContainerSignalNumber {
SELECTION_CHANGED,
BUTTON_PRESS,
ACTIVATE,
CONTEXT_CLICK,
CONTEXT_CLICK_ICON,
CONTEXT_CLICK_BACKGROUND,
ICON_MOVED,
LAST_SIGNAL
};
typedef enum _GnomeIconContainerSignalNumber GnomeIconContainerSignalNumber;
......@@ -1162,6 +1164,9 @@ move_icon (GnomeIconContainer *container,
icon_grid_add (priv->grid, icon, new_grid_x + 1, new_grid_y + 1);
icon_position (icon, container, x, y);
gtk_signal_emit (GTK_OBJECT (container), signals[ICON_MOVED],
icon->text, icon->data, x, y);
}
static void
......@@ -1893,6 +1898,12 @@ button_press_event (GtkWidget *widget,
return TRUE;
}
if (event->button == 3) {
gtk_signal_emit (GTK_OBJECT (widget),
signals[CONTEXT_CLICK_BACKGROUND]);
return TRUE;
}
gtk_signal_emit (GTK_OBJECT (widget), signals[BUTTON_PRESS], event,
&return_value);
......@@ -2092,16 +2103,36 @@ class_init (GnomeIconContainerClass *class)
GTK_TYPE_NONE, 2,
GTK_TYPE_STRING,
GTK_TYPE_POINTER);
signals[CONTEXT_CLICK]
= gtk_signal_new ("context_click",
signals[CONTEXT_CLICK_ICON]
= gtk_signal_new ("context_click_icon",
GTK_RUN_LAST,
object_class->type,
GTK_SIGNAL_OFFSET (GnomeIconContainerClass,
activate),
context_click_icon),
gtk_marshal_NONE__POINTER_POINTER,
GTK_TYPE_NONE, 2,
GTK_TYPE_STRING,
GTK_TYPE_POINTER);
signals[CONTEXT_CLICK_BACKGROUND]
= gtk_signal_new ("context_click_background",
GTK_RUN_LAST,
object_class->type,
GTK_SIGNAL_OFFSET (GnomeIconContainerClass,
context_click_background),
gtk_marshal_NONE__NONE,
GTK_TYPE_NONE, 0);
signals[ICON_MOVED]
= gtk_signal_new ("icon_moved",
GTK_RUN_LAST,
object_class->type,
GTK_SIGNAL_OFFSET (GnomeIconContainerClass,
icon_moved),
gtk_marshal_NONE__POINTER_POINTER_INT_INT,
GTK_TYPE_NONE, 4,
GTK_TYPE_STRING,
GTK_TYPE_POINTER,
GTK_TYPE_INT,
GTK_TYPE_INT);
gtk_object_class_add_signals (object_class, signals, LAST_SIGNAL);
......@@ -2236,7 +2267,7 @@ handle_icon_button_press (GnomeIconContainer *container,
priv->drag_icon = NULL;
gtk_signal_emit (GTK_OBJECT (container),
signals[CONTEXT_CLICK],
signals[CONTEXT_CLICK_ICON],
icon->text, icon->data);
return TRUE;
......
......@@ -72,12 +72,19 @@ struct _GnomeIconContainerClass {
gint (* button_press) (GnomeIconContainer *container,
GdkEventButton *event);
void (* activate) (GnomeIconContainer *container,
const gchar *name,
gpointer data);
const gchar *icon_name,
gpointer icon_data);
void (* context_click) (GnomeIconContainer *container,
const gchar *name,
gpointer data);
void (* context_click_icon) (GnomeIconContainer *container,
const gchar *icon_name,
gpointer icon_data);
void (* context_click_background) (GnomeIconContainer *container);
void (* icon_moved) (GnomeIconContainer *container,
const gchar *icon_name,
gpointer icon_data,
int x, int y);
};
......
......@@ -521,25 +521,18 @@ nautilus_directory_get_files (NautilusDirectory *directory,
callback_data);
}
char *
nautilus_directory_get_metadata (NautilusDirectory *directory,
const char *tag,
const char *default_metadata)
static char *
nautilus_directory_get_metadata_from_node (xmlNode *node,
const char *tag,
const char *default_metadata)
{
xmlNode *root;
xmlChar *property;
char *result;
g_return_val_if_fail (tag, NULL);
g_return_val_if_fail (tag[0], NULL);
/* It's legal to call this on a NULL directory. */
if (directory == NULL)
return NULL;
g_return_val_if_fail (NAUTILUS_IS_DIRECTORY (directory), NULL);
root = xmlDocGetRootElement (directory->details->metafile_tree);
property = xmlGetProp (root, tag);
property = xmlGetProp (node, tag);
if (property == NULL)
result = g_strdup (default_metadata);
else
......@@ -549,6 +542,38 @@ nautilus_directory_get_metadata (NautilusDirectory *directory,
return result;
}
static xmlNode *
nautilus_directory_create_metafile_tree_root (NautilusDirectory *directory)
{
xmlNode *root;
if (directory->details->metafile_tree == NULL)
directory->details->metafile_tree = xmlNewDoc (METAFILE_XML_VERSION);
root = xmlDocGetRootElement (directory->details->metafile_tree);
if (root == NULL) {
root = xmlNewDocNode (directory->details->metafile_tree, NULL, "DIRECTORY", NULL);
xmlDocSetRootElement (directory->details->metafile_tree, root);
}
return root;
}
char *
nautilus_directory_get_metadata (NautilusDirectory *directory,
const char *tag,
const char *default_metadata)
{
/* It's legal to call this on a NULL directory. */
if (directory == NULL)
return NULL;
g_return_val_if_fail (NAUTILUS_IS_DIRECTORY (directory), NULL);
/* The root itself represents the directory. */