]> git.sesse.net Git - vlc/blobdiff - modules/gui/skins2/vars/playtree.cpp
Qt4: missing parentheses
[vlc] / modules / gui / skins2 / vars / playtree.cpp
index 667e33f491ec238d75b47b5f5a73b352cc8be56d..1cb635ad2d27e9a60916146b491a0712b06f3795 100644 (file)
@@ -6,6 +6,7 @@
  *
  * Authors: Antoine Cellerier <dionoea@videolan.org>
  *          ClĂ©ment Stenac <zorglub@videolan.org>
+ *          Erwan Tulou    <erwan10@videolan.org>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
 
 #include "playtree.hpp"
 #include <vlc_playlist.h>
+#include <vlc_url.h>
 #include "../utils/ustring.hpp"
 
-#include "vlc_charset.h"
-
-
-Playtree::Playtree( intf_thread_t *pIntf ): VarTree( pIntf )
+Playtree::Playtree( intf_thread_t *pIntf )
+    : VarTree( pIntf ), m_pPlaylist( pIntf->p_sys->p_playlist )
 {
-    // Get the VLC playlist object
-    m_pPlaylist = pIntf->p_sys->p_playlist;
-
-    i_items_to_append = 0;
-
+    getPositionVar().addObserver( this );
     buildTree();
 }
 
 Playtree::~Playtree()
 {
+    getPositionVar().delObserver( this );
 }
 
 void Playtree::delSelected()
 {
-    Iterator it = begin();
-    vlc_object_lock( getIntf()->p_sys->p_playlist );
-    for( it = begin(); it != end(); it = getNextVisibleItem( it ) )
-    {
-        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() )
+    for( Iterator it = m_children.begin(); it != m_children.end(); )
     {
-        if( (*it).m_deleted )
+        if( it->isSelected() && !it->isReadonly() )
         {
-            VarTree::Iterator it2;
-            playlist_item_t *p_item = (playlist_item_t *)(it->m_pData);
-            if( p_item->i_children == -1 )
-            {
-                playlist_DeleteFromInput( getIntf()->p_sys->p_playlist,
-                                          p_item->p_input->i_id, true );
-                it2 = getNextVisibleItem( it ) ;
-                it->parent()->removeChild( it );
-                it = it2;
-            }
-            else
+            playlist_Lock( m_pPlaylist );
+
+            playlist_item_t *pItem =
+                playlist_ItemGetById( m_pPlaylist, it->getId() );
+            if( pItem )
             {
-                playlist_NodeDelete( getIntf()->p_sys->p_playlist, p_item,
-                                     true, false );
-                it2 = getNextSibling( it );
-                it->parent()->removeChild( it );
-                it = it2;
+                if( pItem->i_children == -1 )
+                {
+                    playlist_DeleteFromInput( m_pPlaylist, pItem->p_input,
+                                              pl_Locked );
+                }
+                else
+                {
+                    playlist_NodeDelete( m_pPlaylist, pItem, true, false );
+                }
             }
+            playlist_Unlock( m_pPlaylist );
+
+            it = it->getNextSiblingOrUncle();
         }
         else
         {
-            it = getNextVisibleItem( it );
+            it = getNextItem( it );
         }
     }
-    vlc_object_unlock( getIntf()->p_sys->p_playlist );
 }
 
