diff options
27 files changed, 954 insertions, 299 deletions
diff --git a/configure.in b/configure.in index fbbb1e2..440e60a 100644 --- a/configure.in +++ b/configure.in @@ -57,7 +57,7 @@ AC_SUBST(TOTEM_PL_PARSER_VERSION_MAJOR) AC_SUBST(TOTEM_PL_PARSER_VERSION_MINOR) AC_SUBST(TOTEM_PL_PARSER_VERSION_MICRO) -pkg_modules="glib-2.0 >= $GLIB_REQS gtk+-2.0 libxml-2.0 gthread-2.0 gio-2.0 >= $GIO_REQS" +pkg_modules="glib-2.0 >= $GLIB_REQS libxml-2.0 gthread-2.0 gio-2.0 >= $GIO_REQS" ################################## # Checking libgmime dependency diff --git a/docs/reference/totem-pl-parser-docs.xml b/docs/reference/totem-pl-parser-docs.xml index b314ffd..8fd5519 100644 --- a/docs/reference/totem-pl-parser-docs.xml +++ b/docs/reference/totem-pl-parser-docs.xml @@ -16,6 +16,7 @@ <chapter id="api-reference"> <title>API Reference</title> <xi:include href="xml/totem-pl-parser.xml"/> + <xi:include href="xml/totem-pl-playlist.xml"/> <xi:include href="xml/totem-disc.xml"/> </chapter> diff --git a/docs/reference/totem-pl-parser-sections.txt b/docs/reference/totem-pl-parser-sections.txt index 07828e0..e2c3308 100644 --- a/docs/reference/totem-pl-parser-sections.txt +++ b/docs/reference/totem-pl-parser-sections.txt @@ -6,15 +6,13 @@ TotemPlParserClass TotemPlParserResult TotemPlParserType TotemPlParserError -TotemPlParserIterFunc totem_pl_parser_new totem_pl_parser_parse totem_pl_parser_parse_async totem_pl_parser_parse_finish totem_pl_parser_parse_with_base totem_pl_parser_parse_with_base_async -totem_pl_parser_write -totem_pl_parser_write_with_title +totem_pl_parser_save totem_pl_parser_parse_duration totem_pl_parser_parse_date totem_pl_parser_add_ignored_scheme @@ -66,6 +64,34 @@ playlist_started </SECTION> <SECTION> +<FILE>totem-pl-playlist</FILE> +<TITLE>TotemPlPlaylist</TITLE> +TotemPlPlaylist +TotemPlPlaylistClass +totem_pl_playlist_new +totem_pl_playlist_size +totem_pl_playlist_prepend +totem_pl_playlist_append +totem_pl_playlist_insert +totem_pl_playlist_iter_first +totem_pl_playlist_iter_next +totem_pl_playlist_iter_prev +totem_pl_playlist_get_value +totem_pl_playlist_get_valist +totem_pl_playlist_get +totem_pl_playlist_set_value +totem_pl_playlist_set_valist +totem_pl_playlist_set +<SUBSECTION Standard> +TOTEM_PL_PLAYLIST +TOTEM_IS_PL_PLAYLIST +TOTEM_TYPE_PL_PLAYLIST +totem_pl_playlist_get_type +TOTEM_PL_PLAYLIST_CLASS +TOTEM_IS_PL_PLAYLIST_CLASS +</SECTION> + +<SECTION> <FILE>totem-disc</FILE> TotemDiscMediaType totem_cd_detect_type diff --git a/docs/reference/totem-pl-parser.types b/docs/reference/totem-pl-parser.types index 9028680..4324176 100644 --- a/docs/reference/totem-pl-parser.types +++ b/docs/reference/totem-pl-parser.types @@ -1 +1,2 @@ totem_pl_parser_get_type +totem_pl_playlist_get_type diff --git a/plparse/Makefile.am b/plparse/Makefile.am index 4d6a7f8..9addf0e 100644 --- a/plparse/Makefile.am +++ b/plparse/Makefile.am @@ -16,6 +16,7 @@ plparserinclude_HEADERS = \ totem-pl-parser-builtins.h \ totem-pl-parser-features.h \ totem-pl-parser.h \ + totem-pl-playlist.h \ totem-disc.h \ totem-pl-parser-mini.h @@ -53,6 +54,8 @@ libtotem_plparser_la_SOURCES = \ totem-pl-parser-smil.h \ totem-pl-parser-wm.h \ totem-pl-parser-xspf.h \ + totem-pl-playlist.c \ + totem-pl-playlist.h \ xmlparser.h xmlparser.c \ xmllexer.h xmllexer.c \ bswap.h @@ -106,7 +109,9 @@ libtotem_plparser_mini_la_SOURCES = \ totem-pl-parser-wm.c \ totem-pl-parser-wm.h \ totem-pl-parser-xspf.c \ - totem-pl-parser-xspf.h + totem-pl-parser-xspf.h \ + totem-pl-playlist.c \ + totem-pl-playlist.h libtotem_plparser_mini_la_CPPFLAGS = \ -I$(top_srcdir) \ diff --git a/plparse/plparser.symbols b/plparse/plparser.symbols index 25572d0..5552e19 100644 --- a/plparse/plparser.symbols +++ b/plparse/plparser.symbols @@ -24,6 +24,20 @@ totem_pl_parser_relative totem_pl_parser_resolve_uri totem_pl_parser_result_get_type totem_pl_parser_type_get_type -totem_pl_parser_write -totem_pl_parser_write_with_title +totem_pl_parser_save totem_pl_parser_metadata_get_type +totem_pl_playlist_get_type +totem_pl_playlist_new +totem_pl_playlist_size +totem_pl_playlist_prepend +totem_pl_playlist_append +totem_pl_playlist_insert +totem_pl_playlist_iter_first +totem_pl_playlist_iter_next +totem_pl_playlist_iter_prev +totem_pl_playlist_get_value +totem_pl_playlist_get_valist +totem_pl_playlist_get +totem_pl_playlist_set_value +totem_pl_playlist_set_valist +totem_pl_playlist_set diff --git a/plparse/totem-pl-parser-lines.c b/plparse/totem-pl-parser-lines.c index b114028..0ff94ff 100644 --- a/plparse/totem-pl-parser-lines.c +++ b/plparse/totem-pl-parser-lines.c @@ -27,7 +27,7 @@ #ifndef TOTEM_PL_PARSER_MINI #include <glib/gi18n-lib.h> -#include <gtk/gtk.h> + #include <gio/gio.h> #include "totem-pl-parser.h" @@ -78,13 +78,15 @@ totem_pl_parser_uri_to_dos (const char *uri, GFile *output) } gboolean -totem_pl_parser_write_m3u (TotemPlParser *parser, GtkTreeModel *model, - TotemPlParserIterFunc func, GFile *output, - gboolean dos_compatible, gpointer user_data, GError **error) +totem_pl_parser_save_m3u (TotemPlParser *parser, + TotemPlPlaylist *playlist, + GFile *output, + gboolean dos_compatible, + GError **error) { + TotemPlPlaylistIter iter; GFileOutputStream *stream; - int num_entries_total, i; - gboolean success; + gboolean valid, success; char *buf; char *cr; @@ -93,9 +95,6 @@ totem_pl_parser_write_m3u (TotemPlParser *parser, GtkTreeModel *model, return FALSE; cr = dos_compatible ? "\r\n" : "\n"; - num_entries_total = gtk_tree_model_iter_n_children (model, NULL); - if (num_entries_total == 0) - return TRUE; buf = g_strdup_printf ("#EXTM3U%s", cr); success = totem_pl_parser_write_string (G_OUTPUT_STREAM (stream), buf, error); @@ -103,18 +102,26 @@ totem_pl_parser_write_m3u (TotemPlParser *parser, GtkTreeModel *model, if (success == FALSE) return FALSE; - for (i = 1; i <= num_entries_total; i++) { - GtkTreeIter iter; + valid = totem_pl_playlist_iter_first (playlist, &iter); + + while (valid) { char *uri, *title, *path2; - gboolean custom_title; GFile *file; - if (gtk_tree_model_iter_nth_child (model, &iter, NULL, i - 1) == FALSE) - continue; + totem_pl_playlist_get (playlist, &iter, + TOTEM_PL_PARSER_FIELD_URI, &uri, + TOTEM_PL_PARSER_FIELD_TITLE, &title, + NULL); + + valid = totem_pl_playlist_iter_next (playlist, &iter); + + if (!uri) { + g_free (title); + continue; + } - func (model, &iter, &uri, &title, &custom_title, user_data); + file = g_file_new_for_uri (uri); - file = g_file_new_for_uri (uri); if (totem_pl_parser_scheme_is_ignored (parser, file) != FALSE) { g_object_unref (file); g_free (uri); @@ -123,7 +130,7 @@ totem_pl_parser_write_m3u (TotemPlParser *parser, GtkTreeModel *model, } g_object_unref (file); - if (custom_title != FALSE) { + if (title) { buf = g_strdup_printf (EXTINF",%s%s", title, cr); success = totem_pl_parser_write_string (G_OUTPUT_STREAM (stream), buf, error); g_free (buf); diff --git a/plparse/totem-pl-parser-lines.h b/plparse/totem-pl-parser-lines.h index 3d7728e..68c6371 100644 --- a/plparse/totem-pl-parser-lines.h +++ b/plparse/totem-pl-parser-lines.h @@ -36,13 +36,12 @@ G_BEGIN_DECLS const char * totem_pl_parser_is_uri_list (const char *data, gsize len); #ifndef TOTEM_PL_PARSER_MINI -gboolean totem_pl_parser_write_m3u (TotemPlParser *parser, - GtkTreeModel *model, - TotemPlParserIterFunc func, - GFile *output, - gboolean dos_compatible, - gpointer user_data, - GError **error); +gboolean totem_pl_parser_save_m3u (TotemPlParser *parser, + TotemPlPlaylist *playlist, + GFile *output, + gboolean dos_compatible, + GError **error); + TotemPlParserResult totem_pl_parser_add_ram (TotemPlParser *parser, GFile *file, TotemPlParseData *parse_data, diff --git a/plparse/totem-pl-parser-media.c b/plparse/totem-pl-parser-media.c index c945316..27d5f6e 100644 --- a/plparse/totem-pl-parser-media.c +++ b/plparse/totem-pl-parser-media.c @@ -25,7 +25,8 @@ #ifndef TOTEM_PL_PARSER_MINI #include <string.h> #include <glib.h> -#include <gtk/gtk.h> +#include <stdio.h> + #include "totem-pl-parser.h" #include "totemplparser-marshal.h" #include "totem-disc.h" diff --git a/plparse/totem-pl-parser-misc.c b/plparse/totem-pl-parser-misc.c index a65f823..8ec54df 100644 --- a/plparse/totem-pl-parser-misc.c +++ b/plparse/totem-pl-parser-misc.c @@ -26,7 +26,7 @@ #include <glib.h> #ifndef TOTEM_PL_PARSER_MINI -#include <gtk/gtk.h> + #include "totem-pl-parser.h" #include "totemplparser-marshal.h" #include "totem-disc.h" diff --git a/plparse/totem-pl-parser-pla.c b/plparse/totem-pl-parser-pla.c index 23087ac..d067d32 100644 --- a/plparse/totem-pl-parser-pla.c +++ b/plparse/totem-pl-parser-pla.c @@ -25,7 +25,7 @@ #include <string.h> #include <glib.h> #include <glib/gi18n-lib.h> -#include <gtk/gtk.h> + #include "totem-pl-parser.h" #include "totemplparser-marshal.h" #endif /* !TOTEM_PL_PARSER_MINI */ @@ -45,22 +45,24 @@ #ifndef TOTEM_PL_PARSER_MINI gboolean -totem_pl_parser_write_pla (TotemPlParser *parser, GtkTreeModel *model, - TotemPlParserIterFunc func, - GFile *output, const char *title, - gpointer user_data, GError **error) +totem_pl_parser_save_pla (TotemPlParser *parser, + TotemPlPlaylist *playlist, + GFile *output, + const char *title, + GError **error) { + TotemPlPlaylistIter iter; GFileOutputStream *stream; - int num_entries_total, i; + gint num_entries_total, i; char *buffer; - gboolean ret; - - num_entries_total = gtk_tree_model_iter_n_children (model, NULL); + gboolean valid, ret; stream = g_file_replace (output, NULL, FALSE, G_FILE_CREATE_NONE, NULL, error); if (stream == NULL) return FALSE; + num_entries_total = totem_pl_playlist_size (playlist); + /* write the header */ buffer = g_malloc0 (RECORD_SIZE); *((gint32 *)buffer) = GINT32_TO_BE (num_entries_total); @@ -78,22 +80,28 @@ totem_pl_parser_write_pla (TotemPlParser *parser, GtkTreeModel *model, } ret = TRUE; - for (i = 1; i <= num_entries_total; i++) { - GtkTreeIter iter; - char *euri, *title, *path, *converted, *filename; + valid = totem_pl_playlist_iter_first (playlist, &iter); + i = 0; + + while (valid) + { + char *euri, *path, *converted, *filename; gsize written; - gboolean custom_title; - if (gtk_tree_model_iter_nth_child (model, &iter, NULL, i - 1) == FALSE) - continue; + totem_pl_playlist_get (playlist, &iter, + TOTEM_PL_PARSER_FIELD_URI, &euri, + NULL); - func (model, &iter, &euri, &title, &custom_title, user_data); - g_free (title); + valid = totem_pl_playlist_iter_next (playlist, &iter); - memset (buffer, 0, RECORD_SIZE); + if (!euri) { + continue; + } - /* convert to filename */ + memset (buffer, 0, RECORD_SIZE); path = g_filename_from_uri (euri, NULL, error); + i++; + if (path == NULL) { DEBUG(NULL, g_print ("Couldn't convert URI '%s' to a filename: %s\n", euri, (*error)->message)); @@ -112,7 +120,9 @@ totem_pl_parser_write_pla (TotemPlParser *parser, GtkTreeModel *model, { /* should never happen, but this would be the right value */ buffer[1] = 0x01; - } else { + } + else + { /* we want the char after the slash, and it's one-based */ guint name_offset = (filename - path) + 2; diff --git a/plparse/totem-pl-parser-pla.h b/plparse/totem-pl-parser-pla.h index 0f416a4..d5081a3 100644 --- a/plparse/totem-pl-parser-pla.h +++ b/plparse/totem-pl-parser-pla.h @@ -32,13 +32,13 @@ G_BEGIN_DECLS #endif /* !TOTEM_PL_PARSER_MINI */ #ifndef TOTEM_PL_PARSER_MINI -gboolean totem_pl_parser_write_pla (TotemPlParser *parser, - GtkTreeModel *model, - TotemPlParserIterFunc func, + +gboolean totem_pl_parser_save_pla (TotemPlParser *parser, + TotemPlPlaylist *playlist, GFile *output, const char *title, - gpointer user_data, GError **error); + TotemPlParserResult totem_pl_parser_add_pla (TotemPlParser *parser, GFile *file, GFile *base_file, diff --git a/plparse/totem-pl-parser-pls.c b/plparse/totem-pl-parser-pls.c index db57617..50b5e68 100644 --- a/plparse/totem-pl-parser-pls.c +++ b/plparse/totem-pl-parser-pls.c @@ -26,7 +26,7 @@ #include <string.h> #include <glib.h> #include <glib/gi18n-lib.h> -#include <gtk/gtk.h> + #include "totem-pl-parser.h" #include "totemplparser-marshal.h" #endif /* !TOTEM_PL_PARSER_MINI */ @@ -37,18 +37,19 @@ #ifndef TOTEM_PL_PARSER_MINI gboolean -totem_pl_parser_write_pls (TotemPlParser *parser, GtkTreeModel *model, - TotemPlParserIterFunc func, - GFile *output, const char *title, - gpointer user_data, GError **error) +totem_pl_parser_save_pls (TotemPlParser *parser, + TotemPlPlaylist *playlist, + GFile *output, + const gchar *title, + GError **error) { + TotemPlPlaylistIter iter; GFileOutputStream *stream; - int num_entries_total, num_entries, i; + int num_entries, i; + gboolean valid, success; char *buf; - gboolean success; - num_entries = totem_pl_parser_num_entries (parser, model, func, user_data); - num_entries_total = gtk_tree_model_iter_n_children (model, NULL); + num_entries = totem_pl_parser_num_entries (parser, playlist); stream = g_file_replace (output, NULL, FALSE, G_FILE_CREATE_NONE, NULL, error); if (stream == NULL) @@ -74,49 +75,63 @@ totem_pl_parser_write_pls (TotemPlParser *parser, GtkTreeModel *model, if (success == FALSE) return FALSE; - for (i = 1; i <= num_entries_total; i++) { - GtkTreeIter iter; - char *uri, *title, *relative; - GFile *file; - gboolean custom_title; + valid = totem_pl_playlist_iter_first (playlist, &iter); + i = 0; - if (gtk_tree_model_iter_nth_child (model, &iter, NULL, i - 1) == FALSE) - continue; + while (valid) { + gchar *uri, *title, *relative; + GFile *file; - func (model, &iter, &uri, &title, &custom_title, user_data); + totem_pl_playlist_get (playlist, &iter, + TOTEM_PL_PARSER_FIELD_URI, &uri, + TOTEM_PL_PARSER_FIELD_TITLE, &title, + NULL); - file = g_file_new_for_uri (uri); - if (totem_pl_parser_scheme_is_ignored (parser, file) != FALSE) { - g_free (uri); - g_free (title); - g_object_unref (file); - continue; - } - g_object_unref (file); + valid = totem_pl_playlist_iter_next (playlist, &iter); - relative = totem_pl_parser_relative (output, uri); - buf = g_strdup_printf ("File%d=%s\n", i, relative ? relative : uri); - g_free (relative); - g_free (uri); - success = totem_pl_parser_write_string (G_OUTPUT_STREAM (stream), buf, error); - g_free (buf); - if (success == FALSE) { - g_free (title); - return FALSE; - } + if (!uri) { + g_free (title); + continue; + } - if (custom_title == FALSE) { - g_free (title); - continue; - } + file = g_file_new_for_uri (uri); - buf = g_strdup_printf ("Title%d=%s\n", i, title); - success = totem_pl_parser_write_string (G_OUTPUT_STREAM (stream), buf, error); - g_free (buf); - g_free (title); - if (success == FALSE) - return FALSE; - } + if (totem_pl_parser_scheme_is_ignored (parser, file)) { + g_object_unref (file); + g_free (uri); + g_free (title); + continue; + } + + g_object_unref (file); + i++; + + relative = totem_pl_parser_relative (output, uri); + buf = g_strdup_printf ("File%d=%s\n", i, relative ? relative : uri); + g_free (relative); + g_free (uri); + + success = totem_pl_parser_write_string (G_OUTPUT_STREAM (stream), buf, error); + g_free (buf); + + if (success == FALSE) { + g_free (title); + return FALSE; + } + + if (!title) { + continue; + } + + buf = g_strdup_printf ("Title%d=%s\n", i, title); + success = totem_pl_parser_write_string (G_OUTPUT_STREAM (stream), buf, error); + g_free (buf); + g_free (title); + + if (success == FALSE) { + return FALSE; + } + } g_object_unref (stream); return TRUE; diff --git a/plparse/totem-pl-parser-pls.h b/plparse/totem-pl-parser-pls.h index e74b317..6de1b88 100644 --- a/plparse/totem-pl-parser-pls.h +++ b/plparse/totem-pl-parser-pls.h @@ -32,12 +32,10 @@ G_BEGIN_DECLS #endif /* !TOTEM_PL_PARSER_MINI */ #ifndef TOTEM_PL_PARSER_MINI -gboolean totem_pl_parser_write_pls (TotemPlParser *parser, - GtkTreeModel *model, - TotemPlParserIterFunc func, +gboolean totem_pl_parser_save_pls (TotemPlParser *parser, + TotemPlPlaylist *playlist, GFile *file, const char *title, - gpointer user_data, GError **error); TotemPlParserResult totem_pl_parser_add_pls_with_contents (TotemPlParser *parser, GFile *file, diff --git a/plparse/totem-pl-parser-podcast.c b/plparse/totem-pl-parser-podcast.c index 325fe53..4480b3d 100644 --- a/plparse/totem-pl-parser-podcast.c +++ b/plparse/totem-pl-parser-podcast.c @@ -26,7 +26,7 @@ #ifndef TOTEM_PL_PARSER_MINI #include <zlib.h> -#include <gtk/gtk.h> + #include "xmlparser.h" #include "totem-pl-parser.h" #include "totemplparser-marshal.h" diff --git a/plparse/totem-pl-parser-private.h b/plparse/totem-pl-parser-private.h index deae8d7..626e372 100644 --- a/plparse/totem-pl-parser-private.h +++ b/plparse/totem-pl-parser-private.h @@ -116,10 +116,10 @@ gboolean totem_pl_parser_is_debugging_enabled (TotemPlParser *parser); char *totem_pl_parser_base_uri (GFile *file); void totem_pl_parser_playlist_end (TotemPlParser *parser, const char *playlist_title); -int totem_pl_parser_num_entries (TotemPlParser *parser, - GtkTreeModel *model, - TotemPlParserIterFunc func, - gpointer user_data); + +int totem_pl_parser_num_entries (TotemPlParser *parser, + TotemPlPlaylist *playlist); + gboolean totem_pl_parser_scheme_is_ignored (TotemPlParser *parser, GFile *file); gboolean totem_pl_parser_line_is_empty (const char *line); diff --git a/plparse/totem-pl-parser-qt.c b/plparse/totem-pl-parser-qt.c index 416cb12..db0d4ee 100644 --- a/plparse/totem-pl-parser-qt.c +++ b/plparse/totem-pl-parser-qt.c @@ -27,7 +27,7 @@ #ifndef TOTEM_PL_PARSER_MINI #include "xmlparser.h" -#include <gtk/gtk.h> + #include "totem-pl-parser.h" #include "totemplparser-marshal.h" #endif /* !TOTEM_PL_PARSER_MINI */ diff --git a/plparse/totem-pl-parser-smil.c b/plparse/totem-pl-parser-smil.c index 0e284ef..7818b5f 100644 --- a/plparse/totem-pl-parser-smil.c +++ b/plparse/totem-pl-parser-smil.c @@ -24,7 +24,7 @@ #ifndef TOTEM_PL_PARSER_MINI #include <glib.h> -#include <gtk/gtk.h> + #include <gio/gio.h> #include "xmlparser.h" #include "totem-pl-parser.h" diff --git a/plparse/totem-pl-parser-wm.c b/plparse/totem-pl-parser-wm.c index bbce3bd..3a544c2 100644 --- a/plparse/totem-pl-parser-wm.c +++ b/plparse/totem-pl-parser-wm.c @@ -27,7 +27,7 @@ #ifndef TOTEM_PL_PARSER_MINI #include "xmlparser.h" -#include <gtk/gtk.h> + #include "totem-pl-parser.h" #include "totemplparser-marshal.h" #include "totem-disc.h" diff --git a/plparse/totem-pl-parser-xspf.c b/plparse/totem-pl-parser-xspf.c index 563f2be..7de49ef 100644 --- a/plparse/totem-pl-parser-xspf.c +++ b/plparse/totem-pl-parser-xspf.c @@ -28,7 +28,7 @@ #include <glib/gi18n-lib.h> #include <libxml/tree.h> #include <libxml/parser.h> -#include <gtk/gtk.h> + #include "totem-pl-parser.h" #include "totemplparser-marshal.h" #endif /* !TOTEM_PL_PARSER_MINI */ @@ -74,17 +74,16 @@ totem_pl_parser_parse_xml_file (GFile *file) } gboolean -totem_pl_parser_write_xspf (TotemPlParser *parser, GtkTreeModel *model, - TotemPlParserIterFunc func, - GFile *output, const char *title, - gpointer user_data, GError **error) +totem_pl_parser_save_xspf (TotemPlParser *parser, + TotemPlPlaylist *playlist, + GFile *output, + const char *title, + GError **error) { + TotemPlPlaylistIter iter; GFileOutputStream *stream; - int num_entries_total, i; char *buf; - gboolean success; - - num_entries_total = gtk_tree_model_iter_n_children (model, NULL); + gboolean valid, success; stream = g_file_replace (output, NULL, FALSE, G_FILE_CREATE_NONE, NULL, error); if (stream == NULL) @@ -98,17 +97,25 @@ totem_pl_parser_write_xspf (TotemPlParser *parser, GtkTreeModel *model, if (success == FALSE) return FALSE; - for (i = 1; i <= num_entries_total; i++) { - GtkTreeIter iter; + valid = totem_pl_playlist_iter_first (playlist, &iter); + + while (valid) { char *uri, *uri_escaped, *relative, *title; GFile *file; - gboolean custom_title; - if (gtk_tree_model_iter_nth_child (model, &iter, NULL, i - 1) == FALSE) - continue; + totem_pl_playlist_get (playlist, &iter, + TOTEM_PL_PARSER_FIELD_URI, &uri, + TOTEM_PL_PARSER_FIELD_TITLE, &title, + NULL); + + valid = totem_pl_playlist_iter_next (playlist, &iter); - func (model, &iter, &uri, &title, &custom_title, user_data); - file = g_file_new_for_uri (uri); + if (!uri) { + g_free (title); + continue; + } + + file = g_file_new_for_uri (uri); if (totem_pl_parser_scheme_is_ignored (parser, file) != FALSE) { g_object_unref (file); @@ -121,32 +128,35 @@ totem_pl_parser_write_xspf (TotemPlParser *parser, GtkTreeModel *model, relative = totem_pl_parser_relative (output, uri); uri_escaped = g_markup_escape_text (relative ? relative : uri, -1); buf = g_strdup_printf (" <track>\n" - " <location>%s</location>\n", uri_escaped); + " <location>%s</location>\n", uri_escaped); success = totem_pl_parser_write_string (G_OUTPUT_STREAM (stream), buf, error); g_free (uri); g_free (uri_escaped); g_free (relative); g_free (buf); - if (success == FALSE) { + + if (success == FALSE) { g_free (title); return FALSE; } - if (custom_title == TRUE) + if (title) { buf = g_strdup_printf (" <title>%s</title>\n" - " </track>\n", title); - else + " </track>\n", title); + } else { buf = g_strdup_printf (" </track>\n"); - + } + success = totem_pl_parser_write_string (G_OUTPUT_STREAM (stream), buf, error); g_free (buf); g_free (title); - if (success == FALSE) + + if (success == FALSE) return FALSE; } buf = g_strdup_printf (" </trackList>\n" - "</playlist>"); + "</playlist>"); success = totem_pl_parser_write_string (G_OUTPUT_STREAM (stream), buf, error); g_free (buf); diff --git a/plparse/totem-pl-parser-xspf.h b/plparse/totem-pl-parser-xspf.h index e1717f4..c8e3695 100644 --- a/plparse/totem-pl-parser-xspf.h +++ b/plparse/totem-pl-parser-xspf.h @@ -32,13 +32,14 @@ G_BEGIN_DECLS #endif /* !TOTEM_PL_PARSER_MINI */ #ifndef TOTEM_PL_PARSER_MINI -gboolean totem_pl_parser_write_xspf (TotemPlParser *parser, - GtkTreeModel *model, - TotemPlParserIterFunc func, - GFile *output, - const char *title, - gpointer user_data, - GError **error); + +gboolean totem_pl_parser_save_xspf (TotemPlParser *parser, + TotemPlPlaylist *playlist, + GFile *output, + const char *title, + GError **error); + + TotemPlParserResult totem_pl_parser_add_xspf (TotemPlParser *parser, GFile *file, GFile *base_file, diff --git a/plparse/totem-pl-parser.c b/plparse/totem-pl-parser.c index 788e720..742db02 100644 --- a/plparse/totem-pl-parser.c +++ b/plparse/totem-pl-parser.c @@ -87,36 +87,35 @@ * <example> * <title>Writing a Playlist</title> * <programlisting> - * void - * parser_func (GtkTreeModel *model, GtkTreeIter *iter, - * gchar **uri, gchar **title, gboolean *custom_title, - * gpointer user_data) - * { - * gtk_tree_model_get (model, iter, - * 0, uri, - * 1, title, - * 2, custom_title, - * -1); - * } - * * { * TotemPlParser *pl; - * GtkTreeModel *tree_model; + * TotemPlPlaylist *playlist; + * TotemPlPlaylistIter iter; + * GFile *file; * * pl = totem_pl_parser_new (); - * - * &slash;* Your tree model can be as simple or as complex as you like; - * * parser_func() will just have to return the entry title, URI and custom title flag from it. *&slash; - * tree_model = gtk_list_store_new (3, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_BOOLEAN); - * populate_model (tree_model); - * - * if (totem_pl_parser_write (pl, tree_model, parser_func, "/tmp/playlist.pls", - * TOTEM_PL_PARSER_PLS, NULL, NULL) != TRUE) { + * playlist = totem_pl_playlist_new (); + * file = g_file_new_for_path ("/tmp/playlist.pls"); + * + * totem_pl_playlist_append (playlist, &iter); + * totem_pl_playlist_set (playlist, &iter, + * TOTEM_PL_PARSER_FIELD_URI, "file:///1.ogg", + * TOTEM_PL_PARSER_FIELD_TITLE, "1.ogg", + * NULL); + * + * totem_pl_playlist_append (playlist, &iter); + * totem_pl_playlist_set (playlist, &iter, + * TOTEM_PL_PARSER_FIELD_URI, "file:///2.ogg", + * NULL); + * + * if (totem_pl_parser_save (pl, playlist, file, "Title", + * TOTEM_PL_PARSER_PLS, NULL) != TRUE) { * g_error ("Playlist writing failed."); * } * - * g_object_unref (tree_model); + * g_object_unref (playlist); * g_object_unref (pl); + * g_object_unref (file); * } * </programlisting> * </example> @@ -132,7 +131,6 @@ #ifndef TOTEM_PL_PARSER_MINI #include <gobject/gvaluecollector.h> -#include <gtk/gtk.h> #ifdef HAVE_GMIME #include <gmime/gmime-utils.h> @@ -884,43 +882,48 @@ totem_pl_parser_write_buffer (GOutputStream *stream, const char *buf, guint len, /** * totem_pl_parser_num_entries: * @parser: a #TotemPlParser - * @model: a #GtkTreeModel - * @func: a pointer to a #TotemPlParserIterFunc callback function - * @user_data: a pointer to be passed to each call of @func + * @playlist: a #TotemPlPlaylist * - * Returns the number of entries in @parser's playlist, and calls - * @func for each valid entry in the playlist. + * Returns the number of valid entries in @playlist. * * Return value: the number of entries in the playlist **/ int -totem_pl_parser_num_entries (TotemPlParser *parser, GtkTreeModel *model, - TotemPlParserIterFunc func, gpointer user_data) +totem_pl_parser_num_entries (TotemPlParser *parser, + TotemPlPlaylist *playlist) { - int num_entries, i, ignored; + int num_entries, ignored; + TotemPlPlaylistIter iter; + gboolean valid; - num_entries = gtk_tree_model_iter_n_children (model, NULL); + num_entries = totem_pl_playlist_size (playlist); + valid = totem_pl_playlist_iter_first (playlist, &iter); ignored = 0; - for (i = 1; i <= num_entries; i++) - { - GtkTreeIter iter; - char *uri, *title; - GFile *file; - gboolean custom_title; + while (valid) { + gchar *uri; + GFile *file; - if (gtk_tree_model_iter_nth_child (model, &iter, NULL, i - 1) == FALSE) - return i - ignored; + totem_pl_playlist_get (playlist, &iter, + TOTEM_PL_PARSER_FIELD_URI, &uri, + NULL); - func (model, &iter, &uri, &title, &custom_title, user_data); - file = g_file_new_for_uri (uri); - if (totem_pl_parser_scheme_is_ignored (parser, file) != FALSE) - ignored++; + valid = totem_pl_playlist_iter_next (playlist, &iter); - g_object_unref (file); - g_free (uri); - g_free (title); - } + if (!uri) { + ignored++; + continue; + } + + file = g_file_new_for_uri (uri); + + if (totem_pl_parser_scheme_is_ignored (parser, file)) { + ignored++; + } + + g_object_unref (file); + g_free (uri); + } return num_entries - ignored; } @@ -1081,24 +1084,18 @@ totem_pl_parser_resolve_uri (GFile *base_gfile, #ifndef TOTEM_PL_PARSER_MINI /** - * totem_pl_parser_write_with_title: + * totem_pl_parser_save: * @parser: a #TotemPlParser - * @model: a #GtkTreeModel - * @func: a pointer to a #TotemPlParserIterFunc callback function - * @output: the output path and filename + * @playlist: a #TotemPlPlaylist + * @dest: output #GFile * @title: the playlist title - * @type: a #TotemPlParserType for the ouputted playlist - * @user_data: a pointer to be passed to each call of @func - * @error: return location for a #GError, or %NULL + * @type: a #TotemPlParserType for the outputted playlist + * @error: return loction for a #GError, or %NULL * - * Writes the playlist held by @parser and @model out to the file of - * path @output. The playlist is written in the format @type and is + * Writes the playlist held by @parser and @playlist out to the path + * pointed by @dest. The playlist is written in the format @type and is * given the title @title. * - * For each entry in the @model, the function @func is called (and passed - * @user_data), which gets various metadata values about the entry for - * the playlist writer. - * * If the @output file is a directory the #G_IO_ERROR_IS_DIRECTORY error * will be returned, and if the file is some other form of non-regular file * then a #G_IO_ERROR_NOT_REGULAR_FILE error will be returned. Some file @@ -1113,77 +1110,43 @@ totem_pl_parser_resolve_uri (GFile *base_gfile, * If writing a PLA playlist and there is an error converting a URI's encoding, * a code from #GConvertError will be returned. * - * Return value: %TRUE on success + * Returns: %TRUE on success **/ gboolean -totem_pl_parser_write_with_title (TotemPlParser *parser, GtkTreeModel *model, - TotemPlParserIterFunc func, - const char *output, const char *title, - TotemPlParserType type, - gpointer user_data, GError **error) +totem_pl_parser_save (TotemPlParser *parser, + TotemPlPlaylist *playlist, + GFile *dest, + const gchar *title, + TotemPlParserType type, + GError **error) { - GFile *file; + g_return_val_if_fail (TOTEM_IS_PL_PARSER (parser), FALSE); + g_return_val_if_fail (TOTEM_IS_PL_PLAYLIST (playlist), FALSE); + g_return_val_if_fail (G_IS_FILE (dest), FALSE); - file = g_file_new_for_commandline_arg (output); + if (totem_pl_playlist_size (playlist) == 0) { + return FALSE; + } - switch (type) - { + switch (type) + { case TOTEM_PL_PARSER_PLS: - return totem_pl_parser_write_pls (parser, model, func, - file, title, user_data, error); + return totem_pl_parser_save_pls (parser, playlist, dest, title, error); case TOTEM_PL_PARSER_M3U: case TOTEM_PL_PARSER_M3U_DOS: - return totem_pl_parser_write_m3u (parser, model, func, - file, (type == TOTEM_PL_PARSER_M3U_DOS), - user_data, error); + return totem_pl_parser_save_m3u (parser, playlist, dest, + (type == TOTEM_PL_PARSER_M3U_DOS), + error); case TOTEM_PL_PARSER_XSPF: - return totem_pl_parser_write_xspf (parser, model, func, - file, title, user_data, error); + return totem_pl_parser_save_xspf (parser, playlist, dest, title, error); case TOTEM_PL_PARSER_IRIVER_PLA: - return totem_pl_parser_write_pla (parser, model, func, - file, title, user_data, error); + return totem_pl_parser_save_pla (parser, playlist, dest, title, error); default: g_assert_not_reached (); } - g_object_unref (file); - return FALSE; } - -/** - * totem_pl_parser_write: - * @parser: a #TotemPlParser - * @model: a #GtkTreeModel - * @func: a pointer to a #TotemPlParserIterFunc callback function - * @output: the output path and filename - * @type: a #TotemPlParserType for the ouputted playlist - * @user_data: a pointer to be passed to each call of @func - * @error: return location for a #GError, or %NULL - * - * Writes the playlist held by @parser and @model out to the file of - * path @output. The playlist is written in the format @type and is given - * a %NULL title. - * - * For each entry in the @model, the function @func is called (and passed - * @user_data), which gets various metadata values about the entry for - * the playlist writer. - * - * Possible error codes are as per totem_pl_parser_write_with_title(). - * - * Return value: %TRUE on success - **/ -gboolean -totem_pl_parser_write (TotemPlParser *parser, GtkTreeModel *model, - TotemPlParserIterFunc func, - const char *output, TotemPlParserType type, - gpointer user_data, - GError **error) -{ - return totem_pl_parser_write_with_title (parser, model, func, output, - NULL, type, user_data, error); -} - #endif /* TOTEM_PL_PARSER_MINI */ /** diff --git a/plparse/totem-pl-parser.h b/plparse/totem-pl-parser.h index fe87df7..ffac31d 100644 --- a/plparse/totem-pl-parser.h +++ b/plparse/totem-pl-parser.h @@ -25,9 +25,10 @@ #include <glib.h> #include <gio/gio.h> -#include <gtk/gtk.h> + #include "totem-pl-parser-features.h" #include "totem-pl-parser-builtins.h" +#include "totem-pl-playlist.h" G_BEGIN_DECLS @@ -314,45 +315,17 @@ typedef enum { GQuark totem_pl_parser_error_quark (void); -/** - * TotemPlParserIterFunc: - * @model: a #GtkTreeModel containing the playlist entries - * @iter: a #GtkTreeIter pointing to the current row - * @uri: (out) (transfer full): return location for the entry's URI, or %NULL - * @title: (out) (transfer full): return location for the entry's title, or %NULL - * @custom_title: (out) (transfer full): return location for a boolean which, if %TRUE, indicates that the entry's @title is custom; or %NULL - * @user_data: user data to pass to the function - * - * Functions such as totem_pl_parser_write() accept pointers to TotemPlParserIterFunc()s - * as callbacks to call for each entry in the playlist. These functions - * are specific to each use of the playlist API, and should set the entry's - * @uri, @title and @custom_title return values, getting the data from @model - * or otherwise. - **/ -typedef void (*TotemPlParserIterFunc) (GtkTreeModel *model, GtkTreeIter *iter, - char **uri, char **title, - gboolean *custom_title, - gpointer user_data); - GType totem_pl_parser_get_type (void); gint64 totem_pl_parser_parse_duration (const char *duration, gboolean debug); guint64 totem_pl_parser_parse_date (const char *date_str, gboolean debug); -gboolean totem_pl_parser_write (TotemPlParser *parser, GtkTreeModel *model, - TotemPlParserIterFunc func, - const char *output, TotemPlParserType type, - gpointer user_data, - GError **error); - -gboolean totem_pl_parser_write_with_title (TotemPlParser *parser, - GtkTreeModel *model, - TotemPlParserIterFunc func, - const char *output, - const char *title, - TotemPlParserType type, - gpointer user_data, - GError **error); +gboolean totem_pl_parser_save (TotemPlParser *parser, + TotemPlPlaylist *playlist, + GFile *dest, + const gchar *title, + TotemPlParserType type, + GError **error); void totem_pl_parser_add_ignored_scheme (TotemPlParser *parser, const char *scheme); diff --git a/plparse/totem-pl-playlist.c b/plparse/totem-pl-playlist.c new file mode 100644 index 0000000..c3dfded --- /dev/null +++ b/plparse/totem-pl-playlist.c @@ -0,0 +1,533 @@ +/* + Copyright (C) 2009, Nokia + + The Gnome Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Gnome Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Gnome Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301 USA. + + Author: Carlos Garnacho <carlos@lanedo.com> + */ + +/** + * SECTION:totem-pl-playlist + * @short_description: playlist object + * @stability: Stable + * @include: totem-pl-playlist.h + * + * #TotemPlPlaylist represents a playlist, provides API to either navigate through + * the playlist elements, or perform additions or modifications. See also + * totem_pl_parser_save(). + **/ + +#include "totem-pl-playlist.h" + +typedef struct TotemPlPlaylistPrivate TotemPlPlaylistPrivate; + +struct TotemPlPlaylistPrivate { + GList *items; +}; + +#define TOTEM_PL_PLAYLIST_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), TOTEM_TYPE_PL_PLAYLIST, TotemPlPlaylistPrivate)) + +static void totem_pl_playlist_finalize (GObject *object); + + +G_DEFINE_TYPE (TotemPlPlaylist, totem_pl_playlist, G_TYPE_OBJECT) + + +static void +totem_pl_playlist_class_init (TotemPlPlaylistClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->finalize = totem_pl_playlist_finalize; + + g_type_class_add_private (klass, sizeof (TotemPlPlaylistPrivate)); +} + +static void +totem_pl_playlist_init (TotemPlPlaylist *playlist) +{ +} + +static void +totem_pl_playlist_finalize (GObject *object) +{ + TotemPlPlaylistPrivate *priv; + + priv = TOTEM_PL_PLAYLIST_GET_PRIVATE (object); + + g_list_foreach (priv->items, (GFunc) g_hash_table_destroy, NULL); + g_list_free (priv->items); + + G_OBJECT_CLASS (totem_pl_playlist_parent_class)->finalize (object); +} + +/** + * totem_pl_playlist_new: + * + * Creates a new #TotemPlPlaylist object. + * + * Returns: The newly created #TotemPlPlaylist + **/ +TotemPlPlaylist * +totem_pl_playlist_new (void) +{ + return g_object_new (TOTEM_TYPE_PL_PLAYLIST, NULL); +} + +/** + * totem_pl_playlist_size: + * @playlist: a #TotemPlPlaylist + * + * Returns the number of elements in @playlist. + * + * Returns: The number of elements + **/ +guint +totem_pl_playlist_size (TotemPlPlaylist *playlist) +{ + TotemPlPlaylistPrivate *priv; + + g_return_val_if_fail (TOTEM_IS_PL_PLAYLIST (playlist), 0); + + priv = TOTEM_PL_PLAYLIST_GET_PRIVATE (playlist); + + return g_list_length (priv->items); +} + +static GHashTable * +create_playlist_item (void) +{ + return g_hash_table_new_full (g_str_hash, + g_str_equal, + (GDestroyNotify) g_free, + (GDestroyNotify) g_free); +} + +/** + * totem_pl_playlist_prepend: + * @playlist: a #TotemPlPlaylist + * @iter: an unset #TotemPlPlaylistIter for returning the location + * + * Prepends a new empty element to @playlist, and modifies @iter so + * it points to it. To fill in values, you need to call + * totem_pl_playlist_set() or totem_pl_playlist_set_value(). + **/ +void +totem_pl_playlist_prepend (TotemPlPlaylist *playlist, + TotemPlPlaylistIter *iter) +{ + TotemPlPlaylistPrivate *priv; + GHashTable *item; + + g_return_if_fail (TOTEM_IS_PL_PLAYLIST (playlist)); + g_return_if_fail (iter != NULL); + + priv = TOTEM_PL_PLAYLIST_GET_PRIVATE (playlist); + + item = create_playlist_item (); + priv->items = g_list_prepend (priv->items, item); + + iter->data1 = playlist; + iter->data2 = priv->items; +} + +/** + * totem_pl_playlist_append: + * @playlist: a #TotemPlPlaylist + * @iter: an unset #TotemPlPlaylistIter for returning the location + * + * Appends a new empty element to @playlist, and modifies @iter so + * it points to it. To fill in values, you need to call + * totem_pl_playlist_set() or totem_pl_playlist_set_value(). + **/ +void +totem_pl_playlist_append (TotemPlPlaylist *playlist, + TotemPlPlaylistIter *iter) +{ + TotemPlPlaylistPrivate *priv; + GHashTable *item; + GList *list_item; + + g_return_if_fail (TOTEM_IS_PL_PLAYLIST (playlist)); + g_return_if_fail (iter != NULL); + + priv = TOTEM_PL_PLAYLIST_GET_PRIVATE (playlist); + + item = create_playlist_item (); + + list_item = g_list_alloc (); + list_item->data = item; + + priv->items = g_list_concat (priv->items, list_item); + + iter->data1 = playlist; + iter->data2 = list_item; +} + +/** + * totem_pl_playlist_insert: + * @playlist: a #TotemPlPlaylist + * @position: position in the playlist + * @iter: an unset #TotemPlPlaylistIter for returning the location + * + * Inserts a new empty element to @playlist at @position, and modifies + * @iter so it points to it. To fill in values, you need to call + * totem_pl_playlist_set() or totem_pl_playlist_set_value(). + * + * @position may be minor than 0 to prepend elements, or bigger than + * the current @playlist size to append elements. + **/ +void +totem_pl_playlist_insert (TotemPlPlaylist *playlist, + gint position, + TotemPlPlaylistIter *iter) +{ + TotemPlPlaylistPrivate *priv; + GHashTable *item; + + g_return_if_fail (TOTEM_IS_PL_PLAYLIST (playlist)); + g_return_if_fail (iter != NULL); + + priv = TOTEM_PL_PLAYLIST_GET_PRIVATE (playlist); + + item = create_playlist_item (); + priv->items = g_list_insert (priv->items, item, position); + + iter->data1 = playlist; + iter->data2 = g_list_find (priv->items, item); +} + +static gboolean +check_iter (TotemPlPlaylist *playlist, + TotemPlPlaylistIter *iter) +{ + TotemPlPlaylistPrivate *priv; + + if (!iter) { + return FALSE; + } + + if (iter->data1 != playlist) { + return FALSE; + } + + priv = TOTEM_PL_PLAYLIST_GET_PRIVATE (playlist); + + if (g_list_position (priv->items, iter->data2) == -1) { + return FALSE; + } + + return TRUE; +} + +/** + * totem_pl_playlist_iter_first: + * @playlist: a #TotemPlPlaylist + * @iter: an unset #TotemPlPlaylistIter for returning the location + * + * Modifies @iter so it points to the first element in @playlist. + * + * Returns: %TRUE if there is such first element. + **/ +gboolean +totem_pl_playlist_iter_first (TotemPlPlaylist *playlist, + TotemPlPlaylistIter *iter) +{ + TotemPlPlaylistPrivate *priv; + + g_return_val_if_fail (TOTEM_IS_PL_PLAYLIST (playlist), FALSE); + g_return_val_if_fail (iter != NULL, FALSE); + + priv = TOTEM_PL_PLAYLIST_GET_PRIVATE (playlist); + + if (!priv->items) { + /* Empty playlist */ + return FALSE; + } + + iter->data1 = playlist; + iter->data2 = priv->items; + + return TRUE; +} + +/** + * totem_pl_playlist_iter_next: + * @playlist: a #TotemPlPlaylist + * @iter: a #TotemPlPlaylistIter pointing to some item in @playlist + * + * Modifies @iter so it points to the next element it previously + * pointed to. This function will return %FALSE if there was no + * next element, or @iter didn't actually point to any element + * in @playlist. + * + * Returns: %TRUE if there was next element. + **/ +gboolean +totem_pl_playlist_iter_next (TotemPlPlaylist *playlist, + TotemPlPlaylistIter *iter) +{ + g_return_val_if_fail (TOTEM_IS_PL_PLAYLIST (playlist), FALSE); + g_return_val_if_fail (check_iter (playlist, iter), FALSE); + + iter->data2 = ((GList *) iter->data2)->next; + + return (iter->data2 != NULL); +} + +/** + * totem_pl_playlist_iter_prev: + * @playlist: a #TotemPlPlaylist + * @iter: a #TotemPlPlaylistIter pointing to some item in @playlist + * + * Modifies @iter so it points to the previous element it previously + * pointed to. This function will return %FALSE if there was no + * previous element, or @iter didn't actually point to any element + * in @playlist. + * + * Returns: %TRUE if there was previous element. + **/ +gboolean +totem_pl_playlist_iter_prev (TotemPlPlaylist *playlist, + TotemPlPlaylistIter *iter) +{ + g_return_val_if_fail (TOTEM_IS_PL_PLAYLIST (playlist), FALSE); + g_return_val_if_fail (check_iter (playlist, iter), FALSE); + + iter->data2 = ((GList *) iter->data2)->prev; + + return (iter->data2 != NULL); +} + +/** + * totem_pl_playlist_get_value: + * @playlist: a #TotemPlPlaylist + * @iter: a #TotemPlPlaylistIter pointing to some item in @playlist + * @key: data key + * @value: an empty #GValue to set + * + * Gets the value for @key (Such as %TOTEM_PL_PARSER_FIELD_URI) in + * the playlist item pointed by @iter. + * + * Returns: %TRUE if @iter contains data for @key. + **/ +gboolean +totem_pl_playlist_get_value (TotemPlPlaylist *playlist, + TotemPlPlaylistIter *iter, + const gchar *key, + GValue *value) +{ + TotemPlPlaylistPrivate *priv; + GHashTable *item_data; + gchar *str; + + g_return_val_if_fail (TOTEM_IS_PL_PLAYLIST (playlist), FALSE); + g_return_val_if_fail (check_iter (playlist, iter), FALSE); + g_return_val_if_fail (key != NULL, FALSE); + g_return_val_if_fail (value != NULL, FALSE); + + priv = TOTEM_PL_PLAYLIST_GET_PRIVATE (playlist); + item_data = ((GList *) iter->data2)->data; + + str = g_hash_table_lookup (item_data, key); + + if (!str) { + return FALSE; + } + + g_value_init (value, G_TYPE_STRING); + g_value_set_string (value, str); + + return TRUE; +} + +/** + * totem_pl_playlist_get_valist: + * @playlist: a #TotemPlPlaylist + * @iter: a #TotemPlPlaylistIter pointing to some item in @playlist + * @args: a va_list + * + * See totem_pl_playlist_get(), this function takes a va_list. + **/ +void +totem_pl_playlist_get_valist (TotemPlPlaylist *playlist, + TotemPlPlaylistIter *iter, + va_list args) +{ + TotemPlPlaylistPrivate *priv; + GHashTable *item_data; + gchar *key, **value; + + g_return_if_fail (TOTEM_IS_PL_PLAYLIST (playlist)); + g_return_if_fail (check_iter (playlist, iter)); + + priv = TOTEM_PL_PLAYLIST_GET_PRIVATE (playlist); + item_data = ((GList *) iter->data2)->data; + + key = va_arg (args, gchar *); + + while (key) { + value = va_arg (args, gchar **); + + if (value) { + gchar *str; + + str = g_hash_table_lookup (item_data, key); + *value = g_strdup (str); + } + + key = va_arg (args, gchar *); + } +} + +/** + * totem_pl_playlist_get: + * @playlist: a #TotemPlPlaylist + * @iter: a #TotemPlPlaylistIter pointing to some item in @playlist + * @...: pairs of key/return location for value, terminated by %NULL + * + * Gets the value for one or more keys from the element pointed + * by @iter. + **/ +void +totem_pl_playlist_get (TotemPlPlaylist *playlist, + TotemPlPlaylistIter *iter, + ...) +{ + va_list args; + + g_return_if_fail (TOTEM_IS_PL_PLAYLIST (playlist)); + g_return_if_fail (check_iter (playlist, iter)); + + va_start (args, iter); + totem_pl_playlist_get_valist (playlist, iter, args); + va_end (args); +} + +/** + * totem_pl_playlist_set_value: + * @playlist: a #TotemPlPlaylist + * @iter: a #TotemPlPlaylistIter pointing to some item in @playlist + * @key: key to set the value for + * @value: #GValue containing the key value + * + * Sets the value for @key in the element pointed by @iter. + * + * Returns: %TRUE if the value could be stored in @playlist + **/ +gboolean +totem_pl_playlist_set_value (TotemPlPlaylist *playlist, + TotemPlPlaylistIter *iter, + const gchar *key, + GValue *value) +{ + TotemPlPlaylistPrivate *priv; + GHashTable *item_data; + gchar *str; + + g_return_val_if_fail (TOTEM_IS_PL_PLAYLIST (playlist), FALSE); + g_return_val_if_fail (check_iter (playlist, iter), FALSE); + g_return_val_if_fail (key != NULL, FALSE); + g_return_val_if_fail (value != NULL, FALSE); + + priv = TOTEM_PL_PLAYLIST_GET_PRIVATE (playlist); + item_data = ((GList *) iter->data2)->data; + + if (G_VALUE_TYPE (value) == G_TYPE_STRING) { + str = g_value_dup_string (value); + } else { + GValue str_value = { 0 }; + + g_value_init (&str_value, G_TYPE_STRING); + + if (g_value_transform (value, &str_value)) { + str = g_value_dup_string (&str_value); + } else { + str = NULL; + } + + g_value_unset (&str_value); + } + + if (!str) { + g_critical ("Value could not be transformed to string"); + return FALSE; + } + + g_hash_table_replace (item_data, g_strdup (key), str); + + return TRUE; +} + +/** + * totem_pl_playlist_set_valist: + * @playlist: a #TotemPlPlaylist + * @iter: a #TotemPlPlaylistIter pointing to some item in @playlist + * @args: a va_list + * + * See totem_pl_playlist_set(), this function takes a va_list. + **/ +void +totem_pl_playlist_set_valist (TotemPlPlaylist *playlist, + TotemPlPlaylistIter *iter, + va_list args) +{ + TotemPlPlaylistPrivate *priv; + GHashTable *item_data; + gchar *key, *value; + + g_return_if_fail (TOTEM_IS_PL_PLAYLIST (playlist)); + g_return_if_fail (check_iter (playlist, iter)); + + priv = TOTEM_PL_PLAYLIST_GET_PRIVATE (playlist); + item_data = ((GList *) iter->data2)->data; + + key = va_arg (args, gchar *); + + while (key) { + value = va_arg (args, gchar *); + + g_hash_table_replace (item_data, + g_strdup (key), + g_strdup (value)); + + key = va_arg (args, gchar *); + } +} + +/** + * totem_pl_playlist_set: + * @playlist: a #TotemPlPlaylist + * @iter: a #TotemPlPlaylistIter pointing to some item in @playlist + * @...: key/value string pairs, terminated with %NULL + * + * Sets the value for one or several keys in the element pointed + * by @iter. + **/ +void +totem_pl_playlist_set (TotemPlPlaylist *playlist, + TotemPlPlaylistIter *iter, + ...) +{ + va_list args; + + g_return_if_fail (TOTEM_IS_PL_PLAYLIST (playlist)); + g_return_if_fail (check_iter (playlist, iter)); + + va_start (args, iter); + totem_pl_playlist_set_valist (playlist, iter, args); + va_end (args); +} diff --git a/plparse/totem-pl-playlist.h b/plparse/totem-pl-playlist.h new file mode 100644 index 0000000..ceddfdc --- /dev/null +++ b/plparse/totem-pl-playlist.h @@ -0,0 +1,100 @@ +/* + Copyright (C) 2009, Nokia + + The Gnome Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Gnome Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Gnome Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301 USA. + + Author: Carlos Garnacho <carlos@lanedo.com> + */ + +#ifndef __TOTEM_PL_PLAYLIST_H__ +#define __TOTEM_PL_PLAYLIST_H__ + +#include <glib-object.h> + +G_BEGIN_DECLS + +#define TOTEM_TYPE_PL_PLAYLIST (totem_pl_playlist_get_type ()) +#define TOTEM_PL_PLAYLIST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TOTEM_TYPE_PL_PLAYLIST, TotemPlPlaylist)) +#define TOTEM_PL_PLAYLIST_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TOTEM_TYPE_PL_PLAYLIST, TotemPlPlaylistClass)) +#define TOTEM_IS_PL_PLAYLIST(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TOTEM_TYPE_PL_PLAYLIST)) +#define TOTEM_IS_PL_PLAYLIST_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TOTEM_TYPE_PL_PLAYLIST)) + +typedef struct TotemPlPlaylist TotemPlPlaylist; +typedef struct TotemPlPlaylistClass TotemPlPlaylistClass; +typedef struct TotemPlPlaylistIter TotemPlPlaylistIter; + +struct TotemPlPlaylist { + GObject parent_instance; +}; + +struct TotemPlPlaylistClass { + GObjectClass parent_class; +}; + +struct TotemPlPlaylistIter { + gpointer data1; + gpointer data2; +}; + +GType totem_pl_playlist_get_type (void) G_GNUC_CONST; + +TotemPlPlaylist * totem_pl_playlist_new (void); + +guint totem_pl_playlist_size (TotemPlPlaylist *playlist); + +/* Item insertion methods */ +void totem_pl_playlist_prepend (TotemPlPlaylist *playlist, + TotemPlPlaylistIter *iter); +void totem_pl_playlist_append (TotemPlPlaylist *playlist, + TotemPlPlaylistIter *iter); +void totem_pl_playlist_insert (TotemPlPlaylist *playlist, + gint position, + TotemPlPlaylistIter *iter); + +/* Navigation methods */ +gboolean totem_pl_playlist_iter_first (TotemPlPlaylist *playlist, + TotemPlPlaylistIter *iter); +gboolean totem_pl_playlist_iter_next (TotemPlPlaylist *playlist, + TotemPlPlaylistIter *iter); +gboolean totem_pl_playlist_iter_prev (TotemPlPlaylist *playlist, + TotemPlPlaylistIter *iter); + +/* Item edition methods */ +gboolean totem_pl_playlist_get_value (TotemPlPlaylist *playlist, + TotemPlPlaylistIter *iter, + const gchar *key, + GValue *value); +void totem_pl_playlist_get_valist (TotemPlPlaylist *playlist, + TotemPlPlaylistIter *iter, + va_list args); +void totem_pl_playlist_get (TotemPlPlaylist *playlist, + TotemPlPlaylistIter *iter, + ...) G_GNUC_NULL_TERMINATED; + +gboolean totem_pl_playlist_set_value (TotemPlPlaylist *playlist, + TotemPlPlaylistIter *iter, + const gchar *key, + GValue *value); +void totem_pl_playlist_set_valist (TotemPlPlaylist *playlist, + TotemPlPlaylistIter *iter, + va_list args); +void totem_pl_playlist_set (TotemPlPlaylist *playlist, + TotemPlPlaylistIter *iter, + ...) G_GNUC_NULL_TERMINATED; + +G_END_DECLS + +#endif /* __TOTEM_PL_PLAYLIST_H__ */ diff --git a/totem-plparser-uninstalled.pc.in b/totem-plparser-uninstalled.pc.in index 47f0748..43a9a6e 100644 --- a/totem-plparser-uninstalled.pc.in +++ b/totem-plparser-uninstalled.pc.in @@ -8,7 +8,6 @@ gconf_serverdir=@libexecdir@ Name: totem-plparser Description: Totem Playlist Parser library Version: @VERSION@ -Requires: gtk+-2.0 Requires.private: libxml-2.0 gmime-2.4 Libs: ${pc_top_builddir}/${pcfiledir}/plparse/libtotem-plparser.la Cflags: -I${pc_top_builddir}/${pcfiledir}/plparse diff --git a/totem-plparser.pc.in b/totem-plparser.pc.in index 685a8db..66043dd 100644 --- a/totem-plparser.pc.in +++ b/totem-plparser.pc.in @@ -8,7 +8,6 @@ gconf_serverdir=@libexecdir@ Name: totem-plparser Description: Totem Playlist Parser library Version: @VERSION@ -Requires: gtk+-2.0 Requires.private: libxml-2.0 @GMIME@ Libs: -L${libdir} -ltotem-plparser Cflags: -I${includedir}/totem-pl-parser/1/plparser |