Commit 0f968b65 authored by Clément Stenac's avatar Clément Stenac

Playtree: handle delete nicely

parent ed9e26d2
...@@ -71,6 +71,13 @@ void CmdPlaytreeAppend::execute() ...@@ -71,6 +71,13 @@ void CmdPlaytreeAppend::execute()
rVar.onAppend( m_pAdd ); rVar.onAppend( m_pAdd );
} }
void CmdPlaytreeDelete::execute()
{
// Notify the playtree variable
Playtree &rVar = VlcProc::instance( getIntf() )->getPlaytreeVar();
rVar.onDelete( m_id );
}
void CmdSetText::execute() void CmdSetText::execute()
{ {
// Change the text variable // Change the text variable
......
...@@ -77,6 +77,26 @@ class CmdPlaytreeAppend: public CmdGeneric ...@@ -77,6 +77,26 @@ class CmdPlaytreeAppend: public CmdGeneric
playlist_add_t * m_pAdd; playlist_add_t * m_pAdd;
}; };
/// Command to notify the playtree of an item deletion
class CmdPlaytreeDelete: public CmdGeneric
{
public:
CmdPlaytreeDelete( intf_thread_t *pIntf, int i_id ) :
CmdGeneric( pIntf ), m_id( i_id ) {}
virtual ~CmdPlaytreeDelete() {}
/// This method does the real job of the command
virtual void execute();
/// Return the type of the command
virtual string getType() const { return "playtree append"; }
private:
int m_id;
};
/// Command to set a text variable /// Command to set a text variable
class CmdSetText: public CmdGeneric class CmdSetText: public CmdGeneric
......
...@@ -150,7 +150,22 @@ void CtrlTree::onUpdate( Subject<VarTree, tree_update*> &rTree, ...@@ -150,7 +150,22 @@ void CtrlTree::onUpdate( Subject<VarTree, tree_update*> &rTree,
} }
else if ( arg->i_type == 2 ) // Item-append else if ( arg->i_type == 2 ) // Item-append
{ {
/// \todo Check if the item is really visible in the view (we only check if it in the document) /// \todo Check if the item is really visible in the view
// (we only check if it in the document)
if( arg->b_visible == true )
{
makeImage();
}
}
else if( arg->i_type == 3 ) // item-del
{
/* Make sure firstPos and lastSelected are still valid */
while( m_firstPos->m_deleted && m_firstPos != m_rTree.root()->begin() )
{
m_firstPos = m_rTree.getPrevVisibleItem( m_firstPos );
}
if( m_firstPos->m_deleted ) m_firstPos = m_rTree.root()->begin();
if( arg->b_visible == true ) if( arg->b_visible == true )
{ {
makeImage(); makeImage();
...@@ -453,27 +468,30 @@ void CtrlTree::handleEvent( EvtGeneric &rEvent ) ...@@ -453,27 +468,30 @@ void CtrlTree::handleEvent( EvtGeneric &rEvent )
string::npos ) string::npos )
{ {
it = findItemAtPos(yPos); it = findItemAtPos(yPos);
if( it->size() && xPos > (it->depth() - 1) * itemImageWidth() if( it != m_rTree.end() )
&& xPos < it->depth() * itemImageWidth() )
{
// Fold/unfold the item
it->m_expanded = !it->m_expanded;
bChangedPosition = true;
}
else
{ {
// Unselect any previously selected item if( it->size() && xPos > (it->depth() - 1) * itemImageWidth()
VarTree::Iterator it2; && xPos < it->depth() * itemImageWidth() )
for( it2 = m_rTree.begin(); it2 != m_rTree.end();
it2 = m_rTree.getNextVisibleItem( it2 ) )
{ {
it2->m_selected = false; // Fold/unfold the item
it->m_expanded = !it->m_expanded;
bChangedPosition = true;
} }
// Select the new item else
if( it != m_rTree.end() )
{ {
it->m_selected = true; // Unselect any previously selected item
m_pLastSelected = &*it; VarTree::Iterator it2;
for( it2 = m_rTree.begin(); it2 != m_rTree.end();
it2 = m_rTree.getNextVisibleItem( it2 ) )
{
it2->m_selected = false;
}
// Select the new item
if( it != m_rTree.end() )
{
it->m_selected = true;
m_pLastSelected = &*it;
}
} }
} }
} }
...@@ -666,7 +684,10 @@ void CtrlTree::makeImage() ...@@ -666,7 +684,10 @@ void CtrlTree::makeImage()
m_pImage->fillRect( 0, yPos, width, rectHeight, m_pImage->fillRect( 0, yPos, width, rectHeight,
m_selColor ); m_selColor );
} }
it = m_rTree.getNextVisibleItem( it ); do
{
it = m_rTree.getNextVisibleItem( it );
} while( it->m_deleted );
} }
} }
} }
...@@ -683,7 +704,10 @@ void CtrlTree::makeImage() ...@@ -683,7 +704,10 @@ void CtrlTree::makeImage()
{ {
uint32_t color = ( it->m_selected ? m_selColor : bgColor ); uint32_t color = ( it->m_selected ? m_selColor : bgColor );
m_pImage->fillRect( 0, yPos, width, rectHeight, color ); m_pImage->fillRect( 0, yPos, width, rectHeight, color );
it = m_rTree.getNextVisibleItem( it ); do
{
it = m_rTree.getNextVisibleItem( it );
} while( it->m_deleted );
} }
else else
{ {
...@@ -746,7 +770,9 @@ void CtrlTree::makeImage() ...@@ -746,7 +770,9 @@ void CtrlTree::makeImage()
yPos += (pText->getHeight() - ySrc ); yPos += (pText->getHeight() - ySrc );
delete pText; delete pText;
} }
do {
it = m_rTree.getNextVisibleItem( it ); it = m_rTree.getNextVisibleItem( it );
} while( it->m_deleted );
} }
} }
......
...@@ -128,7 +128,7 @@ VlcProc::VlcProc( intf_thread_t *pIntf ): SkinObject( pIntf ), ...@@ -128,7 +128,7 @@ VlcProc::VlcProc( intf_thread_t *pIntf ): SkinObject( pIntf ),
// Called when a playlist item is deleted // Called when a playlist item is deleted
// TODO: properly handle item-deleted // TODO: properly handle item-deleted
var_AddCallback( pIntf->p_sys->p_playlist, "item-deleted", var_AddCallback( pIntf->p_sys->p_playlist, "item-deleted",
onIntfChange, this ); onItemDelete, this );
// Called when the "interface shower" wants us to show the skin // Called when the "interface shower" wants us to show the skin
var_AddCallback( pIntf->p_sys->p_playlist, "intf-show", var_AddCallback( pIntf->p_sys->p_playlist, "intf-show",
onIntfShow, this ); onIntfShow, this );
...@@ -174,7 +174,7 @@ VlcProc::~VlcProc() ...@@ -174,7 +174,7 @@ VlcProc::~VlcProc()
var_DelCallback( getIntf()->p_sys->p_playlist, "item-append", var_DelCallback( getIntf()->p_sys->p_playlist, "item-append",
onItemAppend, this ); onItemAppend, this );
var_DelCallback( getIntf()->p_sys->p_playlist, "item-deleted", var_DelCallback( getIntf()->p_sys->p_playlist, "item-deleted",
onIntfChange, this ); onItemDelete, this );
var_DelCallback( getIntf()->p_sys->p_playlist, "intf-show", var_DelCallback( getIntf()->p_sys->p_playlist, "intf-show",
onIntfShow, this ); onIntfShow, this );
var_DelCallback( getIntf()->p_sys->p_playlist, "playlist-current", var_DelCallback( getIntf()->p_sys->p_playlist, "playlist-current",
...@@ -443,6 +443,31 @@ int VlcProc::onItemAppend( vlc_object_t *pObj, const char *pVariable, ...@@ -443,6 +443,31 @@ int VlcProc::onItemAppend( vlc_object_t *pObj, const char *pVariable,
return VLC_SUCCESS; return VLC_SUCCESS;
} }
int VlcProc::onItemDelete( vlc_object_t *pObj, const char *pVariable,
vlc_value_t oldVal, vlc_value_t newVal,
void *pParam )
{
VlcProc *pThis = (VlcProc*)pParam;
int i_id = newVal.i_int;
CmdGenericPtr ptrTree;
CmdPlaytreeDelete *pCmdTree = new CmdPlaytreeDelete( pThis->getIntf(),
i_id);
ptrTree = CmdGenericPtr( pCmdTree );
// Create a playlist notify command (for old style playlist)
CmdNotifyPlaylist *pCmd = new CmdNotifyPlaylist( pThis->getIntf() );
// Push the command in the asynchronous command queue
AsyncQueue *pQueue = AsyncQueue::instance( pThis->getIntf() );
pQueue->push( CmdGenericPtr( pCmd ) );
pQueue->push( ptrTree , false );
return VLC_SUCCESS;
}
int VlcProc::onPlaylistChange( vlc_object_t *pObj, const char *pVariable, int VlcProc::onPlaylistChange( vlc_object_t *pObj, const char *pVariable,
......
...@@ -173,6 +173,12 @@ class VlcProc: public SkinObject ...@@ -173,6 +173,12 @@ class VlcProc: public SkinObject
vlc_value_t oldVal, vlc_value_t newVal, vlc_value_t oldVal, vlc_value_t newVal,
void *pParam ); void *pParam );
/// Callback for item-change variable
static int onItemDelete( vlc_object_t *pObj, const char *pVariable,
vlc_value_t oldVal, vlc_value_t newVal,
void *pParam );
/// Callback for playlist-current variable /// Callback for playlist-current variable
static int onPlaylistChange( vlc_object_t *pObj, const char *pVariable, static int onPlaylistChange( vlc_object_t *pObj, const char *pVariable,
vlc_value_t oldVal, vlc_value_t newVal, vlc_value_t oldVal, vlc_value_t newVal,
......
...@@ -28,7 +28,8 @@ const string VarTree::m_type = "tree"; ...@@ -28,7 +28,8 @@ const string VarTree::m_type = "tree";
VarTree::VarTree( intf_thread_t *pIntf ) VarTree::VarTree( intf_thread_t *pIntf )
: Variable( pIntf ), m_id( 0 ), m_selected( false ), m_playing( false ), : Variable( pIntf ), m_id( 0 ), m_selected( false ), m_playing( false ),
m_expanded( false ), m_pData( NULL ), m_pParent( NULL ) m_expanded( false ), m_deleted( false ), m_readonly( false),
m_pData( NULL ), m_pParent( NULL )
{ {
// Create the position variable // Create the position variable
m_cPosition = VariablePtr( new VarPercent( pIntf ) ); m_cPosition = VariablePtr( new VarPercent( pIntf ) );
...@@ -37,11 +38,14 @@ VarTree::VarTree( intf_thread_t *pIntf ) ...@@ -37,11 +38,14 @@ VarTree::VarTree( intf_thread_t *pIntf )
VarTree::VarTree( intf_thread_t *pIntf, VarTree *pParent, int id, VarTree::VarTree( intf_thread_t *pIntf, VarTree *pParent, int id,
const UStringPtr &rcString, bool selected, bool playing, const UStringPtr &rcString, bool selected, bool playing,
bool expanded, void *pData ) bool expanded, bool readonly,
void *pData )
: Variable( pIntf ), m_id( id ), m_cString( rcString ), : Variable( pIntf ), m_id( id ), m_cString( rcString ),
m_selected( selected ), m_playing( playing ), m_expanded( expanded ), m_selected( selected ), m_playing( playing ), m_expanded( expanded ),
m_deleted( false ), m_readonly( readonly ),
m_pData( pData ), m_pParent( pParent ) m_pData( pData ), m_pParent( pParent )
{ {
fprintf( stderr, "Expanded is %i - RO %i\n", m_expanded, m_readonly );
// Create the position variable // Create the position variable
m_cPosition = VariablePtr( new VarPercent( pIntf ) ); m_cPosition = VariablePtr( new VarPercent( pIntf ) );
getPositionVar().set( 1.0 ); getPositionVar().set( 1.0 );
...@@ -53,10 +57,12 @@ VarTree::~VarTree() ...@@ -53,10 +57,12 @@ VarTree::~VarTree()
} }
void VarTree::add( int id, const UStringPtr &rcString, bool selected, void VarTree::add( int id, const UStringPtr &rcString, bool selected,
bool playing, bool expanded, void *pData ) bool playing, bool expanded, bool readonly,
void *pData )
{ {
m_children.push_back( VarTree( getIntf(), this, id, rcString, selected, m_children.push_back( VarTree( getIntf(), this, id, rcString, selected,
playing, expanded, pData ) ); playing, expanded, readonly,
pData ) );
} }
void VarTree::delSelected() void VarTree::delSelected()
...@@ -105,6 +111,22 @@ VarTree::ConstIterator VarTree::operator[]( int n ) const ...@@ -105,6 +111,22 @@ VarTree::ConstIterator VarTree::operator[]( int n ) const
return it; return it;
} }
VarTree::Iterator VarTree::getNextSibling( VarTree::Iterator current )
{
VarTree *p_parent = current->parent();
if( p_parent && current != p_parent->end() )
{
Iterator it = current->parent()->begin();
while( it != p_parent->end() && it != current ) it++;
if( it != p_parent->end() )
{
it++;
}
return root()->end();
}
return root()->end();
}
/* find iterator to next ancestor /* find iterator to next ancestor
* ... which means parent++ or grandparent++ or grandgrandparent++ ... */ * ... which means parent++ or grandparent++ or grandgrandparent++ ... */
VarTree::Iterator VarTree::next_uncle() VarTree::Iterator VarTree::next_uncle()
......
...@@ -49,7 +49,7 @@ class VarTree: public Variable, public Subject<VarTree, tree_update*> ...@@ -49,7 +49,7 @@ class VarTree: public Variable, public Subject<VarTree, tree_update*>
VarTree( intf_thread_t *pIntf, VarTree *pParent, int id, VarTree( intf_thread_t *pIntf, VarTree *pParent, int id,
const UStringPtr &rcString, bool selected, bool playing, const UStringPtr &rcString, bool selected, bool playing,
bool expanded, void *pData ); bool expanded,bool readonly, void *pData );
virtual ~VarTree(); virtual ~VarTree();
...@@ -58,7 +58,8 @@ class VarTree: public Variable, public Subject<VarTree, tree_update*> ...@@ -58,7 +58,8 @@ class VarTree: public Variable, public Subject<VarTree, tree_update*>
/// Add a pointer on string in the children's list /// Add a pointer on string in the children's list
virtual void add( int id, const UStringPtr &rcString, bool selected, virtual void add( int id, const UStringPtr &rcString, bool selected,
bool playing, bool expanded, void *pData ); bool playing, bool expanded, bool readonly,
void *pData );
/// Remove the selected item from the children's list /// Remove the selected item from the children's list
virtual void delSelected(); virtual void delSelected();
...@@ -72,8 +73,11 @@ class VarTree: public Variable, public Subject<VarTree, tree_update*> ...@@ -72,8 +73,11 @@ class VarTree: public Variable, public Subject<VarTree, tree_update*>
bool m_selected; bool m_selected;
bool m_playing; bool m_playing;
bool m_expanded; bool m_expanded;
bool m_deleted;
void *m_pData; void *m_pData;
inline bool isReadonly() { return m_readonly; };
/// Get the number of children /// Get the number of children
int size() const { return m_children.size(); } int size() const { return m_children.size(); }
...@@ -100,6 +104,9 @@ class VarTree: public Variable, public Subject<VarTree, tree_update*> ...@@ -100,6 +104,9 @@ class VarTree: public Variable, public Subject<VarTree, tree_update*>
VarTree *parent() { return m_pParent; } VarTree *parent() { return m_pParent; }
void checkParents( VarTree *pParent ); void checkParents( VarTree *pParent );
/// Get next sibling
Iterator getNextSibling( Iterator );
Iterator next_uncle(); Iterator next_uncle();
Iterator prev_uncle(); Iterator prev_uncle();
...@@ -122,6 +129,11 @@ class VarTree: public Variable, public Subject<VarTree, tree_update*> ...@@ -122,6 +129,11 @@ class VarTree: public Variable, public Subject<VarTree, tree_update*>
return depth; return depth;
} }
void removeChild( VarTree::Iterator item )
{
m_children.erase( item );
}
/// Execute the action associated to this item /// Execute the action associated to this item
virtual void action( VarTree *pItem ) {} virtual void action( VarTree *pItem ) {}
...@@ -160,6 +172,8 @@ class VarTree: public Variable, public Subject<VarTree, tree_update*> ...@@ -160,6 +172,8 @@ class VarTree: public Variable, public Subject<VarTree, tree_update*>
/// Pointer to parent node /// Pointer to parent node
VarTree *m_pParent; VarTree *m_pParent;
bool m_readonly;
/// Variable type /// Variable type
static const string m_type; static const string m_type;
......
...@@ -58,31 +58,49 @@ Playtree::~Playtree() ...@@ -58,31 +58,49 @@ Playtree::~Playtree()
void Playtree::delSelected() void Playtree::delSelected()
{ {
Iterator it; Iterator it = begin();
for (it = begin(); it != end() ; it = getNextVisibleItem( it ) ) vlc_mutex_lock( &getIntf()->p_sys->p_playlist->object_lock );
for( it = begin(); it != end(); it = getNextVisibleItem( it ) )
{ {
if( (*it).m_selected ) if( (*it).m_selected && !(*it).isReadonly() )
{ {
(*it).m_deleted = true;
}
}
/// \todo Do this better (handle item-deleted)
tree_update descr;
descr.i_type = 3;
notify( &descr );
it = begin();
while( it != end() )
{
if( (*it).m_deleted )
{
VarTree::Iterator it2;
playlist_item_t *p_item = (playlist_item_t *)(it->m_pData); playlist_item_t *p_item = (playlist_item_t *)(it->m_pData);
if( p_item->i_children == -1 ) if( p_item->i_children == -1 )
{ {
playlist_LockDelete( getIntf()->p_sys->p_playlist, playlist_Delete( getIntf()->p_sys->p_playlist,
p_item->input.i_id ); p_item->input.i_id );
it2 = getNextVisibleItem( it ) ;
it->parent()->removeChild( it );
it = it2;
} }
else else
{ {
vlc_mutex_lock( &getIntf()->p_sys->p_playlist->object_lock );
playlist_NodeDelete( getIntf()->p_sys->p_playlist, p_item, playlist_NodeDelete( getIntf()->p_sys->p_playlist, p_item,
VLC_TRUE, VLC_FALSE ); VLC_TRUE, VLC_FALSE );
vlc_mutex_unlock( &getIntf()->p_sys->p_playlist->object_lock ); it2 = getNextSibling( it );
it->parent()->removeChild( it );
it = it2;
} }
} }
else
{
it = getNextVisibleItem( it );
}
} }
/// \todo Do this better (handle item-deleted) vlc_mutex_unlock( &getIntf()->p_sys->p_playlist->object_lock );
buildTree();
tree_update descr;
descr.i_type = 1;
notify( &descr );
} }
void Playtree::action( VarTree *pItem ) void Playtree::action( VarTree *pItem )
...@@ -137,6 +155,23 @@ void Playtree::onUpdateItem( int id ) ...@@ -137,6 +155,23 @@ void Playtree::onUpdateItem( int id )
notify( &descr ); notify( &descr );
} }
/// \todo keep a list of "recently removed" to avoid looking up if we
// already removed it
void Playtree::onDelete( int i_id )
{
tree_update descr;
descr.i_id = i_id;
descr.i_type = 3;
Iterator item = findById( i_id ) ;
if( item != end() )
{
if( item->parent() )
item->parent()->removeChild( item );
descr.b_visible = item->parent() ? true : item->parent()->m_expanded;
notify( &descr );
}
}
void Playtree::onAppend( playlist_add_t *p_add ) void Playtree::onAppend( playlist_add_t *p_add )
{ {
i_items_to_append --; i_items_to_append --;
...@@ -152,7 +187,8 @@ void Playtree::onAppend( playlist_add_t *p_add ) ...@@ -152,7 +187,8 @@ void Playtree::onAppend( playlist_add_t *p_add )
if( !p_item ) return; if( !p_item ) return;
UString *pName = new UString( getIntf(), p_item->input.psz_name ); UString *pName = new UString( getIntf(), p_item->input.psz_name );
node->add( p_add->i_item, UStringPtr( pName ), node->add( p_add->i_item, UStringPtr( pName ),
false,false, false, p_item ); false,false, false, p_item->i_flags & PLAYLIST_RO_FLAG,
p_item );
} }
} }
tree_update descr; tree_update descr;
...@@ -172,7 +208,8 @@ void Playtree::buildNode( playlist_item_t *pNode, VarTree &rTree ) ...@@ -172,7 +208,8 @@ void Playtree::buildNode( playlist_item_t *pNode, VarTree &rTree )
rTree.add( pNode->pp_children[i]->input.i_id, UStringPtr( pName ), rTree.add( pNode->pp_children[i]->input.i_id, UStringPtr( pName ),
false, false,
m_pPlaylist->status.p_item == pNode->pp_children[i], m_pPlaylist->status.p_item == pNode->pp_children[i],
false, pNode->pp_children[i] ); false, pNode->pp_children[i]->i_flags & PLAYLIST_RO_FLAG,
pNode->pp_children[i] );
if( pNode->pp_children[i]->i_children ) if( pNode->pp_children[i]->i_children )
{ {
buildNode( pNode->pp_children[i], rTree.back() ); buildNode( pNode->pp_children[i], rTree.back() );
......
...@@ -48,6 +48,9 @@ class Playtree: public VarTree ...@@ -48,6 +48,9 @@ class Playtree: public VarTree
/// Function called to notify playlist item append /// Function called to notify playlist item append
void onAppend( playlist_add_t * ); void onAppend( playlist_add_t * );
/// Function called to notify playlist item delete
void onDelete( int );
/// Items waiting to be appended /// Items waiting to be appended
int i_items_to_append; int i_items_to_append;
......
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