]> git.sesse.net Git - vlc/blob - modules/gui/skins2/vars/playtree.cpp
Merge branch 'master' into lpcm_encoder
[vlc] / modules / gui / skins2 / vars / playtree.cpp
1 /*****************************************************************************
2  * playtree.cpp
3  *****************************************************************************
4  * Copyright (C) 2005 the VideoLAN team
5  * $Id$
6  *
7  * Authors: Antoine Cellerier <dionoea@videolan.org>
8  *          ClĂ©ment Stenac <zorglub@videolan.org>
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
23  *****************************************************************************/
24
25 #ifdef HAVE_CONFIG_H
26 # include "config.h"
27 #endif
28
29 #include <vlc_common.h>
30
31 #include "playtree.hpp"
32 #include <vlc_playlist.h>
33 #include "../utils/ustring.hpp"
34
35 Playtree::Playtree( intf_thread_t *pIntf ):
36     VarTree( pIntf ), m_currentItem( NULL )
37 {
38     // Get the VLC playlist object
39     m_pPlaylist = pIntf->p_sys->p_playlist;
40
41     i_items_to_append = 0;
42
43     buildTree();
44 }
45
46 Playtree::~Playtree()
47 {
48 }
49
50 void Playtree::delSelected()
51 {
52     Iterator it = begin();
53     playlist_Lock( getIntf()->p_sys->p_playlist );
54     for( it = begin(); it != end(); it = getNextItem( it ) )
55     {
56         if( it->m_selected && !it->isReadonly() )
57         {
58             it->cascadeDelete();
59         }
60     }
61     /// \todo Do this better (handle item-deleted)
62     tree_update descr;
63     descr.i_type = 3;
64     notify( &descr );
65     it = begin();
66     while( it != end() )
67     {
68         if( it->m_deleted )
69         {
70             VarTree::Iterator it2;
71             playlist_item_t *p_item = (playlist_item_t *)(it->m_pData);
72             if( p_item->i_children == -1 )
73             {
74                 playlist_DeleteFromInput( getIntf()->p_sys->p_playlist,
75                                           p_item->p_input, pl_Locked );
76                 it2 = getNextItem( it ) ;
77             }
78             else
79             {
80                 playlist_NodeDelete( getIntf()->p_sys->p_playlist, p_item,
81                                      true, false );
82                 it2 = it->getNextSiblingOrUncle();
83             }
84             it->parent()->removeChild( it );
85             it = it2;
86         }
87         else
88         {
89             it = getNextItem( it );
90         }
91     }
92     playlist_Unlock( getIntf()->p_sys->p_playlist );
93 }
94
95 void Playtree::action( VarTree *pItem )
96 {
97     playlist_Lock( m_pPlaylist );
98     VarTree::Iterator it;
99
100     playlist_item_t *p_item = (playlist_item_t *)pItem->m_pData;
101     playlist_item_t *p_parent = p_item;
102     while( p_parent )
103     {
104         if( p_parent == m_pPlaylist->p_root_category )
105             break;
106         p_parent = p_parent->p_parent;
107     }
108
109     if( p_parent )
110     {
111         playlist_Control( m_pPlaylist, PLAYLIST_VIEWPLAY, pl_Locked, p_parent, p_item );
112     }
113     playlist_Unlock( m_pPlaylist );
114 }
115
116 void Playtree::onChange()
117 {
118     buildTree();
119     tree_update descr;
120     descr.i_type = 1;
121     notify( &descr );
122 }
123
124 void Playtree::onUpdateItem( int id )
125 {
126     Iterator it = findById( id );
127     tree_update descr;
128     descr.b_active_item = false;
129     if( it != end() )
130     {
131         // Update the item
132         playlist_item_t* pNode = (playlist_item_t*)(it->m_pData);
133         UString *pName = new UString( getIntf(), pNode->p_input->psz_name );
134         it->m_cString = UStringPtr( pName );
135     }
136     else
137     {
138         msg_Warn(getIntf(), "cannot find node with id %d", id );
139     }
140     descr.i_type = 0;
141     notify( &descr );
142 }
143
144
145 void Playtree::onUpdateCurrent( bool b_active )
146 {
147     if( !b_active )
148     {
149         if( !m_currentItem )
150             return;
151
152         Iterator it = findById( m_currentItem->i_id );
153         if( it != end() )
154             it->m_playing = false;
155         m_currentItem = NULL;
156     }
157     else
158     {
159         playlist_Lock( m_pPlaylist );
160
161         playlist_item_t* current = playlist_CurrentPlayingItem( m_pPlaylist );
162         if( !current )
163         {
164             playlist_Unlock( m_pPlaylist );
165             return;
166         }
167
168         Iterator it = findById( current->i_id );
169         if( it != end() )
170             it->m_playing = true;
171         m_currentItem = current;
172
173         playlist_Unlock( m_pPlaylist );
174     }
175
176     tree_update descr;
177     descr.b_active_item = true;
178     descr.i_type = 0;
179     notify( &descr );
180 }
181
182
183 /// \todo keep a list of "recently removed" to avoid looking up if we
184 //  already removed it
185 void Playtree::onDelete( int i_id )
186 {
187     Iterator item = findById( i_id ) ;
188     if( item != end() )
189     {
190         VarTree* parent = item->parent();
191
192         item->m_deleted = true;
193
194         tree_update descr;
195         descr.i_id = i_id;
196         descr.i_type = 3;
197         descr.b_visible = parent ? parent->m_expanded : true;
198         notify( &descr );
199
200         if( parent )
201             parent->removeChild( item );
202     }
203
204 }
205
206 void Playtree::onAppend( playlist_add_t *p_add )
207 {
208     i_items_to_append --;
209
210     Iterator node = findById( p_add->i_node );
211     if( node != end() )
212     {
213         Iterator item =  findById( p_add->i_item );
214         if( item == end() )
215         {
216             playlist_Lock( m_pPlaylist );
217             playlist_item_t *p_item = playlist_ItemGetById(
218                                         m_pPlaylist, p_add->i_item );
219             if( !p_item )
220             {
221                 playlist_Unlock( m_pPlaylist );
222                 return;
223             }
224             UString *pName = new UString( getIntf(),
225                                           p_item->p_input->psz_name );
226             node->add( p_add->i_item, UStringPtr( pName ),
227                       false,false, false, p_item->i_flags & PLAYLIST_RO_FLAG,
228                       p_item );
229             playlist_Unlock( m_pPlaylist );
230         }
231     }
232     tree_update descr;
233     descr.i_id = p_add->i_item;
234     descr.i_parent = p_add->i_node;
235     descr.b_visible = node->m_expanded;
236     descr.i_type = 2;
237     notify( &descr );
238 }
239
240 void Playtree::buildNode( playlist_item_t *pNode, VarTree &rTree )
241 {
242     for( int i = 0; i < pNode->i_children; i++ )
243     {
244         UString *pName = new UString( getIntf(),
245                                    pNode->pp_children[i]->p_input->psz_name );
246         rTree.add( pNode->pp_children[i]->i_id, UStringPtr( pName ),
247                      false,
248                      playlist_CurrentPlayingItem(m_pPlaylist) == pNode->pp_children[i],
249                      false, pNode->pp_children[i]->i_flags & PLAYLIST_RO_FLAG,
250                      pNode->pp_children[i] );
251         if( pNode->pp_children[i]->i_children )
252         {
253             buildNode( pNode->pp_children[i], rTree.back() );
254         }
255     }
256 }
257
258 void Playtree::buildTree()
259 {
260     clear();
261     playlist_Lock( m_pPlaylist );
262
263     i_items_to_append = 0;
264
265     clear();
266
267     /* TODO: Let user choose view - Stick with category ATM */
268
269     /* Set the root's name */
270     UString *pName = new UString( getIntf(),
271                              m_pPlaylist->p_root_category->p_input->psz_name );
272     m_cString = UStringPtr( pName );
273
274     buildNode( m_pPlaylist->p_root_category, *this );
275
276     playlist_Unlock( m_pPlaylist );
277 }
278