]> git.sesse.net Git - vlc/blobdiff - src/playlist/item-ext.c
* DAAP : really include meta information, and don't crash on new hosts
[vlc] / src / playlist / item-ext.c
index 606223f3063b58aeaf1c3e0bb05fd37492792258..d8c54adc0ac1926d8d639db3ffda5954de95d884 100644 (file)
@@ -120,6 +120,8 @@ int playlist_AddItem( playlist_t *p_playlist, playlist_item_t *p_item,
     vlc_bool_t b_end = VLC_FALSE;
     playlist_view_t *p_view = NULL;
 
+    playlist_add_t *p_add = (playlist_add_t *)malloc(sizeof( playlist_add_t));
+
     vlc_mutex_lock( &p_playlist->object_lock );
 
     /*
@@ -196,12 +198,19 @@ int playlist_AddItem( playlist_t *p_playlist, playlist_item_t *p_item,
         {
             playlist_NodeAppend( p_playlist, VIEW_CATEGORY, p_item,
                                  p_playlist->p_general );
+            p_add->p_item = p_item;
+            p_add->p_node = p_playlist->p_general;
+            p_add->i_view = VIEW_CATEGORY;
+            val.p_address = p_add;
+            var_Set( p_playlist, "item-append", val );
         }
         else
         {
             playlist_NodeInsert( p_playlist, VIEW_CATEGORY, p_item,
                                  p_playlist->p_general, i_pos );
         }
+
+
         p_view = playlist_ViewFind( p_playlist, VIEW_ALL );
         playlist_ItemAddParent( p_item, VIEW_ALL, p_view->p_root );
 
@@ -212,6 +221,11 @@ int playlist_AddItem( playlist_t *p_playlist, playlist_item_t *p_item,
         {
             playlist_NodeAppend( p_playlist, VIEW_SIMPLE,p_item,
                                   p_view->p_root );
+            p_add->p_item = p_item;
+            p_add->p_node = p_view->p_root;
+            p_add->i_view = VIEW_SIMPLE;
+            val.p_address = p_add;
+            var_Set( p_playlist, "item-append", val );
         }
         else
         {
@@ -219,6 +233,7 @@ int playlist_AddItem( playlist_t *p_playlist, playlist_item_t *p_item,
                                   p_view->p_root, i_pos );
         }
 
+
         /* FIXME : Update sorted views */
 
         if( p_playlist->i_index >= i_pos )
@@ -248,8 +263,13 @@ int playlist_AddItem( playlist_t *p_playlist, playlist_item_t *p_item,
 
     vlc_mutex_unlock( &p_playlist->object_lock );
 
-    val.b_bool = VLC_TRUE;
-    var_Set( p_playlist, "intf-change", val );
+    if( b_end == VLC_FALSE )
+    {
+        val.b_bool = VLC_TRUE;
+        var_Set( p_playlist, "intf-change", val );
+    }
+
+    free( p_add );
 
     return p_item->input.i_id;
 }
@@ -275,6 +295,8 @@ int playlist_NodeAddItem( playlist_t *p_playlist, playlist_item_t *p_item,
     int i_position;
     playlist_view_t *p_view;
 
+    playlist_add_t *p_add = (playlist_add_t *)malloc(sizeof( playlist_add_t));
+
     vlc_mutex_lock( &p_playlist->object_lock );
 
     /* Sanity checks */
@@ -300,6 +322,7 @@ int playlist_NodeAddItem( playlist_t *p_playlist, playlist_item_t *p_item,
                 {
                     playlist_ItemDelete( p_item );
                     vlc_mutex_unlock( &p_playlist->object_lock );
+                    free( p_add );
                     return -1;
                 }
             }
@@ -327,6 +350,12 @@ int playlist_NodeAddItem( playlist_t *p_playlist, playlist_item_t *p_item,
     /* TODO: Handle modes */
     playlist_NodeAppend( p_playlist, i_view, p_item, p_parent );
 
+    p_add->p_item = p_item;
+    p_add->p_node = p_parent;
+    p_add->i_view = i_view;
+    val.p_address = p_add;
+    var_Set( p_playlist, "item-append", val );
+
     /* We update the ALL view directly */
     p_view = playlist_ViewFind( p_playlist, VIEW_ALL );
     playlist_ItemAddParent( p_item, VIEW_ALL, p_view->p_root );
@@ -350,7 +379,9 @@ int playlist_NodeAddItem( playlist_t *p_playlist, playlist_item_t *p_item,
     vlc_mutex_unlock( &p_playlist->object_lock );
 
     val.b_bool = VLC_TRUE;
-    var_Set( p_playlist, "intf-change", val );
+//    var_Set( p_playlist, "intf-change", val );
+//
+    free( p_add );
 
     return p_item->input.i_id;
 }
@@ -405,6 +436,15 @@ playlist_item_t * playlist_ItemGetByPos( playlist_t * p_playlist , int i_pos )
     }
 }
 
+playlist_item_t *playlist_LockItemGetByPos( playlist_t *p_playlist, int i_pos )
+{
+    playlist_item_t *p_ret;
+    vlc_mutex_lock( &p_playlist->object_lock );
+    p_ret = playlist_ItemGetByPos( p_playlist, i_pos );
+    vlc_mutex_unlock( &p_playlist->object_lock );
+    return p_ret;
+}
+
 /**
  * Search an item by its id
  *
@@ -425,7 +465,50 @@ playlist_item_t * playlist_ItemGetById( playlist_t * p_playlist , int i_id )
     return NULL;
 }
 
+playlist_item_t *playlist_LockItemGetById( playlist_t *p_playlist, int i_id)
+{
+    playlist_item_t *p_ret;
+    vlc_mutex_lock( &p_playlist->object_lock );
+    p_ret = playlist_ItemGetById( p_playlist, i_id );
+    vlc_mutex_unlock( &p_playlist->object_lock );
+    return p_ret;
+}
 
+/**
+ * Search an item by its input_item_t
+ *
+ * \param p_playlist the playlist
+ * \param p_item the input_item_t to find
+ * \return the item, or NULL on failure
+ */
+playlist_item_t * playlist_ItemGetByInput( playlist_t * p_playlist ,
+                                           input_item_t *p_item )
+{
+    int i;
+    if( &p_playlist->status.p_item->input == p_item )
+    {
+        return p_playlist->status.p_item;
+    }
+
+    for( i =  0 ; i < p_playlist->i_size ; i++ )
+    {
+        if( &p_playlist->pp_items[i]->input == p_item )
+        {
+            return p_playlist->pp_items[i];
+        }
+    }
+    return NULL;
+}
+
+playlist_item_t *playlist_LockItemGetByInput( playlist_t *p_playlist,
+                                               input_item_t *p_item )
+{
+    playlist_item_t *p_ret;
+    vlc_mutex_lock( &p_playlist->object_lock );
+    p_ret = playlist_ItemGetByInput( p_playlist, p_item );
+    vlc_mutex_unlock( &p_playlist->object_lock );
+    return p_ret;
+}
 
 
 /***********************************************************************
@@ -435,11 +518,13 @@ playlist_item_t * playlist_ItemGetById( playlist_t * p_playlist , int i_id )
 /**
  * Transform an item to a node
  *
+ * This function must be entered without the playlist lock
+ *
  * \param p_playlist the playlist object
  * \param p_item the item to transform
  * \return nothing
  */
-void playlist_ItemToNode( playlist_t *p_playlist,playlist_item_t *p_item )
+int playlist_ItemToNode( playlist_t *p_playlist,playlist_item_t *p_item )
 {
     int i = 0;
     if( p_item->i_children == -1 )
@@ -447,8 +532,6 @@ void playlist_ItemToNode( playlist_t *p_playlist,playlist_item_t *p_item )
         p_item->i_children = 0;
     }
 
-    vlc_mutex_lock( &p_playlist->object_lock );
-
     /* Remove it from the array of available items */
     for( i = 0 ; i < p_playlist->i_size ; i++ )
     {
@@ -457,14 +540,82 @@ void playlist_ItemToNode( playlist_t *p_playlist,playlist_item_t *p_item )
             REMOVE_ELEM( p_playlist->pp_items, p_playlist->i_size, i );
         }
     }
