GHashTable * nautilus_trashed_files_get_original_directories (GList *files, GList **unhandled_files) { GHashTable *directories; NautilusFile *file, *original_file, *original_dir; GList *l, *m; directories = NULL; if (unhandled_files != NULL) { *unhandled_files = NULL; } for (l = files; l != NULL; l = l->next) { file = NAUTILUS_FILE (l->data); original_file = nautilus_file_get_trash_original_file (file); original_dir = NULL; if (original_file != NULL) { original_dir = nautilus_file_get_parent (original_file); } if (original_dir != NULL) { if (directories == NULL) { directories = g_hash_table_new_full (g_direct_hash, g_direct_equal, (GDestroyNotify) nautilus_file_unref, (GDestroyNotify) nautilus_file_list_unref); } nautilus_file_ref (original_dir); m = g_hash_table_lookup (directories, original_dir); if (m != NULL) { g_hash_table_steal (directories, original_dir); nautilus_file_unref (original_dir); } m = g_list_append (m, nautilus_file_ref (file)); g_hash_table_insert (directories, original_dir, m); } else if (unhandled_files != NULL) { *unhandled_files = g_list_append (*unhandled_files, nautilus_file_ref (file)); } if (original_file != NULL) { nautilus_file_unref (original_file); } if (original_dir != NULL) { nautilus_file_unref (original_dir); } } return directories; }
GList * nautilus_directory_match_pattern (NautilusDirectory *directory, const char *pattern) { GList *files, *l, *ret; GPatternSpec *spec; ret = NULL; spec = g_pattern_spec_new (pattern); files = nautilus_directory_get_file_list (directory); for (l = files; l; l = l->next) { NautilusFile *file; char *name; file = NAUTILUS_FILE (l->data); name = nautilus_file_get_display_name (file); if (g_pattern_match_string (spec, name)) { ret = g_list_prepend(ret, nautilus_file_ref (file)); } g_free (name); } g_pattern_spec_free (spec); nautilus_file_list_free (files); return ret; }
static void vfs_file_set_metadata_as_list (NautilusFile *file, const char *key, char **value) { GFile *location; GFileInfo *info; char *gio_key; info = g_file_info_new (); gio_key = g_strconcat ("metadata::", key, NULL); g_file_info_set_attribute_stringv (info, gio_key, value); g_free (gio_key); location = nautilus_file_get_location (file); g_file_set_attributes_async (location, info, 0, G_PRIORITY_DEFAULT, NULL, set_metadata_callback, nautilus_file_ref (file)); g_object_unref (info); g_object_unref (location); }
void nautilus_directory_add_file (NautilusDirectory *directory, NautilusFile *file) { GList *node; gboolean add_to_work_queue; g_assert (NAUTILUS_IS_DIRECTORY (directory)); g_assert (NAUTILUS_IS_FILE (file)); g_assert (file->details->name != NULL); /* Add to list. */ node = g_list_prepend (directory->details->file_list, file); directory->details->file_list = node; /* Add to hash table. */ add_to_hash_table (directory, file, node); directory->details->confirmed_file_count++; add_to_work_queue = FALSE; if (nautilus_directory_is_file_list_monitored (directory)) { /* Ref if we are monitoring, since monitoring owns the file list. */ nautilus_file_ref (file); add_to_work_queue = TRUE; } else if (nautilus_directory_has_active_request_for_file (directory, file)) { /* We're waiting for the file in a call_when_ready. Make sure we add the file to the work queue so that said waiter won't wait forever for e.g. all files in the directory to be done */ add_to_work_queue = TRUE; } if (add_to_work_queue) { nautilus_directory_add_file_to_work_queue (directory, file); } }
static void desktop_directory_file_call_when_ready (NautilusFile *file, NautilusFileAttributes attributes, NautilusFileCallback callback, gpointer callback_data) { NautilusDesktopDirectoryFile *desktop_file; DesktopCallback search_key, *desktop_callback; desktop_file = NAUTILUS_DESKTOP_DIRECTORY_FILE (file); /* Check to be sure we aren't overwriting. */ search_key.callback = callback; search_key.callback_data = callback_data; if (g_hash_table_lookup (desktop_file->details->callbacks, &search_key) != NULL) { g_warning ("tried to add a new callback while an old one was pending"); return; } /* Create a desktop_callback record. */ desktop_callback = g_new0 (DesktopCallback, 1); nautilus_file_ref (file); desktop_callback->desktop_file = desktop_file; desktop_callback->callback = callback; desktop_callback->callback_data = callback_data; desktop_callback->initializing = TRUE; partition_attributes (attributes, &desktop_callback->delegated_attributes, &desktop_callback->non_delegated_attributes); desktop_callback->non_ready_files = g_list_prepend (desktop_callback->non_ready_files, file); desktop_callback->non_ready_files = g_list_prepend (desktop_callback->non_ready_files, desktop_file->details->real_dir_file); /* Put it in the hash table. */ g_hash_table_insert (desktop_file->details->callbacks, desktop_callback, desktop_callback); /* Now connect to each file's call_when_ready. */ nautilus_directory_call_when_ready_internal (file->details->directory, file, desktop_callback->non_delegated_attributes, FALSE, NULL, ready_callback, desktop_callback); nautilus_file_call_when_ready (desktop_file->details->real_dir_file, desktop_callback->delegated_attributes, ready_callback, desktop_callback); desktop_callback->initializing = FALSE; /* Check if any files became read while we were connecting up * the call_when_ready callbacks (also handles the pathological * case where there are no files at all). */ desktop_callback_check_done (desktop_callback); }
void nautilus_directory_moved (const char *old_uri, const char *new_uri) { GList *list, *node; GHashTable *hash; NautilusFile *file; GFile *old_location; GFile *new_location; hash = g_hash_table_new (NULL, NULL); old_location = g_file_new_for_uri (old_uri); new_location = g_file_new_for_uri (new_uri); list = nautilus_directory_moved_internal (old_location, new_location); for (node = list; node != NULL; node = node->next) { file = NAUTILUS_FILE (node->data); hash_table_list_prepend (hash, file->details->directory, nautilus_file_ref (file)); } nautilus_file_list_free (list); g_object_unref (old_location); g_object_unref (new_location); g_hash_table_foreach (hash, call_files_changed_unref_free_list, NULL); g_hash_table_destroy (hash); }
void nautilus_drag_slot_proxy_init (GtkWidget *widget, NautilusFile *target_file, NautilusWindowSlot *target_slot) { NautilusDragSlotProxyInfo *drag_info; const GtkTargetEntry targets[] = { { NAUTILUS_ICON_DND_GNOME_ICON_LIST_TYPE, 0, NAUTILUS_ICON_DND_GNOME_ICON_LIST }, { NAUTILUS_ICON_DND_NETSCAPE_URL_TYPE, 0, NAUTILUS_ICON_DND_NETSCAPE_URL }, { NAUTILUS_ICON_DND_XDNDDIRECTSAVE_TYPE, 0, NAUTILUS_ICON_DND_XDNDDIRECTSAVE }, /* XDS Protocol Type */ { NAUTILUS_ICON_DND_RAW_TYPE, 0, NAUTILUS_ICON_DND_RAW } }; GtkTargetList *target_list; g_assert (GTK_IS_WIDGET (widget)); drag_info = g_slice_new0 (NautilusDragSlotProxyInfo); g_object_set_data_full (G_OBJECT (widget), "drag-slot-proxy-data", drag_info, drag_info_free); drag_info->is_notebook = (g_object_get_data (G_OBJECT (widget), "nautilus-notebook-tab") != NULL); if (target_file != NULL) drag_info->target_file = nautilus_file_ref (target_file); if (target_slot != NULL) drag_info->target_slot = g_object_ref (target_slot); drag_info->widget = widget; gtk_drag_dest_set (widget, 0, NULL, 0, GDK_ACTION_MOVE | GDK_ACTION_COPY | GDK_ACTION_LINK | GDK_ACTION_ASK); target_list = gtk_target_list_new (targets, G_N_ELEMENTS (targets)); gtk_target_list_add_uri_targets (target_list, NAUTILUS_ICON_DND_URI_LIST); gtk_target_list_add_text_targets (target_list, NAUTILUS_ICON_DND_TEXT); gtk_drag_dest_set_target_list (widget, target_list); gtk_target_list_unref (target_list); g_signal_connect (widget, "drag-motion", G_CALLBACK (slot_proxy_drag_motion), drag_info); g_signal_connect (widget, "drag-drop", G_CALLBACK (slot_proxy_drag_drop), drag_info); g_signal_connect (widget, "drag-data-received", G_CALLBACK (slot_proxy_drag_data_received), drag_info); g_signal_connect (widget, "drag-leave", G_CALLBACK (slot_proxy_drag_leave), drag_info); }
static GList * nautilus_directory_moved_internal (GFile *old_location, GFile *new_location) { CollectData collection; NautilusDirectory *directory; GList *node, *affected_files; GFile *new_directory_location; char *relative_path; collection.container = old_location; collection.directories = NULL; g_hash_table_foreach (directories, collect_directories_by_container, &collection); affected_files = NULL; for (node = collection.directories; node != NULL; node = node->next) { directory = NAUTILUS_DIRECTORY (node->data); new_directory_location = NULL; if (g_file_equal (directory->details->location, old_location)) { new_directory_location = g_object_ref (new_location); } else { relative_path = g_file_get_relative_path (old_location, directory->details->location); if (relative_path != NULL) { new_directory_location = g_file_resolve_relative_path (new_location, relative_path); g_free (relative_path); } } if (new_directory_location) { change_directory_location (directory, new_directory_location); g_object_unref (new_directory_location); /* Collect affected files. */ if (directory->details->as_file != NULL) { affected_files = g_list_prepend (affected_files, nautilus_file_ref (directory->details->as_file)); } affected_files = g_list_concat (affected_files, nautilus_file_list_copy (directory->details->file_list)); } nautilus_directory_unref (directory); } g_list_free (collection.directories); return affected_files; }
void nautilus_directory_notify_files_removed (GList *files) { GHashTable *changed_lists; GList *p; NautilusDirectory *directory; GHashTable *parent_directories; NautilusFile *file; GFile *location; /* Make a list of changed files in each directory. */ changed_lists = g_hash_table_new (NULL, NULL); /* Make a list of parent directories that will need their counts updated. */ parent_directories = g_hash_table_new (NULL, NULL); /* Go through all the notifications. */ for (p = files; p != NULL; p = p->next) { location = p->data; /* Update file count for parent directory if anyone might care. */ directory = get_parent_directory_if_exists (location); if (directory != NULL) { collect_parent_directories (parent_directories, directory); nautilus_directory_unref (directory); } /* Find the file. */ file = nautilus_file_get_existing (location); if (file != NULL && !nautilus_file_rename_in_progress (file)) { /* Mark it gone and prepare to send the changed signal. */ nautilus_file_mark_gone (file); hash_table_list_prepend (changed_lists, file->details->directory, nautilus_file_ref (file)); } nautilus_file_unref (file); } /* Now send out the changed signals. */ g_hash_table_foreach (changed_lists, call_files_changed_unref_free_list, NULL); g_hash_table_destroy (changed_lists); /* Invalidate count for each parent directory. */ g_hash_table_foreach (parent_directories, invalidate_count_and_unref, NULL); g_hash_table_destroy (parent_directories); }
/* Returns a reffed NautilusFile object for this directory, but only if the * NautilusFile object has already been created. */ NautilusFile * nautilus_directory_get_existing_corresponding_file (NautilusDirectory *directory) { NautilusFile *file; char *uri; file = directory->details->as_file; if (file != NULL) { nautilus_file_ref (file); return file; } uri = nautilus_directory_get_uri (directory); file = nautilus_file_get_existing_by_uri (uri); g_free (uri); return file; }
void nautilus_file_queue_enqueue (NautilusFileQueue *queue, NautilusFile *file) { if (g_hash_table_lookup (queue->item_to_link_map, file) != NULL) { /* It's already on the queue. */ return; } if (queue->tail == NULL) { queue->head = g_list_append (NULL, file); queue->tail = queue->head; } else { queue->tail = g_list_append (queue->tail, file); queue->tail = queue->tail->next; } nautilus_file_ref (file); g_hash_table_insert (queue->item_to_link_map, file, queue->tail); }
NautilusFile* nautilus_directory_get_file_by_name (NautilusDirectory *directory, const gchar *name) { GList *files; GList *l; NautilusFile *result = NULL; files = nautilus_directory_get_file_list (directory); for (l = files; l != NULL; l = l->next) { if (nautilus_file_compare_display_name (l->data, name) == 0) { result = nautilus_file_ref (l->data); break; } } nautilus_file_list_free (files); return result; }
static char * vfs_file_get_where_string (NautilusFile *file) { GFile *activation_location; NautilusFile *location; char *where_string; if (!nautilus_file_is_in_recent (file)) { location = nautilus_file_ref (file); } else { activation_location = nautilus_file_get_activation_location (file); location = nautilus_file_get (activation_location); g_object_unref (activation_location); } where_string = nautilus_file_get_parent_uri_for_display (location); nautilus_file_unref (location); return where_string; }
gboolean fm_ogl_model_add_file (FMOGLModel *model, NautilusFile *file, NautilusDirectory *directory) { FileEntry *file_entry; GSequence *files; file_entry = g_new0 (FileEntry, 1); file_entry->file = nautilus_file_ref (file); file_entry->parent = NULL; file_entry->subdirectory = NULL; file_entry->files = NULL; files = model->details->files; file_entry->ptr = g_sequence_insert_sorted (files, file_entry, fm_ogl_model_file_entry_compare_func, model); return TRUE; }
static void vfs_file_set_metadata (NautilusFile *file, const char *key, const char *value) { GFileInfo *info; GFile *location; char *gio_key; info = g_file_info_new (); gio_key = g_strconcat ("metadata::", key, NULL); if (value != NULL) { g_file_info_set_attribute_string (info, gio_key, value); } else { /* Unset the key */ g_file_info_set_attribute (info, gio_key, G_FILE_ATTRIBUTE_TYPE_INVALID, NULL); } g_free (gio_key); location = nautilus_file_get_location (file); g_file_set_attributes_async (location, info, 0, G_PRIORITY_DEFAULT, NULL, set_metadata_callback, nautilus_file_ref (file)); g_object_unref (location); g_object_unref (info); }
/* key routine that hooks up a background and location */ void nautilus_connect_background_to_file_metadata (GtkWidget *widget, NautilusFile *file, GdkDragAction default_drag_action) { EelBackground *background; gpointer old_file; /* Get at the background object we'll be connecting. */ background = eel_get_widget_background (widget); /* Check if it is already connected. */ old_file = g_object_get_data (G_OBJECT (background), "eel_background_file"); if (old_file == file) { return; } /* Disconnect old signal handlers. */ if (old_file != NULL) { g_assert (NAUTILUS_IS_FILE (old_file)); g_signal_handlers_disconnect_by_func (background, G_CALLBACK (background_changed_callback), old_file); g_signal_handlers_disconnect_by_func (background, G_CALLBACK (background_destroyed_callback), old_file); g_signal_handlers_disconnect_by_func (background, G_CALLBACK (background_reset_callback), old_file); g_signal_handlers_disconnect_by_func (old_file, G_CALLBACK (saved_settings_changed_callback), background); nautilus_file_monitor_remove (old_file, background); eel_preferences_remove_callback (NAUTILUS_PREFERENCES_THEME, nautilus_file_background_theme_changed, background); eel_preferences_remove_callback (NAUTILUS_PREFERENCES_BACKGROUND_SET, nautilus_file_background_theme_changed, background); eel_preferences_remove_callback (NAUTILUS_PREFERENCES_BACKGROUND_COLOR, nautilus_file_background_theme_changed, background); eel_preferences_remove_callback (NAUTILUS_PREFERENCES_BACKGROUND_FILENAME, nautilus_file_background_theme_changed, background); } /* Attach the new directory. */ nautilus_file_ref (file); g_object_set_data_full (G_OBJECT (background), "eel_background_file", file, (GDestroyNotify) nautilus_file_unref); g_object_set_data (G_OBJECT (background), "default_drag_action", GINT_TO_POINTER (default_drag_action)); /* Connect new signal handlers. */ if (file != NULL) { g_signal_connect_object (background, "settings_changed", G_CALLBACK (background_changed_callback), file, 0); g_signal_connect_object (background, "destroy", G_CALLBACK (background_destroyed_callback), file, 0); g_signal_connect_object (background, "reset", G_CALLBACK (background_reset_callback), file, 0); g_signal_connect_object (file, "changed", G_CALLBACK (saved_settings_changed_callback), background, 0); /* arrange to receive file metadata */ nautilus_file_monitor_add (file, background, NAUTILUS_FILE_ATTRIBUTE_INFO); /* arrange for notification when the theme changes */ eel_preferences_add_callback (NAUTILUS_PREFERENCES_THEME, nautilus_file_background_theme_changed, background); eel_preferences_add_callback (NAUTILUS_PREFERENCES_BACKGROUND_SET, nautilus_file_background_theme_changed, background); eel_preferences_add_callback (NAUTILUS_PREFERENCES_BACKGROUND_COLOR, nautilus_file_background_theme_changed, background); eel_preferences_add_callback (NAUTILUS_PREFERENCES_BACKGROUND_FILENAME, nautilus_file_background_theme_changed, background); } /* Update the background based on the file metadata. */ initialize_background_from_settings (file, background); }
gboolean nautilus_list_model_add_file (NautilusListModel *model, NautilusFile *file, NautilusDirectory *directory) { GtkTreeIter iter; GtkTreePath *path; FileEntry *file_entry; GSequenceIter *ptr, *parent_ptr; GSequence *files; gboolean replace_dummy; GHashTable *parent_hash; parent_ptr = g_hash_table_lookup (model->details->directory_reverse_map, directory); if (parent_ptr) { file_entry = g_sequence_get (parent_ptr); ptr = g_hash_table_lookup (file_entry->reverse_map, file); } else { file_entry = NULL; ptr = g_hash_table_lookup (model->details->top_reverse_map, file); } if (ptr != NULL) { g_warning ("file already in tree (parent_ptr: %p)!!!\n", parent_ptr); return FALSE; } file_entry = g_new0 (FileEntry, 1); file_entry->file = nautilus_file_ref (file); file_entry->parent = NULL; file_entry->subdirectory = NULL; file_entry->files = NULL; files = model->details->files; parent_hash = model->details->top_reverse_map; replace_dummy = FALSE; if (parent_ptr != NULL) { file_entry->parent = g_sequence_get (parent_ptr); /* At this point we set loaded. Either we saw * "done" and ignored it waiting for this, or we do this * earlier, but then we replace the dummy row anyway, * so it doesn't matter */ file_entry->parent->loaded = 1; parent_hash = file_entry->parent->reverse_map; files = file_entry->parent->files; if (g_sequence_get_length (files) == 1) { GSequenceIter *dummy_ptr = g_sequence_get_iter_at_pos (files, 0); FileEntry *dummy_entry = g_sequence_get (dummy_ptr); if (dummy_entry->file == NULL) { /* replace the dummy loading entry */ model->details->stamp++; g_sequence_remove (dummy_ptr); replace_dummy = TRUE; } } } file_entry->ptr = g_sequence_insert_sorted (files, file_entry, nautilus_list_model_file_entry_compare_func, model); g_hash_table_insert (parent_hash, file, file_entry->ptr); iter.stamp = model->details->stamp; iter.user_data = file_entry->ptr; path = gtk_tree_model_get_path (GTK_TREE_MODEL (model), &iter); if (replace_dummy) { gtk_tree_model_row_changed (GTK_TREE_MODEL (model), path, &iter); } else { gtk_tree_model_row_inserted (GTK_TREE_MODEL (model), path, &iter); } if (nautilus_file_is_directory (file)) { file_entry->files = g_sequence_new ((GDestroyNotify)file_entry_free); add_dummy_row (model, file_entry); gtk_tree_model_row_has_child_toggled (GTK_TREE_MODEL (model), path, &iter); } gtk_tree_path_free (path); return TRUE; }