* 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,
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)
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) */
* 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 );
* 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()
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 );
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 );
return;
}
+ /* Update the colour of items */
vlc_mutex_lock( &p_playlist->object_lock );
if( p_intf->p_sys->i_playing != p_playlist->i_index )
{
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) )
}
}
+/*****************************************************************************
+ * 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;
+}