static void
rb_static_playlist_source_add_uri_list (RBStaticPlaylistSource *source,
					GList *list)
{
	GList *i, *uri_list = NULL;
	RBPlaylistSource *psource = RB_PLAYLIST_SOURCE (source);
	RhythmDBEntry *entry;

	g_return_if_fail (list != NULL);

	for (i = list; i != NULL; i = g_list_next (i)) {
		char *uri = (char *) i->data;
		uri_list = g_list_prepend (uri_list, rb_canonicalise_uri (uri));
	}

	uri_list = g_list_reverse (uri_list);
	if (uri_list == NULL)
		return;

	for (i = uri_list; i != NULL; i = i->next) {
		char *uri = i->data;
		if (uri != NULL) {
			entry = rhythmdb_entry_lookup_by_location (rb_playlist_source_get_db (psource), uri);
			if (entry == NULL)
				rhythmdb_add_uri (rb_playlist_source_get_db (psource), uri);

			rb_static_playlist_source_add_location (source, uri, -1);
		}

		g_free (uri);
	}
	g_list_free (uri_list);
}
static void
rb_static_playlist_source_non_entry_dropped (GtkTreeModel *model,
					     const char *uri,
					     int position,
					     RBStaticPlaylistSource *source)
{
	g_assert (g_utf8_strlen (uri, -1) > 0);

	rhythmdb_add_uri (rb_playlist_source_get_db (RB_PLAYLIST_SOURCE (source)), uri);
	rb_static_playlist_source_add_location (source, uri, position);
}
static gboolean
rhythmdb_check_changed_file (RBRefString *uri, gpointer data, RhythmDB *db)
{
	GTimeVal time;
	glong time_sec = GPOINTER_TO_INT (data);

	g_get_current_time (&time);
	if (time.tv_sec >= time_sec + RHYTHMDB_FILE_MODIFY_PROCESS_TIME) {
		rb_debug ("adding newly located file %s", rb_refstring_get (uri));
		rhythmdb_add_uri (db, rb_refstring_get (uri));
		return TRUE;
	}

	rb_debug ("waiting to add newly located file %s", rb_refstring_get (uri));

	return FALSE;
}
static gboolean
monitor_subdirectory (GFile *file, gboolean dir, RhythmDB *db)
{
	char *uri;

	uri = g_file_get_uri (file);
	if (dir) {
		actually_add_monitor (db, file, NULL);
	} else {
		/* add the file to the database if it's not already there */
		RhythmDBEntry *entry;

		entry = rhythmdb_entry_lookup_by_location (db, uri);
		if (entry == NULL) {
			rhythmdb_add_uri (db, uri);
		}
	}
	g_free (uri);
	return TRUE;	
}
static void
rhythmdb_directory_change_cb (GFileMonitor *monitor,
			      GFile *file,
			      GFile *other_file,
			      GFileMonitorEvent event_type,
			      RhythmDB *db)
{
	char *canon_uri;
	char *other_canon_uri = NULL;
	RhythmDBEntry *entry;

	canon_uri = g_file_get_uri (file);
	if (other_file != NULL) {
		other_canon_uri = g_file_get_uri (other_file);
	}

	rb_debug ("directory event %d for %s", event_type, canon_uri);

	switch (event_type) {
        case G_FILE_MONITOR_EVENT_CREATED:
		{
			gboolean in_library = FALSE;
			int i;

			if (!g_settings_get_boolean (db->priv->settings, "monitor-library"))
				break;

			if (rb_uri_is_hidden (canon_uri))
				break;

			/* ignore new files outside of the library locations */
			for (i = 0; db->priv->library_locations[i] != NULL; i++) {
				if (g_str_has_prefix (canon_uri, db->priv->library_locations[i])) {
					in_library = TRUE;
					break;
				}
			}

			if (!in_library)
				break;
		}

		/* process directories immediately */
		if (rb_uri_is_directory (canon_uri)) {
			actually_add_monitor (db, file, NULL);
			rhythmdb_add_uri (db, canon_uri);
		} else {
			add_changed_file (db, canon_uri);
		}
		break;
	case G_FILE_MONITOR_EVENT_CHANGED:
        case G_FILE_MONITOR_EVENT_ATTRIBUTE_CHANGED:
		if (rhythmdb_entry_lookup_by_location (db, canon_uri)) {
			add_changed_file (db, canon_uri);
		}
		break;
	case G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT:
		/* hmm.. */
		break;
	case G_FILE_MONITOR_EVENT_DELETED:
		entry = rhythmdb_entry_lookup_by_location (db, canon_uri);
		if (entry != NULL) {
			g_hash_table_remove (db->priv->changed_files, entry->location);
			rhythmdb_entry_set_visibility (db, entry, FALSE);
			rhythmdb_commit (db);
		}
		break;
	case G_FILE_MONITOR_EVENT_MOVED:
		if (other_canon_uri == NULL) {
			break;
		}

		entry = rhythmdb_entry_lookup_by_location (db, other_canon_uri);
		if (entry != NULL) {
			rb_debug ("file move target %s already exists in database", other_canon_uri);
			entry = rhythmdb_entry_lookup_by_location (db, canon_uri);
			if (entry != NULL) {
				g_hash_table_remove (db->priv->changed_files, entry->location);
				rhythmdb_entry_set_visibility (db, entry, FALSE);
				rhythmdb_commit (db);
			}
		} else {
			entry = rhythmdb_entry_lookup_by_location (db, canon_uri);
			if (entry != NULL) {
				GValue v = {0,};
				g_value_init (&v, G_TYPE_STRING);
				g_value_set_string (&v, other_canon_uri);
				rhythmdb_entry_set_internal (db, entry, TRUE, RHYTHMDB_PROP_LOCATION, &v);
				g_value_unset (&v);
			}
		}
		break;
	case G_FILE_MONITOR_EVENT_PRE_UNMOUNT:
	case G_FILE_MONITOR_EVENT_UNMOUNTED:
	default:
		break;
	}

	g_free (canon_uri);
	g_free (other_canon_uri);
}