]> git.sesse.net Git - vlc/blobdiff - modules/gui/wxwindows/playlist.cpp
* modules/gui/skins/src/*: oops, forgot to add a bunch of files.
[vlc] / modules / gui / wxwindows / playlist.cpp
index 0556bfd5ba0e6d574f5ccd321db92ee0fd435841..dafdbc556564e29b4f1caee9a341784e2bd4d05f 100644 (file)
@@ -2,7 +2,7 @@
  * playlist.cpp : wxWindows plugin for vlc
  *****************************************************************************
  * Copyright (C) 2000-2001 VideoLAN
- * $Id: playlist.cpp,v 1.4 2002/11/23 18:42:59 gbazin Exp $
+ * $Id: playlist.cpp,v 1.11 2003/05/20 23:17:59 gbazin Exp $
  *
  * Authors: Olivier Teulière <ipkiss@via.ecp.fr>
  *
 
 #include "wxwindows.h"
 
+/* Callback prototype */
+int PlaylistChanged( vlc_object_t *p_this, const char *psz_variable,
+                     vlc_value_t old_val, vlc_value_t new_val, void *param );
+
 /*****************************************************************************
  * Event Table.
  *****************************************************************************/
 enum
 {
     /* menu items */
-    AddUrl_Event = 1,
-    AddDirectory_Event,
+    AddMRL_Event = 1,
     Close_Event,
+    Open_Event,
+    Save_Event,
 
     InvertSelection_Event,
     DeleteSelection_Event,
@@ -69,9 +74,10 @@ enum
 
 BEGIN_EVENT_TABLE(Playlist, wxFrame)
     /* Menu events */
-    EVT_MENU(AddUrl_Event, Playlist::OnAddUrl)
-    EVT_MENU(AddDirectory_Event, Playlist::OnAddDirectory)
+    EVT_MENU(AddMRL_Event, Playlist::OnAddMRL)
     EVT_MENU(Close_Event, Playlist::OnClose)
+    EVT_MENU(Open_Event, Playlist::OnOpen)
+    EVT_MENU(Save_Event, Playlist::OnSave)
     EVT_MENU(InvertSelection_Event, Playlist::OnInvertSelection)
     EVT_MENU(DeleteSelection_Event, Playlist::OnDeleteSelection)
     EVT_MENU(SelectAll_Event, Playlist::OnSelectAll)
@@ -81,7 +87,8 @@ BEGIN_EVENT_TABLE(Playlist, wxFrame)
     EVT_LIST_KEY_DOWN(ListView_Event, Playlist::OnKeyDown)
 
     /* Button events */
-    EVT_BUTTON( wxID_OK, Playlist::OnClose)
+    EVT_BUTTON( Close_Event, Playlist::OnClose)
+    EVT_BUTTON( Save_Event, Playlist::OnSave)
 
     /* Special events : we don't want to destroy the window when the user
      * clicks on (X) */
@@ -92,30 +99,35 @@ END_EVENT_TABLE()
  * Constructor.
  *****************************************************************************/
 Playlist::Playlist( intf_thread_t *_p_intf, Interface *_p_main_interface ):
-    wxFrame( _p_main_interface, -1, "Playlist", wxDefaultPosition,
-             wxSize::wxSize( 400, 500 ), wxDEFAULT_FRAME_STYLE )
+    wxFrame( _p_main_interface, -1, wxU(_("Playlist")), wxDefaultPosition,
+             wxDefaultSize, wxDEFAULT_FRAME_STYLE )
 {
     /* Initializations */
     p_intf = _p_intf;
     p_main_interface = _p_main_interface;
+    i_update_counter = 0;
+    b_need_update = VLC_FALSE;
+    vlc_mutex_init( p_intf, &lock );
+    SetIcon( *p_intf->p_sys->p_icon );
 
     /* Create our "Manage" menu */
     wxMenu *manage_menu = new wxMenu;
-    manage_menu->Append( AddUrl_Event, _("Add &Url...") );
-    manage_menu->Append( AddDirectory_Event, _("Add &Directory...") );
+    manage_menu->Append( AddMRL_Event, wxU(_("&Add MRL...")) );
+    manage_menu->Append( Open_Event, wxU(_("&Open Playlist...")) );
+    manage_menu->Append( Save_Event, wxU(_("&Save Playlist...")) );
     manage_menu->AppendSeparator();
-    manage_menu->Append( Close_Event, _("&Close") );
+    manage_menu->Append( Close_Event, wxU(_("&Close")) );
 
     /* Create our "Selection" menu */
     wxMenu *selection_menu = new wxMenu;
-    selection_menu->Append( InvertSelection_Event, _("&Invert") );
-    selection_menu->Append( DeleteSelection_Event, _("&Delete") );
-    selection_menu->Append( SelectAll_Event, _("&Select All") );
+    selection_menu->Append( InvertSelection_Event, wxU(_("&Invert")) );
+    selection_menu->Append( DeleteSelection_Event, wxU(_("&Delete")) );
+    selection_menu->Append( SelectAll_Event, wxU(_("&Select All")) );
 
     /* Append the freshly created menus to the menu bar */
     wxMenuBar *menubar = new wxMenuBar( wxMB_DOCKABLE );
-    menubar->Append( manage_menu, _("&Manage") );
-    menubar->Append( selection_menu, _("&Selection") );
+    menubar->Append( manage_menu, wxU(_("&Manage")) );
+    menubar->Append( selection_menu, wxU(_("&Selection")) );
 
     /* Attach the menu bar to the frame */
     SetMenuBar( menubar );
@@ -130,41 +142,65 @@ Playlist::Playlist( intf_thread_t *_p_intf, Interface *_p_main_interface ):
      * themselves to the size of a listview, and with a wxDefaultSize the
      * playlist window is ridiculously small */
     listview = new wxListView( playlist_panel, ListView_Event,
-                               wxDefaultPosition,
-                               wxSize( 350, 300 ), wxLC_REPORT );
-    listview->InsertColumn( 0, _("Url") );
-    listview->InsertColumn( 1, _("Duration") );
+                               wxDefaultPosition, wxSize( 355, 300 ),
+                               wxLC_REPORT | wxSUNKEN_BORDER );
+    listview->InsertColumn( 0, wxU(_("Url")) );
+    listview->InsertColumn( 1, wxU(_("Duration")) );
     listview->SetColumnWidth( 0, 250 );
     listview->SetColumnWidth( 1, 100 );
 
-    /* Create the OK button */
-    ok_button = new wxButton( playlist_panel, wxID_OK, _("OK") );
-    ok_button->SetDefault();
+    /* Create the Close button */
+    wxButton *close_button = new wxButton( playlist_panel, Close_Event,
+                                           wxU(_("Close")) );
+    close_button->SetDefault();
 
     /* Place everything in sizers */
-    wxBoxSizer *ok_button_sizer = new wxBoxSizer( wxHORIZONTAL );
-    ok_button_sizer->Add( ok_button, 0, wxALL, 5 );
-    ok_button_sizer->Layout();
+    wxBoxSizer *close_button_sizer = new wxBoxSizer( wxHORIZONTAL );
+    close_button_sizer->Add( close_button, 0, wxALL, 5 );
+    close_button_sizer->Layout();
     wxBoxSizer *main_sizer = new wxBoxSizer( wxVERTICAL );
     wxBoxSizer *panel_sizer = new wxBoxSizer( wxVERTICAL );
     panel_sizer->Add( listview, 1, wxEXPAND | wxALL, 5 );
-    panel_sizer->Add( ok_button_sizer, 0, wxALIGN_CENTRE );
+    panel_sizer->Add( close_button_sizer, 0, wxALIGN_CENTRE );
     panel_sizer->Layout();
     playlist_panel->SetSizerAndFit( panel_sizer );
     main_sizer->Add( playlist_panel, 1, wxGROW, 0 );
     main_sizer->Layout();
     SetSizerAndFit( main_sizer );
 
+#if !defined(__WXX11__)
     /* Associate drop targets with the playlist */
     SetDropTarget( new DragAndDrop( p_intf ) );
+#endif
+
+    playlist_t *p_playlist =
+        (playlist_t *)vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
+                                       FIND_ANYWHERE );
+    if( p_playlist == NULL )
+    {
+        return;
+    }
+
+    /* We want to be noticed of playlit changes */
+    var_AddCallback( p_playlist, "intf-change", PlaylistChanged, this );
+    vlc_object_release( p_playlist );
 
     /* Update the playlist */
     Rebuild();
