1 /*****************************************************************************
2 * playlist.cpp : wxWindows plugin for vlc
3 *****************************************************************************
4 * Copyright (C) 2000-2001 VideoLAN
5 * $Id: playlist.cpp,v 1.23 2003/10/29 17:32:54 zorglub Exp $
7 * Authors: Olivier Teulière <ipkiss@via.ecp.fr>
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
22 *****************************************************************************/
24 /*****************************************************************************
26 *****************************************************************************/
27 #include <stdlib.h> /* malloc(), free() */
28 #include <errno.h> /* ENOMEM */
29 #include <string.h> /* strerror() */
35 #include "wxwindows.h"
36 #include <wx/listctrl.h>
38 /* Callback prototype */
39 int PlaylistChanged( vlc_object_t *p_this, const char *psz_variable,
40 vlc_value_t old_val, vlc_value_t new_val, void *param );
42 /*****************************************************************************
44 *****************************************************************************/
46 /* IDs for the controls and the menu commands */
63 EnableSelection_Event,
64 DisableSelection_Event,
66 InvertSelection_Event,
67 DeleteSelection_Event,
87 BEGIN_EVENT_TABLE(Playlist, wxFrame)
89 EVT_MENU(AddFile_Event, Playlist::OnAddFile)
90 EVT_MENU(AddMRL_Event, Playlist::OnAddMRL)
91 EVT_MENU(Close_Event, Playlist::OnClose)
92 EVT_MENU(Open_Event, Playlist::OnOpen)
93 EVT_MENU(Save_Event, Playlist::OnSave)
95 EVT_MENU(SortTitle_Event, Playlist::OnSort)
96 EVT_MENU(RSortTitle_Event, Playlist::OnSort)
97 EVT_MENU(SortAuthor_Event, Playlist::OnSort)
98 EVT_MENU(RSortAuthor_Event, Playlist::OnSort)
99 EVT_MENU(SortGroup_Event, Playlist::OnSort)
100 EVT_MENU(RSortGroup_Event, Playlist::OnSort)
102 EVT_MENU(EnableSelection_Event, Playlist::OnEnableSelection)
103 EVT_MENU(DisableSelection_Event, Playlist::OnDisableSelection)
104 EVT_MENU(InvertSelection_Event, Playlist::OnInvertSelection)
105 EVT_MENU(DeleteSelection_Event, Playlist::OnDeleteSelection)
106 EVT_MENU(SelectAll_Event, Playlist::OnSelectAll)
107 EVT_MENU(Infos_Event, Playlist::OnInfos)
108 EVT_CHECKBOX(Random_Event, Playlist::OnRandom)
109 EVT_CHECKBOX(Repeat_Event, Playlist::OnRepeat)
110 EVT_CHECKBOX(Loop_Event, Playlist::OnLoop)
112 EVT_MENU(EnableGroup_Event, Playlist::OnEnDis)
113 EVT_MENU(DisableGroup_Event, Playlist::OnEnDis)
115 /* Listview events */
116 EVT_LIST_ITEM_ACTIVATED(ListView_Event, Playlist::OnActivateItem)
117 EVT_LIST_KEY_DOWN(ListView_Event, Playlist::OnKeyDown)
120 EVT_BUTTON( Search_Event, Playlist::OnSearch)
121 EVT_BUTTON( Save_Event, Playlist::OnSave)
122 EVT_BUTTON( Infos_Event, Playlist::OnInfos)
124 EVT_BUTTON( Up_Event, Playlist::OnUp)
125 EVT_BUTTON( Down_Event, Playlist::OnDown)
127 EVT_TEXT(SearchText_Event, Playlist::OnSearchTextChange)
129 /* Special events : we don't want to destroy the window when the user
131 EVT_CLOSE(Playlist::OnClose)
135 /* Event Table for the Newgroup class */
136 BEGIN_EVENT_TABLE(NewGroup, wxDialog)
137 EVT_BUTTON( wxID_OK, NewGroup::OnOk)
138 EVT_BUTTON( wxID_CANCEL, NewGroup::OnCancel)
141 /*****************************************************************************
143 *****************************************************************************/
144 Playlist::Playlist( intf_thread_t *_p_intf, wxWindow *p_parent ):
145 wxFrame( p_parent, -1, wxU(_("Playlist")), wxDefaultPosition,
146 wxDefaultSize, wxDEFAULT_FRAME_STYLE )
148 /* Initializations */
149 iteminfo_dialog = NULL;
152 i_update_counter = 0;
153 i_sort_mode = MODE_NONE;
154 b_need_update = VLC_FALSE;
155 vlc_mutex_init( p_intf, &lock );
156 SetIcon( *p_intf->p_sys->p_icon );
158 var_Create( p_intf, "random", VLC_VAR_BOOL );
159 var_Change( p_intf, "random", VLC_VAR_INHERITVALUE, & val, NULL );
160 var_Create( p_intf, "loop", VLC_VAR_BOOL );
161 var_Create( p_intf, "loop", VLC_VAR_BOOL );
162 var_Change( p_intf, "repeat", VLC_VAR_INHERITVALUE, & val, NULL );
163 var_Change( p_intf, "repeat", VLC_VAR_INHERITVALUE, & val, NULL );
165 /* Create our "Manage" menu */
166 wxMenu *manage_menu = new wxMenu;
167 manage_menu->Append( AddFile_Event, wxU(_("&Simple Add...")) );
168 manage_menu->Append( AddMRL_Event, wxU(_("&Add MRL...")) );
169 manage_menu->AppendSeparator();
170 manage_menu->Append( Open_Event, wxU(_("&Open Playlist...")) );
171 manage_menu->Append( Save_Event, wxU(_("&Save Playlist...")) );
172 manage_menu->AppendSeparator();
173 manage_menu->Append( Close_Event, wxU(_("&Close")) );
175 /* Create our "Sort" menu */
176 wxMenu *sort_menu = new wxMenu;
177 sort_menu->Append( SortTitle_Event, wxU(_("&Sort by title")) );
178 sort_menu->Append( RSortTitle_Event, wxU(_("&Reverse sort by title")) );
179 sort_menu->AppendSeparator();
180 sort_menu->Append( SortAuthor_Event, wxU(_("&Sort by author")) );
181 sort_menu->Append( RSortAuthor_Event, wxU(_("&Reverse sort by author")) );
182 sort_menu->AppendSeparator();
183 sort_menu->Append( SortGroup_Event, wxU(_("&Sort by group")) );
184 sort_menu->Append( RSortGroup_Event, wxU(_("&Reverse sort by group")) );
186 /* Create our "Selection" menu */
187 wxMenu *selection_menu = new wxMenu;
188 selection_menu->Append( EnableSelection_Event, wxU(_("&Enable")) );
189 selection_menu->Append( DisableSelection_Event, wxU(_("&Disable")) );
190 selection_menu->AppendSeparator();
191 selection_menu->Append( InvertSelection_Event, wxU(_("&Invert")) );
192 selection_menu->Append( DeleteSelection_Event, wxU(_("&Delete")) );
193 selection_menu->Append( SelectAll_Event, wxU(_("&Select All")) );
195 /* Create our "Group" menu */
196 wxMenu *group_menu = new wxMenu;
197 group_menu->Append( EnableGroup_Event, wxU(_("&Enable all group items")) );
198 group_menu->Append( DisableGroup_Event,
199 wxU(_("&Disable all group items")) );
201 /* Append the freshly created menus to the menu bar */
202 wxMenuBar *menubar = new wxMenuBar( wxMB_DOCKABLE );
203 menubar->Append( manage_menu, wxU(_("&Manage")) );
204 menubar->Append( sort_menu, wxU(_("S&ort")) );
205 menubar->Append( selection_menu, wxU(_("&Selection")) );
206 menubar->Append( group_menu, wxU(_("&Groups")) );
208 /* Attach the menu bar to the frame */
209 SetMenuBar( menubar );
212 /* Create a panel to put everything in */
213 wxPanel *playlist_panel = new wxPanel( this, -1 );
214 playlist_panel->SetAutoLayout( TRUE );
216 /* Create the Random checkbox */
217 wxCheckBox *random_checkbox =
218 new wxCheckBox( playlist_panel, Random_Event, wxU(_("Random")) );
219 var_Get( p_intf, "random", &val);
220 vlc_bool_t b_random = val.b_bool;
221 random_checkbox->SetValue( b_random == VLC_FALSE ? 0 : 1);
223 /* Create the Loop Checkbox */
224 wxCheckBox *loop_checkbox =
225 new wxCheckBox( playlist_panel, Loop_Event, wxU(_("Loop")) );
226 var_Get( p_intf, "loop", &val );
227 int b_loop = val.b_bool ;
228 loop_checkbox->SetValue( b_loop );
230 /* Create the Repeat one checkbox */
231 wxCheckBox *repeat_checkbox =
232 new wxCheckBox( playlist_panel, Repeat_Event, wxU(_("Repeat one")) );
233 var_Get( p_intf, "repeat", &val );
234 int b_repeat = val.b_bool ;
235 repeat_checkbox->SetValue( b_repeat );
237 /* Create the Search Textbox */
239 new wxTextCtrl( playlist_panel, SearchText_Event, wxT(""),
240 wxDefaultPosition, wxSize( 140, -1),
243 /* Create the search button */
245 new wxButton( playlist_panel, Search_Event, wxU(_("Search")) );
248 /* Create the listview */
249 /* FIXME: the given size is arbitrary, and prevents us from resizing
250 * the window to smaller dimensions. But the sizers don't seem to adjust
251 * themselves to the size of a listview, and with a wxDefaultSize the
252 * playlist window is ridiculously small */
253 listview = new wxListView( playlist_panel, ListView_Event,
254 wxDefaultPosition, wxSize( 500, 300 ),
255 wxLC_REPORT | wxSUNKEN_BORDER );
256 listview->InsertColumn( 0, wxU(_("Name")) );
258 listview->InsertColumn( 1, wxU(_("Duration")) );
260 listview->InsertColumn( 1, wxU(_("Author")) );
261 listview->InsertColumn( 2, wxU(_("Group")) );
262 listview->SetColumnWidth( 0, 270 );
263 listview->SetColumnWidth( 1, 150 );
264 listview->SetColumnWidth( 2, 80 );
266 /* Create the Up-Down buttons */
267 wxButton *up_button =
268 new wxButton( playlist_panel, Up_Event, wxU(_("Up") ) );
270 wxButton *down_button =
271 new wxButton( playlist_panel, Down_Event, wxU(_("Down") ) );
273 /* Create the iteminfo button */
274 wxButton *iteminfo_button =
275 new wxButton( playlist_panel, Infos_Event, wxU(_("Item Infos") ) );
277 /* Place everything in sizers */
278 wxBoxSizer *button_sizer = new wxBoxSizer( wxHORIZONTAL );
279 button_sizer->Add( iteminfo_button, 0, wxALIGN_CENTER|wxLEFT , 5);
280 button_sizer->Layout();
282 wxBoxSizer *updown_sizer = new wxBoxSizer( wxHORIZONTAL );
283 updown_sizer->Add( up_button, 0, wxALIGN_LEFT|wxRIGHT, 3);
284 updown_sizer->Add( down_button, 0, wxALIGN_LEFT|wxLEFT, 3);
285 updown_sizer->Layout();
287 wxBoxSizer *checkbox_sizer = new wxBoxSizer( wxHORIZONTAL );
288 checkbox_sizer->Add( random_checkbox, 0,
289 wxEXPAND|wxALIGN_RIGHT, 5);
290 checkbox_sizer->Add( loop_checkbox, 0,
291 wxEXPAND|wxALIGN_RIGHT, 5);
292 checkbox_sizer->Add( repeat_checkbox, 0,
293 wxEXPAND|wxALIGN_RIGHT, 5);
294 checkbox_sizer->Layout();
296 wxBoxSizer *search_sizer = new wxBoxSizer( wxHORIZONTAL );
297 search_sizer->Add( search_text, 0, wxRIGHT|wxALIGN_CENTER, 3);
298 search_sizer->Add( search_button, 0, wxLEFT|wxALIGN_CENTER, 3);
299 search_sizer->Layout();
301 /* The top and bottom sizers */
302 wxBoxSizer *top_sizer = new wxBoxSizer( wxHORIZONTAL );
303 top_sizer->Add( checkbox_sizer, 0, wxLEFT|wxRIGHT|wxALIGN_LEFT, 4 );
304 top_sizer->Add( search_sizer, 0, wxLEFT|wxRIGHT|wxALIGN_RIGHT, 4 );
307 wxBoxSizer *bottom_sizer = new wxBoxSizer( wxHORIZONTAL );
308 bottom_sizer->Add( updown_sizer, 0, wxEXPAND |wxRIGHT | wxLEFT | wxALIGN_LEFT, 4);
309 bottom_sizer->Add( button_sizer , 0, wxEXPAND|wxLEFT | wxRIGHT | wxALIGN_RIGHT, 4 );
310 bottom_sizer->Layout();
312 wxBoxSizer *main_sizer = new wxBoxSizer( wxVERTICAL );
314 wxBoxSizer *panel_sizer = new wxBoxSizer( wxVERTICAL );
315 panel_sizer->Add( top_sizer, 0, wxEXPAND | wxALL, 5 );
316 panel_sizer->Add( listview, 1, wxEXPAND | wxALL, 5 );
317 panel_sizer->Add( bottom_sizer, 0 , wxEXPAND | wxALL, 5);
318 panel_sizer->Layout();
320 playlist_panel->SetSizerAndFit( panel_sizer );
321 main_sizer->Add( playlist_panel, 1, wxGROW, 0 );
322 main_sizer->Layout();
323 SetSizerAndFit( main_sizer );
325 #if !defined(__WXX11__)
326 /* Associate drop targets with the playlist */
327 SetDropTarget( new DragAndDrop( p_intf ) );
330 playlist_t *p_playlist =
331 (playlist_t *)vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
333 if( p_playlist == NULL )
338 /* We want to be noticed of playlist changes */
339 var_AddCallback( p_playlist, "intf-change", PlaylistChanged, this );
340 vlc_object_release( p_playlist );
342 /* Update the playlist */
346 Playlist::~Playlist()
348 playlist_t *p_playlist =
349 (playlist_t *)vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
351 if( p_playlist == NULL )
356 delete iteminfo_dialog;
358 var_DelCallback( p_playlist, "intf-change", PlaylistChanged, this );
359 vlc_object_release( p_playlist );
362 /**********************************************************************
363 * Rebuild the playlist
364 **********************************************************************/
365 void Playlist::Rebuild()
367 playlist_t *p_playlist =
368 (playlist_t *)vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
370 if( p_playlist == NULL )
375 int i_focused = listview->GetFocusedItem();
377 /* Clear the list... */
378 listview->DeleteAllItems();
380 /* ...and rebuild it */
381 vlc_mutex_lock( &p_playlist->object_lock );
382 for( int i = 0; i < p_playlist->i_size; i++ )
384 wxString filename = wxU(p_playlist->pp_items[i]->psz_name);
385 listview->InsertItem( i, filename );
386 listview->SetItem( i, 1, wxU(p_playlist->pp_items[i]->psz_author));
387 listview->SetItem( i, 2,
388 wxU(playlist_FindGroup(p_playlist,p_playlist->
389 pp_items[i]->i_group)));
390 if( p_playlist->pp_items[i]->b_enabled == VLC_FALSE )
393 listitem.m_itemId = i;
394 listitem.SetTextColour( *wxLIGHT_GREY);
395 listview->SetItem(listitem);
397 /* FIXME: we should try to find the actual duration... */
398 /* While we don't use it, hide it, it's ugly */
400 listview->SetItem( i, 1, wxU(_("no info")) );
403 vlc_mutex_unlock( &p_playlist->object_lock );
405 /* Change the colour for the currenty played stream */
407 listitem.m_itemId = p_playlist->i_index;
408 listitem.SetTextColour( *wxRED );
409 listview->SetItem( listitem );
413 listview->Focus( i_focused );
414 listview->Select( i_focused );
418 listview->Focus( p_playlist->i_index );
421 vlc_object_release( p_playlist );
424 void Playlist::ShowPlaylist( bool show )
426 if( show ) Rebuild();
430 void Playlist::UpdatePlaylist()
432 vlc_bool_t b_need_update = VLC_FALSE;
435 /* If the playlist isn't show there's no need to update it */
436 if( !IsShown() ) return;
438 vlc_mutex_lock( &lock );
439 if( this->b_need_update )
441 b_need_update =VLC_TRUE;
442 this->b_need_update = VLC_FALSE;
444 vlc_mutex_unlock( &lock );
451 /* Updating the playing status every 0.5s is enough */
452 if( i_update_counter % 5 ) return;
454 playlist_t *p_playlist =
455 (playlist_t *)vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
457 if( p_playlist == NULL )
462 /* Update the colour of items */
464 vlc_mutex_lock( &p_playlist->object_lock );
465 if( p_intf->p_sys->i_playing != p_playlist->i_index )
468 listitem.m_itemId = p_playlist->i_index;
469 listitem.SetTextColour( *wxRED );
470 listview->SetItem( listitem );
472 if( p_intf->p_sys->i_playing != -1 )
474 listitem.m_itemId = p_intf->p_sys->i_playing;
475 listitem.SetTextColour( *wxBLACK );
476 listview->SetItem( listitem );
478 p_intf->p_sys->i_playing = p_playlist->i_index;
480 vlc_mutex_unlock( &p_playlist->object_lock );
481 vlc_object_release( p_playlist );
484 /*****************************************************************************
486 *****************************************************************************/
487 void Playlist::DeleteItem( int item )
489 playlist_t *p_playlist =
490 (playlist_t *)vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
492 if( p_playlist == NULL )
497 playlist_Delete( p_playlist, item );
498 listview->DeleteItem( item );
500 vlc_object_release( p_playlist );
503 void Playlist::OnClose( wxCommandEvent& WXUNUSED(event) )
508 void Playlist::OnSave( wxCommandEvent& WXUNUSED(event) )
510 playlist_t *p_playlist =
511 (playlist_t *)vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
513 if( p_playlist == NULL )
518 wxFileDialog dialog( this, wxU(_("Save playlist")),
519 wxT(""), wxT(""), wxT("*"), wxSAVE );
521 if( dialog.ShowModal() == wxID_OK )
523 playlist_SaveFile( p_playlist, dialog.GetPath().mb_str() );
526 vlc_object_release( p_playlist );
529 void Playlist::OnOpen( wxCommandEvent& WXUNUSED(event) )
531 playlist_t *p_playlist =
532 (playlist_t *)vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
534 if( p_playlist == NULL )
539 wxFileDialog dialog( this, wxU(_("Open playlist")),
540 wxT(""), wxT(""), wxT("*"), wxOPEN );
542 if( dialog.ShowModal() == wxID_OK )
544 playlist_LoadFile( p_playlist, dialog.GetPath().mb_str() );
547 vlc_object_release( p_playlist );
550 void Playlist::OnAddFile( wxCommandEvent& WXUNUSED(event) )
552 p_intf->p_sys->pf_show_dialog( p_intf, INTF_DIALOG_FILE_SIMPLE, 0, 0 );
559 void Playlist::OnAddMRL( wxCommandEvent& WXUNUSED(event) )
561 p_intf->p_sys->pf_show_dialog( p_intf, INTF_DIALOG_FILE, 0, 0 );
568 /********************************************************************
570 ********************************************************************/
571 void Playlist::OnUp( wxCommandEvent& event)
573 playlist_t *p_playlist =
574 (playlist_t *)vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
576 if( p_playlist == NULL )
581 /* We use the first selected item, so find it */
583 i_item = listview->GetNextItem(i_item,
585 wxLIST_STATE_SELECTED);
586 if( i_item > 0 && i_item < p_playlist->i_size )
588 playlist_Move( p_playlist , i_item, i_item - 1);
591 listview->Focus( i_item - 1 );
598 vlc_object_release( p_playlist );
602 void Playlist::OnDown( wxCommandEvent& event)
604 playlist_t *p_playlist =
605 (playlist_t *)vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
607 if( p_playlist == NULL )
612 /* We use the first selected item, so find it */
614 i_item = listview->GetNextItem(i_item,
616 wxLIST_STATE_SELECTED);
617 if( i_item >= 0 && i_item < p_playlist->i_size - 1 )
619 playlist_Move( p_playlist , i_item, i_item + 2 );
620 listview->Focus( i_item + 1 );
622 vlc_object_release( p_playlist );
626 /********************************************************************
628 ********************************************************************/
629 void Playlist::OnSort( wxCommandEvent& event )
631 playlist_t *p_playlist =
632 (playlist_t *)vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
634 if( p_playlist == NULL )
638 switch( event.GetId() )
640 case SortTitle_Event:
641 playlist_SortTitle( p_playlist , 0 );
643 case RSortTitle_Event:
644 playlist_SortTitle( p_playlist , 1 );
646 case SortAuthor_Event:
647 playlist_SortAuthor(p_playlist , 0 );
649 case RSortAuthor_Event:
650 playlist_SortAuthor( p_playlist , 1 );
652 case SortGroup_Event:
653 playlist_SortGroup( p_playlist , 0 );
655 case RSortGroup_Event:
656 playlist_SortGroup( p_playlist , 1 );
659 vlc_object_release( p_playlist );
666 /**********************************************************************
668 **********************************************************************/
669 void Playlist::OnSearchTextChange( wxCommandEvent& WXUNUSED(event) )
671 search_button->SetDefault();
674 void Playlist::OnSearch( wxCommandEvent& WXUNUSED(event) )
676 wxString search_string= search_text->GetValue();
682 for( i_current = 0 ; i_current <= listview->GetItemCount() ; i_current++ )
684 if( listview->GetItemState( i_current, wxLIST_STATE_SELECTED)
685 == wxLIST_STATE_SELECTED )
692 for ( i_current = i_first + 1; i_current <= listview->GetItemCount() ;
696 listitem.SetId( i_current );
697 listview->GetItem( listitem );
698 if( listitem.m_text.Lower().Contains( search_string.Lower() ) )
704 for( long item = 0; item < listview->GetItemCount(); item++ )
706 listview->Select( item, FALSE );
710 listitem.SetId(i_item);
711 listitem.m_state = wxLIST_STATE_SELECTED;
712 listview->Select( i_item, TRUE );
713 listview->Focus( i_item );
717 /**********************************************************************
718 * Selection functions
719 **********************************************************************/
720 void Playlist::OnInvertSelection( wxCommandEvent& WXUNUSED(event) )
722 for( long item = 0; item < listview->GetItemCount(); item++ )
724 listview->Select( item, ! listview->IsSelected( item ) );
728 void Playlist::OnDeleteSelection( wxCommandEvent& WXUNUSED(event) )
730 /* Delete from the end to the beginning, to avoid a shift of indices */
731 for( long item = listview->GetItemCount() - 1; item >= 0; item-- )
733 if( listview->IsSelected( item ) )
742 void Playlist::OnEnableSelection( wxCommandEvent& WXUNUSED(event) )
744 playlist_t *p_playlist =
745 (playlist_t *)vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
747 if( p_playlist == NULL )
752 for( long item = listview->GetItemCount() - 1; item >= 0; item-- )
754 if( listview->IsSelected( item ) )
756 playlist_Enable( p_playlist, item );
759 vlc_object_release( p_playlist);
763 void Playlist::OnDisableSelection( wxCommandEvent& WXUNUSED(event) )
765 playlist_t *p_playlist =
766 (playlist_t *)vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
768 if( p_playlist == NULL )
773 for( long item = listview->GetItemCount() - 1; item >= 0; item-- )
775 if( listview->IsSelected( item ) )
777 playlist_Disable( p_playlist, item );
780 vlc_object_release( p_playlist);
784 void Playlist::OnSelectAll( wxCommandEvent& WXUNUSED(event) )
786 for( long item = 0; item < listview->GetItemCount(); item++ )
788 listview->Select( item, TRUE );
792 /**********************************************************************
793 * Playlist mode functions
794 **********************************************************************/
795 void Playlist::OnRandom( wxCommandEvent& event )
798 val.b_bool = event.IsChecked();
799 playlist_t *p_playlist =
800 (playlist_t *)vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
802 if( p_playlist == NULL )
806 var_Set( p_playlist , "random", val);
807 vlc_object_release( p_playlist );
809 void Playlist::OnLoop ( wxCommandEvent& event )
812 val.b_bool = event.IsChecked();
813 playlist_t *p_playlist =
814 (playlist_t *)vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
816 if( p_playlist == NULL )
820 var_Set( p_playlist , "loop", val);
821 vlc_object_release( p_playlist );
824 void Playlist::OnRepeat ( wxCommandEvent& event )
827 val.b_bool = event.IsChecked();
828 playlist_t *p_playlist =
829 (playlist_t *)vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
831 if( p_playlist == NULL )
835 var_Set( p_playlist , "repeat", val);
836 vlc_object_release( p_playlist );
841 void Playlist::OnActivateItem( wxListEvent& event )
843 playlist_t *p_playlist =
844 (playlist_t *)vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
846 if( p_playlist == NULL )
850 playlist_Goto( p_playlist, event.GetIndex() );
852 vlc_object_release( p_playlist );
854 void Playlist::OnKeyDown( wxListEvent& event )
856 long keycode = event.GetKeyCode();
857 /* Delete selected items */
858 if( keycode == WXK_BACK || keycode == WXK_DELETE )
860 /* We send a dummy event */
861 OnDeleteSelection( event );
865 void Playlist::OnInfos( wxCommandEvent& WXUNUSED(event) )
867 playlist_t *p_playlist =
868 (playlist_t *)vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
870 if( p_playlist == NULL )
875 if( iteminfo_dialog == NULL )
877 /* We use the first selected item, so find it */
879 i_item = listview->GetNextItem(i_item,
881 wxLIST_STATE_SELECTED);
882 if( i_item >= 0 && i_item < p_playlist->i_size )
884 iteminfo_dialog = new ItemInfoDialog(
885 p_intf, p_playlist->pp_items[i_item], this );
886 if( iteminfo_dialog->ShowModal() == wxID_OK )
888 delete iteminfo_dialog;
889 iteminfo_dialog = NULL;
892 vlc_object_release( p_playlist );
895 void Playlist::OnEnDis( wxCommandEvent& event )
897 playlist_t *p_playlist =
898 (playlist_t *)vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
900 if( p_playlist == NULL )
906 i_item = listview->GetNextItem(i_item,
908 wxLIST_STATE_SELECTED);
910 if( i_item >= 0 && i_item < p_playlist->i_size )
912 switch( event.GetId() )
914 case EnableGroup_Event:
915 playlist_EnableGroup( p_playlist ,
916 p_playlist->pp_items[i_item]->i_group );
918 case DisableGroup_Event:
919 playlist_DisableGroup( p_playlist ,
920 p_playlist->pp_items[i_item]->i_group );
926 vlc_object_release( p_playlist );
929 /*****************************************************************************
930 * PlaylistChanged: callback triggered by the intf-change playlist variable
931 * We don't rebuild the playlist directly here because we don't want the
932 * caller to block for a too long time.
933 *****************************************************************************/
934 int PlaylistChanged( vlc_object_t *p_this, const char *psz_variable,
935 vlc_value_t old_val, vlc_value_t new_val, void *param )
937 Playlist *p_playlist_dialog = (Playlist *)param;
938 vlc_mutex_lock( &p_playlist_dialog->lock );
939 p_playlist_dialog->b_need_update = VLC_TRUE;
940 vlc_mutex_unlock( &p_playlist_dialog->lock );
945 /***************************************************************************
947 ***************************************************************************/
948 NewGroup::NewGroup( intf_thread_t *_p_intf, wxWindow *_p_parent ):
949 wxDialog( _p_parent, -1, wxU(_("New Group")), wxDefaultPosition,
950 wxDefaultSize, wxDEFAULT_FRAME_STYLE )
952 /* Initializations */
955 SetIcon( *p_intf->p_sys->p_icon );
957 /* Create a panel to put everything in*/
958 wxPanel *panel = new wxPanel( this, -1 );
959 panel->SetAutoLayout( TRUE );
961 wxStaticText *group_label =
962 new wxStaticText( panel , -1,
963 wxU(_("Enter the name for the new group")));
965 groupname = new wxTextCtrl(panel, -1, wxU(""),wxDefaultPosition,
966 wxSize(80,27),wxTE_PROCESS_ENTER);
968 wxButton *ok_button = new wxButton(panel, wxID_OK, wxU(_("OK")) );
969 ok_button->SetDefault();
970 wxButton *cancel_button = new wxButton( panel, wxID_CANCEL,
973 wxBoxSizer *button_sizer = new wxBoxSizer( wxHORIZONTAL );
975 button_sizer->Add( ok_button, 0, wxALL, 5 );
976 button_sizer->Add( cancel_button, 0, wxALL, 5 );
977 button_sizer->Layout();
979 wxBoxSizer *panel_sizer = new wxBoxSizer( wxVERTICAL );
980 panel_sizer->Add( group_label, 0, wxEXPAND | wxALL, 5 );
981 panel_sizer->Add( groupname, 0, wxEXPAND | wxALL, 5 );
982 panel_sizer->Add( button_sizer, 0, wxEXPAND | wxALL, 5 );
983 panel_sizer->Layout();
985 panel->SetSizerAndFit( panel_sizer );
987 wxBoxSizer *main_sizer = new wxBoxSizer( wxVERTICAL );
988 main_sizer->Add( panel, 1, wxEXPAND, 0 );
989 main_sizer->Layout();
990 SetSizerAndFit( main_sizer );
993 NewGroup::~NewGroup()
997 void NewGroup::OnOk( wxCommandEvent& event )
999 psz_name = strdup( groupname->GetLineText(0).mb_str() );
1001 playlist_t * p_playlist =
1002 (playlist_t *)vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
1007 if( !playlist_CreateGroup( p_playlist, psz_name ) )
1013 vlc_object_release( p_playlist );
1014 EndModal( wxID_OK );
1017 void NewGroup::OnCancel( wxCommandEvent& WXUNUSED(event) )
1019 EndModal( wxID_CANCEL );