コード例 #1
0
ファイル: nemo-directory.c プロジェクト: daschuer/nemo
void
nemo_directory_notify_files_added_by_uri (GList *uris)
{
	GList *files;

	files = nemo_file_list_from_uris (uris);
	nemo_directory_notify_files_added (files);
	g_list_free_full (files, g_object_unref);
}
コード例 #2
0
ファイル: nemo-link.c プロジェクト: JosephMcc/nemo
gboolean
nemo_link_local_create (const char     *directory_uri,
			    const char     *base_name,
			    const char     *display_name,
			    const char     *image,
			    const char     *target_uri,
			    const GdkPoint *point,
			    int             screen,
			    gboolean        unique_filename)
{
	char *real_directory_uri;
	char *uri, *contents;
	GFile *file;
	GList dummy_list;
	NemoFileChangesQueuePosition item;

	g_return_val_if_fail (directory_uri != NULL, FALSE);
	g_return_val_if_fail (base_name != NULL, FALSE);
	g_return_val_if_fail (display_name != NULL, FALSE);
	g_return_val_if_fail (target_uri != NULL, FALSE);

	if (eel_uri_is_trash (directory_uri) ||
	    eel_uri_is_search (directory_uri)) {
		return FALSE;
	}

	if (eel_uri_is_desktop (directory_uri)) {
		real_directory_uri = nemo_get_desktop_directory_uri ();
	} else {
		real_directory_uri = g_strdup (directory_uri);
	}

	if (unique_filename) {
		uri = nemo_ensure_unique_file_name (real_directory_uri,
							base_name, ".desktop");
		if (uri == NULL) {
			g_free (real_directory_uri);
			return FALSE;
		}
		file = g_file_new_for_uri (uri);
		g_free (uri);
	} else {
		char *link_name;
		GFile *dir;

		link_name = g_strdup_printf ("%s.desktop", base_name);

		/* replace '/' with '-', just in case */
		g_strdelimit (link_name, "/", '-');

		dir = g_file_new_for_uri (directory_uri);
		file = g_file_get_child (dir, link_name);

		g_free (link_name);
		g_object_unref (dir);
	}

	g_free (real_directory_uri);

	contents = g_strdup_printf ("[Desktop Entry]\n"
				    "Encoding=UTF-8\n"
				    "Name=%s\n"
				    "Type=Link\n"
				    "URL=%s\n"
				    "%s%s\n",
				    display_name,
				    target_uri,
				    image != NULL ? "Icon=" : "",
				    image != NULL ? image : "");


	if (!g_file_replace_contents (file,
				      contents, strlen (contents),
				      NULL, FALSE,
				      G_FILE_CREATE_NONE,
				      NULL, NULL, NULL)) {
		g_free (contents);
		g_object_unref (file);
		return FALSE;
	}
	g_free (contents);

	dummy_list.data = file;
	dummy_list.next = NULL;
	dummy_list.prev = NULL;
	nemo_directory_notify_files_added (&dummy_list);

	if (point != NULL) {
		item.location = file;
		item.set = TRUE;
		item.point.x = point->x;
		item.point.y = point->y;
		item.screen = screen;
		dummy_list.data = &item;
		dummy_list.next = NULL;
		dummy_list.prev = NULL;
	
		nemo_directory_schedule_position_set (&dummy_list);
	}

	g_object_unref (file);
	return TRUE;
}
コード例 #3
0
/* go through changes in the change queue, send ones with the same kind
 * in a list to the different nemo_directory_notify calls
 */ 
