Exemplo n.º 1
0
void
nemo_directory_notify_files_moved_by_uri (GList *uri_pairs)
{
	GList *file_pairs;

	file_pairs = uri_pairs_to_file_pairs (uri_pairs);
	nemo_directory_notify_files_moved (file_pairs);
	g_list_foreach (file_pairs, (GFunc)g_file_pair_free, NULL);
	g_list_free (file_pairs);
}
/* 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);
	}	
}