+++ /dev/null
-/*
- * This file is a part of MAFW
- *
- * Copyright (C) 2007, 2008, 2009 Nokia Corporation, all rights reserved.
- *
- * Contact: Visa Smolander <visa.smolander@nokia.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#include "mafw-playlist-iterator.h"
-#include "mafw-gst-renderer-marshal.h"
-
-#undef G_LOG_DOMAIN
-#define G_LOG_DOMAIN "mafw-gst-renderer-playlist-iterator"
-
-struct _MafwPlaylistIteratorPrivate {
- MafwPlaylist *playlist;
- gint current_index;
- gchar *current_objectid;
- gint size;
-};
-
-typedef gboolean (*movement_function) (MafwPlaylist *playlist,
- guint *index,
- gchar **objectid,
- GError **error);
-
-enum {
- PLAYLIST_CHANGED = 0,
- LAST_SIGNAL,
-};
-
-static guint mafw_playlist_iterator_signals[LAST_SIGNAL];
-
-G_DEFINE_TYPE(MafwPlaylistIterator, mafw_playlist_iterator, G_TYPE_OBJECT);
-
-static void
-mafw_playlist_iterator_dispose(GObject *object)
-{
- MafwPlaylistIterator *iterator = (MafwPlaylistIterator *) object;
-
- g_return_if_fail(MAFW_IS_PLAYLIST_ITERATOR(iterator));
-
- mafw_playlist_iterator_invalidate(iterator);
-
- G_OBJECT_CLASS(mafw_playlist_iterator_parent_class)->dispose(object);
-}
-
-static void
-mafw_playlist_iterator_class_init(MafwPlaylistIteratorClass *klass)
-{
- GObjectClass *gclass = NULL;
-
- gclass = G_OBJECT_CLASS(klass);
- g_return_if_fail(gclass != NULL);
-
- g_type_class_add_private(klass, sizeof(MafwPlaylistIteratorPrivate));
-
- gclass->dispose = mafw_playlist_iterator_dispose;
-
- mafw_playlist_iterator_signals[PLAYLIST_CHANGED] =
- g_signal_new("playlist-changed",
- G_TYPE_FROM_CLASS(klass),
- G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET(MafwPlaylistIteratorClass, playlist_changed),
- NULL,
- NULL,
- mafw_gst_renderer_marshal_VOID__BOOLEAN_UINT_INT_STRING,
- G_TYPE_NONE,
- 4,
- G_TYPE_BOOLEAN,
- G_TYPE_UINT, G_TYPE_INT, G_TYPE_STRING);
-}
-
-static void
-mafw_playlist_iterator_init(MafwPlaylistIterator *self)
-{
- self->priv = G_TYPE_INSTANCE_GET_PRIVATE(self,
- MAFW_TYPE_PLAYLIST_ITERATOR,
- MafwPlaylistIteratorPrivate);
-}
-
-static void
-mafw_playlist_iterator_set_data(MafwPlaylistIterator *iterator, gint index,
- gchar *objectid)
-{
- g_assert(mafw_playlist_iterator_is_valid(iterator));
-
- g_free(iterator->priv->current_objectid);
- iterator->priv->current_index = index;
- iterator->priv->current_objectid = objectid;
-}
-
-static MafwPlaylistIteratorMovementResult
-mafw_playlist_iterator_move_to_next_in_direction(MafwPlaylistIterator *iterator,
- movement_function get_next_in_direction,
- GError **error)
-{
- gint index;
- gchar *objectid = NULL;
- GError *new_error = NULL;
- gboolean playlist_movement_result = FALSE;
- MafwPlaylistIteratorMovementResult iterator_movement_result =
- MAFW_PLAYLIST_ITERATOR_MOVE_RESULT_OK;
-
- g_return_val_if_fail(mafw_playlist_iterator_is_valid(iterator),
- MAFW_PLAYLIST_ITERATOR_MOVE_RESULT_INVALID);
-
- index = iterator->priv->current_index;
-
- playlist_movement_result =
- get_next_in_direction (iterator->priv->playlist,
- (guint *) &index,
- &objectid, &new_error);
-
- if (new_error != NULL) {
- g_propagate_error(error, new_error);
- iterator_movement_result =
- MAFW_PLAYLIST_ITERATOR_MOVE_RESULT_ERROR;
- } else if (playlist_movement_result) {
- mafw_playlist_iterator_set_data(iterator, index, objectid);
- } else {
- iterator_movement_result =
- MAFW_PLAYLIST_ITERATOR_MOVE_RESULT_LIMIT;
- }
-
- return iterator_movement_result;
-}
-
-static void
-mafw_playlist_iterator_playlist_contents_changed_handler(MafwPlaylist *playlist,
- guint from,
- guint nremove,
- guint nreplace,
- gpointer user_data)
-{
- gint play_index;
- gboolean clip_changed = FALSE;
- GError *error = NULL;
- MafwPlaylistIterator *iterator = (MafwPlaylistIterator*) user_data;
-
- g_return_if_fail(MAFW_IS_PLAYLIST(playlist));
- g_return_if_fail(MAFW_IS_PLAYLIST_ITERATOR(iterator));
-
- if (iterator->priv->playlist == NULL) {
- g_critical("Got playlist:contents-changed but renderer has no" \
- "playlist assigned!. Skipping...");
- return;
- }
-
- play_index = iterator->priv->current_index;
- iterator->priv->size += nreplace;
-
- if (nremove > 0) {
- /* Items have been removed from the playlist */
- iterator->priv->size -= nremove;
- if ((play_index >= from) &&
- (play_index < from + nremove)) {
- /* The current index has been removed */
- guint pls_size =
- mafw_playlist_iterator_get_size(iterator,
- &error);
- if (error == NULL) {
- /* Is the current index invalid now? If not,
- set current item to the last in the playlist,
- otherwise the keep the index and update the
- media */
- if (pls_size == 0) {
- mafw_playlist_iterator_set_data(iterator, -1, NULL);
- } else if (play_index >= pls_size) {
- mafw_playlist_iterator_move_to_index(iterator,
- pls_size - 1,
- &error);
- } else {
- mafw_playlist_iterator_update(iterator,
- &error);
- }
-
- clip_changed = TRUE;
- }
- } else if (from < play_index) {
- /* The current index has been moved towards
- the head of the playlist */
- play_index -= nremove;
- if (play_index < 0) {
- play_index = 0;
- }
- mafw_playlist_iterator_move_to_index(iterator,
- play_index,
- &error);
- }
- } else if (nremove == 0) {
- /* Items have been inserted in the playlist */
- if (play_index == -1) {
- /* First item has been added to an empty playlist */
- mafw_playlist_iterator_reset(iterator,
- &error);
- clip_changed = TRUE;
- } else if (play_index >= from) {
- /* The current item has been moved towards the
- tail of the playlist */
- mafw_playlist_iterator_move_to_index(iterator,
- play_index + nreplace,
- &error);
- }
- }
-
- if (error != NULL) {
- g_critical("playlist::contents-changed handler failed "
- "with \"%s\"", error->message);
- g_signal_emit(iterator,
- mafw_playlist_iterator_signals[PLAYLIST_CHANGED],
- 0, FALSE, error->domain, error->code, error->message);
- g_error_free (error);
- } else {
- g_signal_emit(iterator,
- mafw_playlist_iterator_signals[PLAYLIST_CHANGED],
- 0, clip_changed, 0, 0, NULL);
- }
-}
-
-static void
-mafw_playlist_iterator_playlist_item_moved_handler(MafwPlaylist *playlist,
- guint from,
- guint to,
- gpointer user_data)
-{
- MafwPlaylistIterator *iterator = (MafwPlaylistIterator *) user_data;
- gint play_index;
- GError *error = NULL;
-
- g_return_if_fail(MAFW_IS_PLAYLIST(playlist));
- g_return_if_fail(MAFW_IS_PLAYLIST_ITERATOR(iterator));
-
- if (iterator->priv->playlist == NULL) {
- g_critical("Got playlist:item-moved but renderer has not a " \
- "playlist assigned! Skipping...");
- return;
- }
-
- play_index = iterator->priv->current_index;
-
- if (play_index == from) {
- /* So the current item has been moved, let's update the
- the current index to the new location */
- mafw_playlist_iterator_move_to_index(iterator, to, &error);
- } else if (play_index > from && play_index <= to) {
- /* So we current item has been pushed one position towards
- the head, let's update the current index */
- mafw_playlist_iterator_move_to_prev(iterator, &error);
- } else if (play_index >= to && play_index < from) {
- /* So we current item has been pushed one position towards
- the head, let's update the current index */
- mafw_playlist_iterator_move_to_next(iterator, &error);
- }
-
- if (error != NULL) {
- g_critical("playlist::item-moved handler failed "
- "with \"%s\"", error->message);
- g_error_free (error);
- }
-}
-
-MafwPlaylistIterator *
-mafw_playlist_iterator_new(void)
-{
- MafwPlaylistIterator *iterator = (MafwPlaylistIterator *)
- g_object_new(MAFW_TYPE_PLAYLIST_ITERATOR, NULL);
-
- g_assert(iterator != NULL);
-
- iterator->priv->playlist = NULL;
- iterator->priv->current_index = -1;
- iterator->priv->current_objectid = NULL;
- iterator->priv->size = -1;
-
- return iterator;
-}
-
-void
-mafw_playlist_iterator_initialize(MafwPlaylistIterator *iterator,
- MafwPlaylist *playlist, GError **error)
-{
- guint size;
- gint index = -1;
- gchar *objectid = NULL;
- GError *new_error = NULL;
-
- g_return_if_fail(MAFW_IS_PLAYLIST_ITERATOR(iterator));
- g_return_if_fail(iterator->priv->playlist == NULL);
-
- iterator->priv->size = -1;
-
- mafw_playlist_get_starting_index(playlist, (guint *) &index, &objectid,
- &new_error);
-
- if (new_error == NULL) {
- size = mafw_playlist_get_size(playlist, &new_error);
- }
-
- if (new_error == NULL) {
- iterator->priv->playlist = g_object_ref(playlist);
- iterator->priv->current_index = index;
- iterator->priv->current_objectid = objectid;
- iterator->priv->size = size;
-
- g_signal_connect(playlist,
- "item-moved",
- G_CALLBACK(mafw_playlist_iterator_playlist_item_moved_handler),
- iterator);
- g_signal_connect(playlist,
- "contents-changed",
- G_CALLBACK(mafw_playlist_iterator_playlist_contents_changed_handler),
- iterator);
- }
- else {
- g_propagate_error (error, new_error);
- }
-}
-
-void
-mafw_playlist_iterator_invalidate(MafwPlaylistIterator *iterator)
-{
- g_return_if_fail(MAFW_IS_PLAYLIST_ITERATOR(iterator));
-
- if (iterator->priv->playlist != NULL) {
- g_signal_handlers_disconnect_matched(iterator->priv->playlist,
- (GSignalMatchType) G_SIGNAL_MATCH_FUNC,
- 0, 0, NULL,
- mafw_playlist_iterator_playlist_item_moved_handler,
- NULL);
-
- g_signal_handlers_disconnect_matched(iterator->priv->playlist,
- (GSignalMatchType) G_SIGNAL_MATCH_FUNC,
- 0, 0, NULL,
- mafw_playlist_iterator_playlist_contents_changed_handler,
- NULL);
-
- g_object_unref(iterator->priv->playlist);
- g_free(iterator->priv->current_objectid);
- iterator->priv->playlist = NULL;
- iterator->priv->current_index = -1;
- iterator->priv->current_objectid = NULL;
- iterator->priv->size = -1;
- }
-}
-
-gboolean
-mafw_playlist_iterator_is_valid(MafwPlaylistIterator *iterator)
-{
- g_return_val_if_fail(MAFW_IS_PLAYLIST_ITERATOR(iterator), FALSE);
-
- return iterator->priv->playlist != NULL;
-}
-
-void
-mafw_playlist_iterator_reset(MafwPlaylistIterator *iterator, GError **error)
-{
- gint index = -1;
- gchar *objectid = NULL;
- GError *new_error = NULL;
-
- g_return_if_fail(mafw_playlist_iterator_is_valid(iterator));
-
- mafw_playlist_get_starting_index(iterator->priv->playlist,
- (guint *) &index,
- &objectid, &new_error);
-
- if (new_error == NULL) {
- mafw_playlist_iterator_set_data(iterator, index, objectid);
- }
- else {
- g_propagate_error (error, new_error);
- }
-}
-
-void
-mafw_playlist_iterator_move_to_last(MafwPlaylistIterator *iterator,
- GError **error)
-{
- GError *new_error = NULL;
- gint index = -1;
- gchar *objectid = NULL;
-
- g_return_if_fail(mafw_playlist_iterator_is_valid(iterator));
-
- mafw_playlist_get_last_index(iterator->priv->playlist,
- (guint *) &index,
- &objectid, &new_error);
-
- if (new_error == NULL) {
- mafw_playlist_iterator_set_data(iterator, index, objectid);
- }
- else {
- g_propagate_error (error, new_error);
- }
-}
-
-MafwPlaylistIteratorMovementResult
-mafw_playlist_iterator_move_to_next(MafwPlaylistIterator *iterator,
- GError **error)
-{
- return mafw_playlist_iterator_move_to_next_in_direction(iterator,
- mafw_playlist_get_next,
- error);
-}
-
-MafwPlaylistIteratorMovementResult
-mafw_playlist_iterator_move_to_prev(MafwPlaylistIterator *iterator,
- GError **error)
-{
- return mafw_playlist_iterator_move_to_next_in_direction(iterator,
- mafw_playlist_get_prev,
- error);
-}
-
-MafwPlaylistIteratorMovementResult
-mafw_playlist_iterator_move_to_index(MafwPlaylistIterator *iterator,
- gint index,
- GError **error)
-{
- GError *new_error = NULL;
- MafwPlaylistIteratorMovementResult iterator_movement_result =
- MAFW_PLAYLIST_ITERATOR_MOVE_RESULT_OK;
- gint playlist_size;
-
- g_return_val_if_fail(mafw_playlist_iterator_is_valid(iterator),
- MAFW_PLAYLIST_ITERATOR_MOVE_RESULT_INVALID);
-
- playlist_size = mafw_playlist_iterator_get_size(iterator, &new_error);
-
- if (new_error != NULL) {
- g_propagate_error(error, new_error);
- iterator_movement_result =
- MAFW_PLAYLIST_ITERATOR_MOVE_RESULT_ERROR;
- } else if ((index < 0) || (index >= playlist_size)) {
- iterator_movement_result =
- MAFW_PLAYLIST_ITERATOR_MOVE_RESULT_LIMIT;
- } else {
- gchar *objectid =
- mafw_playlist_get_item(iterator->priv->playlist,
- index,
- &new_error);
-
- if (new_error != NULL) {
- g_propagate_error(error, new_error);
- iterator_movement_result =
- MAFW_PLAYLIST_ITERATOR_MOVE_RESULT_ERROR;
- } else {
- mafw_playlist_iterator_set_data(iterator, index, objectid);
- }
- }
-
- return iterator_movement_result;
-}
-
-void
-mafw_playlist_iterator_update(MafwPlaylistIterator *iterator, GError **error)
-{
- GError *new_error = NULL;
- gchar *objectid = NULL;
-
- objectid =
- mafw_playlist_get_item(iterator->priv->playlist,
- iterator->priv->current_index,
- &new_error);
-
- if (new_error != NULL) {
- g_propagate_error(error, new_error);
- } else {
- mafw_playlist_iterator_set_data(iterator,
- iterator->priv->current_index,
- objectid);
- }
-}
-
-const gchar *
-mafw_playlist_iterator_get_current_objectid(MafwPlaylistIterator *iterator)
-{
- g_return_val_if_fail(mafw_playlist_iterator_is_valid(iterator), NULL);
-
- return iterator->priv->current_objectid;
-}
-
-gint
-mafw_playlist_iterator_get_current_index(MafwPlaylistIterator *iterator)
-{
- g_return_val_if_fail(mafw_playlist_iterator_is_valid(iterator), 0);
-
- return iterator->priv->current_index;
-}
-
-gint
-mafw_playlist_iterator_get_size(MafwPlaylistIterator *iterator,
- GError **error)
-{
- g_return_val_if_fail(mafw_playlist_iterator_is_valid(iterator), -1);
-
- if (iterator->priv->size == -1) {
- iterator->priv->size =
- mafw_playlist_get_size(iterator->priv->playlist,
- error);
- }
-
- return iterator->priv->size;
-}