Commit 9cd8ee7b authored by Clément Stenac's avatar Clément Stenac

Improve drag&drop handling

parent 0e5c9717
...@@ -368,7 +368,8 @@ VLC_EXPORT( playlist_item_t*, playlist_ItemToNode, (playlist_t *,playlist_item_t ...@@ -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 *) ); VLC_EXPORT( playlist_item_t*, playlist_LockItemToNode, (playlist_t *,playlist_item_t *) );
playlist_item_t *playlist_ItemFindFromInputAndRoot( playlist_t *p_playlist, 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 *************************/ /********************************** Item search *************************/
VLC_EXPORT( playlist_item_t *, playlist_ItemGetById, (playlist_t *, int) ); VLC_EXPORT( playlist_item_t *, playlist_ItemGetById, (playlist_t *, int) );
......
...@@ -300,7 +300,12 @@ PlaylistWidget::PlaylistWidget( intf_thread_t *_p_intf ) : ...@@ -300,7 +300,12 @@ PlaylistWidget::PlaylistWidget( intf_thread_t *_p_intf ) :
CONNECT( selector, activated( int ), rightPanel, setRoot( int ) ); CONNECT( selector, activated( int ), rightPanel, setRoot( int ) );
CONNECT( qobject_cast<StandardPLPanel *>(rightPanel)->model, artSet( QString ) , this, setArt( QString ) ); CONNECT( qobject_cast<StandardPLPanel *>(rightPanel)->model,
artSet( QString ) , this, setArt( QString ) );
/* Forward removal requests from the selector to the main panel */
CONNECT( qobject_cast<PLSelector *>(selector)->model,
shouldRemove( int ),
qobject_cast<StandardPLPanel *>(rightPanel), removeItem(int) );
connect( selector, SIGNAL(activated( int )), connect( selector, SIGNAL(activated( int )),
this, SIGNAL( rootChanged( int ) ) ); this, SIGNAL( rootChanged( int ) ) );
......
...@@ -75,6 +75,7 @@ private: ...@@ -75,6 +75,7 @@ private:
ClickLineEdit *searchLine; ClickLineEdit *searchLine;
int currentRootId; int currentRootId;
public slots: public slots:
void removeItem( int );
virtual void setRoot( int ); virtual void setRoot( int );
private slots: private slots:
void deleteSelection(); void deleteSelection();
......
...@@ -48,6 +48,7 @@ private slots: ...@@ -48,6 +48,7 @@ private slots:
void setSource( const QModelIndex& ); void setSource( const QModelIndex& );
signals: signals:
void activated( int ); void activated( int );
void shouldRemove( int );
}; };
#endif #endif
...@@ -217,6 +217,11 @@ void StandardPLPanel::setRoot( int i_root_id ) ...@@ -217,6 +217,11 @@ void StandardPLPanel::setRoot( int i_root_id )
model->rebuild( p_item ); model->rebuild( p_item );
} }
void StandardPLPanel::removeItem( int i_id )
{
model->removeItem( i_id );
}
void StandardPLPanel::keyPressEvent( QKeyEvent *e ) void StandardPLPanel::keyPressEvent( QKeyEvent *e )
{ {
switch( e->key() ) switch( e->key() )
......
...@@ -251,7 +251,6 @@ bool PLModel::dropMimeData(const QMimeData *data, Qt::DropAction action, ...@@ -251,7 +251,6 @@ bool PLModel::dropMimeData(const QMimeData *data, Qt::DropAction action,
PL_UNLOCK; PL_UNLOCK;
return false; return false;
} }
if( p_target->i_children == -1 ) /* A leaf */ if( p_target->i_children == -1 ) /* A leaf */
{ {
PLItem *parentItem = targetItem->parent(); PLItem *parentItem = targetItem->parent();
...@@ -276,8 +275,16 @@ bool PLModel::dropMimeData(const QMimeData *data, Qt::DropAction action, ...@@ -276,8 +275,16 @@ bool PLModel::dropMimeData(const QMimeData *data, Qt::DropAction action,
newParentItem = targetItem; newParentItem = targetItem;
} }
/* Remove from source */ /* Remove from source */
PLItem *srcItem = FindByInput( rootItem, p_src->p_input->i_id ); PLItem *srcItem = FindById( rootItem, p_src->i_id );
srcItem->remove( srcItem ); // 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 */ /* Display at new destination */
PLItem *newItem = new PLItem( p_src, newParentItem, this ); PLItem *newItem = new PLItem( p_src, newParentItem, this );
newParentItem->insertChild( newItem, i, true ); newParentItem->insertChild( newItem, i, true );
...@@ -288,8 +295,13 @@ bool PLModel::dropMimeData(const QMimeData *data, Qt::DropAction action, ...@@ -288,8 +295,13 @@ bool PLModel::dropMimeData(const QMimeData *data, Qt::DropAction action,
} }
} }
return true; return true;
} }
void PLModel::removeItem( int i_id )
{
PLItem *item = FindById( rootItem,i_id );
if( item ) item->remove( item );
}
void PLModel::addCallbacks() void PLModel::addCallbacks()
{ {
......
...@@ -123,6 +123,7 @@ public: ...@@ -123,6 +123,7 @@ public:
void doDelete( QModelIndexList selected ); void doDelete( QModelIndexList selected );
void search( QString search ); void search( QString search );
void sort( int column, Qt::SortOrder order ); void sort( int column, Qt::SortOrder order );
void removeItem( int );
/* DnD handling */ /* DnD handling */
Qt::DropActions supportedDropActions() const; Qt::DropActions supportedDropActions() const;
...@@ -172,6 +173,7 @@ private: ...@@ -172,6 +173,7 @@ private:
int i_cached_input_id; int i_cached_input_id;
signals: signals:
void artSet( QString ); void artSet( QString );
void shouldRemove( int );
public slots: public slots:
void activateItem( const QModelIndex &index ); void activateItem( const QModelIndex &index );
void activateItem( playlist_item_t *p_item ); void activateItem( playlist_item_t *p_item );
......
...@@ -386,13 +386,15 @@ playlist_item_t *playlist_ItemToNode( playlist_t *p_playlist, ...@@ -386,13 +386,15 @@ playlist_item_t *playlist_ItemToNode( playlist_t *p_playlist,
/** \todo First look if we don't already have it */ /** \todo First look if we don't already have it */
p_item_in_category = playlist_ItemFindFromInputAndRoot( p_item_in_category = playlist_ItemFindFromInputAndRoot(
p_playlist, p_item->p_input->i_id, 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 ) if( p_item_in_category )
{ {
playlist_item_t *p_item_in_one = playlist_ItemFindFromInputAndRoot( playlist_item_t *p_item_in_one = playlist_ItemFindFromInputAndRoot(
p_playlist, p_item->p_input->i_id, 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 ); ChangeToNode( p_playlist, p_item_in_category );
if( p_item_in_one->p_parent == p_playlist->p_root_onelevel ) if( p_item_in_one->p_parent == p_playlist->p_root_onelevel )
ChangeToNode( p_playlist, p_item_in_one ); ChangeToNode( p_playlist, p_item_in_one );
...@@ -432,12 +434,13 @@ playlist_item_t * playlist_LockItemToNode( playlist_t *p_playlist, ...@@ -432,12 +434,13 @@ playlist_item_t * playlist_LockItemToNode( playlist_t *p_playlist,
*/ */
playlist_item_t *playlist_ItemFindFromInputAndRoot( playlist_t *p_playlist, playlist_item_t *playlist_ItemFindFromInputAndRoot( playlist_t *p_playlist,
int i_input_id, int i_input_id,
playlist_item_t *p_root ) playlist_item_t *p_root,
vlc_bool_t b_items_only )
{ {
int i; int i;
for( i = 0 ; i< p_root->i_children ; 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 ) p_root->pp_children[i]->p_input->i_id == i_input_id )
{ {
return p_root->pp_children[i]; return p_root->pp_children[i];
...@@ -446,7 +449,8 @@ playlist_item_t *playlist_ItemFindFromInputAndRoot( playlist_t *p_playlist, ...@@ -446,7 +449,8 @@ playlist_item_t *playlist_ItemFindFromInputAndRoot( playlist_t *p_playlist,
{ {
playlist_item_t *p_search = playlist_item_t *p_search =
playlist_ItemFindFromInputAndRoot( p_playlist, i_input_id, 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; if( p_search ) return p_search;
} }
} }
...@@ -454,6 +458,26 @@ playlist_item_t *playlist_ItemFindFromInputAndRoot( playlist_t *p_playlist, ...@@ -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 * Moves an item
* *
...@@ -468,23 +492,41 @@ playlist_item_t *playlist_ItemFindFromInputAndRoot( playlist_t *p_playlist, ...@@ -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, int playlist_TreeMove( playlist_t * p_playlist, playlist_item_t *p_item,
playlist_item_t *p_node, int i_newpos ) playlist_item_t *p_node, int i_newpos )
{ {
int j; /* Drop on a top level node. Move in the two trees */
playlist_item_t *p_detach = NULL; 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;
p_detach = p_item->p_parent;
for( j = 0; j < p_detach->i_children; j++ )
{ {
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 ); else
return TreeMove( p_playlist, p_item, p_node, 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;
return VLC_SUCCESS;
} }
/** Send a notification that an item has been added to a node */ /** Send a notification that an item has been added to a node */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment