Example #1
0
/**
 * rb_playlist_source_get_query_model:
 * @source: a #RBPlaylistSource
 *
 * Returns the current #RhythmDBQueryModel for the playlist.
 * The caller must not unref the object once finished with it.
 *
 * Return value: (transfer none): the current #RhythmDBQueryModel
 */
RhythmDBQueryModel *
rb_playlist_source_get_query_model (RBPlaylistSource *source)
{
	g_return_val_if_fail (RB_IS_PLAYLIST_SOURCE (source), NULL);

	return source->priv->model;
}
Example #2
0
/**
 * rb_playlist_source_get_db:
 * @source: a #RBPlaylistSource
 *
 * Returns the #RhythmDB instance.  The caller must not
 * unref the object once finished with it.
 *
 * Return value: (transfer none): the #RhythmDB instance
 */
RhythmDB *
rb_playlist_source_get_db (RBPlaylistSource *source)
{
	g_return_val_if_fail (RB_IS_PLAYLIST_SOURCE (source), NULL);

	return source->priv->db;
}
Example #3
0
/**
 * rb_playlist_source_set_query_model:
 * @source: the #RBPlaylistSource
 * @model: the new #RhythmDBQueryModel
 *
 * Sets a new query model for the playlist.  This updates the
 * entry view to use the new query model and also updates the
 * source query-model property.
 *
 * This needs to be called when the playlist subclass
 * creates a new query model.
 */
void
rb_playlist_source_set_query_model (RBPlaylistSource *source,
				    RhythmDBQueryModel *model)
{
	g_return_if_fail (RB_IS_PLAYLIST_SOURCE (source));

	if (source->priv->model != NULL) {
		/* if the query model is replaced, the set of entries in
		 * the playlist will change, so we should mark the playlist dirty.
		 */
		source->priv->dirty = TRUE;
		g_signal_handlers_disconnect_by_func (source->priv->model,
						      G_CALLBACK (rb_playlist_source_row_deleted),
						      source);
		g_object_unref (source->priv->model);
	}

	source->priv->model = model;

	if (source->priv->model != NULL) {
		g_object_ref (source->priv->model);
		g_signal_connect_object (source->priv->model, "row_deleted",
					 G_CALLBACK (rb_playlist_source_row_deleted), source, 0);
	}

	rb_entry_view_set_model (source->priv->songs, RHYTHMDB_QUERY_MODEL (source->priv->model));

	g_object_set (source, "query-model", source->priv->model, NULL);
}
Example #4
0
/**
 * rb_playlist_source_save_playlist:
 * @source: a #RBPlaylistSource
 * @uri: destination URI
 * @export_type: format to save in
 *
 * Saves the playlist to an external file in a standard
 * format (M3U, PLS, or XSPF).
 */
void
rb_playlist_source_save_playlist (RBPlaylistSource *source,
				  const char *uri,
				  RBPlaylistExportType export_type)
{
	TotemPlParser *pl;
	GError *error = NULL;
	char *name;
	gint totem_format;
#if TOTEM_PL_PARSER_CHECK_VERSION(2,29,1)
	TotemPlPlaylist *playlist;
	GFile *file;
#endif

	g_return_if_fail (RB_IS_PLAYLIST_SOURCE (source));

	rb_debug ("saving playlist");
	pl = totem_pl_parser_new ();

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

	switch (export_type) {
	case RB_PLAYLIST_EXPORT_TYPE_XSPF:
		totem_format = TOTEM_PL_PARSER_XSPF;
		break;
	case RB_PLAYLIST_EXPORT_TYPE_M3U:
		totem_format = TOTEM_PL_PARSER_M3U;
		break;
	case RB_PLAYLIST_EXPORT_TYPE_PLS:
	default:
		totem_format = TOTEM_PL_PARSER_PLS;
		break;
	}

#if TOTEM_PL_PARSER_CHECK_VERSION(2,29,1)
	file = g_file_new_for_uri (uri);
	playlist = totem_pl_playlist_new ();

	gtk_tree_model_foreach (GTK_TREE_MODEL (source->priv->model),
				(GtkTreeModelForeachFunc)playlist_iter_foreach,
				playlist);
	totem_pl_parser_save (pl, playlist, file, name, totem_format, &error);
	g_object_unref (playlist);
	g_object_unref (file);
#else
	totem_pl_parser_write_with_title (pl, GTK_TREE_MODEL (source->priv->model),
					  playlist_iter_func, uri, name,
					  totem_format,
					  NULL, &error);
#endif
	g_object_unref (pl);
	g_free (name);
	if (error != NULL) {
		rb_error_dialog (NULL, _("Couldn't save playlist"),
				 "%s", error->message);
		g_error_free (error);
	}
}
Example #5
0
/**
 * rb_playlist_source_mark_dirty:
 * @source: a #RBPlaylistSource
 *
 * Marks the playlist dirty.  This generally means that the playlist
 * will be saved to disk fairly soon, but the exact meaning can vary
 * between playlist types.
 */
void
rb_playlist_source_mark_dirty (RBPlaylistSource *source)
{
	RBPlaylistSourceClass *klass;
	g_return_if_fail (RB_IS_PLAYLIST_SOURCE (source));

	klass = RB_PLAYLIST_SOURCE_GET_CLASS (source);
	klass->impl_mark_dirty (source);
	g_object_notify (G_OBJECT (source), "dirty");
}
Example #6
0
/**
 * rb_playlist_source_setup_entry_view:
 * @source: the #RBPlaylistSource
 * @entry_view: the new #RBEntryView to set up
 *
 * Connects signal handlers and sets up drag and drop support for
 * an entry view to be used by a playlist source.  This only needs
 * to be called if the playlist subclass is creating a new entry view.
 */
void
rb_playlist_source_setup_entry_view (RBPlaylistSource *source,
				     RBEntryView *entry_view)
{
	g_return_if_fail (RB_IS_PLAYLIST_SOURCE (source));

	g_signal_connect_object (entry_view, "show_popup",
				 G_CALLBACK (rb_playlist_source_songs_show_popup_cb), source, 0);
	g_signal_connect_object (entry_view, "drag_data_received",
				 G_CALLBACK (rb_playlist_source_drop_cb), source, 0);
	gtk_drag_dest_set (GTK_WIDGET (entry_view),
			   GTK_DEST_DEFAULT_ALL,
			   target_uri,
			   G_N_ELEMENTS (target_uri),
			   GDK_ACTION_COPY);
}
Example #7
0
/**
 * rb_playlist_source_add_to_map:
 * @source: a #RBPlaylistSource
 * @location: a URI to add
 *
 * Adds a URI to the playlist's entry map.  This is useful when the
 * URI is being added to the database, but no entry exists for it yet.
 * When the entry is created, it will be added to the query model.
 *
 * Return value: TRUE if the URI was added to the entry map,
 *  FALSE if it was already there.
 */
gboolean
rb_playlist_source_add_to_map (RBPlaylistSource *source,
			       const char *location)
{
	RBRefString *refstr;

	g_return_val_if_fail (RB_IS_PLAYLIST_SOURCE (source), FALSE);

	refstr = rb_refstring_new (location);
	if (g_hash_table_lookup (source->priv->entries, refstr)) {
		rb_refstring_unref (refstr);
		return FALSE;
	}

	g_hash_table_insert (source->priv->entries,
			     refstr, GINT_TO_POINTER (1));

	return TRUE;
}
Example #8
0
/**
 * rb_playlist_source_location_in_map:
 * @source: a #RBPlaylistSource
 * @location: a URI to check
 *
 * Returns TRUE if the specified URI is in the playlist entry map
 *
 * Return value: %TRUE if the URI is present
 */
gboolean
rb_playlist_source_location_in_map (RBPlaylistSource *source,
				    const char *location)
{
	RBRefString *refstr;
	gboolean found;

	g_return_val_if_fail (RB_IS_PLAYLIST_SOURCE (source), FALSE);

	refstr = rb_refstring_find (location);
	if (refstr == NULL) {
		return FALSE;
	}

	found = (g_hash_table_lookup (source->priv->entries, refstr) != NULL);
	rb_refstring_unref (refstr);

	return found;
}
Example #9
0
static void
rb_playlist_source_finalize (GObject *object)
{
	RBPlaylistSource *source;

	g_return_if_fail (object != NULL);
	g_return_if_fail (RB_IS_PLAYLIST_SOURCE (object));

	source = RB_PLAYLIST_SOURCE (object);
	g_return_if_fail (source->priv != NULL);

	rb_debug ("Finalizing playlist source %p", source);

	g_hash_table_destroy (source->priv->entries);

	g_free (source->priv->title);
	source->priv = NULL;

	G_OBJECT_CLASS (rb_playlist_source_parent_class)->finalize (object);
}
Example #10
0
/**
 * rb_playlist_source_save_to_xml:
 * @source: the playlist source to save
 * @parent_node: libxml node below which to save the playlist
 *
 * Converts the playlist to XML format, below the specified
 * parent node.
 */