+    var_SetInteger( p_playlist, "item-change", p_item->input.i_id );
+
+    return VLC_SUCCESS;
+}
+
+int playlist_LockItemToNode( playlist_t *p_playlist, playlist_item_t *p_item )
+{
+    int i_ret;
+    vlc_mutex_lock( &p_playlist->object_lock );
+    i_ret = playlist_ItemToNode( p_playlist, p_item );
+    vlc_mutex_unlock( &p_playlist->object_lock );
+    return i_ret;
+}
+
+/**
+ * Replaces an item with another one
+ * This function must be entered without the playlist lock
+ *
+ * \see playlist_Replace
+ */
+int playlist_LockReplace( playlist_t *p_playlist,
+                             playlist_item_t *p_olditem,
+                             input_item_t *p_new )
+{
+    int i_ret;
+    vlc_mutex_lock( &p_playlist->object_lock );
+    i_ret = playlist_Replace( p_playlist, p_olditem, p_new );
     vlc_mutex_unlock( &p_playlist->object_lock );
+    return i_ret;
+}
+
+/**
+ * Replaces an item with another one
+ * This function must be entered with the playlist lock:
+ *
+ * \param p_playlist the playlist
+ * \param p_olditem the item to replace
+ * \param p_new the new input_item
+ * \return VLC_SUCCESS or an error
+ */
+int playlist_Replace( playlist_t *p_playlist, playlist_item_t *p_olditem,
+                       input_item_t *p_new )
+{
+    int i;
+    int j;
+
+    if( p_olditem->i_children != -1 )
+    {
+        msg_Err( p_playlist, "playlist_Replace can only be used on leafs");
+        return VLC_EGENERIC;
+    }
 
-    /* Handle the parents
-     * Nothing to do ! */
+    p_olditem->i_nb_played = 0;
+    memcpy( &p_olditem->input, p_new, sizeof( input_item_t ) );
+
+    p_olditem->i_nb_played = 0;
+
+    for( i = 0 ; i< p_olditem->i_parents ; i++ )
+    {
+        playlist_item_t *p_parent = p_olditem->pp_parents[i]->p_parent;
+
+        for( j = 0 ; j< p_parent->i_children ; i++ )
+        {
+            if( p_parent->pp_children[j] == p_olditem )
+            {
+                p_parent->i_serial++;
+            }
+        }
+    }
+    return VLC_SUCCESS;
 }
 
 /**
- * delete an item from a playlist.
+ * Deletes an item from a playlist.
+ *
+ * This function must be entered without the playlist lock
  *
  * \param p_playlist the playlist to remove from.
  * \param i_id the identifier of the item to delete
@@ -472,7 +623,6 @@ void playlist_ItemToNode( playlist_t *p_playlist,playlist_item_t *p_item )
  */
 int playlist_Delete( playlist_t * p_playlist, int i_id )
 {
-    vlc_value_t     val;
     int             i;
 
     playlist_item_t *p_item = playlist_ItemGetById( p_playlist, i_id );
@@ -481,16 +631,17 @@ int playlist_Delete( playlist_t * p_playlist, int i_id )
     {
         return VLC_EGENERIC;
     }
+    var_SetInteger( p_playlist, "item-deleted", i_id );
 
     /* Check if it is the current item */
     if( p_playlist->status.p_item == p_item )
     {
-        playlist_Control( p_playlist, PLAYLIST_STOP );
+        /* Hack we don't call playlist_Control for lock reasons */
+        p_playlist->status.i_status = PLAYLIST_STOPPED;
+        p_playlist->request.b_request = VLC_TRUE;
         p_playlist->status.p_item = NULL;
     }
 
-    vlc_mutex_lock( &p_playlist->object_lock );
-
     msg_Dbg( p_playlist, "deleting playlist item `%s'",
                           p_item->input.psz_name );
 
@@ -509,14 +660,18 @@ int playlist_Delete( playlist_t * p_playlist, int i_id )
 
     playlist_ItemDelete( p_item );
 
-    vlc_mutex_unlock( &p_playlist->object_lock );
-
-    val.b_bool = VLC_TRUE;
-    var_Set( p_playlist, "intf-change", val );
-
     return VLC_SUCCESS;
 }
 
