/** * 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; }
/** * 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; }
/** * 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); }
/** * 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); } }
/** * 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"); }
/** * 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); }
/** * 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; }
/** * 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; }
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); }
/** * 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; }