-
 }
 
 Playlist::~Playlist()
 {
+    playlist_t *p_playlist =
+        (playlist_t *)vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
+                                       FIND_ANYWHERE );
+    if( p_playlist == NULL )
+    {
+        return;
+    }
+
+    var_DelCallback( p_playlist, "intf-change", PlaylistChanged, this );
+    vlc_object_release( p_playlist );
 }
 
 void Playlist::Rebuild()
@@ -184,10 +220,10 @@ void Playlist::Rebuild()
     vlc_mutex_lock( &p_playlist->object_lock );
     for( int i = 0; i < p_playlist->i_size; i++ )
     {
-        wxString filename = p_playlist->pp_items[i]->psz_name;
+        wxString filename = wxU(p_playlist->pp_items[i]->psz_name);
         listview->InsertItem( i, filename );
         /* FIXME: we should try to find the actual duration... */
-        listview->SetItem( i, 1, _("no info") );
+        listview->SetItem( i, 1, wxU(_("no info")) );
     }
     vlc_mutex_unlock( &p_playlist->object_lock );
 
@@ -200,9 +236,33 @@ void Playlist::Rebuild()
     vlc_object_release( p_playlist );
 }
 
-/* Update the colour of items */
-void Playlist::Manage()
+void Playlist::ShowPlaylist( bool show )
 {
+    if( show ) Rebuild();
+    Show( show );
+}
+
+void Playlist::UpdatePlaylist()
+{
+    vlc_bool_t b_need_update = VLC_FALSE;
+    i_update_counter++;
+
+    /* If the playlist isn't show there's no need to update it */
+    if( !IsShown() ) return;
+
+    vlc_mutex_lock( &lock );
+    if( this->b_need_update )
+    {
+        b_need_update = VLC_TRUE;
+        this->b_need_update = VLC_FALSE;
+    }
+    vlc_mutex_unlock( &lock );
+
+    if( b_need_update ) Rebuild();
+
+    /* Updating the playing status every 0.5s is enough */
+    if( i_update_counter % 5 ) return;
+
     playlist_t *p_playlist =
         (playlist_t *)vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
                                        FIND_ANYWHERE );
@@ -211,6 +271,7 @@ void Playlist::Manage()
         return;
     }
 
+    /* Update the colour of items */
     vlc_mutex_lock( &p_playlist->object_lock );
     if( p_intf->p_sys->i_playing != p_playlist->i_index )
     {
@@ -256,14 +317,78 @@ void Playlist::OnClose( wxCommandEvent& WXUNUSED(event) )
     Hide();
 }
 
-void Playlist::OnAddUrl( wxCommandEvent& WXUNUSED(event) )
+void Playlist::OnSave( wxCommandEvent& WXUNUSED(event) )
+{
+    playlist_t *p_playlist =
+        (playlist_t *)vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
+                                       FIND_ANYWHERE );
+    if( p_playlist == NULL )
+    {
+        return;
+    }
+
+    wxFileDialog dialog( this, wxU(_("Save playlist")),
+                         wxT(""), wxT(""), wxT("*"), wxSAVE );
+
+    if( dialog.ShowModal() == wxID_OK )
+    {
+        playlist_SaveFile( p_playlist, dialog.GetPath().mb_str() );
+    }
+
+    vlc_object_release( p_playlist );
+}
+
+void Playlist::OnOpen( wxCommandEvent& WXUNUSED(event) )
 {
-    /* TODO */
+    playlist_t *p_playlist =
+        (playlist_t *)vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
+                                       FIND_ANYWHERE );
+    if( p_playlist == NULL )
+    {
+        return;
+    }
+
+    wxFileDialog dialog( this, wxU(_("Open playlist")),
+                         wxT(""), wxT(""), wxT("*"), wxOPEN );
+
+    if( dialog.ShowModal() == wxID_OK )
+    {
+        playlist_LoadFile( p_playlist, dialog.GetPath().mb_str() );
+    }
+
+    vlc_object_release( p_playlist );
 }
 
-void Playlist::OnAddDirectory( wxCommandEvent& WXUNUSED(event) )
+void Playlist::OnAddMRL( wxCommandEvent& WXUNUSED(event) )
 {
-    /* TODO */
+    playlist_t *p_playlist =
+        (playlist_t *)vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
+                                       FIND_ANYWHERE );
+    if( p_playlist == NULL )
+    {
+        return;
+    }
+
+    /* Show/hide the open dialog */
+    if( p_main_interface->p_open_dialog == NULL )
+        p_main_interface->p_open_dialog =
+            new OpenDialog( p_intf, this, FILE_ACCESS );
+
+    if( p_main_interface->p_open_dialog &&
+        p_main_interface->p_open_dialog->ShowModal() == wxID_OK )
+    {
+        for( size_t i = 0;
+             i < p_main_interface->p_open_dialog->mrl.GetCount(); i++ )
+        {
+            playlist_Add( p_playlist,
+                (const char *)p_main_interface->p_open_dialog->mrl[i].mb_str(),
+                PLAYLIST_APPEND, PLAYLIST_END );
+        }
+    }
+
+    vlc_object_release( p_playlist );
+
+    Rebuild();
 }
 
 void Playlist::OnInvertSelection( wxCommandEvent& WXUNUSED(event) )
@@ -322,3 +447,17 @@ void Playlist::OnKeyDown( wxListEvent& event )
     }
 }
 
+/*****************************************************************************
+ * PlaylistChanged: callback triggered by the intf-change playlist variable
+ *  We don't rebuild the playlist directly here because we don't want the
+ *  caller to block for a too long time.
+ *****************************************************************************/
+int PlaylistChanged( vlc_object_t *p_this, const char *psz_variable,
+                     vlc_value_t old_val, vlc_value_t new_val, void *param )
+{
+    Playlist *p_playlist_dialog = (Playlist *)param;
+    vlc_mutex_lock( &p_playlist_dialog->lock );
+    p_playlist_dialog->b_need_update = VLC_TRUE;
+    vlc_mutex_unlock( &p_playlist_dialog->lock );
+    return VLC_SUCCESS;
+}