]> git.sesse.net Git - vlc/blobdiff - modules/gui/wxwidgets/dialogs/playlist.cpp
* Protect input item's meta through setters and getters. That allows tracking of...
[vlc] / modules / gui / wxwidgets / dialogs / playlist.cpp
index 81565fa3ef2bc36ef4123507636092cb50b33344..4f91dc6fc8301ddeaff6b8d10e1da6db66f1b269 100644 (file)
@@ -47,7 +47,7 @@
 #include <wx/imaglist.h>
 
 #include <vlc_meta.h>
-#include "charset.h"
+#include "vlc_charset.h"
 
 #define HELP_SHUFFLE N_( "Shuffle" )
 #define HELP_LOOP N_( "Repeat All" )
@@ -226,9 +226,8 @@ Playlist::Playlist( intf_thread_t *_p_intf, wxWindow *p_parent ):
     p_view_menu = NULL;
     p_sd_menu = SDMenu();
 
-//    i_current_view = VIEW_ONELEVEL;
-    p_current_viewroot = p_playlist->p_root_onelevel;
-    p_current_treeroot = p_playlist->p_local_onelevel;
+    p_current_viewroot = p_playlist->p_root_category;
+    p_current_treeroot = NULL;
 
     i_title_sorted = 0;
     i_group_sorted = 0;
@@ -367,8 +366,6 @@ Playlist::Playlist( intf_thread_t *_p_intf, wxWindow *p_parent ):
     p_images->Add( wxIcon( type_node_xpm ) );
     treectrl->AssignImageList( p_images );
 
-    treectrl->AddRoot( wxU(_("root" )), -1, -1, NULL );
-
     /* Reduce font size */
     wxFont font= treectrl->GetFont();
     font.SetPointSize(9);
@@ -408,8 +405,8 @@ Playlist::Playlist( intf_thread_t *_p_intf, wxWindow *p_parent ):
     var_AddCallback( p_playlist, "item-deleted", ItemDeleted, this );
 
     /* Update the playlist */
+    p_current_treeroot = p_playlist->p_local_category;
     Rebuild( VLC_TRUE );
-
 }
 
 Playlist::~Playlist()
@@ -505,7 +502,7 @@ void Playlist::UpdateTreeItem( wxTreeItemId item )
     if( !p_data ) return;
 
     playlist_item_t *p_item = playlist_ItemGetById( p_playlist,
-                                          ((PlaylistItem *)p_data)->i_id );
+                                    ((PlaylistItem *)p_data)->i_id, VLC_TRUE );
     if( !p_item )
     {
         UnlockPlaylist( p_intf->p_sys, p_playlist );
@@ -516,14 +513,9 @@ void Playlist::UpdateTreeItem( wxTreeItemId item )
     wxString duration = wxU( "" );
 
     char *psz_artist;
-    if( p_item->p_input->p_meta )
-    {
-        psz_artist= p_item->p_input->p_meta->psz_artist ?
-                        strdup( p_item->p_input->p_meta->psz_artist ) :
-                        strdup("");
-    }
-    else
-        psz_artist = strdup( "" );
+    psz_artist = input_item_GetArtist( p_item->p_input ) ?
+                    strdup( input_item_GetArtist( p_item->p_input ) ) :
+                    strdup("");
 
     char psz_duration[MSTRTIME_MAX_SIZE];
     mtime_t dur = p_item->p_input->i_duration;
@@ -581,7 +573,7 @@ void Playlist::AppendItem( wxCommandEvent& event )
     node = FindItem( treectrl->GetRootItem(), p_add->i_node );
     if( !node.IsOk() ) goto update;
 
-    p_item = playlist_ItemGetById( p_playlist, p_add->i_item );
+    p_item = playlist_ItemGetById( p_playlist, p_add->i_item, VLC_TRUE );
     if( !p_item ) goto update;
     if( (p_item->i_flags & PLAYLIST_DBL_FLAG ) ) goto update;
 
@@ -744,7 +736,7 @@ int Playlist::CountItems( wxTreeItemId root )
         {
             playlist_item_t *p_item;
             LockPlaylist( p_intf->p_sys, p_playlist );
-            p_item = playlist_ItemGetById( p_playlist, ((PlaylistItem *)treectrl->GetItemData( item ))->i_id );
+            p_item = playlist_ItemGetById( p_playlist, ((PlaylistItem *)treectrl->GetItemData( item ))->i_id, VLC_TRUE );
             if( p_item && p_item->i_children == -1 )
                 count++;
             UnlockPlaylist( p_intf->p_sys, p_playlist );
@@ -799,19 +791,8 @@ void Playlist::Rebuild( vlc_bool_t b_root )
 {
     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 );
+    LockPlaylist( p_intf->p_sys, p_playlist );
 
-        /* ...and rebuild it */
-        LockPlaylist( p_intf->p_sys, p_playlist );
-    }
     /* Invalidate cache */
     i_saved_id = -1;
     i_saved_input_id = -1;
@@ -834,8 +815,6 @@ void Playlist::Rebuild( vlc_bool_t b_root )
                          new PlaylistItem( p_current_treeroot ) );
 
     wxTreeItemId root = treectrl->GetRootItem();
