mirror of
https://gitlab.gnome.org/GNOME/nautilus
synced 2024-09-19 15:51:40 +00:00
e82bab8c49
Fixed bug 2147 (NautilusFile for trash needs non-empty values for more properties), bug 5652 (MIME type field appears but shouldn't in properties window for Trash), and bug 4620 (trash sidebar should show number of items). * libnautilus-extensions/nautilus-file.h: * libnautilus-extensions/nautilus-file-private.h: * libnautilus-extensions/nautilus-file.c: (nautilus_file_new_from_relative_uri): Create trash file subclass when appropriate. (nautilus_file_info_missing): Rename so it can be used in other source files. (nautilus_file_get_date): New method that returns numeric dates. (nautilus_file_get_date_as_string): Change to call nautilus_file_get_date to get the numeric date. (nautilus_file_get_file_type): Turn into a method. * libnautilus-extensions/nautilus-merged-directory.h: * libnautilus-extensions/nautilus-merged-directory.c: (merged_call_when_ready): Rolled in the old merged_callback_connect_directory function. (merged_contains_file): Moved down to a more appropriate part of the source file. (nautilus_merged_directory_get_real_directories): New public function for use by trash. * libnautilus-extensions/nautilus-trash-file.c: (trash_callback_hash), (trash_callback_equal), (trash_callback_destroy), (trash_callback_check_done), (trash_callback_remove_file), (ready_callback), (real_file_changed_callback), (monitor_add_file), (add_real_file), (trash_callback_remove_file_cover), (monitor_remove_file), (remove_real_file), (add_real_file_given_directory), (add_directory_callback), (remove_directory_callback), (trash_file_call_when_ready), (trash_file_cancel_call_when_ready), (trash_file_check_if_ready), (trash_file_monitor_add), (trash_file_monitor_remove), (trash_file_get_file_type), (trash_file_get_item_count), (trash_file_get_deep_counts), (trash_file_get_date), (remove_all_real_files), (nautilus_trash_file_initialize), (trash_destroy), (nautilus_trash_file_initialize_class): New code. First implementation of getting some attributes for the merged trash. Gets list of directories from the NautilusTrashDirectory object. The code in here is similar to the NautilusMergedDirectory class and at some point perhaps we can make the two share more. * libnautilus-extensions/nautilus-vfs-file.c: (vfs_file_get_file_type), (vfs_file_get_date), (nautilus_vfs_file_initialize_class): Implement the two new methods for the standard vfs case. Fixed various things that affect the properties window for the trash that showed up while I was testing the above work: * libnautilus-extensions/nautilus-icon-factory.c: (nautilus_icon_factory_get_icon_name_for_regular_file), (nautilus_icon_factory_get_icon_name_for_file): Move trash special case out so it doesn't matter what type the trash seems to be. The old code relied on trash not being a directory. * src/file-manager/fm-properties-window.c: (create_properties_window), (create_properties_window_callback), (cancel_create_properties_window_callback), (directory_view_destroyed_callback), (remove_pending_file): Rework code to fix problems where the timed wait or the signal handler wasn't properly cleaned up. Fixed remaining bit of bug 5631 (Tear-offs of right-click menus don't work.): * src/file-manager/nautilus-desktop-icon-view-ui.xml: Mark Disks right-click submenu so it won't get a tear-off item. Fixed bug 5650 (nautilus --quit fails to return to prompt sometimes): * src/nautilus-application.c: (nautilus_application_startup): Add special case so "nautilus --quit" doesn't hang waiting for a response from the (now quit) "server" instance of Nautilus. * src/nautilus-shell-interface.idl: Had to make the quit call no longer be "oneway" to get it to work right, otherwise the quit message could be lost when the sending application exited too fast. Fix bug 5675 (Nitpicks in new "could not be moved to new special location" dialog): * libnautilus-extensions/nautilus-file-operations.c: (handle_transfer_overwrite): Updated message wording as Eli (and Vera) suggest. Other changes: * libnautilus-extensions/nautilus-view-identifier.c: (get_lang_list): Fix comment and a small storage leak in the case where lang_with_locale is non-NULL but empty. * po/POTFILES.ignore: Obsolete file, no longer used. * src/file-manager/fm-desktop-icon-view.c: (update_home_link_and_delete_copies): Update comment to help translators understand better. * libnautilus-extensions/nautilus-directory-async.c: (directory_load_callback): Added a new assertion that could help in future gnome-vfs debugging. * libnautilus/nautilus-view-component.idl: Removed long-ago-fixed FIXME comment. * src/nautilus-window-manage-views.c: Tweak spacing.
631 lines
19 KiB
C
631 lines
19 KiB
C
/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*-
|
|
|
|
nautilus-merged-directory.c: Subclass of NautilusDirectory to implement the
|
|
virtual merged directory.
|
|
|
|
Copyright (C) 1999, 2000 Eazel, Inc.
|
|
|
|
This program is free software; you can redistribute it and/or
|
|
modify it under the terms of the GNU General Public License as
|
|
published by the Free Software Foundation; either version 2 of the
|
|
License, or (at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public
|
|
License along with this program; if not, write to the
|
|
Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
|
Boston, MA 02111-1307, USA.
|
|
|
|
Author: Darin Adler <darin@eazel.com>
|
|
*/
|
|
|
|
#include <config.h>
|
|
#include "nautilus-merged-directory.h"
|
|
|
|
#include "nautilus-directory-private.h"
|
|
#include "nautilus-file.h"
|
|
#include "nautilus-glib-extensions.h"
|
|
#include "nautilus-gtk-macros.h"
|
|
#include <gtk/gtksignal.h>
|
|
|
|
struct NautilusMergedDirectoryDetails {
|
|
GList *directories;
|
|
GList *directories_not_done_loading;
|
|
GHashTable *callbacks;
|
|
GHashTable *monitors;
|
|
};
|
|
|
|
typedef struct {
|
|
/* Basic configuration. */
|
|
NautilusMergedDirectory *merged;
|
|
NautilusDirectoryCallback callback;
|
|
gpointer callback_data;
|
|
|
|
GList *wait_for_attributes;
|
|
|
|
GList *non_ready_directories;
|
|
GList *merged_file_list;
|
|
} MergedCallback;
|
|
|
|
typedef struct {
|
|
NautilusMergedDirectory *merged;
|
|
|
|
gboolean monitor_hidden_files;
|
|
gboolean monitor_backup_files;
|
|
GList *monitor_attributes;
|
|
gboolean force_reload;
|
|
} MergedMonitor;
|
|
|
|
enum {
|
|
ADD_REAL_DIRECTORY,
|
|
REMOVE_REAL_DIRECTORY,
|
|
LAST_SIGNAL
|
|
};
|
|
|
|
static guint signals[LAST_SIGNAL];
|
|
|
|
static void nautilus_merged_directory_initialize (gpointer object,
|
|
gpointer klass);
|
|
static void nautilus_merged_directory_initialize_class (gpointer klass);
|
|
static void remove_all_real_directories (NautilusMergedDirectory *merged);
|
|
static guint merged_callback_hash (gconstpointer merged_callback);
|
|
static gboolean merged_callback_equal (gconstpointer merged_callback,
|
|
gconstpointer merged_callback_2);
|
|
|
|
NAUTILUS_DEFINE_CLASS_BOILERPLATE (NautilusMergedDirectory,
|
|
nautilus_merged_directory,
|
|
NAUTILUS_TYPE_DIRECTORY)
|
|
|
|
static void
|
|
nautilus_merged_directory_initialize (gpointer object, gpointer klass)
|
|
{
|
|
NautilusMergedDirectory *merged;
|
|
|
|
merged = NAUTILUS_MERGED_DIRECTORY (object);
|
|
|
|
merged->details = g_new0 (NautilusMergedDirectoryDetails, 1);
|
|
merged->details->callbacks = g_hash_table_new
|
|
(merged_callback_hash, merged_callback_equal);
|
|
merged->details->monitors = g_hash_table_new (NULL, NULL);
|
|
}
|
|
|
|
static void
|
|
merged_destroy (GtkObject *object)
|
|
{
|
|
NautilusMergedDirectory *merged;
|
|
|
|
merged = NAUTILUS_MERGED_DIRECTORY (object);
|
|
|
|
remove_all_real_directories (merged);
|
|
|
|
if (g_hash_table_size (merged->details->callbacks) != 0) {
|
|
g_warning ("call_when_ready still pending when merged virtual directory is destroyed");
|
|
}
|
|
if (g_hash_table_size (merged->details->monitors) != 0) {
|
|
g_warning ("file monitor still active when merged virtual directory is destroyed");
|
|
}
|
|
|
|
g_hash_table_destroy (merged->details->callbacks);
|
|
g_hash_table_destroy (merged->details->monitors);
|
|
g_free (merged->details);
|
|
|
|
NAUTILUS_CALL_PARENT_CLASS (GTK_OBJECT_CLASS, destroy, (object));
|
|
}
|
|
|
|
static guint
|
|
merged_callback_hash (gconstpointer merged_callback_as_pointer)
|
|
{
|
|
const MergedCallback *merged_callback;
|
|
|
|
merged_callback = merged_callback_as_pointer;
|
|
return GPOINTER_TO_UINT (merged_callback->callback)
|
|
^ GPOINTER_TO_UINT (merged_callback->callback_data);
|
|
}
|
|
|
|
static gboolean
|
|
merged_callback_equal (gconstpointer merged_callback_as_pointer,
|
|
gconstpointer merged_callback_as_pointer_2)
|
|
{
|
|
const MergedCallback *merged_callback, *merged_callback_2;
|
|
|
|
merged_callback = merged_callback_as_pointer;
|
|
merged_callback_2 = merged_callback_as_pointer_2;
|
|
|
|
return merged_callback->callback == merged_callback_2->callback
|
|
&& merged_callback->callback_data == merged_callback_2->callback_data;
|
|
}
|
|
|
|
static void
|
|
merged_callback_destroy (MergedCallback *merged_callback)
|
|
{
|
|
g_assert (merged_callback != NULL);
|
|
g_assert (NAUTILUS_IS_MERGED_DIRECTORY (merged_callback->merged));
|
|
|
|
nautilus_g_list_free_deep (merged_callback->wait_for_attributes);
|
|
g_list_free (merged_callback->non_ready_directories);
|
|
nautilus_file_list_free (merged_callback->merged_file_list);
|
|
g_free (merged_callback);
|
|
}
|
|
|
|
static void
|
|
merged_callback_check_done (MergedCallback *merged_callback)
|
|
{
|
|
/* Check if we are ready. */
|
|
if (merged_callback->non_ready_directories != NULL) {
|
|
return;
|
|
}
|
|
|
|
/* Remove from the hash table before sending it. */
|
|
g_hash_table_remove (merged_callback->merged->details->callbacks, merged_callback);
|
|
|
|
/* We are ready, so do the real callback. */
|
|
(* merged_callback->callback) (NAUTILUS_DIRECTORY (merged_callback->merged),
|
|
merged_callback->merged_file_list,
|
|
merged_callback->callback_data);
|
|
|
|
/* And we are done. */
|
|
merged_callback_destroy (merged_callback);
|
|
}
|
|
|
|
static void
|
|
merged_callback_remove_directory (MergedCallback *merged_callback,
|
|
NautilusDirectory *directory)
|
|
{
|
|
merged_callback->non_ready_directories = g_list_remove
|
|
(merged_callback->non_ready_directories,
|
|
directory);
|
|
merged_callback_check_done (merged_callback);
|
|
}
|
|
|
|
static void
|
|
directory_ready_callback (NautilusDirectory *directory,
|
|
GList *files,
|
|
gpointer callback_data)
|
|
{
|
|
MergedCallback *merged_callback;
|
|
|
|
g_assert (NAUTILUS_IS_DIRECTORY (directory));
|
|
g_assert (callback_data != NULL);
|
|
|
|
merged_callback = callback_data;
|
|
g_assert (g_list_find (merged_callback->non_ready_directories, directory) != NULL);
|
|
|
|
/* Update based on this call. */
|
|
merged_callback->merged_file_list = g_list_concat
|
|
(merged_callback->merged_file_list,
|
|
nautilus_file_list_copy (files));
|
|
|
|
/* Check if we are ready. */
|
|
merged_callback_remove_directory (merged_callback, directory);
|
|
}
|
|
|
|
static void
|
|
merged_call_when_ready (NautilusDirectory *directory,
|
|
GList *file_attributes,
|
|
NautilusDirectoryCallback callback,
|
|
gpointer callback_data)
|
|
{
|
|
NautilusMergedDirectory *merged;
|
|
MergedCallback search_key, *merged_callback;
|
|
GList *node;
|
|
|
|
merged = NAUTILUS_MERGED_DIRECTORY (directory);
|
|
|
|
/* Check to be sure we aren't overwriting. */
|
|
search_key.callback = callback;
|
|
search_key.callback_data = callback_data;
|
|
if (g_hash_table_lookup (merged->details->callbacks, &search_key) != NULL) {
|
|
g_warning ("tried to add a new callback while an old one was pending");
|
|
return;
|
|
}
|
|
|
|
/* Create a merged_callback record. */
|
|
merged_callback = g_new0 (MergedCallback, 1);
|
|
merged_callback->merged = merged;
|
|
merged_callback->callback = callback;
|
|
merged_callback->callback_data = callback_data;
|
|
merged_callback->wait_for_attributes = nautilus_g_str_list_copy (file_attributes);
|
|
for (node = merged->details->directories; node != NULL; node = node->next) {
|
|
merged_callback->non_ready_directories = g_list_prepend
|
|
(merged_callback->non_ready_directories, node->data);
|
|
}
|
|
|
|
/* Put it in the hash table. */
|
|
g_hash_table_insert (merged->details->callbacks,
|
|
merged_callback, merged_callback);
|
|
|
|
/* Handle the pathological case where there are no directories. */
|
|
if (merged->details->directories == NULL) {
|
|
merged_callback_check_done (merged_callback);
|
|
}
|
|
|
|
/* Now tell all the directories about it. */
|
|
for (node = merged->details->directories; node != NULL; node = node->next) {
|
|
nautilus_directory_call_when_ready
|
|
(node->data,
|
|
merged_callback->wait_for_attributes,
|
|
directory_ready_callback, merged_callback);
|
|
}
|
|
}
|
|
|
|
static void
|
|
merged_cancel_callback (NautilusDirectory *directory,
|
|
NautilusDirectoryCallback callback,
|
|
gpointer callback_data)
|
|
{
|
|
NautilusMergedDirectory *merged;
|
|
MergedCallback search_key, *merged_callback;
|
|
GList *node;
|
|
|
|
merged = NAUTILUS_MERGED_DIRECTORY (directory);
|
|
|
|
/* Find the entry in the table. */
|
|
search_key.callback = callback;
|
|
search_key.callback_data = callback_data;
|
|
merged_callback = g_hash_table_lookup (merged->details->callbacks, &search_key);
|
|
if (merged_callback == NULL) {
|
|
return;
|
|
}
|
|
|
|
/* Remove from the hash table before working with it. */
|
|
g_hash_table_remove (merged_callback->merged->details->callbacks, merged_callback);
|
|
|
|
/* Tell all the directories to cancel the call. */
|
|
for (node = merged_callback->non_ready_directories; node != NULL; node = node->next) {
|
|
nautilus_directory_cancel_callback
|
|
(node->data,
|
|
directory_ready_callback, merged_callback);
|
|
}
|
|
merged_callback_destroy (merged_callback);
|
|
}
|
|
|
|
/* Create a monitor on each of the directories in the list. */
|
|
static void
|
|
merged_file_monitor_add (NautilusDirectory *directory,
|
|
gconstpointer client,
|
|
gboolean monitor_hidden_files,
|
|
gboolean monitor_backup_files,
|
|
GList *file_attributes,
|
|
gboolean force_reload)
|
|
{
|
|
NautilusMergedDirectory *merged;
|
|
MergedMonitor *monitor;
|
|
GList *node;
|
|
|
|
merged = NAUTILUS_MERGED_DIRECTORY (directory);
|
|
|
|
/* Map the client to a unique value so this doesn't interfere
|
|
* with direct monitoring of the directory by the same client.
|
|
*/
|
|
monitor = g_hash_table_lookup (merged->details->monitors, client);
|
|
if (monitor != NULL) {
|
|
g_assert (monitor->merged == merged);
|
|
nautilus_g_list_free_deep (monitor->monitor_attributes);
|
|
} else {
|
|
monitor = g_new0 (MergedMonitor, 1);
|
|
monitor->merged = merged;
|
|
g_hash_table_insert (merged->details->monitors,
|
|
(gpointer) client, monitor);
|
|
}
|
|
monitor->monitor_hidden_files = monitor_hidden_files;
|
|
monitor->monitor_backup_files = monitor_backup_files;
|
|
monitor->monitor_attributes = nautilus_g_str_list_copy (file_attributes);
|
|
monitor->force_reload = force_reload;
|
|
|
|
/* Call through to the real directory add calls. */
|
|
for (node = merged->details->directories; node != NULL; node = node->next) {
|
|
nautilus_directory_file_monitor_add
|
|
(node->data, monitor,
|
|
monitor_hidden_files, monitor_backup_files,
|
|
file_attributes, force_reload);
|
|
}
|
|
}
|
|
|
|
/* Remove the monitor from each of the directories in the list. */
|
|
static void
|
|
merged_file_monitor_remove (NautilusDirectory *directory,
|
|
gconstpointer client)
|
|
{
|
|
NautilusMergedDirectory *merged;
|
|
MergedMonitor *monitor;
|
|
GList *node;
|
|
|
|
merged = NAUTILUS_MERGED_DIRECTORY (directory);
|
|
|
|
/* Map the client to the value used by the earlier add call. */
|
|
monitor = g_hash_table_lookup (merged->details->monitors, client);
|
|
if (monitor == NULL) {
|
|
return;
|
|
}
|
|
g_hash_table_remove (merged->details->monitors, client);
|
|
|
|
/* Call through to the real directory remove calls. */
|
|
for (node = merged->details->directories; node != NULL; node = node->next) {
|
|
nautilus_directory_file_monitor_remove
|
|
(node->data, monitor);
|
|
}
|
|
|
|
nautilus_g_list_free_deep (monitor->monitor_attributes);
|
|
g_free (monitor);
|
|
}
|
|
|
|
/* Return true if any directory in the list does. */
|
|
static gboolean
|
|
merged_contains_file (NautilusDirectory *directory,
|
|
NautilusFile *file)
|
|
{
|
|
NautilusMergedDirectory *merged;
|
|
GList *node;
|
|
|
|
merged = NAUTILUS_MERGED_DIRECTORY (directory);
|
|
|
|
for (node = merged->details->directories; node != NULL; node = node->next) {
|
|
if (nautilus_directory_contains_file (node->data, file)) {
|
|
return TRUE;
|
|
}
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
/* Return true only if all directories in the list do. */
|
|
static gboolean
|
|
merged_are_all_files_seen (NautilusDirectory *directory)
|
|
{
|
|
NautilusMergedDirectory *merged;
|
|
GList *node;
|
|
|
|
merged = NAUTILUS_MERGED_DIRECTORY (directory);
|
|
|
|
for (node = merged->details->directories; node != NULL; node = node->next) {
|
|
if (!nautilus_directory_are_all_files_seen (node->data)) {
|
|
return FALSE;
|
|
}
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
/* Return true if any directory in the list does. */
|
|
static gboolean
|
|
merged_is_not_empty (NautilusDirectory *directory)
|
|
{
|
|
NautilusMergedDirectory *merged;
|
|
GList *node;
|
|
|
|
merged = NAUTILUS_MERGED_DIRECTORY (directory);
|
|
|
|
for (node = merged->details->directories; node != NULL; node = node->next) {
|
|
if (nautilus_directory_is_not_empty (node->data)) {
|
|
return TRUE;
|
|
}
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
static void
|
|
forward_files_added_cover (NautilusDirectory *real_directory,
|
|
GList *files,
|
|
NautilusMergedDirectory *merged)
|
|
{
|
|
nautilus_directory_emit_files_added (NAUTILUS_DIRECTORY (merged), files);
|
|
}
|
|
|
|
static void
|
|
forward_files_changed_cover (NautilusDirectory *real_directory,
|
|
GList *files,
|
|
NautilusMergedDirectory *merged)
|
|
{
|
|
nautilus_directory_emit_files_changed (NAUTILUS_DIRECTORY (merged), files);
|
|
}
|
|
|
|
static void
|
|
done_loading_callback (NautilusDirectory *real_directory,
|
|
NautilusMergedDirectory *merged)
|
|
{
|
|
merged->details->directories_not_done_loading = g_list_remove
|
|
(merged->details->directories_not_done_loading, real_directory);
|
|
if (merged->details->directories_not_done_loading == NULL) {
|
|
nautilus_directory_emit_done_loading (NAUTILUS_DIRECTORY (merged));
|
|
}
|
|
}
|
|
|
|
static void
|
|
monitor_add_directory (gpointer key,
|
|
gpointer value,
|
|
gpointer callback_data)
|
|
{
|
|
MergedMonitor *monitor;
|
|
|
|
monitor = value;
|
|
nautilus_directory_file_monitor_add
|
|
(NAUTILUS_DIRECTORY (callback_data), monitor,
|
|
monitor->monitor_hidden_files,
|
|
monitor->monitor_backup_files,
|
|
monitor->monitor_attributes,
|
|
monitor->force_reload);
|
|
}
|
|
|
|
static void
|
|
merged_add_real_directory (NautilusMergedDirectory *merged,
|
|
NautilusDirectory *real_directory)
|
|
{
|
|
g_return_if_fail (NAUTILUS_IS_MERGED_DIRECTORY (merged));
|
|
g_return_if_fail (NAUTILUS_IS_DIRECTORY (real_directory));
|
|
g_return_if_fail (!NAUTILUS_IS_MERGED_DIRECTORY (real_directory));
|
|
g_return_if_fail (g_list_find (merged->details->directories, real_directory) == NULL);
|
|
|
|
/* Add to our list of directories. */
|
|
nautilus_directory_ref (real_directory);
|
|
merged->details->directories = g_list_prepend
|
|
(merged->details->directories, real_directory);
|
|
merged->details->directories_not_done_loading = g_list_prepend
|
|
(merged->details->directories_not_done_loading, real_directory);
|
|
|
|
/* Connect signals. */
|
|
gtk_signal_connect (GTK_OBJECT (real_directory),
|
|
"files_added",
|
|
forward_files_added_cover,
|
|
merged);
|
|
gtk_signal_connect (GTK_OBJECT (real_directory),
|
|
"files_changed",
|
|
forward_files_changed_cover,
|
|
merged);
|
|
gtk_signal_connect (GTK_OBJECT (real_directory),
|
|
"done_loading",
|
|
done_loading_callback,
|
|
merged);
|
|
|
|
/* FIXME bugzilla.eazel.com 5084: The done_loading part won't work for the case where
|
|
* we have no directories in our list.
|
|
*/
|
|
|
|
/* Add the directory to any extant monitors. */
|
|
g_hash_table_foreach (merged->details->monitors,
|
|
monitor_add_directory,
|
|
real_directory);
|
|
/* FIXME bugzilla.eazel.com 2541: Do we need to add the directory to callbacks too? */
|
|
}
|
|
|
|
void
|
|
nautilus_merged_directory_add_real_directory (NautilusMergedDirectory *merged,
|
|
NautilusDirectory *real_directory)
|
|
{
|
|
g_return_if_fail (NAUTILUS_IS_MERGED_DIRECTORY (merged));
|
|
g_return_if_fail (NAUTILUS_IS_DIRECTORY (real_directory));
|
|
g_return_if_fail (!NAUTILUS_IS_MERGED_DIRECTORY (real_directory));
|
|
|
|
/* Quietly do nothing if asked to add something that's already there. */
|
|
if (g_list_find (merged->details->directories, real_directory) != NULL) {
|
|
return;
|
|
}
|
|
|
|
gtk_signal_emit (GTK_OBJECT (merged),
|
|
signals[ADD_REAL_DIRECTORY],
|
|
real_directory);
|
|
}
|
|
|
|
GList *
|
|
nautilus_merged_directory_get_real_directories (NautilusMergedDirectory *merged)
|
|
{
|
|
return g_list_copy (merged->details->directories);
|
|
}
|
|
|
|
static void
|
|
merged_callback_remove_directory_cover (gpointer key,
|
|
gpointer value,
|
|
gpointer callback_data)
|
|
{
|
|
merged_callback_remove_directory
|
|
(value, NAUTILUS_DIRECTORY (callback_data));
|
|
}
|
|
|
|
static void
|
|
monitor_remove_directory (gpointer key,
|
|
gpointer value,
|
|
gpointer callback_data)
|
|
{
|
|
nautilus_directory_file_monitor_remove
|
|
(NAUTILUS_DIRECTORY (callback_data), value);
|
|
}
|
|
|
|
static void
|
|
merged_remove_real_directory (NautilusMergedDirectory *merged,
|
|
NautilusDirectory *real_directory)
|
|
{
|
|
g_return_if_fail (NAUTILUS_IS_MERGED_DIRECTORY (merged));
|
|
g_return_if_fail (NAUTILUS_IS_DIRECTORY (real_directory));
|
|
g_return_if_fail (g_list_find (merged->details->directories, real_directory) != NULL);
|
|
|
|
/* Remove this directory from callbacks and monitors. */
|
|
nautilus_g_hash_table_safe_for_each
|
|
(merged->details->callbacks,
|
|
merged_callback_remove_directory_cover,
|
|
real_directory);
|
|
g_hash_table_foreach
|
|
(merged->details->monitors,
|
|
monitor_remove_directory,
|
|
real_directory);
|
|
|
|
/* Disconnect all the signals. */
|
|
gtk_signal_disconnect_by_data (GTK_OBJECT (real_directory), merged);
|
|
|
|
/* Remove from our list of directories. */
|
|
merged->details->directories = g_list_remove
|
|
(merged->details->directories, real_directory);
|
|
merged->details->directories_not_done_loading = g_list_remove
|
|
(merged->details->directories_not_done_loading, real_directory);
|
|
nautilus_directory_unref (real_directory);
|
|
}
|
|
|
|
void
|
|
nautilus_merged_directory_remove_real_directory (NautilusMergedDirectory *merged,
|
|
NautilusDirectory *real_directory)
|
|
{
|
|
g_return_if_fail (NAUTILUS_IS_MERGED_DIRECTORY (merged));
|
|
|
|
/* Quietly do nothing if asked to remove something that's not there. */
|
|
if (g_list_find (merged->details->directories, real_directory) == NULL) {
|
|
return;
|
|
}
|
|
|
|
gtk_signal_emit (GTK_OBJECT (merged),
|
|
signals[REMOVE_REAL_DIRECTORY],
|
|
real_directory);
|
|
}
|
|
|
|
static void
|
|
remove_all_real_directories (NautilusMergedDirectory *merged)
|
|
{
|
|
while (merged->details->directories != NULL) {
|
|
nautilus_merged_directory_remove_real_directory
|
|
(merged, merged->details->directories->data);
|
|
}
|
|
}
|
|
|
|
static void
|
|
nautilus_merged_directory_initialize_class (gpointer klass)
|
|
{
|
|
GtkObjectClass *object_class;
|
|
NautilusDirectoryClass *directory_class;
|
|
NautilusMergedDirectoryClass *merged_directory_class;
|
|
|
|
object_class = GTK_OBJECT_CLASS (klass);
|
|
directory_class = NAUTILUS_DIRECTORY_CLASS (klass);
|
|
merged_directory_class = NAUTILUS_MERGED_DIRECTORY_CLASS (klass);
|
|
|
|
object_class->destroy = merged_destroy;
|
|
|
|
directory_class->contains_file = merged_contains_file;
|
|
directory_class->call_when_ready = merged_call_when_ready;
|
|
directory_class->cancel_callback = merged_cancel_callback;
|
|
directory_class->file_monitor_add = merged_file_monitor_add;
|
|
directory_class->file_monitor_remove = merged_file_monitor_remove;
|
|
directory_class->are_all_files_seen = merged_are_all_files_seen;
|
|
directory_class->is_not_empty = merged_is_not_empty;
|
|
|
|
merged_directory_class->add_real_directory = merged_add_real_directory;
|
|
merged_directory_class->remove_real_directory = merged_remove_real_directory;
|
|
|
|
signals[ADD_REAL_DIRECTORY]
|
|
= gtk_signal_new ("add_real_directory",
|
|
GTK_RUN_LAST,
|
|
object_class->type,
|
|
GTK_SIGNAL_OFFSET (NautilusMergedDirectoryClass,
|
|
add_real_directory),
|
|
gtk_marshal_NONE__POINTER,
|
|
GTK_TYPE_NONE, 1, GTK_TYPE_POINTER);
|
|
signals[REMOVE_REAL_DIRECTORY]
|
|
= gtk_signal_new ("remove_real_directory",
|
|
GTK_RUN_LAST,
|
|
object_class->type,
|
|
GTK_SIGNAL_OFFSET (NautilusMergedDirectoryClass,
|
|
remove_real_directory),
|
|
gtk_marshal_NONE__POINTER,
|
|
GTK_TYPE_NONE, 1, GTK_TYPE_POINTER);
|
|
|
|
gtk_object_class_add_signals (object_class, signals, LAST_SIGNAL);
|
|
}
|