diff options
31 files changed, 1412 insertions, 470 deletions
@@ -1,3 +1,93 @@ +2001-02-21 Michael Engber <engber@eazel.com> + + reviewed by: Darin Adler <darin@eazel.com> + John Sullivan <sullivan@eazel.com> + + * libnautilus-extensions/Makefile.am: + * libnautilus-extensions/nautilus-directory-metafile-monitor.h: + * libnautilus-extensions/nautilus-directory-metafile-monitor.c: + (nautilus_metafile_monitor_initialize_class), + (nautilus_metafile_monitor_get_epv), + (nautilus_metafile_monitor_get_vepv), + (nautilus_metafile_monitor_create_servant), + (nautilus_metafile_monitor_initialize), (destroy), + (nautilus_metafile_monitor_new), (corba_metafile_changed): + Added implementation of monitors for directories to recieve + notification when their metadata changes. This works across + processes. + + * libnautilus-extensions/nautilus-directory.c: + (nautilus_directory_destroy), + (nautilus_directory_emit_change_signals): + * libnautilus-extensions/nautilus-directory-private.h: + * libnautilus-extensions/nautilus-directory-async.c: + (metafile_read_mark_done), (metafile_read_start), + (nautilus_directory_monitor_add_internal), + (update_metadata_monitors), + (nautilus_directory_monitor_remove_internal), + (nautilus_directory_call_when_ready_internal), + (nautilus_directory_cancel_callback_internal), + (nautilus_async_destroying_file), (request_is_satisfied), + (call_ready_callbacks): + The state machine now uses monitors in the metadata server + process. + + * libnautilus-extensions/nautilus-directory-metafile.c: + (get_metafile), (nautilus_directory_is_metadata_read), + (nautilus_directory_get_file_metadata), + (nautilus_directory_get_file_metadata_list), + (nautilus_directory_set_file_metadata), + (nautilus_directory_set_file_metadata_list), + (nautilus_directory_set_boolean_file_metadata), + (nautilus_directory_set_integer_file_metadata), + (nautilus_directory_copy_file_metadata), + (nautilus_directory_remove_file_metadata), + (nautilus_directory_rename_file_metadata), + (nautilus_directory_register_metadata_monitor), + (nautilus_directory_unregister_metadata_monitor): + * libnautilus-extensions/nautilus-directory-metafile.h: + -new calls for registering/unregistering monitors + -Metadata setters no longer return booleans. + -misc cleanup of CORBA exception code (or lack thereof) + + * libnautilus-extensions/nautilus-file-private.h: + * libnautilus-extensions/nautilus-file.c: + (nautilus_file_is_self_owned), (destroy), + (nautilus_file_get_parent_uri), (get_file_for_parent_directory), + (nautilus_file_can_rename), (nautilus_file_get_gnome_vfs_uri), + (rename_callback), (nautilus_file_rename), + (nautilus_file_set_directory), (get_metadata_name), + (nautilus_file_set_metadata), (nautilus_file_set_metadata_list), + (nautilus_file_set_boolean_metadata), + (nautilus_file_set_integer_metadata), (nautilus_file_get_uri), + (nautilus_file_mark_gone), (nautilus_file_changed): + -exposed (& renamed) is_self_owned in the private header. + -metadata setters no longer emit changes (it's done by the server) + + * libnautilus-extensions/nautilus-metafile-server.idl: + -metafile_changed now is passed a list of file names + + * libnautilus-extensions/nautilus-metafile.c: + (nautilus_metafile_get_epv), (destroy), (corba_is_read), + (corba_get), (corba_get_list), (corba_set), (corba_set_list), + (corba_copy), (corba_remove), (corba_rename), (find_monitor_node), + (corba_register_monitor), (corba_unregister_monitor), + (call_metatfile_changed), (file_list_filler_ghfunc), + (call_metafile_changed_for_all_files_mentioned_in_metafile), + (call_metatfile_changed_for_one_file): + * libnautilus-extensions/nautilus-metafile.h: + - metafile setters now emit changes and do not return boolean values + - added call_metafile_changed_for_all_files_mentioned_in_metafile + + * libnautilus-extensions/nautilus-stock-dialogs.c: + (timed_wait_callback): + Un-canelable timed wait dialogs now have an ok button + which dismisses them. + + * libnautilus-extensions/nautilus-trash-directory.c: + (find_directory_start): + Slightly clarified the text in the infamous searching for text dialog. + 2001-02-21 John Harper <jsh@eazel.com> reviewed by: Darin Adler <darin@eazel.com> diff --git a/libnautilus-extensions/Makefile.am b/libnautilus-extensions/Makefile.am index 9f00f352d..c19415d5d 100644 --- a/libnautilus-extensions/Makefile.am +++ b/libnautilus-extensions/Makefile.am @@ -122,8 +122,9 @@ libnautilus_extensions_la_SOURCES = \ nautilus-list.c \ nautilus-medusa-support.c \ nautilus-merged-directory.c \ - nautilus-metafile-factory.c \ nautilus-metafile.c \ + nautilus-metafile-factory.c \ + nautilus-directory-metafile-monitor.c \ nautilus-mime-actions.c \ nautilus-password-dialog.c \ nautilus-preferences-box.c \ @@ -241,8 +242,9 @@ noinst_HEADERS = \ nautilus-medusa-support.h \ nautilus-merged-directory.h \ nautilus-metadata.h \ - nautilus-metafile-factory.h \ nautilus-metafile.h \ + nautilus-metafile-factory.h \ + nautilus-directory-metafile-monitor.h \ nautilus-mime-actions.h \ nautilus-password-dialog.h \ nautilus-preferences-box.h \ diff --git a/libnautilus-extensions/nautilus-directory-async.c b/libnautilus-extensions/nautilus-directory-async.c index 010e383c1..dc3013787 100644 --- a/libnautilus-extensions/nautilus-directory-async.c +++ b/libnautilus-extensions/nautilus-directory-async.c @@ -25,6 +25,7 @@ #include <config.h> #include "nautilus-metafile.h" +#include "nautilus-directory-metafile.h" #include "nautilus-directory-notify.h" #include "nautilus-directory-private.h" #include "nautilus-file-attributes.h" @@ -457,7 +458,7 @@ metafile_read_mark_done (NautilusDirectory *directory) nautilus_metafile_apply_pending_changes (directory); /* Tell change-watchers that we have update information. */ - nautilus_directory_emit_metadata_changed (directory); + call_metafile_changed_for_all_files_mentioned_in_metafile (directory); /* Let the callers that were waiting for the metafile know. */ nautilus_directory_async_state_changed (directory); @@ -704,7 +705,7 @@ metafile_read_start (NautilusDirectory *directory) g_assert (directory->details->metafile == NULL); - if (!is_anyone_waiting_for_metafile (directory)) { + if (!directory->details->load_metafile_for_server) { return; } @@ -1121,7 +1122,14 @@ nautilus_directory_monitor_add_internal (NautilusDirectory *directory, nautilus_file_list_free (file_list); } } - + + /* We could just call update_metadata_monitors here, but we can be smarter + * since we know what monitor was just added. + */ + if (monitor->request.metafile && directory->details->metafile_monitor == NULL) { + nautilus_directory_register_metadata_monitor (directory); + } + /* Kick off I/O. */ nautilus_directory_async_state_changed (directory); } @@ -1482,6 +1490,24 @@ directory_load_callback (GnomeVFSAsyncHandle *handle, } } +static void +update_metadata_monitors (NautilusDirectory *directory) +{ + gboolean is_metadata_monitored; + + is_metadata_monitored = is_anyone_waiting_for_metafile (directory); + + if (directory->details->metafile_monitor == NULL) { + if (is_metadata_monitored) { + nautilus_directory_register_metadata_monitor (directory); + } + } else { + if (!is_metadata_monitored) { + nautilus_directory_unregister_metadata_monitor (directory); + } + } +} + void nautilus_directory_monitor_remove_internal (NautilusDirectory *directory, NautilusFile *file, @@ -1493,6 +1519,8 @@ nautilus_directory_monitor_remove_internal (NautilusDirectory *directory, remove_monitor (directory, file, client); + update_metadata_monitors (directory); + nautilus_directory_async_state_changed (directory); } @@ -1604,6 +1632,14 @@ nautilus_directory_call_when_ready_internal (NautilusDirectory *directory, (directory->details->call_when_ready_list, g_memdup (&callback, sizeof (callback))); + /* When we change the ready list we need to sync up metadata monitors. + * We could just call update_metadata_monitors here, but we can be smarter + * since we know what was just added. + */ + if (callback.request.metafile && directory->details->metafile_monitor == NULL) { + nautilus_directory_register_metadata_monitor (directory); + } + nautilus_directory_async_state_changed (directory); } @@ -1671,6 +1707,9 @@ nautilus_directory_cancel_callback_internal (NautilusDirectory *directory, ready_callback_key_compare); if (node != NULL) { remove_callback_link (directory, node); + /* When we change the ready list we need to sync up metadata monitors. */ + update_metadata_monitors (directory); + nautilus_directory_async_state_changed (directory); } } @@ -1799,6 +1838,11 @@ nautilus_async_destroying_file (NautilusFile *file) } } + /* When we change the monitor or ready list we need to sync up metadata monitors */ + if (changed) { + update_metadata_monitors (directory); + } + /* Check if it's a file that's currently being worked on. * If so, make that NULL so it gets canceled right away. */ @@ -1954,7 +1998,7 @@ request_is_satisfied (NautilusDirectory *directory, NautilusFile *file, Request *request) { - if (request->metafile && !directory->details->metafile_read) { + if (request->metafile && !nautilus_directory_is_metadata_read (directory)) { return FALSE; } @@ -2023,6 +2067,10 @@ call_ready_callbacks (NautilusDirectory *directory) } } if (node == NULL) { + if (called_any) { + /* When we change the ready list we need to sync up metadata monitors. */ + update_metadata_monitors (directory); + } return called_any; } diff --git a/libnautilus-extensions/nautilus-directory-metafile-monitor.c b/libnautilus-extensions/nautilus-directory-metafile-monitor.c new file mode 100644 index 000000000..b7fecd6df --- /dev/null +++ b/libnautilus-extensions/nautilus-directory-metafile-monitor.c @@ -0,0 +1,159 @@ +/* -*- Mode: IDL; tab-width: 8; indent-tabs-mode: 8; c-basic-offset: 8 -*- */ + +/* nautilus-directory-metafile-monitor.c + * + * Copyright (C) 2001 Eazel, Inc. + * + * This 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. + * + * This 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 this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include <config.h> +#include "nautilus-directory-metafile-monitor.h" +#include "nautilus-metafile-server.h" + +#include "nautilus-directory-private.h" +#include "nautilus-file-private.h" + +#include <libnautilus-extensions/nautilus-gtk-macros.h> +#include <libnautilus-extensions/nautilus-glib-extensions.h> +#include <libnautilus/nautilus-bonobo-workarounds.h> + +struct NautilusMetafileMonitorDetails { + NautilusDirectory *directory; +}; + +static void nautilus_metafile_monitor_initialize (NautilusMetafileMonitor *monitor); +static void nautilus_metafile_monitor_initialize_class (NautilusMetafileMonitorClass *klass); + +static void destroy (GtkObject *monitor); + +static void corba_metafile_changed (PortableServer_Servant servant, + const Nautilus_FileNameList *file_names, + CORBA_Environment *ev); + +NAUTILUS_DEFINE_CLASS_BOILERPLATE (NautilusMetafileMonitor, nautilus_metafile_monitor, BONOBO_OBJECT_TYPE) + +static void +nautilus_metafile_monitor_initialize_class (NautilusMetafileMonitorClass *klass) +{ + GTK_OBJECT_CLASS (klass)->destroy = destroy; +} + +static POA_Nautilus_MetafileMonitor__epv * +nautilus_metafile_monitor_get_epv (void) +{ + static POA_Nautilus_MetafileMonitor__epv epv; + + epv.metafile_changed = corba_metafile_changed; + + return &epv; +} + +static POA_Nautilus_MetafileMonitor__vepv * +nautilus_metafile_monitor_get_vepv (void) +{ + static POA_Nautilus_MetafileMonitor__vepv vepv; + + vepv.Bonobo_Unknown_epv = nautilus_bonobo_object_get_epv (); + vepv.Nautilus_MetafileMonitor_epv = nautilus_metafile_monitor_get_epv (); + + return &vepv; +} + +static POA_Nautilus_MetafileMonitor * +nautilus_metafile_monitor_create_servant (void) +{ + POA_Nautilus_MetafileMonitor *servant; + CORBA_Environment ev; + + servant = (POA_Nautilus_MetafileMonitor *) g_new0 (BonoboObjectServant, 1); + servant->vepv = nautilus_metafile_monitor_get_vepv (); + CORBA_exception_init (&ev); + POA_Nautilus_MetafileMonitor__init ((PortableServer_Servant) servant, &ev); + if (ev._major != CORBA_NO_EXCEPTION){ + g_error ("can't initialize Nautilus metafile monitor"); + } + CORBA_exception_free (&ev); + + return servant; +} + +static void +nautilus_metafile_monitor_initialize (NautilusMetafileMonitor *monitor) +{ + Nautilus_MetafileMonitor corba_monitor; + + monitor->details = g_new0 (NautilusMetafileMonitorDetails, 1); + + corba_monitor = bonobo_object_activate_servant + (BONOBO_OBJECT (monitor), nautilus_metafile_monitor_create_servant ()); + bonobo_object_construct (BONOBO_OBJECT (monitor), corba_monitor); +} + +static void +destroy (GtkObject *object) +{ + NautilusMetafileMonitor *monitor; + + monitor = NAUTILUS_METAFILE_MONITOR (object); + g_free (monitor->details); + + NAUTILUS_CALL_PARENT_CLASS (GTK_OBJECT_CLASS, destroy, (object)); +} + +NautilusMetafileMonitor * +nautilus_metafile_monitor_new (NautilusDirectory *directory) +{ + NautilusMetafileMonitor *monitor; + monitor = NAUTILUS_METAFILE_MONITOR (gtk_object_new (NAUTILUS_TYPE_METAFILE_MONITOR, NULL)); + monitor->details->directory = directory; + /* The monitor is owned by the directory, so we don't ref the directory. */ + return monitor; +} + +static void +corba_metafile_changed (PortableServer_Servant servant, + const Nautilus_FileNameList *file_names, + CORBA_Environment *ev) +{ + GList *file_list; + NautilusFile *file; + CORBA_unsigned_long buf_pos; + NautilusMetafileMonitor *monitor; + + monitor = NAUTILUS_METAFILE_MONITOR (bonobo_object_from_servant (servant)); + + file_list = NULL; + + for (buf_pos = 0; buf_pos < file_names->_length; ++buf_pos) { + file = nautilus_directory_find_file_by_relative_uri + (monitor->details->directory, file_names->_buffer [buf_pos]); + + if (file != NULL) { + if (nautilus_file_is_self_owned (file)) { + nautilus_file_emit_changed (file); + } else { + file_list = g_list_prepend (file_list, file); + } + } + } + + if (file_list != NULL) { + file_list = g_list_reverse (file_list); + nautilus_directory_emit_change_signals (monitor->details->directory, file_list); + g_list_free (file_list); + } +} diff --git a/libnautilus-extensions/nautilus-directory-metafile-monitor.h b/libnautilus-extensions/nautilus-directory-metafile-monitor.h new file mode 100644 index 000000000..cb464fa63 --- /dev/null +++ b/libnautilus-extensions/nautilus-directory-metafile-monitor.h @@ -0,0 +1,51 @@ +/* -*- Mode: IDL; tab-width: 8; indent-tabs-mode: 8; c-basic-offset: 8 -*- */ + +/* nautilus-directory-metafile-monitor.h + * + * Copyright (C) 2001 Eazel, Inc. + * + * This 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. + * + * This 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 this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef NAUTILUS_METAFILE_MONITOR_H +#define NAUTILUS_METAFILE_MONITOR_H + +#include <bonobo/bonobo-object.h> +#include <libnautilus-extensions/nautilus-directory.h> + +#define NAUTILUS_TYPE_METAFILE_MONITOR (nautilus_metafile_monitor_get_type ()) +#define NAUTILUS_METAFILE_MONITOR(obj) (GTK_CHECK_CAST ((obj), NAUTILUS_TYPE_METAFILE_MONITOR, NautilusMetafileMonitor)) +#define NAUTILUS_METAFILE_MONITOR_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), NAUTILUS_TYPE_METAFILE_MONITOR, NautilusMetafileMonitorClass)) +#define NAUTILUS_IS_METAFILE_MONITOR(obj) (GTK_CHECK_TYPE ((obj), NAUTILUS_TYPE_METAFILE_MONITOR)) +#define NAUTILUS_IS_METAFILE_MONITOR_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), NAUTILUS_TYPE_METAFILE_MONITOR)) + +typedef struct NautilusMetafileMonitorDetails NautilusMetafileMonitorDetails; + +typedef struct { + BonoboObject parent_slot; + NautilusMetafileMonitorDetails *details; +} NautilusMetafileMonitor; + +typedef struct { + BonoboObjectClass parent_slot; +} NautilusMetafileMonitorClass; + +GtkType nautilus_metafile_monitor_get_type (void); + + +NautilusMetafileMonitor *nautilus_metafile_monitor_new (NautilusDirectory *directory); + +#endif /* NAUTILUS_METAFILE_MONITOR_H */ diff --git a/libnautilus-extensions/nautilus-directory-metafile.c b/libnautilus-extensions/nautilus-directory-metafile.c index 6dbd9c971..ec01c2d42 100644 --- a/libnautilus-extensions/nautilus-directory-metafile.c +++ b/libnautilus-extensions/nautilus-directory-metafile.c @@ -25,8 +25,10 @@ #include <config.h> #include "nautilus-directory-metafile.h" +#include "nautilus-directory-private.h" #include <libnautilus-extensions/nautilus-metafile-factory.h> +#include <libnautilus-extensions/nautilus-directory-metafile-monitor.h> #include <libnautilus-extensions/nautilus-metafile-server.h> #include <libnautilus-extensions/nautilus-string.h> #include <liboaf/liboaf.h> @@ -69,18 +71,48 @@ get_factory (void) } static Nautilus_Metafile -get_metafile (NautilusDirectory *directory, CORBA_Environment *ev) +get_metafile (NautilusDirectory *directory) { char *uri; + CORBA_Environment ev; Nautilus_Metafile metafile; uri = nautilus_directory_get_uri (directory); - metafile = Nautilus_MetafileFactory_open (get_factory (), uri, ev); - g_free (uri); + CORBA_exception_init (&ev); + + metafile = Nautilus_MetafileFactory_open (get_factory (), uri, &ev); + + /* FIXME bugzilla.eazel.com 6664: examine ev for errors */ + CORBA_exception_free (&ev); + + g_free (uri); + return metafile; } +gboolean +nautilus_directory_is_metadata_read (NautilusDirectory *directory) +{ + CORBA_Environment ev; + Nautilus_Metafile metafile; + + gboolean result; + + g_return_val_if_fail (NAUTILUS_IS_DIRECTORY (directory), FALSE); + + metafile = get_metafile (directory); + CORBA_exception_init (&ev); + + result = Nautilus_Metafile_is_read (metafile, &ev); + + /* FIXME bugzilla.eazel.com 6664: examine ev for errors */ + CORBA_exception_free (&ev); + bonobo_object_release_unref (metafile, NULL); + + return result; +} + char * nautilus_directory_get_file_metadata (NautilusDirectory *directory, const char *file_name, @@ -101,14 +133,14 @@ nautilus_directory_get_file_metadata (NautilusDirectory *directory, /* We can't pass NULL as a CORBA_string - pass "" instead. */ non_null_default = default_metadata != NULL ? default_metadata : ""; + metafile = get_metafile (directory); CORBA_exception_init (&ev); - metafile = get_metafile (directory, &ev); - - /* FIXME bugzilla.eazel.com 6664: examine ev for errors */ corba_value = Nautilus_Metafile_get (metafile, file_name, key, non_null_default, &ev); /* FIXME bugzilla.eazel.com 6664: examine ev for errors */ + CORBA_exception_free (&ev); + bonobo_object_release_unref (metafile, NULL); if (nautilus_str_is_empty (corba_value)) { /* Even though in all other respects we treat "" as NULL, we want to @@ -120,9 +152,6 @@ nautilus_directory_get_file_metadata (NautilusDirectory *directory, } CORBA_free (corba_value); - - bonobo_object_release_unref (metafile, NULL); - CORBA_exception_free (&ev); return result; } @@ -145,14 +174,14 @@ nautilus_directory_get_file_metadata_list (NautilusDirectory *directory, g_return_val_if_fail (!nautilus_str_is_empty (list_key), NULL); g_return_val_if_fail (!nautilus_str_is_empty (list_subkey), NULL); + metafile = get_metafile (directory); CORBA_exception_init (&ev); - metafile = get_metafile (directory, &ev); - - /* FIXME bugzilla.eazel.com 6664: examine ev for errors */ corba_value = Nautilus_Metafile_get_list (metafile, file_name, list_key, list_subkey, &ev); /* FIXME bugzilla.eazel.com 6664: examine ev for errors */ + CORBA_exception_free (&ev); + bonobo_object_release_unref (metafile, NULL); result = NULL; for (buf_pos = 0; buf_pos < corba_value->_length; ++buf_pos) { @@ -160,14 +189,11 @@ nautilus_directory_get_file_metadata_list (NautilusDirectory *directory, } result = g_list_reverse (result); CORBA_free (corba_value); - - bonobo_object_release_unref (metafile, NULL); - CORBA_exception_free (&ev); return result; } -gboolean +void nautilus_directory_set_file_metadata (NautilusDirectory *directory, const char *file_name, const char *key, @@ -177,11 +203,9 @@ nautilus_directory_set_file_metadata (NautilusDirectory *directory, CORBA_Environment ev; Nautilus_Metafile metafile; - gboolean result; - - g_return_val_if_fail (NAUTILUS_IS_DIRECTORY (directory), FALSE); - g_return_val_if_fail (!nautilus_str_is_empty (file_name), FALSE); - g_return_val_if_fail (!nautilus_str_is_empty (key), FALSE); + g_return_if_fail (NAUTILUS_IS_DIRECTORY (directory)); + g_return_if_fail (!nautilus_str_is_empty (file_name)); + g_return_if_fail (!nautilus_str_is_empty (key)); /* We can't pass NULL as a CORBA_string - pass "" instead. */ @@ -192,22 +216,17 @@ nautilus_directory_set_file_metadata (NautilusDirectory *directory, metadata = ""; } + metafile = get_metafile (directory); CORBA_exception_init (&ev); - metafile = get_metafile (directory, &ev); - /* FIXME bugzilla.eazel.com 6664: examine ev for errors */ + Nautilus_Metafile_set (metafile, file_name, key, default_metadata, metadata, &ev); - result = Nautilus_Metafile_set (metafile, file_name, key, default_metadata, metadata, &ev); - /* FIXME bugzilla.eazel.com 6664: examine ev for errors */ - - bonobo_object_release_unref (metafile, NULL); CORBA_exception_free (&ev); - - return result; + bonobo_object_release_unref (metafile, NULL); } -gboolean +void nautilus_directory_set_file_metadata_list (NautilusDirectory *directory, const char *file_name, const char *list_key, @@ -216,24 +235,17 @@ nautilus_directory_set_file_metadata_list (NautilusDirectory *directory, { CORBA_Environment ev; Nautilus_Metafile metafile; - - gboolean result; Nautilus_MetadataList *corba_list; int len; int buf_pos; GList *list_ptr; - g_return_val_if_fail (NAUTILUS_IS_DIRECTORY (directory), FALSE); - g_return_val_if_fail (!nautilus_str_is_empty (file_name), FALSE); - g_return_val_if_fail (!nautilus_str_is_empty (list_key), FALSE); - g_return_val_if_fail (!nautilus_str_is_empty (list_subkey), FALSE); + g_return_if_fail (NAUTILUS_IS_DIRECTORY (directory)); + g_return_if_fail (!nautilus_str_is_empty (file_name)); + g_return_if_fail (!nautilus_str_is_empty (list_key)); + g_return_if_fail (!nautilus_str_is_empty (list_subkey)); - CORBA_exception_init (&ev); - metafile = get_metafile (directory, &ev); - - /* FIXME bugzilla.eazel.com 6664: examine ev for errors */ - len = g_list_length (list); corba_list = Nautilus_MetadataList__alloc (); @@ -254,16 +266,16 @@ nautilus_directory_set_file_metadata_list (NautilusDirectory *directory, ++buf_pos; } - result = Nautilus_Metafile_set_list (metafile, file_name, list_key, list_subkey, corba_list, &ev); - - /* FIXME bugzilla.eazel.com 6664: examine ev for errors */ + metafile = get_metafile (directory); + CORBA_exception_init (&ev); - CORBA_free (corba_list); + Nautilus_Metafile_set_list (metafile, file_name, list_key, list_subkey, corba_list, &ev); - bonobo_object_release_unref (metafile, NULL); + /* FIXME bugzilla.eazel.com 6664: examine ev for errors */ CORBA_exception_free (&ev); + bonobo_object_release_unref (metafile, NULL); - return result; + CORBA_free (corba_list); } gboolean @@ -295,14 +307,14 @@ nautilus_directory_get_boolean_file_metadata (NautilusDirectory *directory, return result; } -gboolean +void nautilus_directory_set_boolean_file_metadata (NautilusDirectory *directory, const char *file_name, const char *key, gboolean default_metadata, gboolean metadata) { - return nautilus_directory_set_file_metadata + nautilus_directory_set_file_metadata (directory, file_name, key, default_metadata ? "true" : "false", metadata ? "true" : "false"); @@ -338,7 +350,7 @@ nautilus_directory_get_integer_file_metadata (NautilusDirectory *directory, return result; } -gboolean +void nautilus_directory_set_integer_file_metadata (NautilusDirectory *directory, const char *file_name, const char *key, @@ -351,7 +363,7 @@ nautilus_directory_set_integer_file_metadata (NautilusDirectory *directory, value_as_string = g_strdup_printf ("%d", metadata); default_as_string = g_strdup_printf ("%d", default_metadata); - return nautilus_directory_set_file_metadata + nautilus_directory_set_file_metadata (directory, file_name, key, default_as_string, value_as_string); @@ -374,20 +386,18 @@ nautilus_directory_copy_file_metadata (NautilusDirectory *source_directory, g_return_if_fail (NAUTILUS_IS_DIRECTORY (destination_directory)); g_return_if_fail (destination_file_name != NULL); - CORBA_exception_init (&ev); - source_metafile = get_metafile (source_directory, &ev); - - /* FIXME bugzilla.eazel.com 6664: examine ev for errors */ - destination_uri = nautilus_directory_get_uri (destination_directory); + source_metafile = get_metafile (source_directory); + CORBA_exception_init (&ev); + Nautilus_Metafile_copy (source_metafile, source_file_name, destination_uri, destination_file_name, &ev); /* FIXME bugzilla.eazel.com 6664: examine ev for errors */ + CORBA_exception_free (&ev); + bonobo_object_release_unref (source_metafile, NULL); g_free (destination_uri); - bonobo_object_release_unref (source_metafile, NULL); - CORBA_exception_free (&ev); } void @@ -400,17 +410,14 @@ nautilus_directory_remove_file_metadata (NautilusDirectory *directory, g_return_if_fail (NAUTILUS_IS_DIRECTORY (directory)); g_return_if_fail (file_name != NULL); + metafile = get_metafile (directory); CORBA_exception_init (&ev); - metafile = get_metafile (directory, &ev); - - /* FIXME bugzilla.eazel.com 6664: examine ev for errors */ Nautilus_Metafile_remove (metafile, file_name, &ev); /* FIXME bugzilla.eazel.com 6664: examine ev for errors */ - - bonobo_object_release_unref (metafile, NULL); CORBA_exception_free (&ev); + bonobo_object_release_unref (metafile, NULL); } void @@ -425,15 +432,66 @@ nautilus_directory_rename_file_metadata (NautilusDirectory *directory, g_return_if_fail (old_file_name != NULL); g_return_if_fail (new_file_name != NULL); + metafile = get_metafile (directory); CORBA_exception_init (&ev); - metafile = get_metafile (directory, &ev); - - /* FIXME bugzilla.eazel.com 6664: examine ev for errors */ Nautilus_Metafile_rename (metafile, old_file_name, new_file_name, &ev); /* FIXME bugzilla.eazel.com 6664: examine ev for errors */ + CORBA_exception_free (&ev); + bonobo_object_release_unref (metafile, &ev); +} + +void +nautilus_directory_register_metadata_monitor (NautilusDirectory *directory) +{ + CORBA_Environment ev; + Nautilus_Metafile metafile; + + g_return_if_fail (NAUTILUS_IS_DIRECTORY (directory)); + + if (directory->details->metafile_monitor != NULL) { + /* If there's already a monitor, it's already registered. */ + return; + } + directory->details->metafile_monitor = nautilus_metafile_monitor_new (directory); + + metafile = get_metafile (directory); + CORBA_exception_init (&ev); + + Nautilus_Metafile_register_monitor + (metafile, + bonobo_object_corba_objref (BONOBO_OBJECT (directory->details->metafile_monitor)), + &ev); + + /* FIXME bugzilla.eazel.com 6664: examine ev for errors */ + CORBA_exception_free (&ev); bonobo_object_release_unref (metafile, NULL); +} + +void +nautilus_directory_unregister_metadata_monitor (NautilusDirectory *directory) +{ + CORBA_Environment ev; + Nautilus_Metafile metafile; + + g_return_if_fail (NAUTILUS_IS_DIRECTORY (directory)); + + g_return_if_fail (NAUTILUS_IS_METAFILE_MONITOR (directory->details->metafile_monitor)); + + metafile = get_metafile (directory); + CORBA_exception_init (&ev); + + Nautilus_Metafile_unregister_monitor + (metafile, + bonobo_object_corba_objref (BONOBO_OBJECT (directory->details->metafile_monitor)), + &ev); + + /* FIXME bugzilla.eazel.com 6664: examine ev for errors */ CORBA_exception_free (&ev); + bonobo_object_release_unref (metafile, NULL); + + directory->details->metafile_monitor = NULL; } + diff --git a/libnautilus-extensions/nautilus-directory-metafile.h b/libnautilus-extensions/nautilus-directory-metafile.h index 5faf3dd59..511355a9b 100644 --- a/libnautilus-extensions/nautilus-directory-metafile.h +++ b/libnautilus-extensions/nautilus-directory-metafile.h @@ -25,43 +25,45 @@ #include "nautilus-directory.h" /* Interface for file metadata. */ -char * nautilus_directory_get_file_metadata (NautilusDirectory *directory, - const char *file_name, - const char *key, - const char *default_metadata); -GList * nautilus_directory_get_file_metadata_list (NautilusDirectory *directory, - const char *file_name, - const char *list_key, - const char *list_subkey); -gboolean nautilus_directory_get_boolean_file_metadata (NautilusDirectory *directory, - const char *file_name, - const char *key, - gboolean default_metadata); -int nautilus_directory_get_integer_file_metadata (NautilusDirectory *directory, - const char *file_name, - const char *key, - int default_metadata); +gboolean nautilus_directory_is_metadata_read (NautilusDirectory *directory); -gboolean nautilus_directory_set_file_metadata (NautilusDirectory *directory, - const char *file_name, - const char *key, - const char *default_metadata, - const char *metadata); -gboolean nautilus_directory_set_file_metadata_list (NautilusDirectory *directory, - const char *file_name, - const char *list_key, - const char *list_subkey, - GList *list); -gboolean nautilus_directory_set_boolean_file_metadata (NautilusDirectory *directory, - const char *file_name, - const char *key, - gboolean default_metadata, - gboolean metadata); -gboolean nautilus_directory_set_integer_file_metadata (NautilusDirectory *directory, - const char *file_name, - const char *key, - int default_metadata, - int metadata); +char * nautilus_directory_get_file_metadata (NautilusDirectory *directory, + const char *file_name, + const char *key, + const char *default_metadata); +GList * nautilus_directory_get_file_metadata_list (NautilusDirectory *directory, + const char *file_name, + const char *list_key, + const char *list_subkey); +gboolean nautilus_directory_get_boolean_file_metadata (NautilusDirectory *directory, + const char *file_name, + const char *key, + gboolean default_metadata); +int nautilus_directory_get_integer_file_metadata (NautilusDirectory *directory, + const char *file_name, + const char *key, + int default_metadata); + +void nautilus_directory_set_file_metadata (NautilusDirectory *directory, + const char *file_name, + const char *key, + const char *default_metadata, + const char *metadata); +void nautilus_directory_set_file_metadata_list (NautilusDirectory *directory, + const char *file_name, + const char *list_key, + const char *list_subkey, + GList *list); +void nautilus_directory_set_boolean_file_metadata (NautilusDirectory *directory, + const char *file_name, + const char *key, + gboolean default_metadata, + gboolean metadata); +void nautilus_directory_set_integer_file_metadata (NautilusDirectory *directory, + const char *file_name, + const char *key, + int default_metadata, + int metadata); void nautilus_directory_copy_file_metadata (NautilusDirectory *source_directory, const char *source_file_name, @@ -73,4 +75,7 @@ void nautilus_directory_rename_file_metadata (NautilusDirectory *d const char *old_file_name, const char *new_file_name); +void nautilus_directory_register_metadata_monitor (NautilusDirectory *directory); +void nautilus_directory_unregister_metadata_monitor (NautilusDirectory *directory); + void nautilus_directory_use_self_contained_metafile_factory (void); diff --git a/libnautilus-extensions/nautilus-directory-private.h b/libnautilus-extensions/nautilus-directory-private.h index a1f117fe2..b6324f10d 100644 --- a/libnautilus-extensions/nautilus-directory-private.h +++ b/libnautilus-extensions/nautilus-directory-private.h @@ -32,6 +32,7 @@ #include "nautilus-file.h" #include "nautilus-file-utilities.h" +#include "nautilus-directory-metafile-monitor.h" typedef struct ActivationURIReadState ActivationURIReadState; typedef struct MetafileReadState MetafileReadState; @@ -68,6 +69,9 @@ struct NautilusDirectoryDetails GList *call_when_ready_list; GList *monitor_list; + NautilusMetafileMonitor *metafile_monitor; + gboolean load_metafile_for_server; + gboolean in_async_service_loop; gboolean state_changed; @@ -168,7 +172,6 @@ void nautilus_directory_cancel_loading_file_attributes (NautilusD GList *file_attributes); /* Calls shared between directory, file, and async. code. */ -void nautilus_directory_emit_metadata_changed (NautilusDirectory *directory); void nautilus_directory_emit_files_added (NautilusDirectory *directory, GList *added_files); void nautilus_directory_emit_files_changed (NautilusDirectory *directory, diff --git a/libnautilus-extensions/nautilus-directory.c b/libnautilus-extensions/nautilus-directory.c index 12bbda9ae..82d8d28db 100644 --- a/libnautilus-extensions/nautilus-directory.c +++ b/libnautilus-extensions/nautilus-directory.c @@ -175,6 +175,10 @@ nautilus_directory_destroy (GtkObject *object) nautilus_g_list_free_deep (directory->details->monitor_list); } + if (directory->details->metafile_monitor != NULL) { + nautilus_directory_unregister_metadata_monitor (directory); + } + g_hash_table_remove (directories, directory->details->uri); if (directory->details->dequeue_pending_idle_id != 0) { @@ -736,16 +740,6 @@ nautilus_directory_emit_change_signals (NautilusDirectory *directory, } void -nautilus_directory_emit_metadata_changed (NautilusDirectory *directory) -{ - /* Say that all the files have changed. - * We could optimize this to only mention files that - * have metadata, but this is a fine rough cut for now. - */ - emit_change_signals_for_all_files (directory); -} - -void nautilus_directory_emit_done_loading (NautilusDirectory *directory) { gtk_signal_emit (GTK_OBJECT (directory), diff --git a/libnautilus-extensions/nautilus-file-private.h b/libnautilus-extensions/nautilus-file-private.h index da0ce7a9c..21e79a025 100644 --- a/libnautilus-extensions/nautilus-file-private.h +++ b/libnautilus-extensions/nautilus-file-private.h @@ -134,3 +134,5 @@ gboolean nautilus_file_should_get_top_left_text (NautilusFile void nautilus_file_invalidate_attributes_internal (NautilusFile *file, GList *file_attributes); GList * nautilus_file_get_all_attributes (void); + +gboolean nautilus_file_is_self_owned (NautilusFile *file); diff --git a/libnautilus-extensions/nautilus-file.c b/libnautilus-extensions/nautilus-file.c index 40db9376b..af90aa02a 100644 --- a/libnautilus-extensions/nautilus-file.c +++ b/libnautilus-extensions/nautilus-file.c @@ -396,8 +396,8 @@ nautilus_file_get (const char *uri) return nautilus_file_get_internal (uri, TRUE); } -static gboolean -is_self_owned (NautilusFile *file) +gboolean +nautilus_file_is_self_owned (NautilusFile *file) { return file->details->directory->details->as_file == file; } @@ -418,7 +418,7 @@ destroy (GtkObject *object) directory = file->details->directory; - if (is_self_owned (file)) { + if (nautilus_file_is_self_owned (file)) { directory->details->as_file = NULL; } else { if (!file->details->is_gone) { @@ -519,7 +519,7 @@ nautilus_file_get_parent_uri (NautilusFile *file) { g_assert (NAUTILUS_IS_FILE (file)); - if (is_self_owned (file)) { + if (nautilus_file_is_self_owned (file)) { /* Callers expect an empty string, not a NULL. */ return g_strdup (""); } @@ -535,7 +535,7 @@ get_file_for_parent_directory (NautilusFile *file) g_assert (NAUTILUS_IS_FILE (file)); - if (is_self_owned (file)) { + if (nautilus_file_is_self_owned (file)) { return NULL; } @@ -727,7 +727,7 @@ nautilus_file_can_rename (NautilusFile *file) } /* Self-owned files can't be renamed */ - if (is_self_owned (file)) { + if (nautilus_file_is_self_owned (file)) { return FALSE; } @@ -791,7 +791,7 @@ nautilus_file_get_gnome_vfs_uri (NautilusFile *file) return NULL; } - if (is_self_owned (file)) { + if (nautilus_file_is_self_owned (file)) { gnome_vfs_uri_ref (vfs_uri); return vfs_uri; } @@ -901,7 +901,7 @@ rename_callback (GnomeVFSAsyncHandle *handle, * hard-code name "." so there's no need to rename * their metadata when they are renamed. */ - if (!is_self_owned (op->file)) { + if (!nautilus_file_is_self_owned (op->file)) { nautilus_directory_rename_file_metadata (directory, old_relative_uri, op->file->details->relative_uri); } @@ -973,7 +973,7 @@ nautilus_file_rename (NautilusFile *file, /* Self-owned files can't be renamed. Test the name-not-actually-changing * case before this case. */ - if (is_self_owned (file)) { + if (nautilus_file_is_self_owned (file)) { /* Claim that something changed even if the rename * failed. This makes it easier for some clients who * see the "reverting" to the old name as "changing @@ -1217,7 +1217,7 @@ nautilus_file_set_directory (NautilusFile *file, g_return_if_fail (NAUTILUS_IS_FILE (file)); g_return_if_fail (NAUTILUS_IS_DIRECTORY (file->details->directory)); g_return_if_fail (!file->details->is_gone); - g_return_if_fail (!is_self_owned (file)); + g_return_if_fail (!nautilus_file_is_self_owned (file)); g_return_if_fail (NAUTILUS_IS_DIRECTORY (new_directory)); old_directory = file->details->directory; @@ -1851,7 +1851,7 @@ nautilus_file_list_filter_hidden_and_backup (GList *files, static const char * get_metadata_name (NautilusFile *file) { - if (is_self_owned (file)) { + if (nautilus_file_is_self_owned (file)) { return FILE_NAME_FOR_DIRECTORY_METADATA; } return file->details->relative_uri; @@ -1907,13 +1907,12 @@ nautilus_file_set_metadata (NautilusFile *file, g_return_if_fail (key != NULL); g_return_if_fail (key[0] != '\0'); - if (nautilus_directory_set_file_metadata (file->details->directory, - get_metadata_name (file), - key, - default_metadata, - metadata)) { - nautilus_file_changed (file); - } + nautilus_directory_set_file_metadata + (file->details->directory, + get_metadata_name (file), + key, + default_metadata, + metadata); } void @@ -1928,13 +1927,12 @@ nautilus_file_set_metadata_list (NautilusFile *file, g_return_if_fail (list_subkey != NULL); g_return_if_fail (list_subkey[0] != '\0'); - if (nautilus_directory_set_file_metadata_list (file->details->directory, - get_metadata_name (file), - list_key, - list_subkey, - list)) { - nautilus_file_changed (file); - } + nautilus_directory_set_file_metadata_list + (file->details->directory, + get_metadata_name (file), + list_key, + list_subkey, + list); } @@ -1987,13 +1985,12 @@ nautilus_file_set_boolean_metadata (NautilusFile *file, g_return_if_fail (key != NULL); g_return_if_fail (key[0] != '\0'); - if (nautilus_directory_set_boolean_file_metadata (file->details->directory, - get_metadata_name (file), - key, - default_metadata, - metadata)) { - nautilus_file_changed (file); - } + nautilus_directory_set_boolean_file_metadata + (file->details->directory, + get_metadata_name (file), + key, + default_metadata, + metadata); } void @@ -2006,13 +2003,12 @@ nautilus_file_set_integer_metadata (NautilusFile *file, g_return_if_fail (key != NULL); g_return_if_fail (key[0] != '\0'); - if (nautilus_directory_set_integer_file_metadata (file->details->directory, - get_metadata_name (file), - key, - default_metadata, - metadata)) { - nautilus_file_changed (file); - } + nautilus_directory_set_integer_file_metadata + (file->details->directory, + get_metadata_name (file), + key, + default_metadata, + metadata); } @@ -2091,7 +2087,7 @@ nautilus_file_get_uri (NautilusFile *file) g_return_val_if_fail (NAUTILUS_IS_FILE (file), NULL); - if (is_self_owned (file)) { + if (nautilus_file_is_self_owned (file)) { return g_strdup (file->details->directory->details->uri); } @@ -4165,7 +4161,7 @@ nautilus_file_mark_gone (NautilusFile *file) /* Let the directory know it's gone. */ directory = file->details->directory; - if (!is_self_owned (file)) { + if (!nautilus_file_is_self_owned (file)) { nautilus_directory_remove_file (directory, file); } @@ -4196,7 +4192,7 @@ nautilus_file_changed (NautilusFile *file) g_return_if_fail (NAUTILUS_IS_FILE (file)); - if (is_self_owned (file)) { + if (nautilus_file_is_self_owned (file)) { nautilus_file_emit_changed (file); } else { fake_list.data = file; diff --git a/libnautilus-extensions/nautilus-metafile-server.idl b/libnautilus-extensions/nautilus-metafile-server.idl index 61f590df2..7fdd262e5 100644 --- a/libnautilus-extensions/nautilus-metafile-server.idl +++ b/libnautilus-extensions/nautilus-metafile-server.idl @@ -28,11 +28,13 @@ module Nautilus { + typedef sequence<string> FileNameList; + /* NautilusFiles creates (and registers) MetafileMonitors in order * to get notified of metafile changes. */ interface MetafileMonitor : ::Bonobo::Unknown { - void metafile_changed (); + void metafile_changed (in FileNameList file_names); }; typedef sequence<string> MetadataList; @@ -45,8 +47,10 @@ module Nautilus { */ interface Metafile : ::Bonobo::Unknown { - /* getters for a file's metadata - */ + /* returns whether the metadata has been read in yet */ + boolean is_read (); + + /* getters for a file's metadata */ string get (in string file_name, in string key, in string default_value); @@ -54,19 +58,17 @@ module Nautilus { in string list_key, in string list_subkey); - /* setters for a file's metadata - */ - boolean set (in string file_name, - in string key, - in string default_value, - in string metadata); - boolean set_list (in string file_name, - in string list_key, - in string list_subkey, - in MetadataList list); + /* setters for a file's metadata */ + void set (in string file_name, + in string key, + in string default_value, + in string metadata); + void set_list (in string file_name, + in string list_key, + in string list_subkey, + in MetadataList list); - /* calls to keep metadata in sync with file operations - */ + /* calls to keep metadata in sync with file operations */ void copy (in string source_file_name, in URI destination_directory_uri, in string destination_file_name); @@ -74,14 +76,12 @@ module Nautilus { void rename (in string old_file_name, in string new_file_name); - /* calls for registering a MetafileMonitor with a Metafile - */ + /* calls for registering a MetafileMonitor with a Metafile */ void register_monitor (in MetafileMonitor monitor); void unregister_monitor (in MetafileMonitor monitor); }; - /* Components use the MetafileFactory to get a Metafile for a directory. - */ + /* Components use the MetafileFactory to get a Metafile for a directory. */ interface MetafileFactory : ::Bonobo::Unknown { Metafile open (in URI directory); }; diff --git a/libnautilus-extensions/nautilus-metafile.c b/libnautilus-extensions/nautilus-metafile.c index de0216355..dfd0fabd9 100644 --- a/libnautilus-extensions/nautilus-metafile.c +++ b/libnautilus-extensions/nautilus-metafile.c @@ -49,6 +49,9 @@ static void nautilus_metafile_initialize_class (NautilusMetafileClass *klass); static void destroy (GtkObject *metafile); +static CORBA_boolean corba_is_read (PortableServer_Servant servant, + CORBA_Environment *ev); + static CORBA_char *corba_get (PortableServer_Servant servant, const CORBA_char *file_name, const CORBA_char *key, @@ -60,18 +63,18 @@ static Nautilus_MetadataList *corba_get_list (PortableServer_Servant servant, const CORBA_char *list_subkey, CORBA_Environment *ev); -static CORBA_boolean corba_set (PortableServer_Servant servant, - const CORBA_char *file_name, - const CORBA_char *key, - const CORBA_char *default_value, - const CORBA_char *metadata, - CORBA_Environment *ev); -static CORBA_boolean corba_set_list (PortableServer_Servant servant, - const CORBA_char *file_name, - const CORBA_char *list_key, - const CORBA_char *list_subkey, - const Nautilus_MetadataList *list, - CORBA_Environment *ev); +static void corba_set (PortableServer_Servant servant, + const CORBA_char *file_name, + const CORBA_char *key, + const CORBA_char *default_value, + const CORBA_char *metadata, + CORBA_Environment *ev); +static void corba_set_list (PortableServer_Servant servant, + const CORBA_char *file_name, + const CORBA_char *list_key, + const CORBA_char *list_subkey, + const Nautilus_MetadataList *list, + CORBA_Environment *ev); static void corba_copy (PortableServer_Servant servant, const CORBA_char *source_file_name, @@ -122,6 +125,9 @@ static void copy_file_metadata (NautilusDirectory *source_directory, static void remove_file_metadata (NautilusDirectory *directory, const char *file_name); +static void call_metatfile_changed_for_one_file (NautilusDirectory *directory, + const CORBA_char *file_name); + NAUTILUS_DEFINE_CLASS_BOILERPLATE (NautilusMetafile, nautilus_metafile, BONOBO_OBJECT_TYPE) static void @@ -135,6 +141,7 @@ nautilus_metafile_get_epv (void) { static POA_Nautilus_Metafile__epv epv; + epv.is_read = corba_is_read; epv.get = corba_get; epv.get_list = corba_get_list; epv.set = corba_set; @@ -196,7 +203,7 @@ destroy (GtkObject *object) NautilusDirectory *directory; metafile = NAUTILUS_METAFILE (object); - directory = NAUTILUS_DIRECTORY (metafile->details->directory); + directory = metafile->details->directory; nautilus_directory_unref (directory); g_free (metafile->details); @@ -213,6 +220,19 @@ nautilus_metafile_new (const char *directory_uri) return metafile; } +static CORBA_boolean +corba_is_read (PortableServer_Servant servant, + CORBA_Environment *ev) +{ + NautilusMetafile *metafile; + NautilusDirectory *directory; + + metafile = NAUTILUS_METAFILE (bonobo_object_from_servant (servant)); + directory = metafile->details->directory; + + return directory->details->metafile_read ? CORBA_TRUE : CORBA_FALSE; +} + static CORBA_char * corba_get (PortableServer_Servant servant, const CORBA_char *file_name, @@ -227,7 +247,7 @@ corba_get (PortableServer_Servant servant, CORBA_char *result; metafile = NAUTILUS_METAFILE (bonobo_object_from_servant (servant)); - directory = NAUTILUS_DIRECTORY (metafile->details->directory); + directory = metafile->details->directory; metadata = get_file_metadata (directory, file_name, key, default_value); @@ -255,7 +275,7 @@ corba_get_list (PortableServer_Servant servant, GList *list_ptr; metafile = NAUTILUS_METAFILE (bonobo_object_from_servant (servant)); - directory = NAUTILUS_DIRECTORY (metafile->details->directory); + directory = metafile->details->directory; metadata_list = get_file_metadata_list (directory, file_name, list_key, list_subkey); @@ -283,7 +303,7 @@ corba_get_list (PortableServer_Servant servant, return result; } -static CORBA_boolean +static void corba_set (PortableServer_Servant servant, const CORBA_char *file_name, const CORBA_char *key, @@ -294,8 +314,6 @@ corba_set (PortableServer_Servant servant, NautilusMetafile *metafile; NautilusDirectory *directory; - CORBA_boolean result; - if (nautilus_str_is_empty (default_value)) { default_value = NULL; } @@ -304,14 +322,14 @@ corba_set (PortableServer_Servant servant, } metafile = NAUTILUS_METAFILE (bonobo_object_from_servant (servant)); - directory = NAUTILUS_DIRECTORY (metafile->details->directory); + directory = metafile->details->directory; - result = set_file_metadata (directory, file_name, key, default_value, metadata); - - return result; + if (set_file_metadata (directory, file_name, key, default_value, metadata)) { + call_metatfile_changed_for_one_file (directory, file_name); + } } -static CORBA_boolean +static void corba_set_list (PortableServer_Servant servant, const CORBA_char *file_name, const CORBA_char *list_key, @@ -323,11 +341,10 @@ corba_set_list (PortableServer_Servant servant, NautilusDirectory *directory; GList *metadata_list; - CORBA_boolean result; CORBA_unsigned_long buf_pos; metafile = NAUTILUS_METAFILE (bonobo_object_from_servant (servant)); - directory = NAUTILUS_DIRECTORY (metafile->details->directory); + directory = metafile->details->directory; metadata_list = NULL; for (buf_pos = 0; buf_pos < list->_length; ++buf_pos) { @@ -335,11 +352,11 @@ corba_set_list (PortableServer_Servant servant, } metadata_list = g_list_reverse (metadata_list); - result = set_file_metadata_list (directory, file_name, list_key, list_subkey, metadata_list); - + if (set_file_metadata_list (directory, file_name, list_key, list_subkey, metadata_list)) { + call_metatfile_changed_for_one_file (directory, file_name); + } + g_list_free (metadata_list); - - return result; } static void @@ -354,7 +371,7 @@ corba_copy (PortableServer_Servant servant, NautilusDirectory *destination_directory; source_metafile = NAUTILUS_METAFILE (bonobo_object_from_servant (servant)); - source_directory = NAUTILUS_DIRECTORY (source_metafile->details->directory); + source_directory = source_metafile->details->directory; destination_directory = nautilus_directory_get (destination_directory_uri); @@ -373,7 +390,7 @@ corba_remove (PortableServer_Servant servant, NautilusDirectory *directory; metafile = NAUTILUS_METAFILE (bonobo_object_from_servant (servant)); - directory = NAUTILUS_DIRECTORY (metafile->details->directory); + directory = metafile->details->directory; remove_file_metadata (directory, file_name); } @@ -388,7 +405,7 @@ corba_rename (PortableServer_Servant servant, NautilusDirectory *directory; metafile = NAUTILUS_METAFILE (bonobo_object_from_servant (servant)); - directory = NAUTILUS_DIRECTORY (metafile->details->directory); + directory = metafile->details->directory; rename_file_metadata (directory, old_file_name, new_file_name); } @@ -441,15 +458,26 @@ remove_directory_monitor_list_entry (NautilusDirectory *directory) } static GList * -find_monitor_link (GList *monitor_list, const Nautilus_MetafileMonitor monitor, CORBA_Environment *ev) +find_monitor_node (GList *monitors, const Nautilus_MetafileMonitor monitor) { - while (monitor_list != NULL) { - if (CORBA_Object_is_equivalent (monitor_list->data, monitor, ev)) { + GList *node; + CORBA_Environment ev; + Nautilus_MetafileMonitor cur_monitor; + + CORBA_exception_init (&ev); + + for (node = monitors; node != NULL; node = node->next) { + cur_monitor = node->data; + if (CORBA_Object_is_equivalent (cur_monitor, monitor, &ev)) { break; } - monitor_list = g_list_next (monitor_list); } - return monitor_list; + + /* FIXME bugzilla.eazel.com 6664: examine ev for errors */ + + CORBA_exception_free (&ev); + + return node; } static void @@ -462,13 +490,17 @@ corba_register_monitor (PortableServer_Servant servant, DirectoryMonitorListEntry *monitor_list; metafile = NAUTILUS_METAFILE (bonobo_object_from_servant (servant)); - directory = NAUTILUS_DIRECTORY (metafile->details->directory); + directory = metafile->details->directory; monitor_list = get_or_add_directory_monitor_list_entry (directory); - g_return_if_fail (find_monitor_link (monitor_list->monitors, monitor, ev) == NULL); + g_return_if_fail (find_monitor_node (monitor_list->monitors, monitor) == NULL); monitor_list->monitors = g_list_prepend (monitor_list->monitors, (gpointer) CORBA_Object_duplicate (monitor, ev)); + + /* cause metafile to be read */ + directory->details->load_metafile_for_server = TRUE; + nautilus_directory_async_state_changed (directory); } static void @@ -478,30 +510,104 @@ corba_unregister_monitor (PortableServer_Servant servant, { NautilusMetafile *metafile; NautilusDirectory *directory; - DirectoryMonitorListEntry *monitor_list; - GList *monitor_link; + DirectoryMonitorListEntry *entry; + GList *node; metafile = NAUTILUS_METAFILE (bonobo_object_from_servant (servant)); - directory = NAUTILUS_DIRECTORY (metafile->details->directory); + directory = metafile->details->directory; - monitor_list = g_hash_table_lookup (directory_monitor_lists, directory); + entry = g_hash_table_lookup (directory_monitor_lists, directory); - g_return_if_fail (monitor_list != NULL); + g_return_if_fail (entry != NULL); - monitor_link = find_monitor_link (monitor_list->monitors, monitor, ev); + node = find_monitor_node (entry->monitors, monitor); - g_return_if_fail (monitor_link != NULL); + g_return_if_fail (node != NULL); - monitor_list->monitors = g_list_remove_link (monitor_list->monitors, monitor_link); + entry->monitors = g_list_remove_link (entry->monitors, node); - CORBA_Object_release (monitor_link->data, ev); - g_list_free_1 (monitor_link); + CORBA_Object_release (node->data, ev); + g_list_free_1 (node); - if (monitor_list->monitors == NULL) { + if (entry->monitors == NULL) { remove_directory_monitor_list_entry (directory); } } +static void +call_metatfile_changed (NautilusDirectory *directory, + const Nautilus_FileNameList *file_names) +{ + GList *node; + CORBA_Environment ev; + Nautilus_MetafileMonitor monitor; + DirectoryMonitorListEntry *entry; + + entry = g_hash_table_lookup (directory_monitor_lists, directory); + + if (entry != NULL) { + CORBA_exception_init (&ev); + + for (node = entry->monitors; node != NULL; node = node->next) { + monitor = node->data; + Nautilus_MetafileMonitor_metafile_changed (monitor, file_names, &ev); + /* FIXME bugzilla.eazel.com 6664: examine ev for errors */ + } + + CORBA_exception_free (&ev); + } +} + +static void +file_list_filler_ghfunc (gpointer key, + gpointer value, + gpointer user_data) +{ + Nautilus_FileNameList *file_names; + + file_names = user_data; + + file_names->_buffer [file_names->_length] = key; + + ++file_names->_length; +} + +void +call_metafile_changed_for_all_files_mentioned_in_metafile (NautilusDirectory *directory) +{ + CORBA_unsigned_long len; + Nautilus_FileNameList file_names; + + len = g_hash_table_size (directory->details->metafile_node_hash); + + if (len > 0) { + file_names._maximum = len; + file_names._length = 0; + file_names._buffer = g_new (CORBA_char *, len); + + g_hash_table_foreach (directory->details->metafile_node_hash, + file_list_filler_ghfunc, + &file_names); + + call_metatfile_changed (directory, &file_names); + + g_free (file_names._buffer); + } +} + +static void +call_metatfile_changed_for_one_file (NautilusDirectory *directory, + const CORBA_char *file_name) +{ + Nautilus_FileNameList file_names; + + file_names._maximum = 1; + file_names._length = 1; + file_names._buffer = (CORBA_char **) &file_name; + + call_metatfile_changed (directory, &file_names); +} + typedef struct { gboolean is_list; union { diff --git a/libnautilus-extensions/nautilus-metafile.h b/libnautilus-extensions/nautilus-metafile.h index 7b0c3804f..dae0a780c 100644 --- a/libnautilus-extensions/nautilus-metafile.h +++ b/libnautilus-extensions/nautilus-metafile.h @@ -49,7 +49,8 @@ GtkType nautilus_metafile_get_type (void); NautilusMetafile *nautilus_metafile_new (const char *directory_uri); - +void call_metafile_changed_for_all_files_mentioned_in_metafile (NautilusDirectory *directory); + void nautilus_metafile_apply_pending_changes (NautilusDirectory *directory); void nautilus_metafile_destroy (NautilusDirectory *directory); diff --git a/libnautilus-extensions/nautilus-stock-dialogs.c b/libnautilus-extensions/nautilus-stock-dialogs.c index 75f6da735..b5b863764 100644 --- a/libnautilus-extensions/nautilus-stock-dialogs.c +++ b/libnautilus-extensions/nautilus-stock-dialogs.c @@ -207,13 +207,14 @@ timed_wait_callback (gpointer callback_data) { TimedWait *wait; GnomeDialog *dialog; + const char *button; wait = callback_data; /* Put up the timed wait window. */ - dialog = GNOME_DIALOG (gnome_dialog_new (wait->window_title, - wait->cancel_callback != NULL ? GNOME_STOCK_BUTTON_CANCEL : NULL, - NULL)); + button = wait->cancel_callback != NULL ? GNOME_STOCK_BUTTON_CANCEL : GNOME_STOCK_BUTTON_OK; + dialog = GNOME_DIALOG (gnome_dialog_new (wait->window_title, button, NULL)); + /* The contents are often very small, causing tiny little * dialogs with their titles clipped if you just let gtk * sizing do its thing. This enforces a minimum width to diff --git a/libnautilus-extensions/nautilus-trash-directory.c b/libnautilus-extensions/nautilus-trash-directory.c index fb16c695c..969228b79 100644 --- a/libnautilus-extensions/nautilus-trash-directory.c +++ b/libnautilus-extensions/nautilus-trash-directory.c @@ -71,7 +71,7 @@ find_directory_start (void) NULL, add_volume, _("Searching Disks"), - _("Nautilus is searching for trash folders."), + _("Nautilus is searching your disks for trash folders."), NULL); } diff --git a/libnautilus-private/Makefile.am b/libnautilus-private/Makefile.am index 9f00f352d..c19415d5d 100644 --- a/libnautilus-private/Makefile.am +++ b/libnautilus-private/Makefile.am @@ -122,8 +122,9 @@ libnautilus_extensions_la_SOURCES = \ nautilus-list.c \ nautilus-medusa-support.c \ nautilus-merged-directory.c \ - nautilus-metafile-factory.c \ nautilus-metafile.c \ + nautilus-metafile-factory.c \ + nautilus-directory-metafile-monitor.c \ nautilus-mime-actions.c \ nautilus-password-dialog.c \ nautilus-preferences-box.c \ @@ -241,8 +242,9 @@ noinst_HEADERS = \ nautilus-medusa-support.h \ nautilus-merged-directory.h \ nautilus-metadata.h \ - nautilus-metafile-factory.h \ nautilus-metafile.h \ + nautilus-metafile-factory.h \ + nautilus-directory-metafile-monitor.h \ nautilus-mime-actions.h \ nautilus-password-dialog.h \ nautilus-preferences-box.h \ diff --git a/libnautilus-private/nautilus-directory-async.c b/libnautilus-private/nautilus-directory-async.c index 010e383c1..dc3013787 100644 --- a/libnautilus-private/nautilus-directory-async.c +++ b/libnautilus-private/nautilus-directory-async.c @@ -25,6 +25,7 @@ #include <config.h> #include "nautilus-metafile.h" +#include "nautilus-directory-metafile.h" #include "nautilus-directory-notify.h" #include "nautilus-directory-private.h" #include "nautilus-file-attributes.h" @@ -457,7 +458,7 @@ metafile_read_mark_done (NautilusDirectory *directory) nautilus_metafile_apply_pending_changes (directory); /* Tell change-watchers that we have update information. */ - nautilus_directory_emit_metadata_changed (directory); + call_metafile_changed_for_all_files_mentioned_in_metafile (directory); /* Let the callers that were waiting for the metafile know. */ nautilus_directory_async_state_changed (directory); @@ -704,7 +705,7 @@ metafile_read_start (NautilusDirectory *directory) g_assert (directory->details->metafile == NULL); - if (!is_anyone_waiting_for_metafile (directory)) { + if (!directory->details->load_metafile_for_server) { return; } @@ -1121,7 +1122,14 @@ nautilus_directory_monitor_add_internal (NautilusDirectory *directory, nautilus_file_list_free (file_list); } } - + + /* We could just call update_metadata_monitors here, but we can be smarter + * since we know what monitor was just added. + */ + if (monitor->request.metafile && directory->details->metafile_monitor == NULL) { + nautilus_directory_register_metadata_monitor (directory); + } + /* Kick off I/O. */ nautilus_directory_async_state_changed (directory); } @@ -1482,6 +1490,24 @@ directory_load_callback (GnomeVFSAsyncHandle *handle, } } +static void +update_metadata_monitors (NautilusDirectory *directory) +{ + gboolean is_metadata_monitored; + + is_metadata_monitored = is_anyone_waiting_for_metafile (directory); + + if (directory->details->metafile_monitor == NULL) { + if (is_metadata_monitored) { + nautilus_directory_register_metadata_monitor (directory); + } + } else { + if (!is_metadata_monitored) { + nautilus_directory_unregister_metadata_monitor (directory); + } + } +} + void nautilus_directory_monitor_remove_internal (NautilusDirectory *directory, NautilusFile *file, @@ -1493,6 +1519,8 @@ nautilus_directory_monitor_remove_internal (NautilusDirectory *directory, remove_monitor (directory, file, client); + update_metadata_monitors (directory); + nautilus_directory_async_state_changed (directory); } @@ -1604,6 +1632,14 @@ nautilus_directory_call_when_ready_internal (NautilusDirectory *directory, (directory->details->call_when_ready_list, g_memdup (&callback, sizeof (callback))); + /* When we change the ready list we need to sync up metadata monitors. + * We could just call update_metadata_monitors here, but we can be smarter + * since we know what was just added. + */ + if (callback.request.metafile && directory->details->metafile_monitor == NULL) { + nautilus_directory_register_metadata_monitor (directory); + } + nautilus_directory_async_state_changed (directory); } @@ -1671,6 +1707,9 @@ nautilus_directory_cancel_callback_internal (NautilusDirectory *directory, ready_callback_key_compare); if (node != NULL) { remove_callback_link (directory, node); + /* When we change the ready list we need to sync up metadata monitors. */ + update_metadata_monitors (directory); + nautilus_directory_async_state_changed (directory); } } @@ -1799,6 +1838,11 @@ nautilus_async_destroying_file (NautilusFile *file) } } + /* When we change the monitor or ready list we need to sync up metadata monitors */ + if (changed) { + update_metadata_monitors (directory); + } + /* Check if it's a file that's currently being worked on. * If so, make that NULL so it gets canceled right away. */ @@ -1954,7 +1998,7 @@ request_is_satisfied (NautilusDirectory *directory, NautilusFile *file, Request *request) { - if (request->metafile && !directory->details->metafile_read) { + if (request->metafile && !nautilus_directory_is_metadata_read (directory)) { return FALSE; } @@ -2023,6 +2067,10 @@ call_ready_callbacks (NautilusDirectory *directory) } } if (node == NULL) { + if (called_any) { + /* When we change the ready list we need to sync up metadata monitors. */ + update_metadata_monitors (directory); + } return called_any; } diff --git a/libnautilus-private/nautilus-directory-metafile-monitor.c b/libnautilus-private/nautilus-directory-metafile-monitor.c new file mode 100644 index 000000000..b7fecd6df --- /dev/null +++ b/libnautilus-private/nautilus-directory-metafile-monitor.c @@ -0,0 +1,159 @@ +/* -*- Mode: IDL; tab-width: 8; indent-tabs-mode: 8; c-basic-offset: 8 -*- */ + +/* nautilus-directory-metafile-monitor.c + * + * Copyright (C) 2001 Eazel, Inc. + * + * This 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. + * + * This 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 this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include <config.h> +#include "nautilus-directory-metafile-monitor.h" +#include "nautilus-metafile-server.h" + +#include "nautilus-directory-private.h" +#include "nautilus-file-private.h" + +#include <libnautilus-extensions/nautilus-gtk-macros.h> +#include <libnautilus-extensions/nautilus-glib-extensions.h> +#include <libnautilus/nautilus-bonobo-workarounds.h> + +struct NautilusMetafileMonitorDetails { + NautilusDirectory *directory; +}; + +static void nautilus_metafile_monitor_initialize (NautilusMetafileMonitor *monitor); +static void nautilus_metafile_monitor_initialize_class (NautilusMetafileMonitorClass *klass); + +static void destroy (GtkObject *monitor); + +static void corba_metafile_changed (PortableServer_Servant servant, + const Nautilus_FileNameList *file_names, + CORBA_Environment *ev); + +NAUTILUS_DEFINE_CLASS_BOILERPLATE (NautilusMetafileMonitor, nautilus_metafile_monitor, BONOBO_OBJECT_TYPE) + +static void +nautilus_metafile_monitor_initialize_class (NautilusMetafileMonitorClass *klass) +{ + GTK_OBJECT_CLASS (klass)->destroy = destroy; +} + +static POA_Nautilus_MetafileMonitor__epv * +nautilus_metafile_monitor_get_epv (void) +{ + static POA_Nautilus_MetafileMonitor__epv epv; + + epv.metafile_changed = corba_metafile_changed; + + return &epv; +} + +static POA_Nautilus_MetafileMonitor__vepv * +nautilus_metafile_monitor_get_vepv (void) +{ + static POA_Nautilus_MetafileMonitor__vepv vepv; + + vepv.Bonobo_Unknown_epv = nautilus_bonobo_object_get_epv (); + vepv.Nautilus_MetafileMonitor_epv = nautilus_metafile_monitor_get_epv (); + + return &vepv; +} + +static POA_Nautilus_MetafileMonitor * +nautilus_metafile_monitor_create_servant (void) +{ + POA_Nautilus_MetafileMonitor *servant; + CORBA_Environment ev; + + servant = (POA_Nautilus_MetafileMonitor *) g_new0 (BonoboObjectServant, 1); + servant->vepv = nautilus_metafile_monitor_get_vepv (); + CORBA_exception_init (&ev); + POA_Nautilus_MetafileMonitor__init ((PortableServer_Servant) servant, &ev); + if (ev._major != CORBA_NO_EXCEPTION){ + g_error ("can't initialize Nautilus metafile monitor"); + } + CORBA_exception_free (&ev); + + return servant; +} + +static void +nautilus_metafile_monitor_initialize (NautilusMetafileMonitor *monitor) +{ + Nautilus_MetafileMonitor corba_monitor; + + monitor->details = g_new0 (NautilusMetafileMonitorDetails, 1); + + corba_monitor = bonobo_object_activate_servant + (BONOBO_OBJECT (monitor), nautilus_metafile_monitor_create_servant ()); + bonobo_object_construct (BONOBO_OBJECT (monitor), corba_monitor); +} + +static void +destroy (GtkObject *object) +{ + NautilusMetafileMonitor *monitor; + + monitor = NAUTILUS_METAFILE_MONITOR (object); + g_free (monitor->details); + + NAUTILUS_CALL_PARENT_CLASS (GTK_OBJECT_CLASS, destroy, (object)); +} + +NautilusMetafileMonitor * +nautilus_metafile_monitor_new (NautilusDirectory *directory) +{ + NautilusMetafileMonitor *monitor; + monitor = NAUTILUS_METAFILE_MONITOR (gtk_object_new (NAUTILUS_TYPE_METAFILE_MONITOR, NULL)); + monitor->details->directory = directory; + /* The monitor is owned by the directory, so we don't ref the directory. */ + return monitor; +} + +static void +corba_metafile_changed (PortableServer_Servant servant, + const Nautilus_FileNameList *file_names, + CORBA_Environment *ev) +{ + GList *file_list; + NautilusFile *file; + CORBA_unsigned_long buf_pos; + NautilusMetafileMonitor *monitor; + + monitor = NAUTILUS_METAFILE_MONITOR (bonobo_object_from_servant (servant)); + + file_list = NULL; + + for (buf_pos = 0; buf_pos < file_names->_length; ++buf_pos) { + file = nautilus_directory_find_file_by_relative_uri + (monitor->details->directory, file_names->_buffer [buf_pos]); + + if (file != NULL) { + if (nautilus_file_is_self_owned (file)) { + nautilus_file_emit_changed (file); + } else { + file_list = g_list_prepend (file_list, file); + } + } + } + + if (file_list != NULL) { + file_list = g_list_reverse (file_list); + nautilus_directory_emit_change_signals (monitor->details->directory, file_list); + g_list_free (file_list); + } +} diff --git a/libnautilus-private/nautilus-directory-metafile-monitor.h b/libnautilus-private/nautilus-directory-metafile-monitor.h new file mode 100644 index 000000000..cb464fa63 --- /dev/null +++ b/libnautilus-private/nautilus-directory-metafile-monitor.h @@ -0,0 +1,51 @@ +/* -*- Mode: IDL; tab-width: 8; indent-tabs-mode: 8; c-basic-offset: 8 -*- */ + +/* nautilus-directory-metafile-monitor.h + * + * Copyright (C) 2001 Eazel, Inc. + * + * This 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. + * + * This 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 this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef NAUTILUS_METAFILE_MONITOR_H +#define NAUTILUS_METAFILE_MONITOR_H + +#include <bonobo/bonobo-object.h> +#include <libnautilus-extensions/nautilus-directory.h> + +#define NAUTILUS_TYPE_METAFILE_MONITOR (nautilus_metafile_monitor_get_type ()) +#define NAUTILUS_METAFILE_MONITOR(obj) (GTK_CHECK_CAST ((obj), NAUTILUS_TYPE_METAFILE_MONITOR, NautilusMetafileMonitor)) +#define NAUTILUS_METAFILE_MONITOR_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), NAUTILUS_TYPE_METAFILE_MONITOR, NautilusMetafileMonitorClass)) +#define NAUTILUS_IS_METAFILE_MONITOR(obj) (GTK_CHECK_TYPE ((obj), NAUTILUS_TYPE_METAFILE_MONITOR)) +#define NAUTILUS_IS_METAFILE_MONITOR_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), NAUTILUS_TYPE_METAFILE_MONITOR)) + +typedef struct NautilusMetafileMonitorDetails NautilusMetafileMonitorDetails; + +typedef struct { + BonoboObject parent_slot; + NautilusMetafileMonitorDetails *details; +} NautilusMetafileMonitor; + +typedef struct { + BonoboObjectClass parent_slot; +} NautilusMetafileMonitorClass; + +GtkType nautilus_metafile_monitor_get_type (void); + + +NautilusMetafileMonitor *nautilus_metafile_monitor_new (NautilusDirectory *directory); + +#endif /* NAUTILUS_METAFILE_MONITOR_H */ diff --git a/libnautilus-private/nautilus-directory-metafile.c b/libnautilus-private/nautilus-directory-metafile.c index 6dbd9c971..ec01c2d42 100644 --- a/libnautilus-private/nautilus-directory-metafile.c +++ b/libnautilus-private/nautilus-directory-metafile.c @@ -25,8 +25,10 @@ #include <config.h> #include "nautilus-directory-metafile.h" +#include "nautilus-directory-private.h" #include <libnautilus-extensions/nautilus-metafile-factory.h> +#include <libnautilus-extensions/nautilus-directory-metafile-monitor.h> #include <libnautilus-extensions/nautilus-metafile-server.h> #include <libnautilus-extensions/nautilus-string.h> #include <liboaf/liboaf.h> @@ -69,18 +71,48 @@ get_factory (void) } static Nautilus_Metafile -get_metafile (NautilusDirectory *directory, CORBA_Environment *ev) +get_metafile (NautilusDirectory *directory) { char *uri; + CORBA_Environment ev; Nautilus_Metafile metafile; uri = nautilus_directory_get_uri (directory); - metafile = Nautilus_MetafileFactory_open (get_factory (), uri, ev); - g_free (uri); + CORBA_exception_init (&ev); + + metafile = Nautilus_MetafileFactory_open (get_factory (), uri, &ev); + + /* FIXME bugzilla.eazel.com 6664: examine ev for errors */ + CORBA_exception_free (&ev); + + g_free (uri); + return metafile; } +gboolean +nautilus_directory_is_metadata_read (NautilusDirectory *directory) +{ + CORBA_Environment ev; + Nautilus_Metafile metafile; + + gboolean result; + + g_return_val_if_fail (NAUTILUS_IS_DIRECTORY (directory), FALSE); + + metafile = get_metafile (directory); + CORBA_exception_init (&ev); + + result = Nautilus_Metafile_is_read (metafile, &ev); + + /* FIXME bugzilla.eazel.com 6664: examine ev for errors */ + CORBA_exception_free (&ev); + bonobo_object_release_unref (metafile, NULL); + + return result; +} + char * nautilus_directory_get_file_metadata (NautilusDirectory *directory, const char *file_name, @@ -101,14 +133,14 @@ nautilus_directory_get_file_metadata (NautilusDirectory *directory, /* We can't pass NULL as a CORBA_string - pass "" instead. */ non_null_default = default_metadata != NULL ? default_metadata : ""; + metafile = get_metafile (directory); CORBA_exception_init (&ev); - metafile = get_metafile (directory, &ev); - - /* FIXME bugzilla.eazel.com 6664: examine ev for errors */ corba_value = Nautilus_Metafile_get (metafile, file_name, key, non_null_default, &ev); /* FIXME bugzilla.eazel.com 6664: examine ev for errors */ + CORBA_exception_free (&ev); + bonobo_object_release_unref (metafile, NULL); if (nautilus_str_is_empty (corba_value)) { /* Even though in all other respects we treat "" as NULL, we want to @@ -120,9 +152,6 @@ nautilus_directory_get_file_metadata (NautilusDirectory *directory, } CORBA_free (corba_value); - - bonobo_object_release_unref (metafile, NULL); - CORBA_exception_free (&ev); return result; } @@ -145,14 +174,14 @@ nautilus_directory_get_file_metadata_list (NautilusDirectory *directory, g_return_val_if_fail (!nautilus_str_is_empty (list_key), NULL); g_return_val_if_fail (!nautilus_str_is_empty (list_subkey), NULL); + metafile = get_metafile (directory); CORBA_exception_init (&ev); - metafile = get_metafile (directory, &ev); - - /* FIXME bugzilla.eazel.com 6664: examine ev for errors */ corba_value = Nautilus_Metafile_get_list (metafile, file_name, list_key, list_subkey, &ev); /* FIXME bugzilla.eazel.com 6664: examine ev for errors */ + CORBA_exception_free (&ev); + bonobo_object_release_unref (metafile, NULL); result = NULL; for (buf_pos = 0; buf_pos < corba_value->_length; ++buf_pos) { @@ -160,14 +189,11 @@ nautilus_directory_get_file_metadata_list (NautilusDirectory *directory, } result = g_list_reverse (result); CORBA_free (corba_value); - - bonobo_object_release_unref (metafile, NULL); - CORBA_exception_free (&ev); return result; } -gboolean +void nautilus_directory_set_file_metadata (NautilusDirectory *directory, const char *file_name, const char *key, @@ -177,11 +203,9 @@ nautilus_directory_set_file_metadata (NautilusDirectory *directory, CORBA_Environment ev; Nautilus_Metafile metafile; - gboolean result; - - g_return_val_if_fail (NAUTILUS_IS_DIRECTORY (directory), FALSE); - g_return_val_if_fail (!nautilus_str_is_empty (file_name), FALSE); - g_return_val_if_fail (!nautilus_str_is_empty (key), FALSE); + g_return_if_fail (NAUTILUS_IS_DIRECTORY (directory)); + g_return_if_fail (!nautilus_str_is_empty (file_name)); + g_return_if_fail (!nautilus_str_is_empty (key)); /* We can't pass NULL as a CORBA_string - pass "" instead. */ @@ -192,22 +216,17 @@ nautilus_directory_set_file_metadata (NautilusDirectory *directory, metadata = ""; } + metafile = get_metafile (directory); CORBA_exception_init (&ev); - metafile = get_metafile (directory, &ev); - /* FIXME bugzilla.eazel.com 6664: examine ev for errors */ + Nautilus_Metafile_set (metafile, file_name, key, default_metadata, metadata, &ev); - result = Nautilus_Metafile_set (metafile, file_name, key, default_metadata, metadata, &ev); - /* FIXME bugzilla.eazel.com 6664: examine ev for errors */ - - bonobo_object_release_unref (metafile, NULL); CORBA_exception_free (&ev); - - return result; + bonobo_object_release_unref (metafile, NULL); } -gboolean +void nautilus_directory_set_file_metadata_list (NautilusDirectory *directory, const char *file_name, const char *list_key, @@ -216,24 +235,17 @@ nautilus_directory_set_file_metadata_list (NautilusDirectory *directory, { CORBA_Environment ev; Nautilus_Metafile metafile; - - gboolean result; Nautilus_MetadataList *corba_list; int len; int buf_pos; GList *list_ptr; - g_return_val_if_fail (NAUTILUS_IS_DIRECTORY (directory), FALSE); - g_return_val_if_fail (!nautilus_str_is_empty (file_name), FALSE); - g_return_val_if_fail (!nautilus_str_is_empty (list_key), FALSE); - g_return_val_if_fail (!nautilus_str_is_empty (list_subkey), FALSE); + g_return_if_fail (NAUTILUS_IS_DIRECTORY (directory)); + g_return_if_fail (!nautilus_str_is_empty (file_name)); + g_return_if_fail (!nautilus_str_is_empty (list_key)); + g_return_if_fail (!nautilus_str_is_empty (list_subkey)); - CORBA_exception_init (&ev); - metafile = get_metafile (directory, &ev); - - /* FIXME bugzilla.eazel.com 6664: examine ev for errors */ - len = g_list_length (list); corba_list = Nautilus_MetadataList__alloc (); @@ -254,16 +266,16 @@ nautilus_directory_set_file_metadata_list (NautilusDirectory *directory, ++buf_pos; } - result = Nautilus_Metafile_set_list (metafile, file_name, list_key, list_subkey, corba_list, &ev); - - /* FIXME bugzilla.eazel.com 6664: examine ev for errors */ + metafile = get_metafile (directory); + CORBA_exception_init (&ev); - CORBA_free (corba_list); + Nautilus_Metafile_set_list (metafile, file_name, list_key, list_subkey, corba_list, &ev); - bonobo_object_release_unref (metafile, NULL); + /* FIXME bugzilla.eazel.com 6664: examine ev for errors */ CORBA_exception_free (&ev); + bonobo_object_release_unref (metafile, NULL); - return result; + CORBA_free (corba_list); } gboolean @@ -295,14 +307,14 @@ nautilus_directory_get_boolean_file_metadata (NautilusDirectory *directory, return result; } -gboolean +void nautilus_directory_set_boolean_file_metadata (NautilusDirectory *directory, const char *file_name, const char *key, gboolean default_metadata, gboolean metadata) { - return nautilus_directory_set_file_metadata + nautilus_directory_set_file_metadata (directory, file_name, key, default_metadata ? "true" : "false", metadata ? "true" : "false"); @@ -338,7 +350,7 @@ nautilus_directory_get_integer_file_metadata (NautilusDirectory *directory, return result; } -gboolean +void nautilus_directory_set_integer_file_metadata (NautilusDirectory *directory, const char *file_name, const char *key, @@ -351,7 +363,7 @@ nautilus_directory_set_integer_file_metadata (NautilusDirectory *directory, value_as_string = g_strdup_printf ("%d", metadata); default_as_string = g_strdup_printf ("%d", default_metadata); - return nautilus_directory_set_file_metadata + nautilus_directory_set_file_metadata (directory, file_name, key, default_as_string, value_as_string); @@ -374,20 +386,18 @@ nautilus_directory_copy_file_metadata (NautilusDirectory *source_directory, g_return_if_fail (NAUTILUS_IS_DIRECTORY (destination_directory)); g_return_if_fail (destination_file_name != NULL); - CORBA_exception_init (&ev); - source_metafile = get_metafile (source_directory, &ev); - - /* FIXME bugzilla.eazel.com 6664: examine ev for errors */ - destination_uri = nautilus_directory_get_uri (destination_directory); + source_metafile = get_metafile (source_directory); + CORBA_exception_init (&ev); + Nautilus_Metafile_copy (source_metafile, source_file_name, destination_uri, destination_file_name, &ev); /* FIXME bugzilla.eazel.com 6664: examine ev for errors */ + CORBA_exception_free (&ev); + bonobo_object_release_unref (source_metafile, NULL); g_free (destination_uri); - bonobo_object_release_unref (source_metafile, NULL); - CORBA_exception_free (&ev); } void @@ -400,17 +410,14 @@ nautilus_directory_remove_file_metadata (NautilusDirectory *directory, g_return_if_fail (NAUTILUS_IS_DIRECTORY (directory)); g_return_if_fail (file_name != NULL); + metafile = get_metafile (directory); CORBA_exception_init (&ev); - metafile = get_metafile (directory, &ev); - - /* FIXME bugzilla.eazel.com 6664: examine ev for errors */ Nautilus_Metafile_remove (metafile, file_name, &ev); /* FIXME bugzilla.eazel.com 6664: examine ev for errors */ - - bonobo_object_release_unref (metafile, NULL); CORBA_exception_free (&ev); + bonobo_object_release_unref (metafile, NULL); } void @@ -425,15 +432,66 @@ nautilus_directory_rename_file_metadata (NautilusDirectory *directory, g_return_if_fail (old_file_name != NULL); g_return_if_fail (new_file_name != NULL); + metafile = get_metafile (directory); CORBA_exception_init (&ev); - metafile = get_metafile (directory, &ev); - - /* FIXME bugzilla.eazel.com 6664: examine ev for errors */ Nautilus_Metafile_rename (metafile, old_file_name, new_file_name, &ev); /* FIXME bugzilla.eazel.com 6664: examine ev for errors */ + CORBA_exception_free (&ev); + bonobo_object_release_unref (metafile, &ev); +} + +void +nautilus_directory_register_metadata_monitor (NautilusDirectory *directory) +{ + CORBA_Environment ev; + Nautilus_Metafile metafile; + + g_return_if_fail (NAUTILUS_IS_DIRECTORY (directory)); + + if (directory->details->metafile_monitor != NULL) { + /* If there's already a monitor, it's already registered. */ + return; + } + directory->details->metafile_monitor = nautilus_metafile_monitor_new (directory); + + metafile = get_metafile (directory); + CORBA_exception_init (&ev); + + Nautilus_Metafile_register_monitor + (metafile, + bonobo_object_corba_objref (BONOBO_OBJECT (directory->details->metafile_monitor)), + &ev); + + /* FIXME bugzilla.eazel.com 6664: examine ev for errors */ + CORBA_exception_free (&ev); bonobo_object_release_unref (metafile, NULL); +} + +void +nautilus_directory_unregister_metadata_monitor (NautilusDirectory *directory) +{ + CORBA_Environment ev; + Nautilus_Metafile metafile; + + g_return_if_fail (NAUTILUS_IS_DIRECTORY (directory)); + + g_return_if_fail (NAUTILUS_IS_METAFILE_MONITOR (directory->details->metafile_monitor)); + + metafile = get_metafile (directory); + CORBA_exception_init (&ev); + + Nautilus_Metafile_unregister_monitor + (metafile, + bonobo_object_corba_objref (BONOBO_OBJECT (directory->details->metafile_monitor)), + &ev); + + /* FIXME bugzilla.eazel.com 6664: examine ev for errors */ CORBA_exception_free (&ev); + bonobo_object_release_unref (metafile, NULL); + + directory->details->metafile_monitor = NULL; } + diff --git a/libnautilus-private/nautilus-directory-metafile.h b/libnautilus-private/nautilus-directory-metafile.h index 5faf3dd59..511355a9b 100644 --- a/libnautilus-private/nautilus-directory-metafile.h +++ b/libnautilus-private/nautilus-directory-metafile.h @@ -25,43 +25,45 @@ #include "nautilus-directory.h" /* Interface for file metadata. */ -char * nautilus_directory_get_file_metadata (NautilusDirectory *directory, - const char *file_name, - const char *key, - const char *default_metadata); -GList * nautilus_directory_get_file_metadata_list (NautilusDirectory *directory, - const char *file_name, - const char *list_key, - const char *list_subkey); -gboolean nautilus_directory_get_boolean_file_metadata (NautilusDirectory *directory, - const char *file_name, - const char *key, - gboolean default_metadata); -int nautilus_directory_get_integer_file_metadata (NautilusDirectory *directory, - const char *file_name, - const char *key, - int default_metadata); +gboolean nautilus_directory_is_metadata_read (NautilusDirectory *directory); -gboolean nautilus_directory_set_file_metadata (NautilusDirectory *directory, - const char *file_name, - const char *key, - const char *default_metadata, - const char *metadata); -gboolean nautilus_directory_set_file_metadata_list (NautilusDirectory *directory, - const char *file_name, - const char *list_key, - const char *list_subkey, - GList *list); -gboolean nautilus_directory_set_boolean_file_metadata (NautilusDirectory *directory, - const char *file_name, - const char *key, - gboolean default_metadata, - gboolean metadata); -gboolean nautilus_directory_set_integer_file_metadata (NautilusDirectory *directory, - const char *file_name, - const char *key, - int default_metadata, - int metadata); +char * nautilus_directory_get_file_metadata (NautilusDirectory *directory, + const char *file_name, + const char *key, + const char *default_metadata); +GList * nautilus_directory_get_file_metadata_list (NautilusDirectory *directory, + const char *file_name, + const char *list_key, + const char *list_subkey); +gboolean nautilus_directory_get_boolean_file_metadata (NautilusDirectory *directory, + const char *file_name, + const char *key, + gboolean default_metadata); +int nautilus_directory_get_integer_file_metadata (NautilusDirectory *directory, + const char *file_name, + const char *key, + int default_metadata); + +void nautilus_directory_set_file_metadata (NautilusDirectory *directory, + const char *file_name, + const char *key, + const char *default_metadata, + const char *metadata); +void nautilus_directory_set_file_metadata_list (NautilusDirectory *directory, + const char *file_name, + const char *list_key, + const char *list_subkey, + GList *list); +void nautilus_directory_set_boolean_file_metadata (NautilusDirectory *directory, + const char *file_name, + const char *key, + gboolean default_metadata, + gboolean metadata); +void nautilus_directory_set_integer_file_metadata (NautilusDirectory *directory, + const char *file_name, + const char *key, + int default_metadata, + int metadata); void nautilus_directory_copy_file_metadata (NautilusDirectory *source_directory, const char *source_file_name, @@ -73,4 +75,7 @@ void nautilus_directory_rename_file_metadata (NautilusDirectory *d const char *old_file_name, const char *new_file_name); +void nautilus_directory_register_metadata_monitor (NautilusDirectory *directory); +void nautilus_directory_unregister_metadata_monitor (NautilusDirectory *directory); + void nautilus_directory_use_self_contained_metafile_factory (void); diff --git a/libnautilus-private/nautilus-directory-private.h b/libnautilus-private/nautilus-directory-private.h index a1f117fe2..b6324f10d 100644 --- a/libnautilus-private/nautilus-directory-private.h +++ b/libnautilus-private/nautilus-directory-private.h @@ -32,6 +32,7 @@ #include "nautilus-file.h" #include "nautilus-file-utilities.h" +#include "nautilus-directory-metafile-monitor.h" typedef struct ActivationURIReadState ActivationURIReadState; typedef struct MetafileReadState MetafileReadState; @@ -68,6 +69,9 @@ struct NautilusDirectoryDetails GList *call_when_ready_list; GList *monitor_list; + NautilusMetafileMonitor *metafile_monitor; + gboolean load_metafile_for_server; + gboolean in_async_service_loop; gboolean state_changed; @@ -168,7 +172,6 @@ void nautilus_directory_cancel_loading_file_attributes (NautilusD GList *file_attributes); /* Calls shared between directory, file, and async. code. */ -void nautilus_directory_emit_metadata_changed (NautilusDirectory *directory); void nautilus_directory_emit_files_added (NautilusDirectory *directory, GList *added_files); void nautilus_directory_emit_files_changed (NautilusDirectory *directory, diff --git a/libnautilus-private/nautilus-directory.c b/libnautilus-private/nautilus-directory.c index 12bbda9ae..82d8d28db 100644 --- a/libnautilus-private/nautilus-directory.c +++ b/libnautilus-private/nautilus-directory.c @@ -175,6 +175,10 @@ nautilus_directory_destroy (GtkObject *object) nautilus_g_list_free_deep (directory->details->monitor_list); } + if (directory->details->metafile_monitor != NULL) { + nautilus_directory_unregister_metadata_monitor (directory); + } + g_hash_table_remove (directories, directory->details->uri); if (directory->details->dequeue_pending_idle_id != 0) { @@ -736,16 +740,6 @@ nautilus_directory_emit_change_signals (NautilusDirectory *directory, } void -nautilus_directory_emit_metadata_changed (NautilusDirectory *directory) -{ - /* Say that all the files have changed. - * We could optimize this to only mention files that - * have metadata, but this is a fine rough cut for now. - */ - emit_change_signals_for_all_files (directory); -} - -void nautilus_directory_emit_done_loading (NautilusDirectory *directory) { gtk_signal_emit (GTK_OBJECT (directory), diff --git a/libnautilus-private/nautilus-file-private.h b/libnautilus-private/nautilus-file-private.h index da0ce7a9c..21e79a025 100644 --- a/libnautilus-private/nautilus-file-private.h +++ b/libnautilus-private/nautilus-file-private.h @@ -134,3 +134,5 @@ gboolean nautilus_file_should_get_top_left_text (NautilusFile void nautilus_file_invalidate_attributes_internal (NautilusFile *file, GList *file_attributes); GList * nautilus_file_get_all_attributes (void); + +gboolean nautilus_file_is_self_owned (NautilusFile *file); diff --git a/libnautilus-private/nautilus-file.c b/libnautilus-private/nautilus-file.c index 40db9376b..af90aa02a 100644 --- a/libnautilus-private/nautilus-file.c +++ b/libnautilus-private/nautilus-file.c @@ -396,8 +396,8 @@ nautilus_file_get (const char *uri) return nautilus_file_get_internal (uri, TRUE); } -static gboolean -is_self_owned (NautilusFile *file) +gboolean +nautilus_file_is_self_owned (NautilusFile *file) { return file->details->directory->details->as_file == file; } @@ -418,7 +418,7 @@ destroy (GtkObject *object) directory = file->details->directory; - if (is_self_owned (file)) { + if (nautilus_file_is_self_owned (file)) { directory->details->as_file = NULL; } else { if (!file->details->is_gone) { @@ -519,7 +519,7 @@ nautilus_file_get_parent_uri (NautilusFile *file) { g_assert (NAUTILUS_IS_FILE (file)); - if (is_self_owned (file)) { + if (nautilus_file_is_self_owned (file)) { /* Callers expect an empty string, not a NULL. */ return g_strdup (""); } @@ -535,7 +535,7 @@ get_file_for_parent_directory (NautilusFile *file) g_assert (NAUTILUS_IS_FILE (file)); - if (is_self_owned (file)) { + if (nautilus_file_is_self_owned (file)) { return NULL; } @@ -727,7 +727,7 @@ nautilus_file_can_rename (NautilusFile *file) } /* Self-owned files can't be renamed */ - if (is_self_owned (file)) { + if (nautilus_file_is_self_owned (file)) { return FALSE; } @@ -791,7 +791,7 @@ nautilus_file_get_gnome_vfs_uri (NautilusFile *file) return NULL; } - if (is_self_owned (file)) { + if (nautilus_file_is_self_owned (file)) { gnome_vfs_uri_ref (vfs_uri); return vfs_uri; } @@ -901,7 +901,7 @@ rename_callback (GnomeVFSAsyncHandle *handle, * hard-code name "." so there's no need to rename * their metadata when they are renamed. */ - if (!is_self_owned (op->file)) { + if (!nautilus_file_is_self_owned (op->file)) { nautilus_directory_rename_file_metadata (directory, old_relative_uri, op->file->details->relative_uri); } @@ -973,7 +973,7 @@ nautilus_file_rename (NautilusFile *file, /* Self-owned files can't be renamed. Test the name-not-actually-changing * case before this case. */ - if (is_self_owned (file)) { + if (nautilus_file_is_self_owned (file)) { /* Claim that something changed even if the rename * failed. This makes it easier for some clients who * see the "reverting" to the old name as "changing @@ -1217,7 +1217,7 @@ nautilus_file_set_directory (NautilusFile *file, g_return_if_fail (NAUTILUS_IS_FILE (file)); g_return_if_fail (NAUTILUS_IS_DIRECTORY (file->details->directory)); g_return_if_fail (!file->details->is_gone); - g_return_if_fail (!is_self_owned (file)); + g_return_if_fail (!nautilus_file_is_self_owned (file)); g_return_if_fail (NAUTILUS_IS_DIRECTORY (new_directory)); old_directory = file->details->directory; @@ -1851,7 +1851,7 @@ nautilus_file_list_filter_hidden_and_backup (GList *files, static const char * get_metadata_name (NautilusFile *file) { - if (is_self_owned (file)) { + if (nautilus_file_is_self_owned (file)) { return FILE_NAME_FOR_DIRECTORY_METADATA; } return file->details->relative_uri; @@ -1907,13 +1907,12 @@ nautilus_file_set_metadata (NautilusFile *file, g_return_if_fail (key != NULL); g_return_if_fail (key[0] != '\0'); - if (nautilus_directory_set_file_metadata (file->details->directory, - get_metadata_name (file), - key, - default_metadata, - metadata)) { - nautilus_file_changed (file); - } + nautilus_directory_set_file_metadata + (file->details->directory, + get_metadata_name (file), + key, + default_metadata, + metadata); } void @@ -1928,13 +1927,12 @@ nautilus_file_set_metadata_list (NautilusFile *file, g_return_if_fail (list_subkey != NULL); g_return_if_fail (list_subkey[0] != '\0'); - if (nautilus_directory_set_file_metadata_list (file->details->directory, - get_metadata_name (file), - list_key, - list_subkey, - list)) { - nautilus_file_changed (file); - } + nautilus_directory_set_file_metadata_list + (file->details->directory, + get_metadata_name (file), + list_key, + list_subkey, + list); } @@ -1987,13 +1985,12 @@ nautilus_file_set_boolean_metadata (NautilusFile *file, g_return_if_fail (key != NULL); g_return_if_fail (key[0] != '\0'); - if (nautilus_directory_set_boolean_file_metadata (file->details->directory, - get_metadata_name (file), - key, - default_metadata, - metadata)) { - nautilus_file_changed (file); - } + nautilus_directory_set_boolean_file_metadata + (file->details->directory, + get_metadata_name (file), + key, + default_metadata, + metadata); } void @@ -2006,13 +2003,12 @@ nautilus_file_set_integer_metadata (NautilusFile *file, g_return_if_fail (key != NULL); g_return_if_fail (key[0] != '\0'); - if (nautilus_directory_set_integer_file_metadata (file->details->directory, - get_metadata_name (file), - key, - default_metadata, - metadata)) { - nautilus_file_changed (file); - } + nautilus_directory_set_integer_file_metadata + (file->details->directory, + get_metadata_name (file), + key, + default_metadata, + metadata); } @@ -2091,7 +2087,7 @@ nautilus_file_get_uri (NautilusFile *file) g_return_val_if_fail (NAUTILUS_IS_FILE (file), NULL); - if (is_self_owned (file)) { + if (nautilus_file_is_self_owned (file)) { return g_strdup (file->details->directory->details->uri); } @@ -4165,7 +4161,7 @@ nautilus_file_mark_gone (NautilusFile *file) /* Let the directory know it's gone. */ directory = file->details->directory; - if (!is_self_owned (file)) { + if (!nautilus_file_is_self_owned (file)) { nautilus_directory_remove_file (directory, file); } @@ -4196,7 +4192,7 @@ nautilus_file_changed (NautilusFile *file) g_return_if_fail (NAUTILUS_IS_FILE (file)); - if (is_self_owned (file)) { + if (nautilus_file_is_self_owned (file)) { nautilus_file_emit_changed (file); } else { fake_list.data = file; diff --git a/libnautilus-private/nautilus-metafile-server.idl b/libnautilus-private/nautilus-metafile-server.idl index 61f590df2..7fdd262e5 100644 --- a/libnautilus-private/nautilus-metafile-server.idl +++ b/libnautilus-private/nautilus-metafile-server.idl @@ -28,11 +28,13 @@ module Nautilus { + typedef sequence<string> FileNameList; + /* NautilusFiles creates (and registers) MetafileMonitors in order * to get notified of metafile changes. */ interface MetafileMonitor : ::Bonobo::Unknown { - void metafile_changed (); + void metafile_changed (in FileNameList file_names); }; typedef sequence<string> MetadataList; @@ -45,8 +47,10 @@ module Nautilus { */ interface Metafile : ::Bonobo::Unknown { - /* getters for a file's metadata - */ + /* returns whether the metadata has been read in yet */ + boolean is_read (); + + /* getters for a file's metadata */ string get (in string file_name, in string key, in string default_value); @@ -54,19 +58,17 @@ module Nautilus { in string list_key, in string list_subkey); - /* setters for a file's metadata - */ - boolean set (in string file_name, - in string key, - in string default_value, - in string metadata); - boolean set_list (in string file_name, - in string list_key, - in string list_subkey, - in MetadataList list); + /* setters for a file's metadata */ + void set (in string file_name, + in string key, + in string default_value, + in string metadata); + void set_list (in string file_name, + in string list_key, + in string list_subkey, + in MetadataList list); - /* calls to keep metadata in sync with file operations - */ + /* calls to keep metadata in sync with file operations */ void copy (in string source_file_name, in URI destination_directory_uri, in string destination_file_name); @@ -74,14 +76,12 @@ module Nautilus { void rename (in string old_file_name, in string new_file_name); - /* calls for registering a MetafileMonitor with a Metafile - */ + /* calls for registering a MetafileMonitor with a Metafile */ void register_monitor (in MetafileMonitor monitor); void unregister_monitor (in MetafileMonitor monitor); }; - /* Components use the MetafileFactory to get a Metafile for a directory. - */ + /* Components use the MetafileFactory to get a Metafile for a directory. */ interface MetafileFactory : ::Bonobo::Unknown { Metafile open (in URI directory); }; diff --git a/libnautilus-private/nautilus-metafile.c b/libnautilus-private/nautilus-metafile.c index de0216355..dfd0fabd9 100644 --- a/libnautilus-private/nautilus-metafile.c +++ b/libnautilus-private/nautilus-metafile.c @@ -49,6 +49,9 @@ static void nautilus_metafile_initialize_class (NautilusMetafileClass *klass); static void destroy (GtkObject *metafile); +static CORBA_boolean corba_is_read (PortableServer_Servant servant, + CORBA_Environment *ev); + static CORBA_char *corba_get (PortableServer_Servant servant, const CORBA_char *file_name, const CORBA_char *key, @@ -60,18 +63,18 @@ static Nautilus_MetadataList *corba_get_list (PortableServer_Servant servant, const CORBA_char *list_subkey, CORBA_Environment *ev); -static CORBA_boolean corba_set (PortableServer_Servant servant, - const CORBA_char *file_name, - const CORBA_char *key, - const CORBA_char *default_value, - const CORBA_char *metadata, - CORBA_Environment *ev); -static CORBA_boolean corba_set_list (PortableServer_Servant servant, - const CORBA_char *file_name, - const CORBA_char *list_key, - const CORBA_char *list_subkey, - const Nautilus_MetadataList *list, - CORBA_Environment *ev); +static void corba_set (PortableServer_Servant servant, + const CORBA_char *file_name, + const CORBA_char *key, + const CORBA_char *default_value, + const CORBA_char *metadata, + CORBA_Environment *ev); +static void corba_set_list (PortableServer_Servant servant, + const CORBA_char *file_name, + const CORBA_char *list_key, + const CORBA_char *list_subkey, + const Nautilus_MetadataList *list, + CORBA_Environment *ev); static void corba_copy (PortableServer_Servant servant, const CORBA_char *source_file_name, @@ -122,6 +125,9 @@ static void copy_file_metadata (NautilusDirectory *source_directory, static void remove_file_metadata (NautilusDirectory *directory, const char *file_name); +static void call_metatfile_changed_for_one_file (NautilusDirectory *directory, + const CORBA_char *file_name); + NAUTILUS_DEFINE_CLASS_BOILERPLATE (NautilusMetafile, nautilus_metafile, BONOBO_OBJECT_TYPE) static void @@ -135,6 +141,7 @@ nautilus_metafile_get_epv (void) { static POA_Nautilus_Metafile__epv epv; + epv.is_read = corba_is_read; epv.get = corba_get; epv.get_list = corba_get_list; epv.set = corba_set; @@ -196,7 +203,7 @@ destroy (GtkObject *object) NautilusDirectory *directory; metafile = NAUTILUS_METAFILE (object); - directory = NAUTILUS_DIRECTORY (metafile->details->directory); + directory = metafile->details->directory; nautilus_directory_unref (directory); g_free (metafile->details); @@ -213,6 +220,19 @@ nautilus_metafile_new (const char *directory_uri) return metafile; } +static CORBA_boolean +corba_is_read (PortableServer_Servant servant, + CORBA_Environment *ev) +{ + NautilusMetafile *metafile; + NautilusDirectory *directory; + + metafile = NAUTILUS_METAFILE (bonobo_object_from_servant (servant)); + directory = metafile->details->directory; + + return directory->details->metafile_read ? CORBA_TRUE : CORBA_FALSE; +} + static CORBA_char * corba_get (PortableServer_Servant servant, const CORBA_char *file_name, @@ -227,7 +247,7 @@ corba_get (PortableServer_Servant servant, CORBA_char *result; metafile = NAUTILUS_METAFILE (bonobo_object_from_servant (servant)); - directory = NAUTILUS_DIRECTORY (metafile->details->directory); + directory = metafile->details->directory; metadata = get_file_metadata (directory, file_name, key, default_value); @@ -255,7 +275,7 @@ corba_get_list (PortableServer_Servant servant, GList *list_ptr; metafile = NAUTILUS_METAFILE (bonobo_object_from_servant (servant)); - directory = NAUTILUS_DIRECTORY (metafile->details->directory); + directory = metafile->details->directory; metadata_list = get_file_metadata_list (directory, file_name, list_key, list_subkey); @@ -283,7 +303,7 @@ corba_get_list (PortableServer_Servant servant, return result; } -static CORBA_boolean +static void corba_set (PortableServer_Servant servant, const CORBA_char *file_name, const CORBA_char *key, @@ -294,8 +314,6 @@ corba_set (PortableServer_Servant servant, NautilusMetafile *metafile; NautilusDirectory *directory; - CORBA_boolean result; - if (nautilus_str_is_empty (default_value)) { default_value = NULL; } @@ -304,14 +322,14 @@ corba_set (PortableServer_Servant servant, } metafile = NAUTILUS_METAFILE (bonobo_object_from_servant (servant)); - directory = NAUTILUS_DIRECTORY (metafile->details->directory); + directory = metafile->details->directory; - result = set_file_metadata (directory, file_name, key, default_value, metadata); - - return result; + if (set_file_metadata (directory, file_name, key, default_value, metadata)) { + call_metatfile_changed_for_one_file (directory, file_name); + } } -static CORBA_boolean +static void corba_set_list (PortableServer_Servant servant, const CORBA_char *file_name, const CORBA_char *list_key, @@ -323,11 +341,10 @@ corba_set_list (PortableServer_Servant servant, NautilusDirectory *directory; GList *metadata_list; - CORBA_boolean result; CORBA_unsigned_long buf_pos; metafile = NAUTILUS_METAFILE (bonobo_object_from_servant (servant)); - directory = NAUTILUS_DIRECTORY (metafile->details->directory); + directory = metafile->details->directory; metadata_list = NULL; for (buf_pos = 0; buf_pos < list->_length; ++buf_pos) { @@ -335,11 +352,11 @@ corba_set_list (PortableServer_Servant servant, } metadata_list = g_list_reverse (metadata_list); - result = set_file_metadata_list (directory, file_name, list_key, list_subkey, metadata_list); - + if (set_file_metadata_list (directory, file_name, list_key, list_subkey, metadata_list)) { + call_metatfile_changed_for_one_file (directory, file_name); + } + g_list_free (metadata_list); - - return result; } static void @@ -354,7 +371,7 @@ corba_copy (PortableServer_Servant servant, NautilusDirectory *destination_directory; source_metafile = NAUTILUS_METAFILE (bonobo_object_from_servant (servant)); - source_directory = NAUTILUS_DIRECTORY (source_metafile->details->directory); + source_directory = source_metafile->details->directory; destination_directory = nautilus_directory_get (destination_directory_uri); @@ -373,7 +390,7 @@ corba_remove (PortableServer_Servant servant, NautilusDirectory *directory; metafile = NAUTILUS_METAFILE (bonobo_object_from_servant (servant)); - directory = NAUTILUS_DIRECTORY (metafile->details->directory); + directory = metafile->details->directory; remove_file_metadata (directory, file_name); } @@ -388,7 +405,7 @@ corba_rename (PortableServer_Servant servant, NautilusDirectory *directory; metafile = NAUTILUS_METAFILE (bonobo_object_from_servant (servant)); - directory = NAUTILUS_DIRECTORY (metafile->details->directory); + directory = metafile->details->directory; rename_file_metadata (directory, old_file_name, new_file_name); } @@ -441,15 +458,26 @@ remove_directory_monitor_list_entry (NautilusDirectory *directory) } static GList * -find_monitor_link (GList *monitor_list, const Nautilus_MetafileMonitor monitor, CORBA_Environment *ev) +find_monitor_node (GList *monitors, const Nautilus_MetafileMonitor monitor) { - while (monitor_list != NULL) { - if (CORBA_Object_is_equivalent (monitor_list->data, monitor, ev)) { + GList *node; + CORBA_Environment ev; + Nautilus_MetafileMonitor cur_monitor; + + CORBA_exception_init (&ev); + + for (node = monitors; node != NULL; node = node->next) { + cur_monitor = node->data; + if (CORBA_Object_is_equivalent (cur_monitor, monitor, &ev)) { break; } - monitor_list = g_list_next (monitor_list); } - return monitor_list; + + /* FIXME bugzilla.eazel.com 6664: examine ev for errors */ + + CORBA_exception_free (&ev); + + return node; } static void @@ -462,13 +490,17 @@ corba_register_monitor (PortableServer_Servant servant, DirectoryMonitorListEntry *monitor_list; metafile = NAUTILUS_METAFILE (bonobo_object_from_servant (servant)); - directory = NAUTILUS_DIRECTORY (metafile->details->directory); + directory = metafile->details->directory; monitor_list = get_or_add_directory_monitor_list_entry (directory); - g_return_if_fail (find_monitor_link (monitor_list->monitors, monitor, ev) == NULL); + g_return_if_fail (find_monitor_node (monitor_list->monitors, monitor) == NULL); monitor_list->monitors = g_list_prepend (monitor_list->monitors, (gpointer) CORBA_Object_duplicate (monitor, ev)); + + /* cause metafile to be read */ + directory->details->load_metafile_for_server = TRUE; + nautilus_directory_async_state_changed (directory); } static void @@ -478,30 +510,104 @@ corba_unregister_monitor (PortableServer_Servant servant, { NautilusMetafile *metafile; NautilusDirectory *directory; - DirectoryMonitorListEntry *monitor_list; - GList *monitor_link; + DirectoryMonitorListEntry *entry; + GList *node; metafile = NAUTILUS_METAFILE (bonobo_object_from_servant (servant)); - directory = NAUTILUS_DIRECTORY (metafile->details->directory); + directory = metafile->details->directory; - monitor_list = g_hash_table_lookup (directory_monitor_lists, directory); + entry = g_hash_table_lookup (directory_monitor_lists, directory); - g_return_if_fail (monitor_list != NULL); + g_return_if_fail (entry != NULL); - monitor_link = find_monitor_link (monitor_list->monitors, monitor, ev); + node = find_monitor_node (entry->monitors, monitor); - g_return_if_fail (monitor_link != NULL); + g_return_if_fail (node != NULL); - monitor_list->monitors = g_list_remove_link (monitor_list->monitors, monitor_link); + entry->monitors = g_list_remove_link (entry->monitors, node); - CORBA_Object_release (monitor_link->data, ev); - g_list_free_1 (monitor_link); + CORBA_Object_release (node->data, ev); + g_list_free_1 (node); - if (monitor_list->monitors == NULL) { + if (entry->monitors == NULL) { remove_directory_monitor_list_entry (directory); } } +static void +call_metatfile_changed (NautilusDirectory *directory, + const Nautilus_FileNameList *file_names) +{ + GList *node; + CORBA_Environment ev; + Nautilus_MetafileMonitor monitor; + DirectoryMonitorListEntry *entry; + + entry = g_hash_table_lookup (directory_monitor_lists, directory); + + if (entry != NULL) { + CORBA_exception_init (&ev); + + for (node = entry->monitors; node != NULL; node = node->next) { + monitor = node->data; + Nautilus_MetafileMonitor_metafile_changed (monitor, file_names, &ev); + /* FIXME bugzilla.eazel.com 6664: examine ev for errors */ + } + + CORBA_exception_free (&ev); + } +} + +static void +file_list_filler_ghfunc (gpointer key, + gpointer value, + gpointer user_data) +{ + Nautilus_FileNameList *file_names; + + file_names = user_data; + + file_names->_buffer [file_names->_length] = key; + + ++file_names->_length; +} + +void +call_metafile_changed_for_all_files_mentioned_in_metafile (NautilusDirectory *directory) +{ + CORBA_unsigned_long len; + Nautilus_FileNameList file_names; + + len = g_hash_table_size (directory->details->metafile_node_hash); + + if (len > 0) { + file_names._maximum = len; + file_names._length = 0; + file_names._buffer = g_new (CORBA_char *, len); + + g_hash_table_foreach (directory->details->metafile_node_hash, + file_list_filler_ghfunc, + &file_names); + + call_metatfile_changed (directory, &file_names); + + g_free (file_names._buffer); + } +} + +static void +call_metatfile_changed_for_one_file (NautilusDirectory *directory, + const CORBA_char *file_name) +{ + Nautilus_FileNameList file_names; + + file_names._maximum = 1; + file_names._length = 1; + file_names._buffer = (CORBA_char **) &file_name; + + call_metatfile_changed (directory, &file_names); +} + typedef struct { gboolean is_list; union { diff --git a/libnautilus-private/nautilus-metafile.h b/libnautilus-private/nautilus-metafile.h index 7b0c3804f..dae0a780c 100644 --- a/libnautilus-private/nautilus-metafile.h +++ b/libnautilus-private/nautilus-metafile.h @@ -49,7 +49,8 @@ GtkType nautilus_metafile_get_type (void); NautilusMetafile *nautilus_metafile_new (const char *directory_uri); - +void call_metafile_changed_for_all_files_mentioned_in_metafile (NautilusDirectory *directory); + void nautilus_metafile_apply_pending_changes (NautilusDirectory *directory); void nautilus_metafile_destroy (NautilusDirectory *directory); diff --git a/libnautilus-private/nautilus-stock-dialogs.c b/libnautilus-private/nautilus-stock-dialogs.c index 75f6da735..b5b863764 100644 --- a/libnautilus-private/nautilus-stock-dialogs.c +++ b/libnautilus-private/nautilus-stock-dialogs.c @@ -207,13 +207,14 @@ timed_wait_callback (gpointer callback_data) { TimedWait *wait; GnomeDialog *dialog; + const char *button; wait = callback_data; /* Put up the timed wait window. */ - dialog = GNOME_DIALOG (gnome_dialog_new (wait->window_title, - wait->cancel_callback != NULL ? GNOME_STOCK_BUTTON_CANCEL : NULL, - NULL)); + button = wait->cancel_callback != NULL ? GNOME_STOCK_BUTTON_CANCEL : GNOME_STOCK_BUTTON_OK; + dialog = GNOME_DIALOG (gnome_dialog_new (wait->window_title, button, NULL)); + /* The contents are often very small, causing tiny little * dialogs with their titles clipped if you just let gtk * sizing do its thing. This enforces a minimum width to diff --git a/libnautilus-private/nautilus-trash-directory.c b/libnautilus-private/nautilus-trash-directory.c index fb16c695c..969228b79 100644 --- a/libnautilus-private/nautilus-trash-directory.c +++ b/libnautilus-private/nautilus-trash-directory.c @@ -71,7 +71,7 @@ find_directory_start (void) NULL, add_volume, _("Searching Disks"), - _("Nautilus is searching for trash folders."), + _("Nautilus is searching your disks for trash folders."), NULL); } |