From: Jakob Leben Date: Tue, 18 Aug 2009 10:13:28 +0000 (+0200) Subject: [PATCH] playlist, Qt4: new playlist_TreeMoveMany() X-Git-Tag: 1.1.0-ff~4288 X-Git-Url: https://git.sesse.net/?a=commitdiff_plain;h=c54fe5a7176e1acf40fd73d560f150cefc3cfe35;p=vlc [PATCH] playlist, Qt4: new playlist_TreeMoveMany() Add new function which simplifies moving more then one item at a time and reduces complexity and increases performance of such action. Also refactor a bit old playlist_TreeMove. Use new function in Qt4 playlist model. --- diff --git a/include/vlc_playlist.h b/include/vlc_playlist.h index b98e13c124..0c63d8d678 100644 --- a/include/vlc_playlist.h +++ b/include/vlc_playlist.h @@ -300,6 +300,7 @@ VLC_EXPORT( int, playlist_AskForArtEnqueue, (playlist_t *, input_item_t *, bool /* Playlist sorting */ VLC_EXPORT( int, playlist_TreeMove, ( playlist_t *, playlist_item_t *, playlist_item_t *, int ) ); +VLC_EXPORT( int, playlist_TreeMoveMany, ( playlist_t *, int, playlist_item_t **, playlist_item_t *, int ) ); VLC_EXPORT( int, playlist_RecursiveNodeSort, ( playlist_t *, playlist_item_t *,int, int ) ); VLC_EXPORT( playlist_item_t *, playlist_CurrentPlayingItem, ( playlist_t * ) ); diff --git a/modules/gui/qt4/components/playlist/playlist_model.cpp b/modules/gui/qt4/components/playlist/playlist_model.cpp index 08c6b563fb..b4a75a0df8 100644 --- a/modules/gui/qt4/components/playlist/playlist_model.cpp +++ b/modules/gui/qt4/components/playlist/playlist_model.cpp @@ -217,22 +217,16 @@ bool PLModel::dropMimeData( const QMimeData *data, Qt::DropAction action, if( !parent.isValid()) { if( row > -1) - { - // dropped into top node p_parent = playlist_ItemGetById( p_playlist, rootItem->i_id ); - } else { - // dropped outside any item PL_UNLOCK; return true; } } else - { - // dropped into/onto an item (depends on (row = -1) or (row > -1)) p_parent = playlist_ItemGetById( p_playlist, itemId ( parent ) ); - } + if( !p_parent || p_parent->i_children == -1 ) { PL_UNLOCK; @@ -248,45 +242,52 @@ bool PLModel::dropMimeData( const QMimeData *data, Qt::DropAction action, QByteArray encodedData = data->data( "vlc/playlist-item-id" ); QDataStream stream( &encodedData, QIODevice::ReadOnly ); - /* easiest way to never miss the right index to move to is to - track the previously moved item */ - playlist_item_t *p_target = NULL; - - while( !stream.atEnd() ) + if( copy ) { - int src_id; - stream >> src_id; - playlist_item_t *p_src = playlist_ItemGetById( p_playlist, src_id ); - - if( !p_src ) - { - PL_UNLOCK; - return false; - } - if( copy ) + while( !stream.atEnd() ) { - input_item_t *input = p_src->p_input; + int i_id; + stream >> i_id; + playlist_item_t *p_item = playlist_ItemGetById( p_playlist, i_id ); + if( !p_item ) + { + PL_UNLOCK; + return false; + } + input_item_t *p_input = p_item->p_input; playlist_AddExt ( p_playlist, - p_src->p_input->psz_uri, p_src->p_input->psz_name, + p_input->psz_uri, p_input->psz_name, PLAYLIST_APPEND | PLAYLIST_SPREPARSE, PLAYLIST_END, - input->i_duration, - input->i_options, input->ppsz_options, input->optflagc, + p_input->i_duration, + p_input->i_options, p_input->ppsz_options, p_input->optflagc, p_parent == p_playlist->p_local_category, true ); - continue; } - if( !p_target ) + } + else + { + QList ids; + while( !stream.atEnd() ) { - if ( row == -1 ) row = p_parent->i_children; - playlist_TreeMove( p_playlist, p_src, p_parent, row ); + int id; + stream >> id; + ids.append(id); } - else + int count = ids.size(); + playlist_item_t *items[count]; + for( int i = 0; i < count; i++ ) { - for( row = 0 ; row < p_target->p_parent->i_children ; row++ ) - if( p_target->p_parent->pp_children[row] == p_target ) break; - playlist_TreeMove( p_playlist, p_src, p_parent, row + 1 ); + playlist_item_t *item = playlist_ItemGetById( p_playlist, ids[i] ); + if( !item ) + { + PL_UNLOCK; + return false; + } + items[i] = item; } - p_target = p_src; + playlist_TreeMoveMany( p_playlist, count, items, p_parent, + (row == -1 ? p_parent->i_children : row) ); } + PL_UNLOCK; /*TODO: That's not a good idea to rebuild the playlist */ rebuild(); diff --git a/src/libvlccore.sym b/src/libvlccore.sym index 94cf63534f..6381f5d8dd 100644 --- a/src/libvlccore.sym +++ b/src/libvlccore.sym @@ -334,6 +334,7 @@ playlist_ServicesDiscoveryAdd playlist_ServicesDiscoveryRemove playlist_Status playlist_TreeMove +playlist_TreeMoveMany playlist_Unlock __pl_Hold __pl_Release diff --git a/src/playlist/item.c b/src/playlist/item.c index 4051a82f7e..d9ea120a4c 100644 --- a/src/playlist/item.c +++ b/src/playlist/item.c @@ -672,57 +672,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( p_detach == p_node && 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; - if( p_node != p_item->p_parent ) return VLC_SUCCESS; - 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; + if ( p_node->i_children == -1 ) return VLC_EGENERIC; + + int i; + for( i = 0; i < i_items; i++ ) + { + 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--; + } + 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; } /**