1 /*****************************************************************************
3 *****************************************************************************
4 * Copyright (C) 2005 the VideoLAN team
7 * Authors: Antoine Cellerier <dionoea@videolan.org>
8 * Clément Stenac <zorglub@videolan.org>
9 * Erwan Tulou <erwan10@videolan.org>
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.
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.
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 *****************************************************************************/
30 #include <vlc_common.h>
32 #include "playtree.hpp"
33 #include <vlc_playlist.h>
35 #include "../utils/ustring.hpp"
37 Playtree::Playtree( intf_thread_t
*pIntf
)
38 : VarTree( pIntf
), m_pPlaylist( pIntf
->p_sys
->p_playlist
)
40 getPositionVar().addObserver( this );
46 getPositionVar().delObserver( this );
49 void Playtree::delSelected()
51 for( Iterator it
= m_children
.begin(); it
!= m_children
.end(); )
53 if( it
->isSelected() && !it
->isReadonly() )
55 playlist_Lock( m_pPlaylist
);
57 playlist_item_t
*pItem
=
58 playlist_ItemGetById( m_pPlaylist
, it
->getId() );
61 if( pItem
->i_children
== -1 )
63 playlist_DeleteFromInput( m_pPlaylist
, pItem
->p_input
,
68 playlist_NodeDelete( m_pPlaylist
, pItem
, true, false );
71 playlist_Unlock( m_pPlaylist
);
73 it
= it
->getNextSiblingOrUncle();
77 it
= getNextItem( it
);
82 void Playtree::action( VarTree
*pElem
)
84 playlist_Lock( m_pPlaylist
);
86 playlist_item_t
*pItem
=
87 playlist_ItemGetById( m_pPlaylist
, pElem
->getId() );
90 playlist_Control( m_pPlaylist
, PLAYLIST_VIEWPLAY
,
91 pl_Locked
, pItem
->p_parent
, pItem
);
94 playlist_Unlock( m_pPlaylist
);
97 void Playtree::onChange()
100 tree_update
descr( tree_update::ResetAll
, end() );
104 void Playtree::onUpdateItem( int id
)
106 Iterator it
= findById( id
);
107 if( it
!= m_children
.end() )
110 playlist_Lock( m_pPlaylist
);
111 playlist_item_t
*pNode
=
112 playlist_ItemGetById( m_pPlaylist
, it
->getId() );
115 playlist_Unlock( m_pPlaylist
);
119 UString
*pName
= getTitle( pNode
->p_input
);
120 playlist_Unlock( m_pPlaylist
);
122 if( *pName
!= *(it
->getString()) )
124 it
->setString( UStringPtr( pName
) );
127 tree_update::ItemUpdated
, IteratorVisible( it
, this ) );
138 msg_Warn( getIntf(), "cannot find node with id %d", id
);
142 void Playtree::onUpdateCurrent( bool b_active
)
146 playlist_Lock( m_pPlaylist
);
148 playlist_item_t
* current
= playlist_CurrentPlayingItem( m_pPlaylist
);
151 playlist_Unlock( m_pPlaylist
);
155 Iterator it
= findById( current
->i_id
);
156 if( it
!= m_children
.end() )
158 it
->setPlaying( true );
161 tree_update::ItemUpdated
, IteratorVisible( it
, this ) );
165 playlist_Unlock( m_pPlaylist
);
169 for( Iterator it
= m_children
.begin(); it
!= m_children
.end();
170 it
= getNextItem( it
) )
172 if( it
->isPlaying() )
174 it
->setPlaying( false );
177 tree_update::ItemUpdated
, IteratorVisible( it
, this ) );
185 void Playtree::onDelete( int i_id
)
187 Iterator it
= findById( i_id
) ;
188 if( it
!= m_children
.end() )
190 VarTree
* parent
= it
->parent();
194 tree_update::DeletingItem
, IteratorVisible( it
, this ) );
197 parent
->removeChild( it
);
198 m_allItems
.erase( i_id
);
201 tree_update::ItemDeleted
, end() );
207 void Playtree::onAppend( playlist_add_t
*p_add
)
209 Iterator it_node
= findById( p_add
->i_node
);
210 if( it_node
!= m_children
.end() )
212 playlist_Lock( m_pPlaylist
);
213 playlist_item_t
*pItem
=
214 playlist_ItemGetById( m_pPlaylist
, p_add
->i_item
);
217 playlist_Unlock( m_pPlaylist
);
222 for( pos
= 0; pos
< pItem
->p_parent
->i_children
; pos
++ )
223 if( pItem
->p_parent
->pp_children
[pos
] == pItem
) break;
225 UString
*pName
= getTitle( pItem
->p_input
);
226 playlist_item_t
* current
= playlist_CurrentPlayingItem( m_pPlaylist
);
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
);
232 m_allItems
[pItem
->i_id
] = &*it
;
234 playlist_Unlock( m_pPlaylist
);
237 tree_update::ItemInserted
,
238 IteratorVisible( it
, this ) );
243 void Playtree::buildNode( playlist_item_t
*pNode
, VarTree
&rTree
)
245 UString
*pName
= getTitle( pNode
->p_input
);
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
;
252 for( int i
= 0; i
< pNode
->i_children
; i
++ )
254 buildNode( pNode
->pp_children
[i
], *it
);
258 void Playtree::buildTree()
261 playlist_Lock( m_pPlaylist
);
263 for( int i
= 0; i
< m_pPlaylist
->p_root
->i_children
; i
++ )
265 buildNode( m_pPlaylist
->p_root
->pp_children
[i
], *this );
268 playlist_Unlock( m_pPlaylist
);
271 void Playtree::onUpdateSlider()
273 tree_update
descr( tree_update::SliderChanged
, end() );
277 void Playtree::insertItems( VarTree
& elem
, const list
<string
>& files
, bool start
)
280 VarTree
* p_elem
= &elem
;
281 playlist_item_t
* p_node
= NULL
;
284 playlist_Lock( m_pPlaylist
);
288 for( Iterator it
= m_children
.begin(); it
!= m_children
.end(); ++it
)
290 if( it
->getId() == m_pPlaylist
->p_local_category
->i_id
)
298 if( p_elem
->getId() == m_pPlaylist
->p_local_category
->i_id
)
300 p_node
= m_pPlaylist
->p_local_category
;
302 p_elem
->setExpanded( true );
304 else if( p_elem
->getId() == m_pPlaylist
->p_ml_category
->i_id
)
306 p_node
= m_pPlaylist
->p_ml_category
;
308 p_elem
->setExpanded( true );
310 else if( p_elem
->size() && p_elem
->isExpanded() )
312 p_node
= playlist_ItemGetById( m_pPlaylist
, p_elem
->getId() );
317 p_node
= playlist_ItemGetById( m_pPlaylist
,
318 p_elem
->parent()->getId() );
319 i_pos
= p_elem
->getIndex();
326 for( list
<string
>::const_iterator it
= files
.begin();
327 it
!= files
.end(); ++it
, i_pos
++, first
= false )
331 if( strstr( it
->c_str(), "://" ) )
332 pItem
= input_item_New( it
->c_str(), NULL
);
335 char *psz_uri
= vlc_path2uri( it
->c_str(), NULL
);
336 if( psz_uri
== NULL
)
338 pItem
= input_item_New( psz_uri
, NULL
);
345 int i_mode
= PLAYLIST_APPEND
;
347 i_mode
|= PLAYLIST_GO
;
349 playlist_NodeAddInput( m_pPlaylist
, pItem
, p_node
,
350 i_mode
, i_pos
, pl_Locked
);
354 playlist_Unlock( m_pPlaylist
);
358 UString
* Playtree::getTitle( input_item_t
*pItem
)
360 char *psz_name
= input_item_GetTitleFbName( pItem
);
361 UString
*pTitle
= new UString( getIntf(), psz_name
);
367 VarTree::Iterator
Playtree::findById( int id
)
369 map
<int,VarTree
*>::iterator it
= m_allItems
.find( id
);
370 if( it
== m_allItems
.end() )
371 return m_children
.end();
373 return it
->second
->getSelf();