playlist: new playlist_NodeAddCopy(), modified playlist_NodeCreate()

- New function to copy a playlist item and all its children.
- Allow node creation at any position in parent.
This commit is contained in:
Jakob Leben 2010-03-11 19:26:53 +01:00
parent 6f436e214f
commit e4b20c82e3
4 changed files with 98 additions and 4 deletions

View File

@ -348,6 +348,7 @@ VLC_EXPORT( int, playlist_Add, ( playlist_t *, const char *, const char *, i
VLC_EXPORT( int, playlist_AddExt, ( playlist_t *, const char *, const char *, int, int, mtime_t, int, const char *const *, unsigned, bool, bool ) );
VLC_EXPORT( int, playlist_AddInput, ( playlist_t *, input_item_t *, int, int, bool, bool ) );
VLC_EXPORT( playlist_item_t *, playlist_NodeAddInput, ( playlist_t *, input_item_t *, playlist_item_t *, int, int, bool ) );
VLC_EXPORT( int, playlist_NodeAddCopy, ( playlist_t *, playlist_item_t *, playlist_item_t *, int ) );
/********************************** Item search *************************/
VLC_EXPORT( playlist_item_t *, playlist_ItemGetById, (playlist_t *, int ) );
@ -359,7 +360,7 @@ VLC_EXPORT( int, playlist_LiveSearchUpdate, (playlist_t *, playlist_item_t *, co
* Tree management
********************************************************/
/* Node management */
VLC_EXPORT( playlist_item_t *, playlist_NodeCreate, ( playlist_t *, const char *, playlist_item_t * p_parent, int i_flags, input_item_t * ) );
VLC_EXPORT( playlist_item_t *, playlist_NodeCreate, ( playlist_t *, const char *, playlist_item_t * p_parent, int i_pos, int i_flags, input_item_t * ) );
VLC_EXPORT( int, playlist_NodeAppend, (playlist_t *,playlist_item_t*,playlist_item_t *) );
VLC_EXPORT( int, playlist_NodeInsert, (playlist_t *,playlist_item_t*,playlist_item_t *, int) );
VLC_EXPORT( int, playlist_NodeRemoveItem, (playlist_t *,playlist_item_t*,playlist_item_t *) );

View File

@ -337,6 +337,7 @@ playlist_ItemGetById
playlist_ItemGetByInput
playlist_LiveSearchUpdate
playlist_Lock
playlist_NodeAddCopy
playlist_NodeAddInput
playlist_NodeAppend
playlist_NodeCreate

View File

@ -40,6 +40,9 @@ static int RecursiveAddIntoParent (
playlist_t *p_playlist, playlist_item_t *p_parent,
input_item_node_t *p_node, int i_pos, bool b_flat,
playlist_item_t **pp_first_leaf );
static int RecursiveInsertCopy (
playlist_t *p_playlist, playlist_item_t *p_item,
playlist_item_t *p_parent, int i_pos, bool b_flat );
/*****************************************************************************
* An input item has gained subitems (Event Callback)
@ -452,6 +455,45 @@ playlist_item_t * playlist_NodeAddInput( playlist_t *p_playlist,
return p_item;
}
/**
* Copy an item (and all its children, if any) into another node
*
* \param p_playlist the playlist to operate on
* \param p_item the playlist item to copy
* \param p_parent the parent item to copy into
* \param i_pos the position in the parent item for the new copy;
* if this is PLAYLIST_END, the copy is appended after all
* parent's children
* \return the position in parent item just behind the last new item inserted
*/
int playlist_NodeAddCopy (
playlist_t *p_playlist, playlist_item_t *p_item,
playlist_item_t *p_parent, int i_pos )
{
PL_ASSERT_LOCKED;
assert( p_parent != NULL && p_item != NULL );
assert( p_parent->i_children > -1 );
if( i_pos == PLAYLIST_END ) i_pos = p_parent->i_children;
bool b_flat = false;
playlist_item_t *p_up = p_parent;
while( p_up )
{
if( p_up == p_playlist->p_playing )
if( !pl_priv(p_playlist)->b_tree ) b_flat = true;
if( p_up == p_item )
/* TODO: We don't support copying a node into itself (yet),
because we insert items as we copy. Instead, we should copy
all items first and then insert. */
return i_pos;
p_up = p_up->p_parent;
}
return RecursiveInsertCopy( p_playlist, p_item, p_parent, i_pos, b_flat );
}
/**
* Insert a tree of input items into a given playlist node
*
@ -474,6 +516,7 @@ playlist_item_t *playlist_InsertInputItemTree (
return p_first_leaf;
}
/*****************************************************************************
* Playlist item misc operations
*****************************************************************************/
@ -790,3 +833,50 @@ static int RecursiveAddIntoParent (
}
return i_pos;
}
static int RecursiveInsertCopy (
playlist_t *p_playlist, playlist_item_t *p_item,
playlist_item_t *p_parent, int i_pos, bool b_flat )
{
PL_ASSERT_LOCKED;
assert( p_parent != NULL && p_item != NULL );
if( p_item == p_parent ) return i_pos;
input_item_t *p_input = p_item->p_input;
if( !(p_item->i_children != -1 && b_flat) )
{
input_item_t *p_new_input = input_item_Copy( VLC_OBJECT(p_playlist),
p_input );
if( !p_new_input ) return i_pos;
playlist_item_t *p_new_item = NULL;
if( p_item->i_children == -1 )
p_new_item = playlist_NodeAddInput( p_playlist, p_new_input,
p_parent, PLAYLIST_INSERT, i_pos,
pl_Locked );
else
p_new_item = playlist_NodeCreate( p_playlist, NULL,
p_parent, i_pos, 0, p_new_input );
vlc_gc_decref( p_new_input );
if( !p_new_item ) return i_pos;
i_pos++;
if( p_new_item->i_children != -1 )
p_parent = p_new_item;
}
for( int i = 0; i < p_item->i_children; i++ )
{
if( b_flat )
i_pos = RecursiveInsertCopy( p_playlist, p_item->pp_children[i],
p_parent, i_pos, true );
else
RecursiveInsertCopy( p_playlist, p_item->pp_children[i],
p_parent, p_parent->i_children, false );
}
return i_pos;
}

View File

@ -50,14 +50,15 @@ playlist_item_t *GetPrevItem( playlist_t *p_playlist,
* \param p_playlist the playlist
* \param psz_name the name of the node
* \param p_parent the parent node to attach to or NULL if no attach
* \param i_pos position of the node in the parent, PLAYLIST_END to append to end.
* \param p_flags miscellaneous flags
* \param p_input the input_item to attach to or NULL if it has to be created
* \return the new node
*/
playlist_item_t * playlist_NodeCreate( playlist_t *p_playlist,
const char *psz_name,
playlist_item_t *p_parent, int i_flags,
input_item_t *p_input )
playlist_item_t *p_parent, int i_pos,
int i_flags, input_item_t *p_input )
{
input_item_t *p_new_input = NULL;
playlist_item_t *p_item;
@ -79,7 +80,8 @@ playlist_item_t * playlist_NodeCreate( playlist_t *p_playlist,
ARRAY_APPEND(p_playlist->all_items, p_item);
if( p_parent != NULL )
playlist_NodeAppend( p_playlist, p_item, p_parent );
playlist_NodeInsert( p_playlist, p_item, p_parent,
i_pos == PLAYLIST_END ? -1 : i_pos );
playlist_SendAddNotify( p_playlist, p_item->i_id,
p_parent ? p_parent->i_id : -1,
!( i_flags & PLAYLIST_NO_REBUILD ));