-    //UpdateNode( p_current_treeroot, root );
-    //CreateNode( p_current_treeroot, root );
     UpdateNodeChildren( p_current_treeroot, root );
 
     int i_count = CountItems( treectrl->GetRootItem() );
@@ -843,17 +822,7 @@ void Playlist::Rebuild( vlc_bool_t b_root )
     statusbar->SetStatusText( wxString::Format( wxU(_(
                               "%i items in playlist")), i_count ), 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 );
-    }
+    UnlockPlaylist( p_intf->p_sys, p_playlist );
 }
 
 void Playlist::ShowPlaylist( bool show )
@@ -890,7 +859,7 @@ void Playlist::DeleteTreeItem( wxTreeItemId item )
    p_wxitem = (PlaylistItem *)treectrl->GetItemData( item );
 
    LockPlaylist( p_intf->p_sys, p_playlist );
-   p_item = playlist_ItemGetById( p_playlist, p_wxitem->i_id );
+   p_item = playlist_ItemGetById( p_playlist, p_wxitem->i_id, VLC_TRUE );
 
    if( !p_item )
    {
@@ -907,7 +876,7 @@ void Playlist::DeleteTreeItem( wxTreeItemId item )
 
 void Playlist::DeleteItem( int item_id )
 {
-    playlist_DeleteAllFromInput( p_playlist, item_id );
+    playlist_DeleteFromInput( p_playlist, item_id, VLC_TRUE );
 }
 
 void Playlist::DeleteNode( playlist_item_t *p_item )
@@ -938,7 +907,7 @@ void Playlist::OnSave( wxCommandEvent& WXUNUSED(event) )
 
     wxString filter = wxT("");
 
-    if( p_playlist->i_size == 0 )
+    if( playlist_IsEmpty( p_playlist ) )
     {
         wxMessageBox( wxU(_("Playlist is empty") ), wxU(_("Can't save")),
                       wxICON_WARNING | wxOK, this );
@@ -957,12 +926,12 @@ void Playlist::OnSave( wxCommandEvent& WXUNUSED(event) )
 
     if( dialog.ShowModal() == wxID_OK )
     {
-        if( dialog.GetPath().mb_str() )
+        if( dialog.GetPath().mb_str(wxConvUTF8) )
         {
             /* what root should we export? */
             if( p_playlist->p_root_category->i_children > 0 )
             {
-                playlist_Export( p_playlist, dialog.GetPath().mb_str(),
+                playlist_Export( p_playlist, dialog.GetPath().mb_str(wxConvUTF8),
                                  p_playlist->p_root_category->pp_children[0],
                                  formats[dialog.GetFilterIndex()].psz_module );
             }
@@ -978,9 +947,7 @@ void Playlist::OnOpen( wxCommandEvent& WXUNUSED(event) )
 
     if( dialog.ShowModal() == wxID_OK )
     {
-        playlist_Import( p_playlist, dialog.GetPath().mb_str(),
-                         /*FIXME: where do we want to insert ? */
-                         p_playlist->p_local_category, VLC_TRUE );
+        playlist_Import( p_playlist, dialog.GetPath().mb_str(wxConvUTF8) );
     }
 }
 
@@ -1015,12 +982,14 @@ void Playlist::OnSort( wxCommandEvent& event )
     {
         case SortTitle_Event:
             playlist_RecursiveNodeSort( p_playlist,
-                            playlist_ItemGetById( p_playlist, p_wxitem->i_id ),
+                            playlist_ItemGetById( p_playlist, p_wxitem->i_id,
+                                                  VLC_TRUE ),
                             SORT_TITLE_NODES_FIRST, ORDER_NORMAL );
             break;
         case RSortTitle_Event:
             playlist_RecursiveNodeSort( p_playlist,
-                            playlist_ItemGetById( p_playlist, p_wxitem->i_id ),
+                            playlist_ItemGetById( p_playlist, p_wxitem->i_id,
+                                                  VLC_TRUE ),
                             SORT_TITLE_NODES_FIRST, ORDER_REVERSE );
     }
     UnlockPlaylist( p_intf->p_sys, p_playlist );
@@ -1041,7 +1010,8 @@ void Playlist::OnSearch( wxCommandEvent& WXUNUSED(event) )
     wxString search_string = search_text->GetValue();
     PlaylistItem *p_wxroot;
     p_wxroot = (PlaylistItem *)treectrl->GetItemData( treectrl->GetRootItem() );
-    playlist_item_t *p_root = playlist_ItemGetById( p_playlist, p_wxroot->i_id );
+    playlist_item_t *p_root = playlist_ItemGetById( p_playlist, p_wxroot->i_id,
+                                                    VLC_TRUE );
 
     assert( p_root );
     char *psz_name = wxFromLocale( search_string );
@@ -1058,16 +1028,23 @@ void Playlist::RecursiveDeleteSelection(  wxTreeItemId root )
 {
     wxTreeItemIdValue cookie;
     wxTreeItemId child = treectrl->GetFirstChild( root, cookie );
+    wxTreeItemId nextchild;
+    bool childIsSelected = FALSE;
+    bool nextchildIsSelected = FALSE;
+
+    if( child.IsOk() ) childIsSelected = treectrl->IsSelected( child );
+
     while( child.IsOk() )
     {
-        if( treectrl->ItemHasChildren( child ) )
-        {
-            RecursiveDeleteSelection( child );
-            if( treectrl->IsSelected(child ) ) DeleteTreeItem( child );
-        }
-        else if( treectrl->IsSelected( child ) )
+        nextchild = treectrl->GetNextChild( root, cookie );
+        if( nextchild.IsOk() )
+            nextchildIsSelected = treectrl->IsSelected( nextchild );
+        if( childIsSelected )
             DeleteTreeItem( child );
-        child = treectrl->GetNextChild( root, cookie );
+        else if( treectrl->ItemHasChildren( child ) )
+            RecursiveDeleteSelection( child );
+        child = nextchild;
+        childIsSelected = nextchildIsSelected;
     }
 }
 
@@ -1117,7 +1094,7 @@ void Playlist::OnActivateItem( wxTreeEvent& event )
         UnlockPlaylist( p_intf->p_sys, p_playlist );
         return;
     }
-    p_item = playlist_ItemGetById( p_playlist, p_wxitem->i_id );
+    p_item = playlist_ItemGetById( p_playlist, p_wxitem->i_id, VLC_TRUE );
 
     p_parent = p_item;
     while( p_parent )
@@ -1129,7 +1106,7 @@ void Playlist::OnActivateItem( wxTreeEvent& event )
 
     if( p_parent )
     {
-        playlist_Control( p_playlist, PLAYLIST_VIEWPLAY, p_parent, p_item );
+        playlist_Control( p_playlist, PLAYLIST_VIEWPLAY, VLC_TRUE, p_parent, p_item );
     }
     UnlockPlaylist( p_intf->p_sys, p_playlist );
 }
@@ -1138,7 +1115,7 @@ void Playlist::OnKeyDown( wxTreeEvent& event )
 {
     long keycode = event.GetKeyCode();
     /* Delete selected items */
-    if( keycode == WXK_BACK || keycode == WXK_DELETE )
+    if( keycode == WXK_BACK || keycode == WXK_DELETE || keycode == WXK_NUMPAD_DELETE )
     {
         /* We send a dummy event */
         OnDeleteSelection( event );
@@ -1172,7 +1149,7 @@ void Playlist::OnDragItemEnd( wxTreeEvent& event )
 
     if( !dest_tree_item.IsOk() ) return;
 
-    /* check that we're not trying to move a node into one of it's children */
+    /* check that we're not trying to move a node into one of its children */
     wxTreeItemId parent = dest_tree_item;
     while( parent != treectrl->GetRootItem() )
     {
@@ -1193,9 +1170,9 @@ void Playlist::OnDragItemEnd( wxTreeEvent& event )
     }
 
     playlist_item_t *p_drageditem =
-        playlist_ItemGetById(p_playlist, p_wxdrageditem->i_id );
+        playlist_ItemGetById(p_playlist, p_wxdrageditem->i_id, VLC_TRUE );
     playlist_item_t *p_destitem =
-        playlist_ItemGetById(p_playlist, p_wxdestitem->i_id );
+        playlist_ItemGetById(p_playlist, p_wxdestitem->i_id, VLC_TRUE );
     if( !p_drageditem || !p_destitem )
     {
         UnlockPlaylist( p_intf->p_sys, p_playlist );
@@ -1214,7 +1191,7 @@ void Playlist::OnDragItemEnd( wxTreeEvent& event )
             return;
         }
         playlist_item_t *p_destitem2 =
-            playlist_ItemGetById( p_playlist, p_parent->i_id );
+            playlist_ItemGetById( p_playlist, p_parent->i_id, VLC_TRUE );
         if( !p_destitem2 )
         {
             UnlockPlaylist( p_intf->p_sys, p_playlist );
@@ -1269,13 +1246,13 @@ bool PlaylistFileDropTarget::OnDropFiles( wxCoord x, wxCoord y,
     {
         PlaylistItem *p_plitem =
             (PlaylistItem *)p->treectrl->GetItemData( item );
-        p_dest = playlist_ItemGetById( p->p_playlist, p_plitem->i_id );
+        p_dest = playlist_ItemGetById( p->p_playlist, p_plitem->i_id, VLC_TRUE );
 
         if( p_dest->i_children == -1 )
         {
             /* This is a leaf. Append right after it
              * We thus need to find the parrent node and the position of the
-             * leaf in it's children list */
+             * leaf in its children list */
             wxTreeItemId parent = p->treectrl->GetItemParent( item );
             PlaylistItem *p_parent =
                 (PlaylistItem *)p->treectrl->GetItemData( parent );
@@ -1285,7 +1262,7 @@ bool PlaylistFileDropTarget::OnDropFiles( wxCoord x, wxCoord y,
                 return FALSE;
             }
             playlist_item_t *p_node =
-                playlist_ItemGetById( p->p_playlist, p_parent->i_id );
+                playlist_ItemGetById( p->p_playlist, p_parent->i_id, VLC_TRUE );
             if( !p_node )
             {
                 UnlockPlaylist( p->p_intf->p_sys, p->p_playlist );
@@ -1308,7 +1285,7 @@ bool PlaylistFileDropTarget::OnDropFiles( wxCoord x, wxCoord y,
         input_item_t *p_input = input_ItemNew( p->p_playlist,
                                               psz_utf8, psz_utf8 );
         playlist_NodeAddInput( p->p_playlist, p_input,
-                               p_dest, PLAYLIST_PREPARSE, i_pos );
+                               p_dest, PLAYLIST_PREPARSE, i_pos, VLC_FALSE );
         wxDnDLocaleFree( psz_utf8 );
     }
 
@@ -1434,7 +1411,7 @@ wxMenu *Playlist::SDMenu()
         if( !strcmp( p_parser->psz_capability, "services_discovery" ) )
             i_number++;
     }
-    if( i_number ) pp_sds = (char **)calloc( i_number, sizeof(void *) );
+    if( i_number ) pp_sds = (const char **)calloc( i_number, sizeof(void *) );
 
     i_number = 0;
     for( int i_index = 0; i_index < p_list->i_count; i_index++ )
@@ -1488,7 +1465,7 @@ void Playlist::OnPopup( wxContextMenuEvent& event )
         treectrl->SelectItem( i_wx_popup_item );
 
         LockPlaylist( p_intf->p_sys, p_playlist );
-        p_item = playlist_ItemGetById( p_playlist, i_popup_item );
+        p_item = playlist_ItemGetById( p_playlist, i_popup_item, VLC_TRUE );
 
         if( !p_item )
         {
@@ -1514,7 +1491,7 @@ void Playlist::OnPopupPlay( wxCommandEvent& event )
 {
     playlist_item_t *p_popup_item, *p_popup_parent;
     LockPlaylist( p_intf->p_sys, p_playlist );
-    p_popup_item = playlist_ItemGetById( p_playlist, i_popup_item );
+    p_popup_item = playlist_ItemGetById( p_playlist, i_popup_item, VLC_TRUE );
 
     p_popup_parent = p_popup_item;
     while( p_popup_parent )
@@ -1526,7 +1503,7 @@ void Playlist::OnPopupPlay( wxCommandEvent& event )
 
     if( p_popup_parent )
     {
-        playlist_Control( p_playlist, PLAYLIST_VIEWPLAY, p_popup_parent,
+        playlist_Control( p_playlist, PLAYLIST_VIEWPLAY, VLC_TRUE, p_popup_parent,
                           p_popup_item );
     }
     UnlockPlaylist( p_intf->p_sys, p_playlist );
@@ -1541,7 +1518,7 @@ void Playlist::Preparse()
 {
     playlist_item_t *p_popup_item;
     LockPlaylist( p_intf->p_sys, p_playlist );
-    p_popup_item = playlist_ItemGetById( p_playlist, i_popup_item );
+    p_popup_item = playlist_ItemGetById( p_playlist, i_popup_item, VLC_TRUE );
 
     if( p_popup_item != NULL )
     {
@@ -1579,7 +1556,7 @@ void Playlist::OnPopupSort( wxCommandEvent& event )
     p_wxitem = (PlaylistItem *)treectrl->GetItemData( i_wx_popup_item );
     LockPlaylist( p_intf->p_sys, p_playlist );
 
-    p_item = playlist_ItemGetById( p_playlist, p_wxitem->i_id );
+    p_item = playlist_ItemGetById( p_playlist, p_wxitem->i_id, VLC_TRUE );
     if( p_item->i_children >= 0 )
     {
         playlist_RecursiveNodeSort( p_playlist, p_item,
@@ -1596,7 +1573,9 @@ void Playlist::OnPopupSort( wxCommandEvent& event )
 void Playlist::OnPopupInfo( wxCommandEvent& event )
 {
     LockPlaylist( p_intf->p_sys, p_playlist );
-    playlist_item_t *p_popup_item = playlist_ItemGetById( p_playlist, i_popup_item );
+    playlist_item_t *p_popup_item = playlist_ItemGetById( p_playlist,
+                                                          i_popup_item,
+                                                          VLC_TRUE );
     if( p_popup_item )
     {
         iteminfo_dialog = new ItemInfoDialog( p_intf, p_popup_item, this );
@@ -1624,9 +1603,9 @@ void Playlist::OnPopupAddNode( wxCommandEvent& event )
 
     p_wxitem = (PlaylistItem *)treectrl->GetItemData( i_wx_popup_item );
 
-    p_item = playlist_ItemGetById( p_playlist, p_wxitem->i_id );
+    p_item = playlist_ItemGetById( p_playlist, p_wxitem->i_id, VLC_TRUE );
 
-    playlist_NodeCreate( p_playlist, psz_name, p_item );
+    playlist_NodeCreate( p_playlist, psz_name, p_item, 0 );
 
     UnlockPlaylist( p_intf->p_sys, p_playlist );
     Rebuild( VLC_TRUE );
@@ -1638,9 +1617,10 @@ void Playlist::OnSourceSelected( wxListEvent &event )
 {
    int i_id = event.GetData();
 
-   if( p_current_treeroot && i_id != p_current_treeroot->i_id )
+   if( !p_current_treeroot || i_id != p_current_treeroot->i_id )
    {
-       playlist_item_t *p_item = playlist_ItemGetById( p_playlist, i_id );
+       playlist_item_t *p_item = playlist_ItemGetById( p_playlist, i_id,
+                                                       VLC_TRUE );
        if( p_item ) p_current_treeroot = p_item;
        Rebuild( VLC_TRUE );
    }