X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=modules%2Fgui%2Fwxwindows%2Fplaylist.cpp;h=6ad8c8c4247261d0c575f0ad71b05dd111e9ebe9;hb=aa733478aa5441828d66fbc87e2ff88452a09e18;hp=fb6f40763d960b9847e740aa112418e9a60a13a9;hpb=035bbae4e2de9cb864b0e9fe92667f8e08386c5e;p=vlc diff --git a/modules/gui/wxwindows/playlist.cpp b/modules/gui/wxwindows/playlist.cpp index fb6f40763d..6ad8c8c424 100644 --- a/modules/gui/wxwindows/playlist.cpp +++ b/modules/gui/wxwindows/playlist.cpp @@ -1,8 +1,8 @@ /***************************************************************************** * playlist.cpp : wxWindows plugin for vlc ***************************************************************************** - * Copyright (C) 2000-2001 VideoLAN - * $Id: playlist.cpp,v 1.10 2003/05/18 16:27:18 gbazin Exp $ + * Copyright (C) 2000-2001, 2003 VideoLAN + * $Id: playlist.cpp,v 1.28 2003/12/03 13:35:19 rocky Exp $ * * Authors: Olivier Teulière * @@ -24,28 +24,11 @@ /***************************************************************************** * Preamble *****************************************************************************/ -#include /* malloc(), free() */ -#include /* ENOMEM */ -#include /* strerror() */ -#include - #include - -#ifdef WIN32 /* mingw32 hack */ -#undef Yield -#undef CreateDialog -#endif - -/* Let vlc take care of the i18n stuff */ -#define WXINTL_NO_GETTEXT_MACRO - -#include -#include -#include - #include #include "wxwindows.h" +#include /* Callback prototype */ int PlaylistChanged( vlc_object_t *p_this, const char *psz_variable, @@ -59,110 +42,285 @@ int PlaylistChanged( vlc_object_t *p_this, const char *psz_variable, enum { /* menu items */ - AddMRL_Event = 1, + AddFile_Event = 1, + AddMRL_Event, Close_Event, Open_Event, Save_Event, + SortTitle_Event, + RSortTitle_Event, + SortAuthor_Event, + RSortAuthor_Event, + SortGroup_Event, + RSortGroup_Event, + Randomize_Event, + + EnableSelection_Event, + DisableSelection_Event, + InvertSelection_Event, DeleteSelection_Event, + Random_Event, + Loop_Event, + Repeat_Event, SelectAll_Event, + EnableGroup_Event, + DisableGroup_Event, + + Up_Event, + Down_Event, + Infos_Event, + + SearchText_Event, + Search_Event, + /* controls */ ListView_Event }; BEGIN_EVENT_TABLE(Playlist, wxFrame) /* Menu events */ + EVT_MENU(AddFile_Event, Playlist::OnAddFile) 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(SortTitle_Event, Playlist::OnSort) + EVT_MENU(RSortTitle_Event, Playlist::OnSort) + EVT_MENU(SortAuthor_Event, Playlist::OnSort) + EVT_MENU(RSortAuthor_Event, Playlist::OnSort) + EVT_MENU(SortGroup_Event, Playlist::OnSort) + EVT_MENU(RSortGroup_Event, Playlist::OnSort) + + EVT_MENU(Randomize_Event, Playlist::OnSort) + + EVT_MENU(EnableSelection_Event, Playlist::OnEnableSelection) + EVT_MENU(DisableSelection_Event, Playlist::OnDisableSelection) EVT_MENU(InvertSelection_Event, Playlist::OnInvertSelection) EVT_MENU(DeleteSelection_Event, Playlist::OnDeleteSelection) EVT_MENU(SelectAll_Event, Playlist::OnSelectAll) + EVT_MENU(Infos_Event, Playlist::OnInfos) + EVT_CHECKBOX(Random_Event, Playlist::OnRandom) + EVT_CHECKBOX(Repeat_Event, Playlist::OnRepeat) + EVT_CHECKBOX(Loop_Event, Playlist::OnLoop) + + EVT_MENU(EnableGroup_Event, Playlist::OnEnDis) + EVT_MENU(DisableGroup_Event, Playlist::OnEnDis) /* Listview events */ EVT_LIST_ITEM_ACTIVATED(ListView_Event, Playlist::OnActivateItem) + EVT_LIST_COL_CLICK(ListView_Event, Playlist::OnColSelect) EVT_LIST_KEY_DOWN(ListView_Event, Playlist::OnKeyDown) /* Button events */ - EVT_BUTTON( Close_Event, Playlist::OnClose) + EVT_BUTTON( Search_Event, Playlist::OnSearch) EVT_BUTTON( Save_Event, Playlist::OnSave) + EVT_BUTTON( Infos_Event, Playlist::OnInfos) + + EVT_BUTTON( Up_Event, Playlist::OnUp) + EVT_BUTTON( Down_Event, Playlist::OnDown) + + EVT_TEXT(SearchText_Event, Playlist::OnSearchTextChange) /* Special events : we don't want to destroy the window when the user * clicks on (X) */ EVT_CLOSE(Playlist::OnClose) END_EVENT_TABLE() + +/* Event Table for the Newgroup class */ +BEGIN_EVENT_TABLE(NewGroup, wxDialog) + EVT_BUTTON( wxID_OK, NewGroup::OnOk) + EVT_BUTTON( wxID_CANCEL, NewGroup::OnCancel) +END_EVENT_TABLE() + /***************************************************************************** * Constructor. *****************************************************************************/ -Playlist::Playlist( intf_thread_t *_p_intf, Interface *_p_main_interface ): - wxFrame( _p_main_interface, -1, wxU(_("Playlist")), wxDefaultPosition, +Playlist::Playlist( intf_thread_t *_p_intf, wxWindow *p_parent ): + wxFrame( p_parent, -1, wxU(_("Playlist")), wxDefaultPosition, wxDefaultSize, wxDEFAULT_FRAME_STYLE ) { /* Initializations */ + iteminfo_dialog = NULL; p_intf = _p_intf; - p_main_interface = _p_main_interface; + vlc_value_t val; i_update_counter = 0; + i_sort_mode = MODE_NONE; b_need_update = VLC_FALSE; vlc_mutex_init( p_intf, &lock ); SetIcon( *p_intf->p_sys->p_icon ); + i_title_sorted = 0; + i_author_sorted = 0; + i_group_sorted = 0; + + + var_Create( p_intf, "random", VLC_VAR_BOOL ); + var_Change( p_intf, "random", VLC_VAR_INHERITVALUE, & val, NULL ); + var_Create( p_intf, "loop", VLC_VAR_BOOL ); + var_Create( p_intf, "loop", VLC_VAR_BOOL ); + var_Change( p_intf, "repeat", VLC_VAR_INHERITVALUE, & val, NULL ); + var_Change( p_intf, "repeat", VLC_VAR_INHERITVALUE, & val, NULL ); + /* Create our "Manage" menu */ wxMenu *manage_menu = new wxMenu; + manage_menu->Append( AddFile_Event, wxU(_("&Simple Add...")) ); manage_menu->Append( AddMRL_Event, wxU(_("&Add MRL...")) ); + manage_menu->AppendSeparator(); manage_menu->Append( Open_Event, wxU(_("&Open Playlist...")) ); manage_menu->Append( Save_Event, wxU(_("&Save Playlist...")) ); manage_menu->AppendSeparator(); manage_menu->Append( Close_Event, wxU(_("&Close")) ); + /* Create our "Sort" menu */ + wxMenu *sort_menu = new wxMenu; + sort_menu->Append( SortTitle_Event, wxU(_("Sort by &title")) ); + sort_menu->Append( RSortTitle_Event, wxU(_("&Reverse sort by title")) ); + sort_menu->AppendSeparator(); + sort_menu->Append( SortAuthor_Event, wxU(_("Sort by &author")) ); + sort_menu->Append( RSortAuthor_Event, wxU(_("&Reverse sort by author")) ); + sort_menu->AppendSeparator(); + sort_menu->Append( SortGroup_Event, wxU(_("Sort by &group")) ); + sort_menu->Append( RSortGroup_Event, wxU(_("&Reverse sort by group")) ); + sort_menu->AppendSeparator(); + sort_menu->Append( Randomize_Event, wxU(_("&Randomize Playlist")) ); + /* Create our "Selection" menu */ wxMenu *selection_menu = new wxMenu; + selection_menu->Append( EnableSelection_Event, wxU(_("&Enable")) ); + selection_menu->Append( DisableSelection_Event, wxU(_("&Disable")) ); + selection_menu->AppendSeparator(); selection_menu->Append( InvertSelection_Event, wxU(_("&Invert")) ); selection_menu->Append( DeleteSelection_Event, wxU(_("&Delete")) ); selection_menu->Append( SelectAll_Event, wxU(_("&Select All")) ); + /* Create our "Group" menu */ + wxMenu *group_menu = new wxMenu; + group_menu->Append( EnableGroup_Event, wxU(_("&Enable all group items")) ); + group_menu->Append( DisableGroup_Event, + wxU(_("&Disable all group items")) ); + /* Append the freshly created menus to the menu bar */ wxMenuBar *menubar = new wxMenuBar( wxMB_DOCKABLE ); menubar->Append( manage_menu, wxU(_("&Manage")) ); + menubar->Append( sort_menu, wxU(_("S&ort")) ); menubar->Append( selection_menu, wxU(_("&Selection")) ); + menubar->Append( group_menu, wxU(_("&Groups")) ); /* Attach the menu bar to the frame */ SetMenuBar( menubar ); + /* Create a panel to put everything in */ wxPanel *playlist_panel = new wxPanel( this, -1 ); playlist_panel->SetAutoLayout( TRUE ); + /* Create the Random checkbox */ + wxCheckBox *random_checkbox = + new wxCheckBox( playlist_panel, Random_Event, wxU(_("Random")) ); + var_Get( p_intf, "random", &val ); + vlc_bool_t b_random = val.b_bool; + random_checkbox->SetValue( b_random == VLC_FALSE ? 0 : 1 ); + + /* Create the Loop Checkbox */ + wxCheckBox *loop_checkbox = + new wxCheckBox( playlist_panel, Loop_Event, wxU(_("Loop")) ); + var_Get( p_intf, "loop", &val ); + int b_loop = val.b_bool ; + loop_checkbox->SetValue( b_loop ); + + /* Create the Repeat one checkbox */ + wxCheckBox *repeat_checkbox = + new wxCheckBox( playlist_panel, Repeat_Event, wxU(_("Repeat one")) ); + var_Get( p_intf, "repeat", &val ); + int b_repeat = val.b_bool ; + repeat_checkbox->SetValue( b_repeat ); + + /* Create the Search Textbox */ + search_text = + new wxTextCtrl( playlist_panel, SearchText_Event, wxT(""), + wxDefaultPosition, wxSize(140, -1), + wxTE_PROCESS_ENTER); + + /* Create the search button */ + search_button = + new wxButton( playlist_panel, Search_Event, wxU(_("Search")) ); + + /* Create the listview */ /* FIXME: the given size is arbitrary, and prevents us from resizing * the window to smaller dimensions. But the sizers don't seem to adjust * 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( 355, 300 ), + wxDefaultPosition, wxSize( 500, 300 ), wxLC_REPORT | wxSUNKEN_BORDER ); - listview->InsertColumn( 0, wxU(_("Url")) ); - listview->InsertColumn( 1, wxU(_("Duration")) ); - listview->SetColumnWidth( 0, 250 ); - listview->SetColumnWidth( 1, 100 ); + listview->InsertColumn( 0, wxU(_("Name")) ); + listview->InsertColumn( 1, wxU(_("Author")) ); + listview->InsertColumn( 2, wxU(_("Group")) ); + listview->InsertColumn( 3, wxU(_("Duration")) ); + listview->SetColumnWidth( 0, 270 ); + listview->SetColumnWidth( 1, 150 ); + listview->SetColumnWidth( 2, 80 ); - /* Create the Close button */ - wxButton *close_button = new wxButton( playlist_panel, Close_Event, - wxU(_("Close")) ); - close_button->SetDefault(); + /* Create the Up-Down buttons */ + wxButton *up_button = + new wxButton( playlist_panel, Up_Event, wxU(_("Up") ) ); + + wxButton *down_button = + new wxButton( playlist_panel, Down_Event, wxU(_("Down") ) ); + + /* Create the iteminfo button */ + wxButton *iteminfo_button = + new wxButton( playlist_panel, Infos_Event, wxU(_("Item Infos") ) ); /* Place everything in sizers */ - wxBoxSizer *close_button_sizer = new wxBoxSizer( wxHORIZONTAL ); - close_button_sizer->Add( close_button, 0, wxALL, 5 ); - close_button_sizer->Layout(); + wxBoxSizer *button_sizer = new wxBoxSizer( wxHORIZONTAL ); + button_sizer->Add( iteminfo_button, 0, wxALIGN_CENTER|wxLEFT , 5); + button_sizer->Layout(); + + wxBoxSizer *updown_sizer = new wxBoxSizer( wxHORIZONTAL ); + updown_sizer->Add( up_button, 0, wxALIGN_LEFT|wxRIGHT, 3); + updown_sizer->Add( down_button, 0, wxALIGN_LEFT|wxLEFT, 3); + updown_sizer->Layout(); + + wxBoxSizer *checkbox_sizer = new wxBoxSizer( wxHORIZONTAL ); + checkbox_sizer->Add( random_checkbox, 0, + wxEXPAND | wxALIGN_RIGHT | wxALL, 5); + checkbox_sizer->Add( loop_checkbox, 0, + wxEXPAND | wxALIGN_RIGHT | wxALL, 5); + checkbox_sizer->Add( repeat_checkbox, 0, + wxEXPAND | wxALIGN_RIGHT | wxALL, 5); + checkbox_sizer->Layout(); + + wxBoxSizer *search_sizer = new wxBoxSizer( wxHORIZONTAL ); + search_sizer->Add( search_text, 0, wxRIGHT|wxALIGN_CENTER, 3); + search_sizer->Add( search_button, 0, wxLEFT|wxALIGN_CENTER, 3); + search_sizer->Layout(); + + /* The top and bottom sizers */ + wxBoxSizer *top_sizer = new wxBoxSizer( wxHORIZONTAL ); + top_sizer->Add( checkbox_sizer, 1, wxLEFT|wxRIGHT|wxALIGN_LEFT, 4 ); + top_sizer->Add( search_sizer, 1, wxLEFT|wxRIGHT|wxALIGN_RIGHT, 4 ); + top_sizer->Layout(); + + wxBoxSizer *bottom_sizer = new wxBoxSizer( wxHORIZONTAL ); + bottom_sizer->Add( updown_sizer, 0, wxEXPAND |wxRIGHT | wxLEFT | wxALIGN_LEFT, 4); + bottom_sizer->Add( button_sizer , 0, wxEXPAND|wxLEFT | wxRIGHT | wxALIGN_RIGHT, 4 ); + bottom_sizer->Layout(); + wxBoxSizer *main_sizer = new wxBoxSizer( wxVERTICAL ); + wxBoxSizer *panel_sizer = new wxBoxSizer( wxVERTICAL ); + panel_sizer->Add( top_sizer, 0, wxEXPAND | wxALL, 5 ); panel_sizer->Add( listview, 1, wxEXPAND | wxALL, 5 ); - panel_sizer->Add( close_button_sizer, 0, wxALIGN_CENTRE ); + panel_sizer->Add( bottom_sizer, 0 , wxEXPAND | wxALL, 5); panel_sizer->Layout(); + playlist_panel->SetSizerAndFit( panel_sizer ); main_sizer->Add( playlist_panel, 1, wxGROW, 0 ); main_sizer->Layout(); @@ -170,7 +328,7 @@ Playlist::Playlist( intf_thread_t *_p_intf, Interface *_p_main_interface ): #if !defined(__WXX11__) /* Associate drop targets with the playlist */ - SetDropTarget( new DragAndDrop( p_intf ) ); + SetDropTarget( new DragAndDrop( p_intf, VLC_TRUE ) ); #endif playlist_t *p_playlist = @@ -181,7 +339,7 @@ Playlist::Playlist( intf_thread_t *_p_intf, Interface *_p_main_interface ): return; } - /* We want to be noticed of playlit changes */ + /* We want to be noticed of playlist changes */ var_AddCallback( p_playlist, "intf-change", PlaylistChanged, this ); vlc_object_release( p_playlist ); @@ -199,10 +357,15 @@ Playlist::~Playlist() return; } + delete iteminfo_dialog; + var_DelCallback( p_playlist, "intf-change", PlaylistChanged, this ); vlc_object_release( p_playlist ); } +/********************************************************************** + * Rebuild the playlist + **********************************************************************/ void Playlist::Rebuild() { playlist_t *p_playlist = @@ -213,6 +376,8 @@ void Playlist::Rebuild() return; } + int i_focused = listview->GetFocusedItem(); + /* Clear the list... */ listview->DeleteAllItems(); @@ -222,8 +387,31 @@ void Playlist::Rebuild() { 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, wxU(_("no info")) ); + listview->SetItem( i, 1, wxU(p_playlist->pp_items[i]->psz_author)); + listview->SetItem( i, 2, + wxU(playlist_FindGroup(p_playlist,p_playlist-> + pp_items[i]->i_group))); + if( p_playlist->pp_items[i]->b_enabled == VLC_FALSE ) + { + wxListItem listitem; + listitem.m_itemId = i; + listitem.SetTextColour( *wxLIGHT_GREY); + listview->SetItem(listitem); + } + { + char psz_duration[MSTRTIME_MAX_SIZE]; + mtime_t dur = p_playlist->pp_items[i]->i_duration; + if ( dur != -1 ) + { + secstotimestr( psz_duration, dur ); + } + else + { + memcpy( psz_duration ,"-:--:--", sizeof("-:--:--")); + } + listview->SetItem( i, 3, psz_duration ); + } + } vlc_mutex_unlock( &p_playlist->object_lock ); @@ -233,6 +421,16 @@ void Playlist::Rebuild() listitem.SetTextColour( *wxRED ); listview->SetItem( listitem ); + if( i_focused ) + { + listview->Focus( i_focused ); + listview->Select( i_focused ); + } + else + { + listview->Focus( p_playlist->i_index ); + } + vlc_object_release( p_playlist ); } @@ -253,12 +451,15 @@ void Playlist::UpdatePlaylist() vlc_mutex_lock( &lock ); if( this->b_need_update ) { - b_need_update = VLC_TRUE; + b_need_update =VLC_TRUE; this->b_need_update = VLC_FALSE; } vlc_mutex_unlock( &lock ); - if( b_need_update ) Rebuild(); + if( b_need_update ) + { + Rebuild(); + } /* Updating the playing status every 0.5s is enough */ if( i_update_counter % 5 ) return; @@ -272,6 +473,7 @@ void Playlist::UpdatePlaylist() } /* Update the colour of items */ + vlc_mutex_lock( &p_playlist->object_lock ); if( p_intf->p_sys->i_playing != p_playlist->i_index ) { @@ -289,7 +491,6 @@ void Playlist::UpdatePlaylist() p_intf->p_sys->i_playing = p_playlist->i_index; } vlc_mutex_unlock( &p_playlist->object_lock ); - vlc_object_release( p_playlist ); } @@ -328,7 +529,7 @@ void Playlist::OnSave( wxCommandEvent& WXUNUSED(event) ) } wxFileDialog dialog( this, wxU(_("Save playlist")), - wxT(""), wxT(""), wxT("*.*"), wxSAVE ); + wxT(""), wxT(""), wxT("*"), wxSAVE ); if( dialog.ShowModal() == wxID_OK ) { @@ -349,7 +550,7 @@ void Playlist::OnOpen( wxCommandEvent& WXUNUSED(event) ) } wxFileDialog dialog( this, wxU(_("Open playlist")), - wxT(""), wxT(""), wxT("*.*"), wxOPEN ); + wxT(""), wxT(""), wxT("*"), wxOPEN ); if( dialog.ShowModal() == wxID_OK ) { @@ -359,7 +560,59 @@ void Playlist::OnOpen( wxCommandEvent& WXUNUSED(event) ) vlc_object_release( p_playlist ); } +void Playlist::OnAddFile( wxCommandEvent& WXUNUSED(event) ) +{ + p_intf->p_sys->pf_show_dialog( p_intf, INTF_DIALOG_FILE_SIMPLE, 0, 0 ); + +#if 0 + Rebuild(); +#endif +} + void Playlist::OnAddMRL( wxCommandEvent& WXUNUSED(event) ) +{ + p_intf->p_sys->pf_show_dialog( p_intf, INTF_DIALOG_FILE, 0, 0 ); + +#if 0 + Rebuild(); +#endif +} + +/******************************************************************** + * Move functions + ********************************************************************/ +void Playlist::OnUp( wxCommandEvent& event) +{ + playlist_t *p_playlist = + (playlist_t *)vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST, + FIND_ANYWHERE ); + if( p_playlist == NULL ) + { + return; + } + + /* We use the first selected item, so find it */ + long i_item = -1; + i_item = listview->GetNextItem(i_item, + wxLIST_NEXT_ALL, + wxLIST_STATE_SELECTED); + if( i_item > 0 && i_item < p_playlist->i_size ) + { + playlist_Move( p_playlist , i_item, i_item - 1); + if( i_item > 1 ) + { + listview->Focus( i_item - 1 ); + } + else + { + listview->Focus(0); + } + } + vlc_object_release( p_playlist ); + return; +} + +void Playlist::OnDown( wxCommandEvent& event) { playlist_t *p_playlist = (playlist_t *)vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST, @@ -369,24 +622,174 @@ void Playlist::OnAddMRL( wxCommandEvent& WXUNUSED(event) ) 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 ); + /* We use the first selected item, so find it */ + long i_item = -1; + i_item = listview->GetNextItem(i_item, + wxLIST_NEXT_ALL, + wxLIST_STATE_SELECTED); + if( i_item >= 0 && i_item < p_playlist->i_size - 1 ) + { + playlist_Move( p_playlist , i_item, i_item + 2 ); + listview->Focus( i_item + 1 ); + } + vlc_object_release( p_playlist ); + return; +} - if( p_main_interface->p_open_dialog && - p_main_interface->p_open_dialog->ShowModal() == wxID_OK ) +/******************************************************************** + * Sorting functions + ********************************************************************/ +void Playlist::OnSort( wxCommandEvent& event ) +{ + playlist_t *p_playlist = + (playlist_t *)vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST, + FIND_ANYWHERE ); + if( p_playlist == NULL ) { - playlist_Add( p_playlist, - (const char *)p_main_interface->p_open_dialog->mrl.mb_str(), - PLAYLIST_APPEND, PLAYLIST_END ); + return; } + switch( event.GetId() ) + { + case SortTitle_Event: + playlist_SortTitle( p_playlist , 0 ); + break; + case RSortTitle_Event: + playlist_SortTitle( p_playlist , 1 ); + break; + case SortAuthor_Event: + playlist_SortAuthor(p_playlist , 0 ); + break; + case RSortAuthor_Event: + playlist_SortAuthor( p_playlist , 1 ); + break; + case SortGroup_Event: + playlist_SortGroup( p_playlist , 0 ); + break; + case RSortGroup_Event: + playlist_SortGroup( p_playlist , 1 ); + break; + case Randomize_Event: + playlist_Sort( p_playlist , SORT_RANDOM, SORT_NORMAL ); + break; + } + vlc_object_release( p_playlist ); + + Rebuild(); + + return; +} +void Playlist::OnColSelect( wxListEvent& event ) +{ + playlist_t *p_playlist = + (playlist_t *)vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST, + FIND_ANYWHERE ); + if( p_playlist == NULL ) + { + return; + } + switch( event.GetColumn() ) + { + case 0: + if( i_title_sorted != 1 ) + { + playlist_SortTitle( p_playlist, 0 ); + i_title_sorted = 1; + } + else + { + playlist_SortTitle( p_playlist, 1 ); + i_title_sorted = -1; + } + break; + case 1: + if( i_author_sorted != 1 ) + { + playlist_SortAuthor( p_playlist, 0 ); + i_author_sorted = 1; + } + else + { + playlist_SortAuthor( p_playlist, 1 ); + i_author_sorted = -1; + } + break; + case 2: + if( i_group_sorted != 1 ) + { + playlist_SortGroup( p_playlist, 0 ); + i_group_sorted = 1; + } + else + { + playlist_SortGroup( p_playlist, 1 ); + i_group_sorted = -1; + } + break; + default: + break; + } vlc_object_release( p_playlist ); Rebuild(); + + return; +} + +/********************************************************************** + * Search functions + **********************************************************************/ +void Playlist::OnSearchTextChange( wxCommandEvent& WXUNUSED(event) ) +{ + search_button->SetDefault(); +} + +void Playlist::OnSearch( wxCommandEvent& WXUNUSED(event) ) +{ + wxString search_string= search_text->GetValue(); + + int i_current; + int i_first = 0 ; + int i_item = -1; + + for( i_current = 0 ; i_current <= listview->GetItemCount() ; i_current++ ) + { + if( listview->GetItemState( i_current, wxLIST_STATE_SELECTED) + == wxLIST_STATE_SELECTED ) + { + i_first = i_current; + break; + } + } + + for ( i_current = i_first + 1; i_current <= listview->GetItemCount() ; + i_current++ ) + { + wxListItem listitem; + listitem.SetId( i_current ); + listview->GetItem( listitem ); + if( listitem.m_text.Lower().Contains( search_string.Lower() ) ) + { + i_item = i_current; + break; + } + } + for( long item = 0; item < listview->GetItemCount(); item++ ) + { + listview->Select( item, FALSE ); + } + + wxListItem listitem; + listitem.SetId(i_item); + listitem.m_state = wxLIST_STATE_SELECTED; + listview->Select( i_item, TRUE ); + listview->Focus( i_item ); + } +/********************************************************************** + * Selection functions + **********************************************************************/ void Playlist::OnInvertSelection( wxCommandEvent& WXUNUSED(event) ) { for( long item = 0; item < listview->GetItemCount(); item++ ) @@ -409,6 +812,48 @@ void Playlist::OnDeleteSelection( wxCommandEvent& WXUNUSED(event) ) Rebuild(); } +void Playlist::OnEnableSelection( wxCommandEvent& WXUNUSED(event) ) +{ + playlist_t *p_playlist = + (playlist_t *)vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST, + FIND_ANYWHERE ); + if( p_playlist == NULL ) + { + return; + } + + for( long item = listview->GetItemCount() - 1; item >= 0; item-- ) + { + if( listview->IsSelected( item ) ) + { + playlist_Enable( p_playlist, item ); + } + } + vlc_object_release( p_playlist); + Rebuild(); +} + +void Playlist::OnDisableSelection( wxCommandEvent& WXUNUSED(event) ) +{ + playlist_t *p_playlist = + (playlist_t *)vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST, + FIND_ANYWHERE ); + if( p_playlist == NULL ) + { + return; + } + + for( long item = listview->GetItemCount() - 1; item >= 0; item-- ) + { + if( listview->IsSelected( item ) ) + { + playlist_Disable( p_playlist, item ); + } + } + vlc_object_release( p_playlist); + Rebuild(); +} + void Playlist::OnSelectAll( wxCommandEvent& WXUNUSED(event) ) { for( long item = 0; item < listview->GetItemCount(); item++ ) @@ -417,8 +862,13 @@ void Playlist::OnSelectAll( wxCommandEvent& WXUNUSED(event) ) } } -void Playlist::OnActivateItem( wxListEvent& event ) +/********************************************************************** + * Playlist mode functions + **********************************************************************/ +void Playlist::OnRandom( wxCommandEvent& event ) { + vlc_value_t val; + val.b_bool = event.IsChecked(); playlist_t *p_playlist = (playlist_t *)vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE ); @@ -426,12 +876,54 @@ void Playlist::OnActivateItem( wxListEvent& event ) { return; } + var_Set( p_playlist , "random", val); + vlc_object_release( p_playlist ); +} +void Playlist::OnLoop ( wxCommandEvent& event ) +{ + vlc_value_t val; + val.b_bool = event.IsChecked(); + playlist_t *p_playlist = + (playlist_t *)vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST, + FIND_ANYWHERE ); + if( p_playlist == NULL ) + { + return; + } + var_Set( p_playlist , "loop", val); + vlc_object_release( p_playlist ); +} + +void Playlist::OnRepeat ( wxCommandEvent& event ) +{ + vlc_value_t val; + val.b_bool = event.IsChecked(); + playlist_t *p_playlist = + (playlist_t *)vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST, + FIND_ANYWHERE ); + if( p_playlist == NULL ) + { + return; + } + var_Set( p_playlist , "repeat", val); + vlc_object_release( p_playlist ); +} + + +void Playlist::OnActivateItem( wxListEvent& event ) +{ + playlist_t *p_playlist = + (playlist_t *)vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST, + FIND_ANYWHERE ); + if( p_playlist == NULL ) + { + return; + } playlist_Goto( p_playlist, event.GetIndex() ); vlc_object_release( p_playlist ); } - void Playlist::OnKeyDown( wxListEvent& event ) { long keycode = event.GetKeyCode(); @@ -443,6 +935,70 @@ void Playlist::OnKeyDown( wxListEvent& event ) } } +void Playlist::OnInfos( wxCommandEvent& WXUNUSED(event) ) +{ + playlist_t *p_playlist = + (playlist_t *)vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST, + FIND_ANYWHERE ); + if( p_playlist == NULL ) + { + return; + } + + if( iteminfo_dialog == NULL ) + { + /* We use the first selected item, so find it */ + long i_item = -1; + i_item = listview->GetNextItem(i_item, + wxLIST_NEXT_ALL, + wxLIST_STATE_SELECTED); + if( i_item >= 0 && i_item < p_playlist->i_size ) + { + iteminfo_dialog = new ItemInfoDialog( + p_intf, p_playlist->pp_items[i_item], this ); + if( iteminfo_dialog->ShowModal() == wxID_OK ) + Rebuild(); + delete iteminfo_dialog; + iteminfo_dialog = NULL; + } + } + vlc_object_release( p_playlist ); +} + +void Playlist::OnEnDis( wxCommandEvent& event ) +{ + playlist_t *p_playlist = + (playlist_t *)vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST, + FIND_ANYWHERE ); + if( p_playlist == NULL ) + { + return; + } + + long i_item = -1; + i_item = listview->GetNextItem(i_item, + wxLIST_NEXT_ALL, + wxLIST_STATE_SELECTED); + + if( i_item >= 0 && i_item < p_playlist->i_size ) + { + switch( event.GetId() ) + { + case EnableGroup_Event: + playlist_EnableGroup( p_playlist , + p_playlist->pp_items[i_item]->i_group ); + break; + case DisableGroup_Event: + playlist_DisableGroup( p_playlist , + p_playlist->pp_items[i_item]->i_group ); + break; + } + Rebuild(); + } + + vlc_object_release( p_playlist ); +} + /***************************************************************************** * PlaylistChanged: callback triggered by the intf-change playlist variable * We don't rebuild the playlist directly here because we don't want the @@ -457,3 +1013,81 @@ int PlaylistChanged( vlc_object_t *p_this, const char *psz_variable, vlc_mutex_unlock( &p_playlist_dialog->lock ); return VLC_SUCCESS; } + + +/*************************************************************************** + * NewGroup + ***************************************************************************/ +NewGroup::NewGroup( intf_thread_t *_p_intf, wxWindow *_p_parent ): + wxDialog( _p_parent, -1, wxU(_("New Group")), wxDefaultPosition, + wxDefaultSize, wxDEFAULT_FRAME_STYLE ) +{ + /* Initializations */ + p_intf = _p_intf; + psz_name = NULL; + SetIcon( *p_intf->p_sys->p_icon ); + + /* Create a panel to put everything in*/ + wxPanel *panel = new wxPanel( this, -1 ); + panel->SetAutoLayout( TRUE ); + + wxStaticText *group_label = + new wxStaticText( panel , -1, + wxU(_("Enter the name for the new group"))); + + groupname = new wxTextCtrl(panel, -1, wxU(""),wxDefaultPosition, + wxSize(80,27),wxTE_PROCESS_ENTER); + + wxButton *ok_button = new wxButton(panel, wxID_OK, wxU(_("OK")) ); + ok_button->SetDefault(); + wxButton *cancel_button = new wxButton( panel, wxID_CANCEL, + wxU(_("Cancel")) ); + + wxBoxSizer *button_sizer = new wxBoxSizer( wxHORIZONTAL ); + + button_sizer->Add( ok_button, 0, wxALL, 5 ); + button_sizer->Add( cancel_button, 0, wxALL, 5 ); + button_sizer->Layout(); + + wxBoxSizer *panel_sizer = new wxBoxSizer( wxVERTICAL ); + panel_sizer->Add( group_label, 0, wxEXPAND | wxALL, 5 ); + panel_sizer->Add( groupname, 0, wxEXPAND | wxALL, 5 ); + panel_sizer->Add( button_sizer, 0, wxEXPAND | wxALL, 5 ); + panel_sizer->Layout(); + + panel->SetSizerAndFit( panel_sizer ); + + wxBoxSizer *main_sizer = new wxBoxSizer( wxVERTICAL ); + main_sizer->Add( panel, 1, wxEXPAND, 0 ); + main_sizer->Layout(); + SetSizerAndFit( main_sizer ); +} + +NewGroup::~NewGroup() +{ +} + +void NewGroup::OnOk( wxCommandEvent& event ) +{ + psz_name = strdup( groupname->GetLineText(0).mb_str() ); + + playlist_t * p_playlist = + (playlist_t *)vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST, + FIND_ANYWHERE ); + + if( p_playlist ) + { + if( !playlist_CreateGroup( p_playlist, psz_name ) ) + { + psz_name = NULL; + } + } + + vlc_object_release( p_playlist ); + EndModal( wxID_OK ); +} + +void NewGroup::OnCancel( wxCommandEvent& WXUNUSED(event) ) +{ + EndModal( wxID_CANCEL ); +}