void
rb_playlist_source_save_to_xml (RBPlaylistSource *source,
				xmlNodePtr parent_node)
{
	xmlNodePtr node;
	xmlChar *name;
	GSettings *settings;
	RBPlaylistSourceClass *klass = RB_PLAYLIST_SOURCE_GET_CLASS (source);

	g_return_if_fail (RB_IS_PLAYLIST_SOURCE (source));

	node = xmlNewChild (parent_node, NULL, RB_PLAYLIST_PLAYLIST, NULL);
	g_object_get (source, "name", &name, NULL);
	xmlSetProp (node, RB_PLAYLIST_NAME, name);
	g_free (name);

	g_object_get (source, "settings", &settings, NULL);
	if (settings) {
		char *p;
		xmlSetProp (node,
			    RB_PLAYLIST_SHOW_BROWSER,
			    (xmlChar *)(g_settings_get_boolean (settings, "show-browser") ? "true" : "false"));

		p = g_strdup_printf ("%d", g_settings_get_int (settings, "paned-position"));
		xmlSetProp (node, RB_PLAYLIST_BROWSER_POSITION, (xmlChar *)p);
		g_free (p);

		xmlSetProp (node, RB_PLAYLIST_SEARCH_TYPE, (xmlChar *)g_settings_get_string (settings, "search-type"));
		g_object_unref (settings);
	}


	klass->impl_save_contents_to_xml (source, node);

	source->priv->dirty = FALSE;
}
static void
update_source (RBDiscRecorderPlugin *pi,
	       RBShell            *shell)
{
	GtkAction *burn_action, *copy_action;
	gboolean   playlist_active, is_audiocd_active;
	RBSource  *selected_source;
	const char *source_type;

	if (pi->selected_source != NULL) {
		RhythmDBQueryModel *model;

		g_object_get (pi->selected_source, "query-model", &model, NULL);
		g_signal_handlers_disconnect_by_func (model, playlist_row_inserted_cb, pi);
		g_signal_handlers_disconnect_by_func (model, playlist_entries_changed, pi);
		g_object_unref (model);
	}

	g_object_get (shell, "selected-source", &selected_source, NULL);

	/* for now restrict to playlist sources */
	playlist_active = RB_IS_PLAYLIST_SOURCE (selected_source);

	source_type = G_OBJECT_TYPE_NAME (selected_source);
	is_audiocd_active = g_str_equal (source_type, "RBAudioCdSource");

	burn_action = gtk_action_group_get_action (pi->action_group,
						   "MusicPlaylistBurnToDiscPlaylist");
	copy_action = gtk_action_group_get_action (pi->action_group,
						   "MusicAudioCDDuplicate");

	if (pi->enabled && playlist_active && rb_disc_recorder_has_burner (pi)) {
		RhythmDBQueryModel *model;

		g_object_get (selected_source, "query-model", &model, NULL);
		/* monitor for changes, to enable/disable the burn menu item */
		g_signal_connect_object (G_OBJECT (model),
					 "row_inserted",
					 G_CALLBACK (playlist_row_inserted_cb),
					 pi, 0);
		g_signal_connect_object (G_OBJECT (model),
					 "post-entry-delete",
					 G_CALLBACK (playlist_entries_changed),
					 pi, 0);

		playlist_entries_changed (GTK_TREE_MODEL (model), NULL, pi);
		g_object_unref (model);
		gtk_action_set_visible (burn_action, TRUE);
	} else {
		gtk_action_set_visible (burn_action, FALSE);
	}

	if (pi->enabled && is_audiocd_active && is_copy_available (pi)) {
		gtk_action_set_visible (copy_action, TRUE);
	} else {
		gtk_action_set_visible (copy_action, FALSE);
	}

	if (pi->selected_source != NULL) {
		g_object_unref (pi->selected_source);
	}
	pi->selected_source = selected_source;
}