From 9cd8ee7b4ee1f29fc1c0d584be813b4130492246 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Cl=C3=A9ment=20Stenac?= Date: Sun, 15 Oct 2006 15:28:34 +0000 Subject: [PATCH] Improve drag&drop handling --- include/vlc_playlist.h | 3 +- .../gui/qt4/components/interface_widgets.cpp | 7 +- .../gui/qt4/components/playlist/panels.hpp | 1 + .../gui/qt4/components/playlist/selector.hpp | 1 + .../qt4/components/playlist/standardpanel.cpp | 5 ++ modules/gui/qt4/playlist_model.cpp | 20 ++++- modules/gui/qt4/playlist_model.hpp | 2 + src/playlist/item.c | 82 ++++++++++++++----- 8 files changed, 95 insertions(+), 26 deletions(-) diff --git a/include/vlc_playlist.h b/include/vlc_playlist.h index 2b396535e5..ec497e203e 100644 --- a/include/vlc_playlist.h +++ b/include/vlc_playlist.h @@ -368,7 +368,8 @@ VLC_EXPORT( playlist_item_t*, playlist_ItemToNode, (playlist_t *,playlist_item_t VLC_EXPORT( playlist_item_t*, playlist_LockItemToNode, (playlist_t *,playlist_item_t *) ); playlist_item_t *playlist_ItemFindFromInputAndRoot( playlist_t *p_playlist, - int i_input_id, playlist_item_t *p_root ); + int i_input_id, playlist_item_t *p_root, + vlc_bool_t ); /********************************** Item search *************************/ VLC_EXPORT( playlist_item_t *, playlist_ItemGetById, (playlist_t *, int) ); diff --git a/modules/gui/qt4/components/interface_widgets.cpp b/modules/gui/qt4/components/interface_widgets.cpp index 3607bcf0d1..7bf327baff 100644 --- a/modules/gui/qt4/components/interface_widgets.cpp +++ b/modules/gui/qt4/components/interface_widgets.cpp @@ -300,7 +300,12 @@ PlaylistWidget::PlaylistWidget( intf_thread_t *_p_intf ) : CONNECT( selector, activated( int ), rightPanel, setRoot( int ) ); - CONNECT( qobject_cast(rightPanel)->model, artSet( QString ) , this, setArt( QString ) ); + CONNECT( qobject_cast(rightPanel)->model, + artSet( QString ) , this, setArt( QString ) ); + /* Forward removal requests from the selector to the main panel */ + CONNECT( qobject_cast(selector)->model, + shouldRemove( int ), + qobject_cast(rightPanel), removeItem(int) ); connect( selector, SIGNAL(activated( int )), this, SIGNAL( rootChanged( int ) ) ); diff --git a/modules/gui/qt4/components/playlist/panels.hpp b/modules/gui/qt4/components/playlist/panels.hpp index bd13eb265f..6f21ffcb6e 100644 --- a/modules/gui/qt4/components/playlist/panels.hpp +++ b/modules/gui/qt4/components/playlist/panels.hpp @@ -75,6 +75,7 @@ private: ClickLineEdit *searchLine; int currentRootId; public slots: + void removeItem( int ); virtual void setRoot( int ); private slots: void deleteSelection(); diff --git a/modules/gui/qt4/components/playlist/selector.hpp b/modules/gui/qt4/components/playlist/selector.hpp index 9a93a551bd..9d413afba6 100644 --- a/modules/gui/qt4/components/playlist/selector.hpp +++ b/modules/gui/qt4/components/playlist/selector.hpp @@ -48,6 +48,7 @@ private slots: void setSource( const QModelIndex& ); signals: void activated( int ); + void shouldRemove( int ); }; #endif diff --git a/modules/gui/qt4/components/playlist/standardpanel.cpp b/modules/gui/qt4/components/playlist/standardpanel.cpp index 57b4b69311..c4f9acc009 100644 --- a/modules/gui/qt4/components/playlist/standardpanel.cpp +++ b/modules/gui/qt4/components/playlist/standardpanel.cpp @@ -217,6 +217,11 @@ void StandardPLPanel::setRoot( int i_root_id ) model->rebuild( p_item ); } +void StandardPLPanel::removeItem( int i_id ) +{ + model->removeItem( i_id ); +} + void StandardPLPanel::keyPressEvent( QKeyEvent *e ) { switch( e->key() ) diff --git a/modules/gui/qt4/playlist_model.cpp b/modules/gui/qt4/playlist_model.cpp index be360f5bc2..b0bbdbabdd 100644 --- a/modules/gui/qt4/playlist_model.cpp +++ b/modules/gui/qt4/playlist_model.cpp @@ -251,7 +251,6 @@ bool PLModel::dropMimeData(const QMimeData *data, Qt::DropAction action, PL_UNLOCK; return false; } - if( p_target->i_children == -1 ) /* A leaf */ { PLItem *parentItem = targetItem->parent(); @@ -276,8 +275,16 @@ bool PLModel::dropMimeData(const QMimeData *data, Qt::DropAction action, newParentItem = targetItem; } /* Remove from source */ - PLItem *srcItem = FindByInput( rootItem, p_src->p_input->i_id ); - srcItem->remove( srcItem ); + PLItem *srcItem = FindById( rootItem, p_src->i_id ); + // We dropped on the source selector. Ask the dialog to forward + // to the main view + if( !srcItem ) + { + emit shouldRemove( p_src->i_id ); + } + else + srcItem->remove( srcItem ); + /* Display at new destination */ PLItem *newItem = new PLItem( p_src, newParentItem, this ); newParentItem->insertChild( newItem, i, true ); @@ -288,8 +295,13 @@ bool PLModel::dropMimeData(const QMimeData *data, Qt::DropAction action, } } return true; - } +} +void PLModel::removeItem( int i_id ) +{ + PLItem *item = FindById( rootItem,i_id ); + if( item ) item->remove( item ); +} void PLModel::addCallbacks() { diff --git a/modules/gui/qt4/playlist_model.hpp b/modules/gui/qt4/playlist_model.hpp index 68a7340e3a..c39c270676 100644 --- a/modules/gui/qt4/playlist_model.hpp +++ b/modules/gui/qt4/playlist_model.hpp @@ -123,6 +123,7 @@ public: void doDelete( QModelIndexList selected ); void search( QString search ); void sort( int column, Qt::SortOrder order ); + void removeItem( int ); /* DnD handling */ Qt::DropActions supportedDropActions() const; @@ -172,6 +173,7 @@ private: int i_cached_input_id; signals: void artSet( QString ); + void shouldRemove( int ); public slots: void activateItem( const QModelIndex &index ); void activateItem( playlist_item_t *p_item ); diff --git a/src/playlist/item.c b/src/playlist/item.c index 96f4b1481b..3de60654c7 100644 --- a/src/playlist/item.c +++ b/src/playlist/item.c @@ -386,13 +386,15 @@ playlist_item_t *playlist_ItemToNode( playlist_t *p_playlist, /** \todo First look if we don't already have it */ p_item_in_category = playlist_ItemFindFromInputAndRoot( p_playlist, p_item->p_input->i_id, - p_playlist->p_root_category ); + p_playlist->p_root_category, + VLC_TRUE ); if( p_item_in_category ) { playlist_item_t *p_item_in_one = playlist_ItemFindFromInputAndRoot( p_playlist, p_item->p_input->i_id, - p_playlist->p_root_onelevel ); + p_playlist->p_root_onelevel, + VLC_TRUE ); ChangeToNode( p_playlist, p_item_in_category ); if( p_item_in_one->p_parent == p_playlist->p_root_onelevel ) ChangeToNode( p_playlist, p_item_in_one ); @@ -432,12 +434,13 @@ playlist_item_t * playlist_LockItemToNode( playlist_t *p_playlist, */ playlist_item_t *playlist_ItemFindFromInputAndRoot( playlist_t *p_playlist, int i_input_id, - playlist_item_t *p_root ) + playlist_item_t *p_root, + vlc_bool_t b_items_only ) { int i; for( i = 0 ; i< p_root->i_children ; i++ ) { - if( p_root->pp_children[i]->i_children == -1 && + if( ( b_items_only ? p_root->pp_children[i]->i_children == -1 : 1 ) && p_root->pp_children[i]->p_input->i_id == i_input_id ) { return p_root->pp_children[i]; @@ -446,7 +449,8 @@ playlist_item_t *playlist_ItemFindFromInputAndRoot( playlist_t *p_playlist, { playlist_item_t *p_search = playlist_ItemFindFromInputAndRoot( p_playlist, i_input_id, - p_root->pp_children[i] ); + p_root->pp_children[i], + b_items_only ); if( p_search ) return p_search; } } @@ -454,6 +458,26 @@ 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 ) +{ + int j; + playlist_item_t *p_detach = p_item->p_parent; + 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 ); + + /* Attach to new parent */ + INSERT_ELEM( p_node->pp_children, p_node->i_children, i_newpos, p_item ); + p_item->p_parent = p_node; + + return VLC_SUCCESS; +} + /** * Moves an item * @@ -468,23 +492,41 @@ playlist_item_t *playlist_ItemFindFromInputAndRoot( playlist_t *p_playlist, int playlist_TreeMove( playlist_t * p_playlist, playlist_item_t *p_item, playlist_item_t *p_node, int i_newpos ) { - int j; - playlist_item_t *p_detach = NULL; - - if( p_node->i_children == -1 ) return VLC_EGENERIC; - - p_detach = p_item->p_parent; - for( j = 0; j < p_detach->i_children; j++ ) + /* 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_detach->pp_children[j] == p_item ) break; + /* Fixme: avoid useless lookups but we need some clean helpers */ + { + playlist_item_t *p_node_onelevel; + playlist_item_t *p_item_onelevel; + p_node_onelevel = playlist_ItemFindFromInputAndRoot( p_playlist, + p_node->p_input->i_id, + p_playlist->p_root_onelevel, + VLC_FALSE ); + p_item_onelevel = playlist_ItemFindFromInputAndRoot( p_playlist, + p_item->p_input->i_id, + p_playlist->p_root_onelevel, + VLC_FALSE ); + TreeMove( p_playlist, p_item_onelevel, p_node_onelevel, 0 ); + } + { + playlist_item_t *p_node_category; + playlist_item_t *p_item_category; + p_node_category = playlist_ItemFindFromInputAndRoot( p_playlist, + p_node->p_input->i_id, + p_playlist->p_root_category, + VLC_FALSE ); + p_item_category = playlist_ItemFindFromInputAndRoot( p_playlist, + p_item->p_input->i_id, + p_playlist->p_root_category, + VLC_FALSE ); + TreeMove( p_playlist, p_item_category, p_node_category, 0 ); + } + return VLC_SUCCESS; } - REMOVE_ELEM( p_detach->pp_children, p_detach->i_children, j ); - - /* Attach to new parent */ - INSERT_ELEM( p_node->pp_children, p_node->i_children, i_newpos, p_item ); - p_item->p_parent = p_node; - - return VLC_SUCCESS; + else + return TreeMove( p_playlist, p_item, p_node, i_newpos ); } /** Send a notification that an item has been added to a node */ -- 2.39.2