summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--configure.in2
-rw-r--r--docs/reference/totem-pl-parser-docs.xml1
-rw-r--r--docs/reference/totem-pl-parser-sections.txt32
-rw-r--r--docs/reference/totem-pl-parser.types1
-rw-r--r--plparse/Makefile.am7
-rw-r--r--plparse/plparser.symbols18
-rw-r--r--plparse/totem-pl-parser-lines.c41
-rw-r--r--plparse/totem-pl-parser-lines.h13
-rw-r--r--plparse/totem-pl-parser-media.c3
-rw-r--r--plparse/totem-pl-parser-misc.c2
-rw-r--r--plparse/totem-pl-parser-pla.c50
-rw-r--r--plparse/totem-pl-parser-pla.h8
-rw-r--r--plparse/totem-pl-parser-pls.c107
-rw-r--r--plparse/totem-pl-parser-pls.h6
-rw-r--r--plparse/totem-pl-parser-podcast.c2
-rw-r--r--plparse/totem-pl-parser-private.h8
-rw-r--r--plparse/totem-pl-parser-qt.c2
-rw-r--r--plparse/totem-pl-parser-smil.c2
-rw-r--r--plparse/totem-pl-parser-wm.c2
-rw-r--r--plparse/totem-pl-parser-xspf.c58
-rw-r--r--plparse/totem-pl-parser-xspf.h15
-rw-r--r--plparse/totem-pl-parser.c195
-rw-r--r--plparse/totem-pl-parser.h43
-rw-r--r--plparse/totem-pl-playlist.c533
-rw-r--r--plparse/totem-pl-playlist.h100
-rw-r--r--totem-plparser-uninstalled.pc.in1
-rw-r--r--totem-plparser.pc.in1
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