[vlc-devel] commit: [PATCH] playlist, Qt4: new playlist_TreeMoveMany() (Jakob Leben )
git version control
git at videolan.org
Tue Aug 18 12:26:58 CEST 2009
vlc | branch: master | Jakob Leben <jleben at videolan.org> | Tue Aug 18 12:13:28 2009 +0200| [c54fe5a7176e1acf40fd73d560f150cefc3cfe35] | committer: Jakob Leben
[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.
> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=c54fe5a7176e1acf40fd73d560f150cefc3cfe35
---
include/vlc_playlist.h | 1 +
.../gui/qt4/components/playlist/playlist_model.cpp | 71 ++++++++--------
src/libvlccore.sym | 1 +
src/playlist/item.c | 85 +++++++++++++-------
4 files changed, 95 insertions(+), 63 deletions(-)
diff --git a/include/vlc_playlist.h b/include/vlc_playlist.h
index b98e13c..0c63d8d 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 08c6b56..b4a75a0 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<int> 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 94cf635..6381f5d 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 4051a82..d9ea120 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;
}
/**
More information about the vlc-devel
mailing list