-void Playtree::action( VarTree *pItem )
+void Playtree::action( VarTree *pElem )
 {
-    vlc_object_lock( m_pPlaylist );
-    VarTree::Iterator it;
+    playlist_Lock( m_pPlaylist );
 
-    playlist_item_t *p_item = (playlist_item_t *)pItem->m_pData;
-    playlist_item_t *p_parent = p_item;
-    while( p_parent )
+    playlist_item_t *pItem =
+        playlist_ItemGetById( m_pPlaylist, pElem->getId() );
+    if( pItem )
     {
-        if( p_parent == m_pPlaylist->p_root_category )
-            break;
-        p_parent = p_parent->p_parent;
+        playlist_Control( m_pPlaylist, PLAYLIST_VIEWPLAY,
+                          pl_Locked, pItem->p_parent, pItem );
     }
 
-    if( p_parent )
-    {
-        playlist_Control( m_pPlaylist, PLAYLIST_VIEWPLAY, true, p_parent, p_item );
-    }
-    vlc_object_unlock( m_pPlaylist );
+    playlist_Unlock( m_pPlaylist );
 }
 
 void Playtree::onChange()
 {
     buildTree();
-    tree_update descr;
-    descr.i_type = 1;
+    tree_update descr( tree_update::ResetAll, end() );
     notify( &descr );
 }
 
 void Playtree::onUpdateItem( int id )
 {
     Iterator it = findById( id );
-    tree_update descr;
-    descr.b_active_item = false;
-    if( it != end() )
+    if( it != m_children.end() )
     {
         // Update the item
-        playlist_item_t* pNode = (playlist_item_t*)(it->m_pData);
-        UString *pName = new UString( getIntf(), pNode->p_input->psz_name );
-        it->m_cString = UStringPtr( pName );
-        it->m_playing = m_pPlaylist->status.p_item == pNode;
-        if( it->m_playing ) descr.b_active_item = true;
+        playlist_Lock( m_pPlaylist );
+        playlist_item_t *pNode =
+            playlist_ItemGetById( m_pPlaylist, it->getId() );
+        if( !pNode )
+        {
+            playlist_Unlock( m_pPlaylist );
+            return;
+        }
+
+        UString *pName = getTitle( pNode->p_input );
+        playlist_Unlock( m_pPlaylist );
+
+        if( *pName != *(it->getString()) )
+        {
+            it->setString( UStringPtr( pName ) );
+
+            tree_update descr(
+                tree_update::ItemUpdated, IteratorVisible( it, this ) );
+            notify( &descr );
+        }
+        else
+        {
+            delete pName;
+        }
+
     }
     else
     {
-        msg_Warn(getIntf(), "cannot find node with id %d", id );
+        msg_Warn( getIntf(), "cannot find node with id %d", id );
+    }
+}
+
+void Playtree::onUpdateCurrent( bool b_active )
+{
+    if( b_active )
+    {
+        playlist_Lock( m_pPlaylist );
+
+        playlist_item_t* current = playlist_CurrentPlayingItem( m_pPlaylist );
+        if( !current )
+        {
+            playlist_Unlock( m_pPlaylist );
+            return;
+        }
+
+        Iterator it = findById( current->i_id );
+        if( it != m_children.end() )
+        {
+            it->setPlaying( true );
+
+            tree_update descr(
+                tree_update::ItemUpdated, IteratorVisible( it, this ) );
+            notify( &descr );
+        }
+
+        playlist_Unlock( m_pPlaylist );
+    }
+    else
+    {
+        for( Iterator it = m_children.begin(); it != m_children.end();
+             it = getNextItem( it ) )
+        {
+            if( it->isPlaying() )
+            {
+                it->setPlaying( false );
+
+                tree_update descr(
+                    tree_update::ItemUpdated, IteratorVisible( it, this ) );
+                notify( &descr );
+                break;
+            }
+        }
     }
-    descr.i_type = 0;
-    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 );
+    Iterator it = findById( i_id ) ;
+    if( it != m_children.end() )
+    {
+        VarTree* parent = it->parent();
+        if( parent )
+        {
+            tree_update descr(
+                tree_update::DeletingItem, IteratorVisible( it, this ) );
+            notify( &descr );
+
+            parent->removeChild( it );
+            m_allItems.erase( i_id );
+
+            tree_update descr2(
+                tree_update::ItemDeleted, end() );
+            notify( &descr2 );
+        }
     }
 }
 
 void Playtree::onAppend( playlist_add_t *p_add )
 {
-    i_items_to_append --;
-
-    Iterator node = findById( p_add->i_node );
-    if( node != end() )
+    Iterator it_node = findById( p_add->i_node );
+    if( it_node != m_children.end() )
     {
-        Iterator item =  findById( p_add->i_item );
-        if( item == end() )
+        playlist_Lock( m_pPlaylist );
+        playlist_item_t *pItem =
+            playlist_ItemGetById( m_pPlaylist, p_add->i_item );
+        if( !pItem )
         {
-            playlist_item_t *p_item = playlist_ItemGetById(
-                                        m_pPlaylist, p_add->i_item, false );
-            if( !p_item ) return;
-            UString *pName = new UString( getIntf(),
-                                          p_item->p_input->psz_name );
-            node->add( p_add->i_item, UStringPtr( pName ),
-                      false,false, false, p_item->i_flags & PLAYLIST_RO_FLAG,
-                      p_item );
+            playlist_Unlock( m_pPlaylist );
+            return;
         }
+
+        int pos;
+        for( pos = 0; pos < pItem->p_parent->i_children; pos++ )
+            if( pItem->p_parent->pp_children[pos] == pItem ) break;
+
+        UString *pName = getTitle( pItem->p_input );
+        playlist_item_t* current = playlist_CurrentPlayingItem( m_pPlaylist );
+
+        Iterator it = it_node->add(
+            p_add->i_item, UStringPtr( pName ), false, pItem == current,
+            false, pItem->i_flags & PLAYLIST_RO_FLAG, pos );
+
+        m_allItems[pItem->i_id] = &*it;
+
+        playlist_Unlock( m_pPlaylist );
+
+        tree_update descr(
+            tree_update::ItemInserted,
+            IteratorVisible( it, this ) );
+        notify( &descr );
     }
-    tree_update descr;
-    descr.i_id = p_add->i_item;
-    descr.i_parent = p_add->i_node;
-    descr.b_visible = node->m_expanded;
-    descr.i_type = 2;
-    notify( &descr );
 }
 
 void Playtree::buildNode( playlist_item_t *pNode, VarTree &rTree )
 {
+    UString *pName = getTitle( pNode->p_input );
+    Iterator it = rTree.add(
+        pNode->i_id, UStringPtr( pName ), false,
+        playlist_CurrentPlayingItem(m_pPlaylist) == pNode,
+        false, pNode->i_flags & PLAYLIST_RO_FLAG );
+    m_allItems[pNode->i_id] = &*it;
+
     for( int i = 0; i < pNode->i_children; i++ )
     {
-        UString *pName = new UString( getIntf(),
-                                   pNode->pp_children[i]->p_input->psz_name );
-        rTree.add( pNode->pp_children[i]->p_input->i_id, UStringPtr( pName ),
-                     false,
-                     m_pPlaylist->status.p_item == 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 )
-        {
-            buildNode( pNode->pp_children[i], rTree.back() );
-        }
+        buildNode( pNode->pp_children[i], *it );
     }
 }
 
 void Playtree::buildTree()
 {
     clear();
-    vlc_object_lock( m_pPlaylist );
+    playlist_Lock( m_pPlaylist );
 
-    i_items_to_append = 0;
+    for( int i = 0; i < m_pPlaylist->p_root->i_children; i++ )
+    {
+        buildNode( m_pPlaylist->p_root->pp_children[i], *this );
+    }
 
-    clear();
+    playlist_Unlock( m_pPlaylist );
+}
 
