]> git.sesse.net Git - vlc/blobdiff - modules/gui/skins2/vars/playtree.cpp
Qt: prefsItem: namespace TYPE_*
[vlc] / modules / gui / skins2 / vars / playtree.cpp
index a001cf47aba2ce60edd89456794d9453832a22bc..88905e03b8e925a3c084cbe856875dccbaa00e62 100644 (file)
@@ -1,10 +1,12 @@
 /*****************************************************************************
  * playtree.cpp
  *****************************************************************************
- * Copyright (C) 2005 VideoLAN
+ * Copyright (C) 2005 the VideoLAN team
  * $Id$
  *
  * 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
  *
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
  *****************************************************************************/
 
-#include <vlc/vlc.h>
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <vlc_common.h>
 
 #include "playtree.hpp"
+#include <vlc_playlist.h>
+#include <vlc_url.h>
 #include "../utils/ustring.hpp"
 
-#include "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;
-
-    // Try to guess the current charset
-    char *pCharset;
-    vlc_current_charset( &pCharset );
-    iconvHandle = vlc_iconv_open( "UTF-8", pCharset );
-    msg_Dbg( pIntf, "Using character encoding: %s", pCharset );
-    free( pCharset );
-
-    if( iconvHandle == (vlc_iconv_t) - 1 )
-    {
-        msg_Warn( pIntf, "Unable to do requested conversion" );
-    }
-
+    getPositionVar().addObserver( this );
     buildTree();
 }
 
 Playtree::~Playtree()
 {
-    if( iconvHandle != (vlc_iconv_t) - 1 ) vlc_iconv_close( iconvHandle );
-    // TODO : check that everything is destroyed
+    getPositionVar().delObserver( this );
 }
 
 void Playtree::delSelected()
 {
-    Iterator it;
-    for (it = begin(); it != end() ; it++ )
+    for( Iterator it = m_children.begin(); it != m_children.end(); )
     {
-        if( (*it).m_selected )
+        if( it->isSelected() && !it->isReadonly() )
         {
-            playlist_item_t *p_item = (playlist_item_t *)(it->m_pData);
-            if( p_item->i_children == -1 )
-            {
-                playlist_LockDelete( getIntf()->p_sys->p_playlist,
-                                     p_item->input.i_id );
-            }
-            else
+            playlist_Lock( m_pPlaylist );
+
+            playlist_item_t *pItem =
+                playlist_ItemGetById( m_pPlaylist, it->getId() );
+            if( pItem )
             {
-                vlc_mutex_lock( &getIntf()->p_sys->p_playlist->object_lock );
-                playlist_NodeDelete( getIntf()->p_sys->p_playlist, p_item,
-                                     VLC_TRUE, VLC_FALSE );
-                vlc_mutex_unlock( &getIntf()->p_sys->p_playlist->object_lock );
+                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 = getNextItem( it );
         }
     }
-    notify();
 }
 
-void Playtree::action( VarTree *pItem )
+void Playtree::action( VarTree *pElem )
 {
-    vlc_mutex_lock( &m_pPlaylist->object_lock );
-    VarTree::Iterator it;
-    if( pItem->size() )
-    {
-        it = pItem->begin();
-        while( it->size() ) it = it->begin();
-    }
-    playlist_Control( m_pPlaylist,
-                      PLAYLIST_VIEWPLAY,
-                      m_pPlaylist->status.i_view,
-                      pItem->size()
-                          ? (playlist_item_t *)pItem->m_pData
-                          : (playlist_item_t *)pItem->parent()->m_pData,
-                      pItem->size()
-                          ? (playlist_item_t *)it->m_pData
-                          : (playlist_item_t *)pItem->m_pData
-                    );
-    vlc_mutex_unlock( &m_pPlaylist->object_lock );
+    playlist_Lock( m_pPlaylist );
+
+    playlist_item_t *pItem =
+        playlist_ItemGetById( m_pPlaylist, pElem->getId() );
+    if( pItem )
+    {
+        playlist_Control( m_pPlaylist, PLAYLIST_VIEWPLAY,
+                          pl_Locked, pItem->p_parent, pItem );
+    }
+
+    playlist_Unlock( m_pPlaylist );
 }
 
 void Playtree::onChange()
 {
     buildTree();
-    notify();
+    tree_update descr( tree_update::ResetAll, end() );
+    notify( &descr );
 }
 
-void Playtree::onUpdate( int id )
+void Playtree::onUpdateItem( int id )
 {
     Iterator it = findById( id );
-    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->input.psz_name );
-        it->m_cString = UStringPtr( pName );
-        it->m_playing = m_pPlaylist->status.p_item == pNode;
+        playlist_Lock( m_pPlaylist );
+        playlist_item_t *pNode =
+            playlist_ItemGetById( m_pPlaylist, it->getId() );
+        if( !pNode )
+        {
+            playlist_Unlock( m_pPlaylist );
+            return;
+        }
+
+        char *psz_name = input_item_GetTitleFbName( pNode->p_input );
+        UString *pName = new UString( getIntf(), psz_name );
+        free(psz_name);
+        playlist_Unlock( m_pPlaylist );
+
+        if( *pName != *(it->getString()) )
+        {
+            it->setString( UStringPtr( pName ) );
+
+            tree_update descr(
+                tree_update::ItemUpdated, IteratorVisible( it, this ) );
+            notify( &descr );
+        }
     }
     else
     {
-        msg_Warn(getIntf(), "Cannot find node with id %d", id );
+        msg_Warn( getIntf(), "cannot find node with id %d", id );
     }
