]> git.sesse.net Git - vlc/blob - modules/gui/skins2/vars/playtree.cpp
skins2: remove vlc_object_alive (deprecated)
[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  *          Erwan Tulou    <erwan10@videolan.org>
10  *
11  * This program is free software; you can redistribute it and/or modify
12  * it under the terms of the GNU General Public License as published by
13  * the Free Software Foundation; either version 2 of the License, or
14  * (at your option) any later version.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program; if not, write to the Free Software
23  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
24  *****************************************************************************/
25
26 #ifdef HAVE_CONFIG_H
27 # include "config.h"
28 #endif
29
30 #include <vlc_common.h>
31
32 #include "playtree.hpp"
33 #include <vlc_playlist.h>
34 #include <vlc_url.h>
35 #include "../utils/ustring.hpp"
36
37 Playtree::Playtree( intf_thread_t *pIntf )
38     : VarTree( pIntf ), m_pPlaylist( pIntf->p_sys->p_playlist )
39 {
40     getPositionVar().addObserver( this );
41     buildTree();
42 }
43
44 Playtree::~Playtree()
45 {
46     getPositionVar().delObserver( this );
47 }
48
49 void Playtree::delSelected()
50 {
51     for( Iterator it = m_children.begin(); it != m_children.end(); )
52     {
53         if( it->isSelected() && !it->isReadonly() )
54         {
55             playlist_Lock( m_pPlaylist );
56
57             playlist_item_t *pItem =
58                 playlist_ItemGetById( m_pPlaylist, it->getId() );
59             if( pItem )
60             {
61                 if( pItem->i_children == -1 )
62                 {
63                     playlist_DeleteFromInput( m_pPlaylist, pItem->p_input,
64                                               pl_Locked );
65                 }
66                 else
67                 {
68                     playlist_NodeDelete( m_pPlaylist, pItem, true, false );
69                 }
70             }
71             playlist_Unlock( m_pPlaylist );
72
73             it = it->getNextSiblingOrUncle();
74         }
75         else
76         {
77             it = getNextItem( it );
78         }
79     }
80 }
81
82 void Playtree::action( VarTree *pElem )
83 {
84     playlist_Lock( m_pPlaylist );
85
86     playlist_item_t *pItem =
87         playlist_ItemGetById( m_pPlaylist, pElem->getId() );
88     if( pItem )
89     {
90         playlist_Control( m_pPlaylist, PLAYLIST_VIEWPLAY,
91                           pl_Locked, pItem->p_parent, pItem );
92     }
93
94     playlist_Unlock( m_pPlaylist );
95 }
96
97 void Playtree::onChange()
98 {
99     buildTree();
100     tree_update descr( tree_update::ResetAll, end() );
101     notify( &descr );
102 }
103
104 void Playtree::onUpdateItem( int id )
105 {
106     Iterator it = findById( id );
107     if( it != m_children.end() )
108     {
109         // Update the item
110         playlist_Lock( m_pPlaylist );
111         playlist_item_t *pNode =
112             playlist_ItemGetById( m_pPlaylist, it->getId() );
113         if( !pNode )
114         {
115             playlist_Unlock( m_pPlaylist );
116             return;
117         }
118
119         char *psz_name = input_item_GetTitleFbName( pNode->p_input );
120         UString *pName = new UString( getIntf(), psz_name );
121         free(psz_name);
122         playlist_Unlock( m_pPlaylist );
123
124         if( *pName != *(it->getString()) )
125         {
126             it->setString( UStringPtr( pName ) );
127
128             tree_update descr(
129                 tree_update::ItemUpdated, IteratorVisible( it, this ) );
130             notify( &descr );
131         }
132     }
133     else
134     {
135         msg_Warn( getIntf(), "cannot find node with id %d", id );
136     }
137 }
138
139 void Playtree::onUpdateCurrent( bool b_active )
140 {
141     if( b_active )
142     {
143         playlist_Lock( m_pPlaylist );
144
145         playlist_item_t* current = playlist_CurrentPlayingItem( m_pPlaylist );
146         if( !current )
147         {
148             playlist_Unlock( m_pPlaylist );
149             return;
150         }
151
152         Iterator it = findById( current->i_id );
153         if( it != m_children.end() )
154         {
155             it->setPlaying( true );
156
157             tree_update descr(
158                 tree_update::ItemUpdated, IteratorVisible( it, this ) );
159             notify( &descr );
160         }
161
162         playlist_Unlock( m_pPlaylist );
163     }
164     else
165     {
166         for( Iterator it = m_children.begin(); it != m_children.end();
167              it = getNextItem( it ) )
168         {
169             if( it->isPlaying() )
170             {
171                 it->setPlaying( false );
172
173                 tree_update descr(
174                     tree_update::ItemUpdated, IteratorVisible( it, this ) );
175                 notify( &descr );
176                 break;
177             }
178         }
179     }
180 }
181
182 void Playtree::onDelete( int i_id )
183 {
184     Iterator it = findById( i_id ) ;
185     if( it != m_children.end() )
186     {
187         VarTree* parent = it->parent();
188         if( parent )
189         {
190             tree_update descr(
191                 tree_update::DeletingItem, IteratorVisible( it, this ) );
192             notify( &descr );
193
194             parent->removeChild( it );
195             m_allItems.erase( i_id );
196
197             tree_update descr2(
198                 tree_update::ItemDeleted, end() );
199             notify( &descr2 );
200         }
201     }
202 }
203
204 void Playtree::onAppend( playlist_add_t *p_add )
205 {
206     Iterator it_node = findById( p_add->i_node );
207     if( it_node != m_children.end() )
208     {
209         playlist_Lock( m_pPlaylist );
210         playlist_item_t *pItem =
211             playlist_ItemGetById( m_pPlaylist, p_add->i_item );
212         if( !pItem )
213         {
214             playlist_Unlock( m_pPlaylist );
215             return;
216         }
217
218         int pos;
219         for( pos = 0; pos < pItem->p_parent->i_children; pos++ )
220             if( pItem->p_parent->pp_children[pos] == pItem ) break;
221
222         char *psz_name = input_item_GetTitleFbName( pItem->p_input );
223         UString *pName = new UString( getIntf(), psz_name );
224         free( psz_name );
225
226         playlist_item_t* current = playlist_CurrentPlayingItem( m_pPlaylist );
227
228         Iterator it = it_node->add(
229             p_add->i_item, UStringPtr( pName ), false, pItem == current,
230             false, pItem->i_flags & PLAYLIST_RO_FLAG, pos );
231
232         m_allItems[pItem->i_id] = &*it;
233
234         playlist_Unlock( m_pPlaylist );
235
236         tree_update descr(
237             tree_update::ItemInserted,
238             IteratorVisible( it, this ) );
239         notify( &descr );
240     }
241 }
242
243 void Playtree::buildNode( playlist_item_t *pNode, VarTree &rTree )
244 {
245     UString *pName = new UString( getIntf(), pNode->p_input->psz_name );
246     Iterator it = rTree.add(
247         pNode->i_id, UStringPtr( pName ), false,
248         playlist_CurrentPlayingItem(m_pPlaylist) == pNode,
249         false, pNode->i_flags & PLAYLIST_RO_FLAG );
250     m_allItems[pNode->i_id] = &*it;
251
252     for( int i = 0; i < pNode->i_children; i++ )
253     {
254         buildNode( pNode->pp_children[i], *it );
255     }
256 }
257
258 void Playtree::buildTree()
259 {
260     clear();
261     playlist_Lock( m_pPlaylist );
262
263     for( int i = 0; i < m_pPlaylist->p_root->i_children; i++ )
264     {
265         buildNode( m_pPlaylist->p_root->pp_children[i], *this );
266     }
267
268     playlist_Unlock( m_pPlaylist );
269 }
270
271 void Playtree::onUpdateSlider()
272 {
273     tree_update descr( tree_update::SliderChanged, end() );
274     notify( &descr );
275 }
276
277 void Playtree::insertItems( VarTree& elem, const list<string>& files, bool start )
278 {
279     bool first = true;
280     VarTree* p_elem = &elem;
281     playlist_item_t* p_node = NULL;
282     int i_pos = -1;
283
284     playlist_Lock( m_pPlaylist );
285
286     if( p_elem == this )
287     {
288         for( Iterator it = m_children.begin(); it != m_children.end(); ++it )
289         {
290             if( it->getId() == m_pPlaylist->p_local_category->i_id )
291             {
292                 p_elem = &*it;
293                 break;
294             }
295         }
296     }
297
298     if( p_elem->getId() == m_pPlaylist->p_local_category->i_id )
299     {
300         p_node = m_pPlaylist->p_local_category;
301         i_pos = 0;
302         p_elem->setExpanded( true );
303     }
304     else if( p_elem->getId() == m_pPlaylist->p_ml_category->i_id )
305     {
306         p_node = m_pPlaylist->p_ml_category;
307         i_pos = 0;
308         p_elem->setExpanded( true );
309     }
310     else if( p_elem->size() && p_elem->isExpanded() )
311     {
312         p_node = playlist_ItemGetById( m_pPlaylist, p_elem->getId() );
313         i_pos = 0;
314     }
315     else
316     {
317         p_node = playlist_ItemGetById( m_pPlaylist,
318                                        p_elem->parent()->getId() );
319         i_pos = p_elem->getIndex();
320         i_pos++;
321     }
322
323     if( !p_node )
324         goto fin;
325
326     for( list<string>::const_iterator it = files.begin();
327          it != files.end(); ++it, i_pos++, first = false )
328     {
329         char* psz_uri = make_URI( it->c_str(), NULL );
330         if( !psz_uri )
331             continue;
332
333         input_item_t* pItem = input_item_New( psz_uri, NULL );
334         if( pItem )
335         {
336             int i_mode = PLAYLIST_APPEND;
337             if( first && start )
338                 i_mode |= PLAYLIST_GO;
339
340             playlist_NodeAddInput( m_pPlaylist, pItem, p_node,
341                                    i_mode, i_pos, pl_Locked );
342         }
343         free( psz_uri );
344     }
345
346 fin:
347     playlist_Unlock( m_pPlaylist );
348 }
349
350 VarTree::Iterator Playtree::findById( int id )
351 {
352     map<int,VarTree*>::iterator it = m_allItems.find( id );
353     if( it == m_allItems.end() )
354         return m_children.end();
355     else
356         return it->second->getSelf();
357 }