-    /* TODO: Let user choose view - Stick with category ATM */
+void Playtree::onUpdateSlider()
+{
+    tree_update descr( tree_update::SliderChanged, end() );
+    notify( &descr );
+}
 
-    /* Set the root's name */
-    UString *pName = new UString( getIntf(),
-                             m_pPlaylist->p_root_category->p_input->psz_name );
-    m_cString = UStringPtr( pName );
+void Playtree::insertItems( VarTree& elem, const list<string>& files, bool start )
+{
+    bool first = true;
+    VarTree* p_elem = &elem;
+    playlist_item_t* p_node = NULL;
+    int i_pos = -1;
+
+    playlist_Lock( m_pPlaylist );
 
-    buildNode( m_pPlaylist->p_root_category, *this );
+    if( p_elem == this )
+    {
+        for( Iterator it = m_children.begin(); it != m_children.end(); ++it )
+        {
+            if( it->getId() == m_pPlaylist->p_local_category->i_id )
+            {
+                p_elem = &*it;
+                break;
+            }
+        }
+    }
 
-    vlc_object_unlock( m_pPlaylist );
-//  What is it ?
-//    checkParents( NULL );
+    if( p_elem->getId() == m_pPlaylist->p_local_category->i_id )
+    {
+        p_node = m_pPlaylist->p_local_category;
+        i_pos = 0;
+        p_elem->setExpanded( true );
+    }
+    else if( p_elem->getId() == m_pPlaylist->p_ml_category->i_id )
+    {
+        p_node = m_pPlaylist->p_ml_category;
+        i_pos = 0;
+        p_elem->setExpanded( true );
+    }
+    else if( p_elem->size() && p_elem->isExpanded() )
+    {
+        p_node = playlist_ItemGetById( m_pPlaylist, p_elem->getId() );
+        i_pos = 0;
+    }
+    else
+    {
+        p_node = playlist_ItemGetById( m_pPlaylist,
+                                       p_elem->parent()->getId() );
+        i_pos = p_elem->getIndex();
+        i_pos++;
+    }
+
+    if( !p_node )
+        goto fin;
+
+    for( list<string>::const_iterator it = files.begin();
+         it != files.end(); ++it, i_pos++, first = false )
+    {
+        input_item_t *pItem;
+
+        if( strstr( it->c_str(), "://" ) )
+            pItem = input_item_New( it->c_str(), NULL );
+        else
+        {
+            char *psz_uri = vlc_path2uri( it->c_str(), NULL );
+            if( psz_uri == NULL )
+                continue;
+            pItem = input_item_New( psz_uri, NULL );
+            free( psz_uri );
+        }
+
+        if( pItem == NULL)
+            continue;
+
+        int i_mode = PLAYLIST_APPEND;
+        if( first && start )
+            i_mode |= PLAYLIST_GO;
+
+        playlist_NodeAddInput( m_pPlaylist, pItem, p_node,
+                               i_mode, i_pos, pl_Locked );
+    }
+
+fin:
+    playlist_Unlock( m_pPlaylist );
 }
 
+
+UString* Playtree::getTitle( input_item_t *pItem )
+{
+    char *psz_name = input_item_GetTitleFbName( pItem );
+    UString *pTitle = new UString( getIntf(), psz_name );
+    free( psz_name );
+    return pTitle;
+}
+
+
+VarTree::Iterator Playtree::findById( int id )
+{
+    map<int,VarTree*>::iterator it = m_allItems.find( id );
+    if( it == m_allItems.end() )
+        return m_children.end();
+    else
+        return it->second->getSelf();
+}