-    // TODO update only the right node
-    notify();
 }
 
-void Playtree::buildNode( playlist_item_t *pNode, VarTree &rTree )
+void Playtree::onUpdateCurrent( bool b_active )
 {
-    for( int i = 0; i < pNode->i_children; i++ )
+    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;
+            }
+        }
+    }
+}
+
+void Playtree::onDelete( int i_id )
+{
+    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 )
+{
+    Iterator it_node = findById( p_add->i_node );
+    if( it_node != m_children.end() )
     {
-        UString *pName = new UString( getIntf(),
-                                      pNode->pp_children[i]->input.psz_name );
-        rTree.add( pNode->pp_children[i]->input.i_id, UStringPtr( pName ),
-                     false,
-                     m_pPlaylist->status.p_item == pNode->pp_children[i],
-                     true, pNode->pp_children[i] );
-        if( pNode->pp_children[i]->i_children )
+        playlist_Lock( m_pPlaylist );
+        playlist_item_t *pItem =
+            playlist_ItemGetById( m_pPlaylist, p_add->i_item );
+        if( !pItem )
         {
-            buildNode( pNode->pp_children[i], rTree.back() );
+            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;
+
+        char *psz_name = input_item_GetTitleFbName( pItem->p_input );
+        UString *pName = new UString( getIntf(), psz_name );
+        free( psz_name );
+
+        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 );
+    }
+}
+
+void Playtree::buildNode( playlist_item_t *pNode, VarTree &rTree )
+{
+    UString *pName = new UString( getIntf(), pNode->p_input->psz_name );
+    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++ )
+    {
+        buildNode( pNode->pp_children[i], *it );
     }
 }
 
 void Playtree::buildTree()
 {
     clear();
-    vlc_mutex_lock( &m_pPlaylist->object_lock );
+    playlist_Lock( m_pPlaylist );
 
-    playlist_view_t *p_view;
-    p_view = playlist_ViewFind( m_pPlaylist, VIEW_CATEGORY );
-    /* TODO : let the user chose the view type */
+    for( int i = 0; i < m_pPlaylist->p_root->i_children; i++ )
+    {
+        buildNode( m_pPlaylist->p_root->pp_children[i], *this );
+    }
 
-    clear();
-    /* XXX : do we need Playlist::clear() instead of VarTree::clear() ? */
+    playlist_Unlock( m_pPlaylist );
+}
 
-    /* Set the root's name */
-    UString *pName = new UString( getIntf(), p_view->p_root->input.psz_name );
-    m_cString = UStringPtr( pName );
+void Playtree::onUpdateSlider()
+{
+    tree_update descr( tree_update::SliderChanged, end() );
+    notify( &descr );
+}
+
+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;
 
-    buildNode( p_view->p_root, *this );
+    playlist_Lock( m_pPlaylist );
 
-    vlc_mutex_unlock( &m_pPlaylist->object_lock );
-    checkParents( NULL );
+    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;
+            }
+        }
+    }
+
+    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 );
 }
 
+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();
+}