X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;ds=sidebyside;f=src%2Fplaylist%2Fitem.c;h=0dc9f1089befd87ae24f7fc03c2047020a723f47;hb=22b2b54f1fae6b33583e588b5afc167ffdd99e11;hp=9210971ccba44b753bc233901ccbbc4eceaa4764;hpb=ad77d955a5dc051976d94d6e08ee0f717ec3a938;p=vlc diff --git a/src/playlist/item.c b/src/playlist/item.c index 9210971ccb..0dc9f1089b 100644 --- a/src/playlist/item.c +++ b/src/playlist/item.c @@ -82,8 +82,11 @@ static void input_item_subitem_added( const vlc_event_t * p_event, return; } + bool b_stop = p_item_in_category->i_flags & PLAYLIST_SUBITEM_STOP_FLAG; + b_play = b_play && - p_item_in_category == get_current_status_item( p_playlist ); + p_item_in_category == get_current_status_item( p_playlist ) && + p_item_in_category->i_children == -1; /* If this item is already a node don't transform it */ if( p_item_in_category->i_children == -1 ) @@ -100,6 +103,13 @@ static void input_item_subitem_added( const vlc_event_t * p_event, if( i_ret == VLC_SUCCESS && b_play ) { + if( b_stop ) + { + p_item_in_category->i_flags &= ~PLAYLIST_SUBITEM_STOP_FLAG; + PL_UNLOCK; + playlist_Stop( p_playlist ); + return; + } playlist_Control( p_playlist, PLAYLIST_VIEWPLAY, pl_Locked, p_item_in_category, NULL ); } @@ -161,7 +171,7 @@ static void uninstall_input_item_observer( playlist_item_t * p_item ) * Playlist item creation *****************************************************************************/ playlist_item_t *playlist_ItemNewFromInput( playlist_t *p_playlist, - input_item_t *p_input ) + input_item_t *p_input, bool install_observer ) { playlist_item_t* p_item = malloc( sizeof( playlist_item_t ) ); if( !p_item ) @@ -179,8 +189,10 @@ playlist_item_t *playlist_ItemNewFromInput( playlist_t *p_playlist, p_item->pp_children = NULL; p_item->i_flags = 0; p_item->p_playlist = p_playlist; + p_item->b_input_item_observer = install_observer; - install_input_item_observer( p_item ); + if( install_observer ) + install_input_item_observer( p_item ); return p_item; } @@ -208,7 +220,8 @@ int playlist_ItemRelease( playlist_item_t *p_item ) * Most of the modules does that. * * Who wants to add proper memory management? */ - uninstall_input_item_observer( p_item ); + if( p_item->b_input_item_observer ) + uninstall_input_item_observer( p_item ); ARRAY_APPEND( pl_priv(p_playlist)->items_to_delete, p_item); return VLC_SUCCESS; } @@ -413,14 +426,14 @@ int playlist_AddInput( playlist_t* p_playlist, input_item_t *p_input, PL_LOCK_IF( !b_locked ); /* Add to ONELEVEL */ - p_item_one = playlist_ItemNewFromInput( p_playlist, p_input ); + p_item_one = playlist_ItemNewFromInput( p_playlist, p_input, false ); if( p_item_one == NULL ) return VLC_ENOMEM; AddItem( p_playlist, p_item_one, b_playlist ? p_playlist->p_local_onelevel : p_playlist->p_ml_onelevel , i_mode, i_pos ); /* Add to CATEGORY */ - p_item_cat = playlist_ItemNewFromInput( p_playlist, p_input ); + p_item_cat = playlist_ItemNewFromInput( p_playlist, p_input, true ); if( p_item_cat == NULL ) return VLC_ENOMEM; AddItem( p_playlist, p_item_cat, b_playlist ? p_playlist->p_local_category : @@ -465,13 +478,13 @@ int playlist_BothAddInput( playlist_t *p_playlist, PL_LOCK_IF( !b_locked ); /* Add to category */ - p_item_cat = playlist_ItemNewFromInput( p_playlist, p_input ); + p_item_cat = playlist_ItemNewFromInput( p_playlist, p_input, true ); if( p_item_cat == NULL ) return VLC_ENOMEM; AddItem( p_playlist, p_item_cat, p_direct_parent, i_mode, i_pos ); /* Add to onelevel */ /** \todo make a faster case for ml import */ - p_item_one = playlist_ItemNewFromInput( p_playlist, p_input ); + p_item_one = playlist_ItemNewFromInput( p_playlist, p_input, false ); if( p_item_one == NULL ) return VLC_ENOMEM; p_up = p_direct_parent; @@ -526,7 +539,7 @@ playlist_item_t * playlist_NodeAddInput( playlist_t *p_playlist, return NULL; PL_LOCK_IF( !b_locked ); - p_item = playlist_ItemNewFromInput( p_playlist, p_input ); + p_item = playlist_ItemNewFromInput( p_playlist, p_input, true ); if( p_item == NULL ) return NULL; AddItem( p_playlist, p_item, p_parent, i_mode, i_pos ); @@ -626,6 +639,7 @@ static playlist_item_t *ItemToNode( playlist_t *p_playlist, pl_priv(p_playlist)->b_reset_currently_playing = true; vlc_cond_signal( &pl_priv(p_playlist)->signal ); var_SetAddress( p_playlist, "item-change", p_item_in_category->p_input ); + var_SetAddress( p_playlist, "leaf-to-parent", p_item_in_category->p_input ); PL_UNLOCK_IF( !b_locked ); return p_item_in_category; } @@ -672,96 +686,86 @@ playlist_item_t *playlist_ItemFindFromInputAndRoot( playlist_t *p_playlist, } -static int TreeMove( playlist_t *p_playlist, playlist_item_t *p_item, - playlist_item_t *p_node, int i_newpos ) +static int ItemIndex ( playlist_item_t *p_item ) { - int j; - playlist_item_t *p_detach = p_item->p_parent; - (void)p_playlist; + for( int i = 0; i < p_item->p_parent->i_children; i++ ) + if( p_item->p_parent->pp_children[i] == p_item ) return i; + return -1; +} + +/** + * Moves an item + * + * This function must be entered with the playlist lock + * + * \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 + * \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 ) +{ + PL_ASSERT_LOCKED; if( p_node->i_children == -1 ) return VLC_EGENERIC; - for( j = 0; j < p_detach->i_children; j++ ) - { - if( p_detach->pp_children[j] == p_item ) break; - } - REMOVE_ELEM( p_detach->pp_children, p_detach->i_children, j ); + playlist_item_t *p_detach = p_item->p_parent; + int i_index = ItemIndex( p_item ); - /* If j < i_newpos, we are moving the element from the top to the - * down of the playlist. So when removing the element we have - * to change the position as we loose one element - */ - if( j < i_newpos ) + REMOVE_ELEM( p_detach->pp_children, p_detach->i_children, i_index ); + + if( p_detach == p_node && i_index < i_newpos ) i_newpos--; - /* Attach to new parent */ INSERT_ELEM( p_node->pp_children, p_node->i_children, i_newpos, p_item ); p_item->p_parent = p_node; + pl_priv( p_playlist )->b_reset_currently_playing = true; + vlc_cond_signal( &pl_priv( p_playlist )->signal ); return VLC_SUCCESS; } /** - * Moves an item + * Moves an array of items * * This function must be entered with the playlist lock * * \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_items the number of indexes to move + * \param pp_items the array of indexes to move + * \param p_node the target node + * \param i_newpos the target position under this node * \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 playlist_TreeMoveMany( playlist_t *p_playlist, + int i_items, playlist_item_t **pp_items, + playlist_item_t *p_node, int i_newpos ) { - int i_ret; PL_ASSERT_LOCKED; - /* Drop on a top level node. Move in the two trees */ - if( p_node->p_parent == p_playlist->p_root_category || - p_node->p_parent == p_playlist->p_root_onelevel ) + if ( p_node->i_children == -1 ) return VLC_EGENERIC; + + int i; + for( i = 0; i < i_items; i++ ) { - /* Fixme: avoid useless lookups but we need some clean helpers */ - { - /* Fixme: if we try to move a node on a top-level node, it will - * fail because the node doesn't exist in onelevel and we will - * do some shit in onelevel. We should recursively move all items - * within the node */ - playlist_item_t *p_node_onelevel; - playlist_item_t *p_item_onelevel; - p_node_onelevel = playlist_ItemFindFromInputAndRoot( p_playlist, - p_node->p_input, - p_playlist->p_root_onelevel, - false ); - p_item_onelevel = playlist_ItemFindFromInputAndRoot( p_playlist, - p_item->p_input, - p_playlist->p_root_onelevel, - false ); - if( p_node_onelevel && p_item_onelevel ) - TreeMove( p_playlist, p_item_onelevel, p_node_onelevel, i_newpos ); - } - { - playlist_item_t *p_node_category; - playlist_item_t *p_item_category; - p_node_category = playlist_ItemFindFromInputAndRoot( p_playlist, - p_node->p_input, - p_playlist->p_root_category, - false ); - p_item_category = playlist_ItemFindFromInputAndRoot( p_playlist, - p_item->p_input, - p_playlist->p_root_category, - false ); - if( p_node_category && p_item_category ) - TreeMove( p_playlist, p_item_category, p_node_category, 0 ); - } - i_ret = VLC_SUCCESS; + playlist_item_t *p_item = pp_items[i]; + int i_index = ItemIndex( p_item ); + playlist_item_t *p_parent = p_item->p_parent; + REMOVE_ELEM( p_parent->pp_children, p_parent->i_children, i_index ); + if ( p_parent == p_node && i_index < i_newpos ) i_newpos--; } - else - i_ret = TreeMove( p_playlist, p_item, p_node, i_newpos ); - pl_priv(p_playlist)->b_reset_currently_playing = true; - vlc_cond_signal( &pl_priv(p_playlist)->signal ); - return i_ret; + for( i = i_items - 1; i >= 0; i-- ) + { + playlist_item_t *p_item = pp_items[i]; + INSERT_ELEM( p_node->pp_children, p_node->i_children, i_newpos, p_item ); + p_item->p_parent = p_node; + } + + pl_priv( p_playlist )->b_reset_currently_playing = true; + vlc_cond_signal( &pl_priv( p_playlist )->signal ); + return VLC_SUCCESS; } /** @@ -900,12 +904,22 @@ static int DeleteInner( playlist_t * p_playlist, playlist_item_t *p_item, ARRAY_REMOVE( p_playlist->items, i ); /* Check if it is the current item */ - if( get_current_status_item( p_playlist ) == p_item && b_stop ) + if( get_current_status_item( p_playlist ) == p_item ) { - playlist_Control( p_playlist, PLAYLIST_STOP, pl_Locked ); - msg_Info( p_playlist, "stopping playback" ); + /* Stop it if we have to */ + if( b_stop ) + { + playlist_Control( p_playlist, PLAYLIST_STOP, pl_Locked ); + msg_Info( p_playlist, "stopping playback" ); + } + /* In any case, this item can't be the next one to be played ! */ + set_current_status_item( p_playlist, NULL ); } + ARRAY_BSEARCH( p_playlist->current,->i_id, int, i_id, i ); + if( i != -1 ) + ARRAY_REMOVE( p_playlist->current, i ); + PL_DEBUG( "deleting item `%s'", p_item->p_input->psz_name ); /* Remove the item from its parent */