void
nemo_file_changes_consume_changes (gboolean consume_all)
{
	NemoFileChange *change;
	GList *additions, *changes, *deletions, *moves;
	GList *position_set_requests;
	GFilePair *pair;
	NemoFileChangesQueuePosition *position_set;
	guint chunk_count;
	NemoFileChangesQueue *queue;
	gboolean flush_needed;
	

	additions = NULL;
	changes = NULL;
	deletions = NULL;
	moves = NULL;
	position_set_requests = NULL;

	queue = nemo_file_changes_queue_get();
		
	/* Consume changes from the queue, stuffing them into one of three lists,
	 * keep doing it while the changes are of the same kind, then send them off.
	 * This is to ensure that the changes get sent off in the same order that they 
	 * arrived.
	 */
	for (chunk_count = 0; ; chunk_count++) {
		change = nemo_file_changes_queue_get_change (queue);

		/* figure out if we need to flush the pending changes that we collected sofar */

		if (change == NULL) {
			flush_needed = TRUE;
			/* no changes left, flush everything */
		} else {
			flush_needed = additions != NULL
				&& change->kind != CHANGE_FILE_ADDED
				&& change->kind != CHANGE_POSITION_SET
				&& change->kind != CHANGE_POSITION_REMOVE;
			
			flush_needed |= changes != NULL
				&& change->kind != CHANGE_FILE_CHANGED;
			
			flush_needed |= moves != NULL
				&& change->kind != CHANGE_FILE_MOVED
				&& change->kind != CHANGE_POSITION_SET
				&& change->kind != CHANGE_POSITION_REMOVE;
			
			flush_needed |= deletions != NULL
				&& change->kind != CHANGE_FILE_REMOVED;
			
			flush_needed |= position_set_requests != NULL
				&& change->kind != CHANGE_POSITION_SET
				&& change->kind != CHANGE_POSITION_REMOVE
				&& change->kind != CHANGE_FILE_ADDED
				&& change->kind != CHANGE_FILE_MOVED;
			
			flush_needed |= !consume_all && chunk_count >= CONSUME_CHANGES_MAX_CHUNK;
				/* we have reached the chunk maximum */
		}
		
		if (flush_needed) {
			/* Send changes we collected off. 
			 * At one time we may only have one of the lists
			 * contain changes.
			 */
			
			if (deletions != NULL) {
				deletions = g_list_reverse (deletions);
				nemo_directory_notify_files_removed (deletions);
				g_list_free_full (deletions, g_object_unref);
				deletions = NULL;
			}
			if (moves != NULL) {
				moves = g_list_reverse (moves);
				nemo_directory_notify_files_moved (moves);
				pairs_list_free (moves);
				moves = NULL;
			}
			if (additions != NULL) {
				additions = g_list_reverse (additions);
				nemo_directory_notify_files_added (additions);
				g_list_free_full (additions, g_object_unref);
				additions = NULL;
			}
			if (changes != NULL) {
				changes = g_list_reverse (changes);
				nemo_directory_notify_files_changed (changes);
				g_list_free_full (changes, g_object_unref);
				changes = NULL;
			}
			if (position_set_requests != NULL) {
				position_set_requests = g_list_reverse (position_set_requests);
				nemo_directory_schedule_position_set (position_set_requests);
				position_set_list_free (position_set_requests);
				position_set_requests = NULL;
			}
		}

		if (change == NULL) {
			/* we are done */
			return;
		}
		
		/* add the new change to the list */
		switch (change->kind) {
		case CHANGE_FILE_ADDED:
			additions = g_list_prepend (additions, change->from);
			break;

		case CHANGE_FILE_CHANGED:
			changes = g_list_prepend (changes, change->from);
			break;

		case CHANGE_FILE_REMOVED:
			deletions = g_list_prepend (deletions, change->from);
			break;

		case CHANGE_FILE_MOVED:
			pair = g_new (GFilePair, 1);
			pair->from = change->from;
			pair->to = change->to;
			moves = g_list_prepend (moves, pair);
			break;

		case CHANGE_POSITION_SET:
			position_set = g_new (NemoFileChangesQueuePosition, 1);
			position_set->location = change->from;
			position_set->set = TRUE;
			position_set->point = change->point;
			position_set->screen = change->screen;
			position_set_requests = g_list_prepend (position_set_requests,
								position_set);
			break;

		case CHANGE_POSITION_REMOVE:
			position_set = g_new (NemoFileChangesQueuePosition, 1);
			position_set->location = change->from;
			position_set->set = FALSE;
			position_set_requests = g_list_prepend (position_set_requests,
								position_set);
			break;

		default:
			g_assert_not_reached ();
			break;
		}

		g_free (change);
	}	
}
コード例 #4
0
ファイル: nemo-directory.c プロジェクト: daschuer/nemo
void
nemo_directory_notify_files_moved (GList *file_pairs)
{
	GList *p, *affected_files, *node;
	GFilePair *pair;
	NemoFile *file;
	NemoDirectory *old_directory, *new_directory;
	GHashTable *parent_directories;
	GList *new_files_list, *unref_list;
	GHashTable *added_lists, *changed_lists;
	char *name;
	NemoFileAttributes cancel_attributes;
	GFile *to_location, *from_location;
	
	/* Make a list of added and changed files in each directory. */
	new_files_list = NULL;
	added_lists = g_hash_table_new (NULL, NULL);
	changed_lists = g_hash_table_new (NULL, NULL);
	unref_list = NULL;

	/* Make a list of parent directories that will need their counts updated. */
	parent_directories = g_hash_table_new (NULL, NULL);

	cancel_attributes = nemo_file_get_all_attributes ();

	for (p = file_pairs; p != NULL; p = p->next) {
		pair = p->data;
		from_location = pair->from;
		to_location = pair->to;

		/* Handle overwriting a file. */
		file = nemo_file_get_existing (to_location);
		if (file != NULL) {
			/* Mark it gone and prepare to send the changed signal. */
			nemo_file_mark_gone (file);
			new_directory = file->details->directory;
			hash_table_list_prepend (changed_lists,
						 new_directory,
						 file);
			collect_parent_directories (parent_directories,
						    new_directory);
		}

		/* Update any directory objects that are affected. */
		affected_files = nemo_directory_moved_internal (from_location,
								    to_location);
		for (node = affected_files; node != NULL; node = node->next) {
			file = NEMO_FILE (node->data);
			hash_table_list_prepend (changed_lists,
						 file->details->directory,
						 file);
		}
		unref_list = g_list_concat (unref_list, affected_files);

		/* Move an existing file. */
		file = nemo_file_get_existing (from_location);
		if (file == NULL) {
			/* Handle this as if it was a new file. */
			new_files_list = g_list_prepend (new_files_list,
							 to_location);
		} else {
			/* Handle notification in the old directory. */
			old_directory = file->details->directory;
			collect_parent_directories (parent_directories, old_directory);

			/* Cancel loading of attributes in the old directory */
			nemo_directory_cancel_loading_file_attributes
				(old_directory, file, cancel_attributes);

			/* Locate the new directory. */
			new_directory = get_parent_directory (to_location);
			collect_parent_directories (parent_directories, new_directory);
			/* We can unref now -- new_directory is in the
			 * parent directories list so it will be
			 * around until the end of this function
			 * anyway.
			 */
			nemo_directory_unref (new_directory);

			/* Update the file's name and directory. */
			name = g_file_get_basename (to_location);
			nemo_file_update_name_and_directory 
				(file, name, new_directory);
			g_free (name);

			/* Update file attributes */
			nemo_file_invalidate_attributes (file, NEMO_FILE_ATTRIBUTE_INFO);

			hash_table_list_prepend (changed_lists,
						 old_directory,
						 file);
			if (old_directory != new_directory) {
				hash_table_list_prepend	(added_lists,
							 new_directory,
							 file);
			}

			/* Unref each file once to balance out nemo_file_get_by_uri. */
			unref_list = g_list_prepend (unref_list, file);
		}
	}

	/* Now send out the changed and added signals for existing file objects. */
	g_hash_table_foreach (changed_lists, call_files_changed_free_list, NULL);
	g_hash_table_destroy (changed_lists);
	g_hash_table_foreach (added_lists, call_files_added_free_list, NULL);
	g_hash_table_destroy (added_lists);

	/* Let the file objects go. */
	nemo_file_list_free (unref_list);

	/* Invalidate count for each parent directory. */
	g_hash_table_foreach (parent_directories, invalidate_count_and_unref, NULL);
	g_hash_table_destroy (parent_directories);

	/* Separate handling for brand new file objects. */
	nemo_directory_notify_files_added (new_files_list);
	g_list_free (new_files_list);
}