static void
impl_dispose (GObject *object)
{
	RBAndroidSourcePrivate *priv = GET_PRIVATE (object);

	if (priv->db != NULL) {
		if (priv->ignore_type != NULL) {
			rhythmdb_entry_delete_by_type (priv->db, priv->ignore_type);
			g_clear_object (&priv->ignore_type);
		}
		if (priv->error_type != NULL) {
			rhythmdb_entry_delete_by_type (priv->db, priv->error_type);
			g_clear_object (&priv->error_type);
		}

		g_clear_object (&priv->db);
	}

	if (priv->import_job != NULL) {
		rhythmdb_import_job_cancel (priv->import_job);
		g_clear_object (&priv->import_job);
	}

	g_clear_object (&priv->device_info);
	g_clear_object (&priv->mount);
	g_clear_object (&priv->gudev_device);

	G_OBJECT_CLASS (rb_android_source_parent_class)->dispose (object);
}
static void
impl_dispose (GObject *object)
{
	RBGenericPlayerSourcePrivate *priv = GENERIC_PLAYER_SOURCE_GET_PRIVATE (object);

	if (priv->load_playlists_id != 0) {
		g_source_remove (priv->load_playlists_id);
		priv->load_playlists_id = 0;
	}

	if (priv->db != NULL) {
		if (priv->ignore_type != RHYTHMDB_ENTRY_TYPE_INVALID) {
			rhythmdb_entry_delete_by_type (priv->db, priv->ignore_type);
			g_boxed_free (RHYTHMDB_TYPE_ENTRY_TYPE, priv->ignore_type);
			priv->ignore_type = RHYTHMDB_ENTRY_TYPE_INVALID;
		}
		if (priv->error_type != RHYTHMDB_ENTRY_TYPE_INVALID) {
			rhythmdb_entry_delete_by_type (priv->db, priv->error_type);
			g_boxed_free (RHYTHMDB_TYPE_ENTRY_TYPE, priv->error_type);
			priv->error_type = RHYTHMDB_ENTRY_TYPE_INVALID;
		}

		g_object_unref (priv->db);
		priv->db = NULL;
	}

	if (priv->import_job != NULL) {
		rhythmdb_import_job_cancel (priv->import_job);
		g_object_unref (priv->import_job);
		priv->import_job = NULL;
	}

	G_OBJECT_CLASS (rb_generic_player_source_parent_class)->dispose (object);
}
static void
close_clicked_cb (GtkButton *button, RBImportDialog *dialog)
{
	hide_import_job (dialog);
	if (dialog->priv->import_job) {
		rhythmdb_import_job_cancel (dialog->priv->import_job);
	}
	g_signal_emit (dialog, signals[CLOSED], 0);
}
static void
impl_close (RBImportDialog *dialog)
{
	hide_import_job (dialog);

	if (dialog->priv->import_job) {
		rhythmdb_import_job_cancel (dialog->priv->import_job);
	}
	g_signal_emit (dialog, signals[CLOSED], 0);
}
static void
impl_eject (RBDeviceSource *source)
{
	RBAndroidSourcePrivate *priv = GET_PRIVATE (source);

	if (priv->import_job != NULL) {
		rhythmdb_import_job_cancel (priv->import_job);
		priv->ejecting = TRUE;
	} else {
		rb_device_source_default_eject (source);
	}
}
static void
impl_dispose (GObject *object)
{
	RBGenericPlayerSourcePrivate *priv = GET_PRIVATE (object);

	if (priv->load_playlists_id != 0) {
		g_source_remove (priv->load_playlists_id);
		priv->load_playlists_id = 0;
	}

	if (priv->db != NULL) {
		if (priv->ignore_type != NULL) {
			rhythmdb_entry_delete_by_type (priv->db, priv->ignore_type);
			g_object_unref (priv->ignore_type);
			priv->ignore_type = NULL;
		}
		if (priv->error_type != NULL) {
			rhythmdb_entry_delete_by_type (priv->db, priv->error_type);
			g_object_unref (priv->error_type);
			priv->error_type = NULL;
		}

		g_object_unref (priv->db);
		priv->db = NULL;
	}

	if (priv->import_job != NULL) {
		rhythmdb_import_job_cancel (priv->import_job);
		g_object_unref (priv->import_job);
		priv->import_job = NULL;
	}

	if (priv->device_info != NULL) {
		g_object_unref (priv->device_info);
		priv->device_info = NULL;
	}

	if (priv->mount != NULL) {
		g_object_unref (priv->mount);
		priv->mount = NULL;
	}

	rb_application_remove_plugin_menu_item (RB_APPLICATION (g_application_get_default ()),
						"display-page-add-playlist",
						priv->new_playlist_action_name);

	G_OBJECT_CLASS (rb_generic_player_source_parent_class)->dispose (object);
}
static void
impl_dispose (GObject *object)
{
	RBGenericPlayerSourcePrivate *priv = GET_PRIVATE (object);

	if (priv->load_playlists_id != 0) {
		g_source_remove (priv->load_playlists_id);
		priv->load_playlists_id = 0;
	}

	if (priv->db != NULL) {
		if (priv->ignore_type != NULL) {
			rhythmdb_entry_delete_by_type (priv->db, priv->ignore_type);
			g_object_unref (priv->ignore_type);
			priv->ignore_type = NULL;
		}
		if (priv->error_type != NULL) {
			rhythmdb_entry_delete_by_type (priv->db, priv->error_type);
			g_object_unref (priv->error_type);
			priv->error_type = NULL;
		}

		g_object_unref (priv->db);
		priv->db = NULL;
	}

	if (priv->import_job != NULL) {
		rhythmdb_import_job_cancel (priv->import_job);
		g_object_unref (priv->import_job);
		priv->import_job = NULL;
	}

	if (priv->device_info != NULL) {
		g_object_unref (priv->device_info);
		priv->device_info = NULL;
	}

	if (priv->mount != NULL) {
		g_object_unref (priv->mount);
		priv->mount = NULL;
	}

	G_OBJECT_CLASS (rb_generic_player_source_parent_class)->dispose (object);
}
static void
task_progress_cancel (RBTaskProgress *progress)
{
	rhythmdb_import_job_cancel (RHYTHMDB_IMPORT_JOB (progress));
}
static void
current_folder_changed_cb (GtkFileChooser *chooser, RBImportDialog *dialog)
{
	GSettings *settings;
	RBSource *source;
	GtkWidget *label;
	const char *uri;
	char **locations;
	int i;
	
	uri = gtk_file_chooser_get_uri (chooser);
	if (g_strcmp0 (uri, dialog->priv->current_uri) == 0)
		return;
	g_free (dialog->priv->current_uri);
	dialog->priv->current_uri = g_strdup (uri);

	if (dialog->priv->import_job != NULL) {
		rhythmdb_import_job_cancel (dialog->priv->import_job);
	}

	clear_info_bar (dialog);

	source = rb_shell_guess_source_for_uri (dialog->priv->shell, uri);
	if (source != NULL) {
		if (RB_IS_DEVICE_SOURCE (source)) {
			char *msg;
			char *name;
			GtkWidget *content;

			rhythmdb_entry_delete_by_type (dialog->priv->db, dialog->priv->entry_type);
			rhythmdb_entry_delete_by_type (dialog->priv->db, dialog->priv->ignore_type);
			rhythmdb_commit (dialog->priv->db);

			dialog->priv->info_bar = gtk_info_bar_new ();
			g_object_set (dialog->priv->info_bar, "hexpand", TRUE, NULL);

			g_object_get (source, "name", &name, NULL);

			/* this isn't a terribly helpful message. */
			msg = g_strdup_printf (_("The location you have selected is on the device %s."), name);
			label = gtk_label_new (msg);
			g_free (msg);
			content = gtk_info_bar_get_content_area (GTK_INFO_BAR (dialog->priv->info_bar));
			gtk_container_add (GTK_CONTAINER (content), label);

			msg = g_strdup_printf (_("Show %s"), name);
			gtk_info_bar_add_button (GTK_INFO_BAR (dialog->priv->info_bar), msg, GTK_RESPONSE_ACCEPT);
			g_free (msg);

			g_signal_connect (dialog->priv->info_bar, "response", G_CALLBACK (device_info_bar_response_cb), dialog);

			gtk_widget_show_all (dialog->priv->info_bar);
			gtk_container_add (GTK_CONTAINER (dialog->priv->info_bar_container), dialog->priv->info_bar);
			return;
		}
	}

	/* disable copy if the selected location is already inside the library */
	settings = g_settings_new ("org.gnome.rhythmbox.rhythmdb");
	locations = g_settings_get_strv (settings, "locations");
	gtk_widget_set_sensitive (dialog->priv->copy_check, TRUE);
	for (i = 0; locations[i] != NULL; i++) {
		if (g_str_has_prefix (uri, locations[i])) {
			gtk_widget_set_sensitive (dialog->priv->copy_check, FALSE);
			break;
		}
	}
	g_strfreev (locations);
	g_object_unref (settings);

	if (dialog->priv->import_job != NULL) {
		/* wait for the previous job to finish up */
		rb_debug ("need to wait for previous import job to finish");
		g_signal_connect (dialog->priv->import_job, "complete", G_CALLBACK (start_deferred_scan), dialog);
	} else {
		start_scanning (dialog);
	}
}