+int playlist_LockDelete( playlist_t * p_playlist, int i_id )
+{
+    int i_ret;
+    vlc_mutex_lock( &p_playlist->object_lock );
+    i_ret = playlist_Delete( p_playlist, i_id );
+    vlc_mutex_unlock( &p_playlist->object_lock );
+    return i_ret;
+}
+
 /**
  * Clear all playlist items
  *
@@ -530,9 +685,22 @@ int playlist_Clear( playlist_t * p_playlist )
     {
         playlist_Delete( p_playlist, p_playlist->pp_items[0]->input.i_id );
     }
+    for( i = 0 ; i< p_playlist->i_views; i++ )
+    {
+        playlist_ViewEmpty( p_playlist, i, VLC_TRUE );
+    }
     return VLC_SUCCESS;
 }
 
+int playlist_LockClear( playlist_t *p_playlist )
+{
+    int i_ret;
+    vlc_mutex_lock( &p_playlist->object_lock );
+    playlist_Clear( p_playlist );
+    vlc_mutex_unlock( &p_playlist->object_lock );
+    return i_ret;
+}
+
 
 /**
  * Disables a playlist item
@@ -585,6 +753,8 @@ int playlist_Enable( playlist_t * p_playlist, playlist_item_t *p_item )
 /**
  * Move an item in a playlist
  *
+ * This function must be entered without the playlist lock
+ *
  * Move the item in the playlist with position i_pos before the current item
  * at position i_newpos.
  * \param p_playlist the playlist to move items in
@@ -653,3 +823,52 @@ int playlist_Move( playlist_t * p_playlist, int i_pos, int i_newpos )
 
     return VLC_SUCCESS;
 }
+
+/**
+ * Moves an item
+ *
+ * \param p_playlist the playlist
+ * \param p_item the item to move
+ * \param p_node the new parent of the item
+ * \param i_newpos the new position under this new parent
+ * \param i_view the view in which the move must be done or ALL_VIEWS
+ * \return VLC_SUCCESS or an error
+ */
+int playlist_TreeMove( playlist_t * p_playlist, playlist_item_t *p_item,
+                       playlist_item_t *p_node, int i_newpos, int i_view )
+{
+    int i;
+    playlist_item_t *p_detach = NULL;
+#if 0
+    if( i_view == ALL_VIEWS )
+    {
+        for( i = 0 ; i < p_playlist->i_views; i++ )
+        {
+            playlist_TreeMove( p_playlist, p_item, p_node, i_newpos,
+                               p_playlist->pp_views[i] );
+        }
+    }
+#endif
+
+    /* Find the parent */
+    for( i = 0 ; i< p_item->i_parents; i++ )
+    {
+        if( p_item->pp_parents[i]->i_view == i_view )
+        {
+            p_detach = p_item->pp_parents[i]->p_parent;
+            break;
+        }
+    }
+    if( p_detach == NULL )
+    {
+        msg_Err( p_playlist, "item not found in view %i", i_view );
+        return VLC_EGENERIC;
+    }
+
+    /* Detach from the parent */
+//    playlist_NodeDetach( p_detach, p_item );
+
+    /* Attach to new parent */
+
+    return VLC_SUCCESS;
+}