📄 playlist.cpp
字号:
CreateNode( p_node->pp_children[i], node ); /* Keep the tree pointer up to date */ child = treectrl->GetNextChild( node, cookie ); } } treectrl->SetItemImage( node, p_node->input.i_type );}/* Creates the node p_node as last child of parent */void Playlist::CreateNode( playlist_item_t *p_node, wxTreeItemId parent ){ wxTreeItemId node = treectrl->AppendItem( parent, wxL2U( p_node->input.psz_name ), -1,-1, new PlaylistItem( p_node ) ); treectrl->SetItemImage( node, p_node->input.i_type ); UpdateNodeChildren( p_node, node );}/* Update all children (recursively) of this node */void Playlist::UpdateNodeChildren( playlist_item_t *p_node, wxTreeItemId node ){ for( int i = 0; i< p_node->i_children ; i++ ) { /* Append the item */ if( p_node->pp_children[i]->i_children == -1 ) { wxTreeItemId item = treectrl->AppendItem( node, wxL2U( p_node->pp_children[i]->input.psz_name ), -1,-1, new PlaylistItem( p_node->pp_children[i]) ); UpdateTreeItem( item ); } else { CreateNode( p_node->pp_children[i], node ); } }}/* Update an item in the tree */void Playlist::UpdateTreeItem( wxTreeItemId item ){ if( ! item.IsOk() ) return; wxTreeItemData *p_data = treectrl->GetItemData( item ); if( !p_data ) return; LockPlaylist( p_intf->p_sys, p_playlist ); playlist_item_t *p_item = playlist_ItemGetById( p_playlist, ((PlaylistItem *)p_data)->i_id ); if( !p_item ) { UnlockPlaylist( p_intf->p_sys, p_playlist ); return; } wxString msg; wxString duration = wxU( "" ); char *psz_author = vlc_input_item_GetInfo( &p_item->input, _(VLC_META_INFO_CAT), _(VLC_META_ARTIST) ); if( !psz_author ) { UnlockPlaylist( p_intf->p_sys, p_playlist ); return; } char psz_duration[MSTRTIME_MAX_SIZE]; mtime_t dur = p_item->input.i_duration; if( dur != -1 ) { secstotimestr( psz_duration, dur/1000000 ); duration.Append( wxU( " ( " ) + wxString( wxU( psz_duration ) ) + wxU( " )" ) ); } if( !strcmp( psz_author, "" ) || p_item->input.b_fixed_name == VLC_TRUE ) { msg = wxString( wxU( p_item->input.psz_name ) ) + duration; } else { msg = wxString(wxU( psz_author )) + wxT(" - ") + wxString(wxU(p_item->input.psz_name)) + duration; } free( psz_author ); treectrl->SetItemText( item , msg ); treectrl->SetItemImage( item, p_item->input.i_type ); if( p_playlist->status.p_item == p_item ) { treectrl->SetItemBold( item, true ); while( treectrl->GetItemParent( item ).IsOk() ) { item = treectrl->GetItemParent( item ); if( ! (item == treectrl->GetRootItem() && treectrl->HasFlag( wxTR_HIDE_ROOT ) ) ) treectrl->Expand( item ); } } else { treectrl->SetItemBold( item, false ); } UnlockPlaylist( p_intf->p_sys, p_playlist );}/* Process a AppendIt em request */void Playlist::AppendItem( wxCommandEvent& event ){ playlist_add_t *p_add = (playlist_add_t *)event.GetClientData(); playlist_item_t *p_item = NULL; wxTreeItemId item, node; i_items_to_append--; /* No need to do anything if the playlist is going to be rebuilt */ if( b_need_update ) return; if( p_add->i_view != i_current_view ) goto update; node = FindItem( treectrl->GetRootItem(), p_add->i_node ); if( !node.IsOk() ) goto update; p_item = playlist_ItemGetById( p_playlist, p_add->i_item ); if( !p_item ) goto update; item = FindItem( treectrl->GetRootItem(), p_add->i_item ); if( item.IsOk() ) goto update; item = treectrl->AppendItem( node, wxL2U( p_item->input.psz_name ), -1,-1, new PlaylistItem( p_item ) ); treectrl->SetItemImage( item, p_item->input.i_type ); if( item.IsOk() && p_item->i_children == -1 ) { UpdateTreeItem( item ); }update: int i_count = CountItems( treectrl->GetRootItem()); if( i_count != p_playlist->i_size ) { statusbar->SetStatusText( wxString::Format( wxU(_( "%i items in playlist (%i not shown)")), p_playlist->i_size, p_playlist->i_size - i_count ) ); if( !b_changed_view ) { i_current_view = VIEW_CATEGORY; b_changed_view = VLC_TRUE; b_need_update = VLC_TRUE; } } else { statusbar->SetStatusText( wxString::Format( wxU(_( "%i items in playlist")), p_playlist->i_size ), 0 ); } return;}/* Process a updateitem request */void Playlist::UpdateItem( int i ){ if( i < 0 ) return; /* Sanity check */ wxTreeItemId item = FindItem( treectrl->GetRootItem(), i ); if( item.IsOk() ) { UpdateTreeItem( item ); }}void Playlist::RemoveItem( int i ){ if( i <= 0 ) return; /* Sanity check */ if( i == i_saved_id ) i_saved_id = -1; wxTreeItemId item = FindItem( treectrl->GetRootItem(), i ); if( item.IsOk() ) { treectrl->Delete( item ); }}/********************************************************************** * Search functions (internal) **********************************************************************//* Find a wxItem from a playlist id */wxTreeItemId Playlist::FindItem( wxTreeItemId root, int i_id ){ wxTreeItemIdValue cookie; PlaylistItem *p_wxcurrent; wxTreeItemId search; wxTreeItemId item = treectrl->GetFirstChild( root, cookie ); wxTreeItemId child; p_wxcurrent = (PlaylistItem *)treectrl->GetItemData( root ); if( i_id < 0 ) { wxTreeItemId dummy; return dummy; } if( i_saved_id == i_id ) { return saved_tree_item; } if( !p_wxcurrent ) { wxTreeItemId dummy; return dummy; } if( p_wxcurrent->i_id == i_id ) { i_saved_id = i_id; saved_tree_item = root; return root; } while( item.IsOk() ) { p_wxcurrent = (PlaylistItem *)treectrl->GetItemData( item ); if( p_wxcurrent->i_id == i_id ) { i_saved_id = i_id; saved_tree_item = item; return item; } if( treectrl->ItemHasChildren( item ) ) { wxTreeItemId search = FindItem( item, i_id ); if( search.IsOk() ) { i_saved_id = i_id; saved_tree_item = search; return search; } } item = treectrl->GetNextChild( root, cookie ); } /* Not found */ wxTreeItemId dummy; return dummy;}int Playlist::CountItems( wxTreeItemId root ){ wxTreeItemIdValue cookie; int count = 0; wxTreeItemId item = treectrl->GetFirstChild( root, cookie ); while( item.IsOk() ) { if( treectrl->ItemHasChildren( item ) ) { count += CountItems( item ); } else { playlist_item_t *p_item; LockPlaylist( p_intf->p_sys, p_playlist ); p_item = playlist_ItemGetById( p_playlist, ((PlaylistItem *)treectrl->GetItemData( item ))->i_id ); if( p_item && p_item->i_children == -1 ) count++; UnlockPlaylist( p_intf->p_sys, p_playlist ); } item = treectrl->GetNextChild( root, cookie ); } return count;}/* Find a wxItem from a name (from current) */wxTreeItemId Playlist::FindItemByName( wxTreeItemId root, wxString search_string, wxTreeItemId current, vlc_bool_t *pb_current_found ){ wxTreeItemIdValue cookie; wxTreeItemId search; wxTreeItemId item = treectrl->GetFirstChild( root, cookie ); wxTreeItemId child; while( item.IsOk() ) { if( treectrl->GetItemText( item).Lower().Contains( search_string.Lower() ) ) { if( !current.IsOk() || *pb_current_found == VLC_TRUE ) { return item; } else if( current.IsOk() && item == current ) { *pb_current_found = VLC_TRUE; } } if( treectrl->ItemHasChildren( item ) ) { wxTreeItemId search = FindItemByName( item, search_string, current, pb_current_found ); if( search.IsOk() ) { return search; } } item = treectrl->GetNextChild( root, cookie); } /* Not found */ wxTreeItemId dummy; return dummy;}/********************************************************************** * Rebuild the playlist **********************************************************************/void Playlist::Rebuild( vlc_bool_t b_root ){ playlist_view_t *p_view; i_items_to_append = 0; /* We can remove the callbacks before locking, anyway, we won't * miss anything */ if( b_root ) { var_DelCallback( p_playlist, "item-change", ItemChanged, this ); var_DelCallback( p_playlist, "playlist-current", PlaylistNext, this ); var_DelCallback( p_playlist, "intf-change", PlaylistChanged, this ); var_DelCallback( p_playlist, "item-append", ItemAppended, this ); var_DelCallback( p_playlist, "item-deleted", ItemDeleted, this ); /* ...and rebuild it */ LockPlaylist( p_intf->p_sys, p_playlist ); } i_saved_id = -1; p_view = playlist_ViewFind( p_playlist, i_current_view ); /* FIXME */ /* HACK we should really get new*/ treectrl->DeleteAllItems(); treectrl->AddRoot( wxU(_("root" )), -1, -1, new PlaylistItem( p_view->p_root) ); wxTreeItemId root = treectrl->GetRootItem(); UpdateNode( p_view->p_root, root ); int i_count = CountItems( treectrl->GetRootItem() ); if( i_count < p_playlist->i_size && !b_changed_view ) { i_current_view = VIEW_CATEGORY; b_changed_view = VLC_TRUE; Rebuild( VLC_FALSE ); } else if( i_count != p_playlist->i_size ) { statusbar->SetStatusText( wxString::Format( wxU(_( "%i items in playlist (%i not shown)")), p_playlist->i_size, p_playlist->i_size - i_count ) ); } else { statusbar->SetStatusText( wxString::Format( wxU(_( "%i items in playlist")), p_playlist->i_size ), 0 ); } if( b_root ) { /* Put callbacks back online */ var_AddCallback( p_playlist, "intf-change", PlaylistChanged, this ); var_AddCallback( p_playlist, "playlist-current", PlaylistNext, this ); var_AddCallback( p_playlist, "item-change", ItemChanged, this ); var_AddCallback( p_playlist, "item-append", ItemAppended, this ); var_AddCallback( p_playlist, "item-deleted", ItemDeleted, this ); UnlockPlaylist( p_intf->p_sys, p_playlist ); }}void Playlist::ShowPlaylist( bool show ){ if( show ) Rebuild( VLC_TRUE ); Show( show );}/* This function is called on a regular basis */void Playlist::UpdatePlaylist(){ i_update_counter++; /* If the playlist isn't show there's no need to update it */ if( !IsShown() ) return; if( this->b_need_update ) { this->b_need_update = VLC_FALSE; Rebuild( VLC_TRUE ); } /* Updating the playing status every 0.5s is enough */ if( i_update_counter % 5 ) return;}/***************************************************************************** * Private methods. *****************************************************************************/void Playlist::DeleteTreeItem( wxTreeItemId item ){ PlaylistItem *p_wxitem; playlist_item_t *p_item; p_wxitem = (PlaylistItem *)treectrl->GetItemData( item ); LockPlaylist( p_intf->p_sys, p_playlist ); p_item = playlist_ItemGetById( p_playlist, p_wxitem->i_id ); if( !p_item ) { UnlockPlaylist( p_intf->p_sys, p_playlist ); return; } if( p_item->i_children == -1 ) DeleteItem( p_item->input.i_id ); else DeleteNode( p_item );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -