1 /*****************************************************************************
2 * playlist.cpp : WinCE gui plugin for VLC
3 *****************************************************************************
4 * Copyright (C) 2000-2004 the VideoLAN team
7 * Authors: Marodon Cedric <cedric_marodon@yahoo.fr>
8 * Gildas Bazin <gbazin@videolan.org>
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
23 *****************************************************************************/
25 /*****************************************************************************
27 *****************************************************************************/
32 #include <vlc_common.h>
33 #include <vlc_interface.h>
34 #include <vlc_playlist.h>
42 #define TEXTMAXBUF 512 // at least 500
45 #define LONG2POINT(l, pt) ((pt).x = (SHORT)LOWORD(l), (pt).y = (SHORT)HIWORD(l))
47 #define NUMIMAGES 11 // Number of buttons in the toolbar
48 #define IMAGEWIDTH 16 // Width of the buttons in the toolbar
49 #define IMAGEHEIGHT 16 // Height of the buttons in the toolbar
50 #define BUTTONWIDTH 0 // Width of the button images in the toolbar
51 #define BUTTONHEIGHT 0 // Height of the button images in the toolbar
52 #define ID_TOOLBAR 2000 // Identifier of the main tool bar
69 #define HELP_OPENPL _T("Open playlist")
70 #define HELP_SAVEPL _T("Save playlist")
71 #define HELP_ADDFILE _T("Add File")
72 #define HELP_ADDMRL _T("Add MRL")
73 #define HELP_DELETE _T("Delete selection")
74 #define HELP_INFOS _T("Item info")
75 #define HELP_UP _T("Up")
76 #define HELP_DOWN _T("Down")
77 #define HELP_RANDOM _T("Random")
78 #define HELP_LOOP _T("Repeat all")
79 #define HELP_REPEAT _T("Repeat one")
81 // The TBBUTTON structure contains information the toolbar buttons.
82 static TBBUTTON tbButton2[] =
84 {0, ID_MANAGE_OPENPL, TBSTATE_ENABLED, TBSTYLE_BUTTON },
85 {1, ID_MANAGE_SAVEPL, TBSTATE_ENABLED, TBSTYLE_BUTTON },
86 {0, 0, TBSTATE_ENABLED, TBSTYLE_SEP },
87 {2, ID_MANAGE_ADDFILE, TBSTATE_ENABLED, TBSTYLE_BUTTON },
88 {3, ID_MANAGE_ADDMRL, TBSTATE_ENABLED, TBSTYLE_BUTTON },
89 {4, ID_SEL_DELETE, TBSTATE_ENABLED, TBSTYLE_BUTTON },
90 {0, 0, TBSTATE_ENABLED, TBSTYLE_SEP },
91 {5, Infos_Event, TBSTATE_ENABLED, TBSTYLE_BUTTON },
92 {0, 0, TBSTATE_ENABLED, TBSTYLE_SEP },
93 {6, Up_Event, TBSTATE_ENABLED, TBSTYLE_BUTTON },
94 {7, Down_Event, TBSTATE_ENABLED, TBSTYLE_BUTTON },
95 {0, 0, TBSTATE_ENABLED, TBSTYLE_SEP },
96 {8, Random_Event, TBSTATE_ENABLED, TBSTYLE_CHECK },
97 {9, Loop_Event, TBSTATE_ENABLED, TBSTYLE_CHECK },
98 {10, Repeat_Event, TBSTATE_ENABLED, TBSTYLE_CHECK }
102 TCHAR * szToolTips2[] =
117 /*****************************************************************************
119 *****************************************************************************/
121 /*****************************************************************************
123 *****************************************************************************/
124 Playlist::Playlist( intf_thread_t *p_intf, CBaseWindow *p_parent,
126 : CBaseWindow( p_intf, p_parent, h_inst )
128 /* Initializations */
133 b_need_update = true;
136 /***********************************************************************
142 ***********************************************************************/
143 static HWND CreateMenuBar( HWND hwnd, HINSTANCE hInst )
147 memset( &mbi, 0, sizeof(SHMENUBARINFO) );
148 mbi.cbSize = sizeof(SHMENUBARINFO);
149 mbi.hwndParent = hwnd;
150 mbi.hInstRes = hInst;
151 mbi.nToolBarId = IDR_MENUBAR2;
153 if( !SHCreateMenuBar( &mbi ) )
155 MessageBox(hwnd, _T("SHCreateMenuBar Failed"), _T("Error"), MB_OK);
160 tbbi.cbSize = sizeof(tbbi);
161 tbbi.dwMask = TBIF_LPARAM;
163 SendMessage( mbi.hwndMB, TB_GETBUTTONINFO, IDM_MANAGE, (LPARAM)&tbbi );
164 HMENU hmenu_file = (HMENU)tbbi.lParam;
165 RemoveMenu( hmenu_file, 0, MF_BYPOSITION );
166 SendMessage( mbi.hwndMB, TB_GETBUTTONINFO, IDM_SORT, (LPARAM)&tbbi );
167 HMENU hmenu_sort = (HMENU)tbbi.lParam;
168 RemoveMenu( hmenu_sort, 0, MF_BYPOSITION );
169 SendMessage( mbi.hwndMB, TB_GETBUTTONINFO, IDM_SEL, (LPARAM)&tbbi );
170 HMENU hmenu_sel = (HMENU)tbbi.lParam;
171 RemoveMenu( hmenu_sel, 0, MF_BYPOSITION );
174 HMENU hmenu_file = CreatePopupMenu();
175 HMENU hmenu_sort = CreatePopupMenu();
176 HMENU hmenu_sel = CreatePopupMenu();
179 AppendMenu( hmenu_file, MF_STRING, ID_MANAGE_ADDFILE,
180 _T("&Add File...") );
181 AppendMenu( hmenu_file, MF_STRING, ID_MANAGE_ADDDIRECTORY,
182 _T("Add Directory...") );
183 AppendMenu( hmenu_file, MF_STRING, ID_MANAGE_ADDMRL,
185 AppendMenu( hmenu_file, MF_SEPARATOR, 0, 0 );
186 AppendMenu( hmenu_file, MF_STRING, ID_MANAGE_OPENPL,
187 _T("Open &Playlist") );
188 AppendMenu( hmenu_file, MF_STRING, ID_MANAGE_SAVEPL,
189 _T("Save Playlist") );
191 AppendMenu( hmenu_sort, MF_STRING, ID_SORT_TITLE,
192 _T("Sort by &title") );
193 AppendMenu( hmenu_sort, MF_STRING, ID_SORT_RTITLE,
194 _T("&Reverse sort by title") );
195 AppendMenu( hmenu_sort, MF_SEPARATOR, 0, 0 );
196 AppendMenu( hmenu_sort, MF_STRING, ID_SORT_AUTHOR,
197 _T("Sort by &author") );
198 AppendMenu( hmenu_sort, MF_STRING, ID_SORT_RAUTHOR,
199 _T("Reverse sort by &author") );
200 AppendMenu( hmenu_sort, MF_SEPARATOR, 0, 0 );
201 AppendMenu( hmenu_sort, MF_STRING, ID_SORT_SHUFFLE,
202 _T("&Shuffle Playlist") );
204 AppendMenu( hmenu_sel, MF_STRING, ID_SEL_ENABLE,
206 AppendMenu( hmenu_sel, MF_STRING, ID_SEL_DISABLE,
208 AppendMenu( hmenu_sel, MF_SEPARATOR, 0, 0 );
209 AppendMenu( hmenu_sel, MF_STRING, ID_SEL_INVERT,
211 AppendMenu( hmenu_sel, MF_STRING, ID_SEL_DELETE,
213 AppendMenu( hmenu_sel, MF_SEPARATOR, 0, 0 );
214 AppendMenu( hmenu_sel, MF_STRING, ID_SEL_SELECTALL,
222 HMENU hmenu = CreateMenu();
224 AppendMenu( hmenu, MF_POPUP|MF_STRING, (UINT)hmenu_file, _T("Manage") );
225 AppendMenu( hmenu, MF_POPUP|MF_STRING, (UINT)hmenu_sort, _T("Sort") );
226 AppendMenu( hmenu, MF_POPUP|MF_STRING, (UINT)hmenu_sel, _T("Selection") );
228 SetMenu( hwnd, hmenu );
234 /***********************************************************************
239 Processes messages sent to the main window.
240 ***********************************************************************/
241 LRESULT Playlist::WndProc( HWND hwnd, UINT msg, WPARAM wp, LPARAM lp )
245 INITCOMMONCONTROLSEX iccex;
250 playlist_t *p_playlist;
255 shidi.dwMask = SHIDIM_FLAGS;
256 shidi.dwFlags = SHIDIF_DONEBUTTON | SHIDIF_SIPDOWN |
257 SHIDIF_FULLSCREENNOMENUBAR;//SHIDIF_SIZEDLGFULLSCREEN;
259 SHInitDialog( &shidi );
261 hwndCB = CreateMenuBar( hwnd, hInst );
263 iccex.dwSize = sizeof (INITCOMMONCONTROLSEX);
264 iccex.dwICC = ICC_BAR_CLASSES;
266 // Registers TOOLBAR control classes from the common control dll
267 InitCommonControlsEx (&iccex);
269 // Create the toolbar control.
270 dwStyle = WS_VISIBLE | WS_CHILD | TBSTYLE_TOOLTIPS |
271 WS_EX_OVERLAPPEDWINDOW | CCS_NOPARENTALIGN;
273 hwndTB = CreateToolbarEx( hwnd, dwStyle, 0, NUMIMAGES,
274 hInst, IDB_BITMAP3, tbButton2,
275 sizeof (tbButton2) / sizeof (TBBUTTON),
276 BUTTONWIDTH, BUTTONHEIGHT,
277 IMAGEWIDTH, IMAGEHEIGHT, sizeof(TBBUTTON) );
280 // Add ToolTips to the toolbar.
281 SendMessage( hwndTB, TB_SETTOOLTIPS, (WPARAM) NUMIMAGES,
282 (LPARAM)szToolTips2 );
284 // Reposition the toolbar.
285 GetClientRect( hwnd, &rect );
286 GetWindowRect( hwndTB, &rectTB );
287 MoveWindow( hwndTB, rect.left, rect.top - 2, rect.right - rect.left,
288 MENU_HEIGHT /*rectTB.bottom - rectTB.top */, TRUE);
290 // random, loop, repeat buttons states
292 p_playlist = pl_Hold( p_intf );
293 if( !p_playlist ) break;
295 var_Get( p_playlist , "random", &val );
296 bState = val.b_bool ? TBSTATE_CHECKED : 0;
297 SendMessage( hwndTB, TB_SETSTATE, Random_Event,
298 MAKELONG(bState | TBSTATE_ENABLED, 0) );
299 var_Get( p_playlist , "loop", &val );
300 bState = val.b_bool ? TBSTATE_CHECKED : 0;
301 SendMessage( hwndTB, TB_SETSTATE, Loop_Event,
302 MAKELONG(bState | TBSTATE_ENABLED, 0) );
303 var_Get( p_playlist , "repeat", &val );
304 bState = val.b_bool ? TBSTATE_CHECKED : 0;
305 SendMessage( hwndTB, TB_SETSTATE, Repeat_Event,
306 MAKELONG(bState | TBSTATE_ENABLED, 0) );
307 pl_Release( p_intf );
309 GetClientRect( hwnd, &rect );
310 hListView = CreateWindow( WC_LISTVIEW, NULL, WS_VISIBLE | WS_CHILD |
311 LVS_REPORT | LVS_SHOWSELALWAYS | WS_VSCROLL | WS_HSCROLL,
312 rect.left, rect.top + 2*(MENU_HEIGHT+1), rect.right - rect.left,
313 rect.bottom - ( rect.top + 2*MENU_HEIGHT) - MENU_HEIGHT,
314 hwnd, NULL, hInst, NULL );
315 ListView_SetExtendedListViewStyle( hListView, LVS_EX_FULLROWSELECT );
318 lv.mask = LVCF_WIDTH | LVCF_FMT | LVCF_TEXT;
319 lv.fmt = LVCFMT_LEFT ;
320 GetClientRect( hwnd, &rect );
322 lv.pszText = _T("Name");
324 ListView_InsertColumn( hListView, 0, &lv);
326 lv.pszText = _T("Author");
328 ListView_InsertColumn( hListView, 1, &lv);
329 lv.cx = rect.right - rect.left - 180;
330 lv.pszText = _T("Duration");
332 ListView_InsertColumn( hListView, 2, &lv);
334 SetTimer( hwnd, 1, 500 /*milliseconds*/, NULL );
342 EndDialog( hwnd, LOWORD( wp ) );
346 SHSipPreference( hwnd, SIP_DOWN );
347 SHFullScreen( hwnd, SHFS_HIDESIPBUTTON );
354 EndDialog( hwnd, LOWORD( wp ) );
357 case ID_MANAGE_OPENPL:
359 b_need_update = true;
362 case ID_MANAGE_SAVEPL:
366 case ID_MANAGE_ADDFILE:
367 p_intf->p_sys->pf_show_dialog( p_intf, INTF_DIALOG_FILE_SIMPLE,
369 b_need_update = true;
372 case ID_MANAGE_ADDDIRECTORY:
373 p_intf->p_sys->pf_show_dialog( p_intf, INTF_DIALOG_DIRECTORY,
375 b_need_update = true;
378 case ID_MANAGE_ADDMRL:
379 p_intf->p_sys->pf_show_dialog( p_intf, INTF_DIALOG_FILE, 0, 0 );
380 b_need_update = true;
385 b_need_update = true;
390 b_need_update = true;
395 b_need_update = true;
400 b_need_update = true;
416 OnSort( ID_SORT_TITLE );
420 OnSort( ID_SORT_RTITLE );
424 OnSort( ID_SORT_AUTHOR );
427 case ID_SORT_RAUTHOR:
428 OnSort( ID_SORT_RAUTHOR );
431 case ID_SORT_SHUFFLE:
432 OnSort( ID_SORT_SHUFFLE );
440 OnDisableSelection();
447 case ID_SEL_SELECTALL:
451 case PopupPlay_Event:
453 b_need_update = true;
458 b_need_update = true;
463 b_need_update = true;
466 case PopupInfo_Event:
468 b_need_update = true;
477 if( ( ((LPNMHDR)lp)->hwndFrom == hListView ) &&
478 ( ((LPNMHDR)lp)->code == NM_CUSTOMDRAW ) )
480 SetWindowLong( hwnd, DWL_MSGRESULT,
481 (LONG)ProcessCustomDraw(lp) );
483 else if( ( ((LPNMHDR)lp)->hwndFrom == hListView ) &&
484 ( ((LPNMHDR)lp)->code == GN_CONTEXTMENU ) )
486 HandlePopupMenu( hwnd, ((PNMRGINFO)lp)->ptAction );
488 else if( ( ((LPNMHDR)lp)->hwndFrom == hListView ) &&
489 ( ((LPNMHDR)lp)->code == LVN_COLUMNCLICK ) )
491 OnColSelect( ((LPNMLISTVIEW)lp)->iSubItem );
493 else if( ( ((LPNMHDR)lp)->hwndFrom == hListView ) &&
494 ( ((LPNMHDR)lp)->code == LVN_ITEMACTIVATE ) )
496 OnActivateItem( ((LPNMLISTVIEW)lp)->iSubItem );
501 // the message was not processed
502 // indicate if the base class handled it
509 LRESULT Playlist::ProcessCustomDraw( LPARAM lParam )
511 LPNMLVCUSTOMDRAW lplvcd = (LPNMLVCUSTOMDRAW)lParam;
513 switch( lplvcd->nmcd.dwDrawStage )
515 case CDDS_PREPAINT : //Before the paint cycle begins
516 //request notifications for individual listview items
517 return CDRF_NOTIFYITEMDRAW;
519 case CDDS_ITEMPREPAINT: //Before an item is drawn
520 playlist_t *p_playlist = pl_Hold( p_intf );
521 if( p_playlist == NULL ) return CDRF_DODEFAULT;
522 if( (int)lplvcd->nmcd.dwItemSpec == p_playlist->i_current_index )
524 lplvcd->clrText = RGB(255,0,0);
525 pl_Release( p_intf );
530 playlist_item_t *p_item = playlist_ItemGetById( p_playlist,
531 (int)lplvcd->nmcd.dwItemSpec );
535 pl_Release( p_intf );
536 return CDRF_DODEFAULT;
538 if( p_item->i_flags & PLAYLIST_DBL_FLAG )
540 lplvcd->clrText = RGB(192,192,192);
542 pl_Release( p_intf );
546 pl_Release( p_intf );
549 return CDRF_DODEFAULT;
552 /**********************************************************************
553 * Handles the display of the "floating" popup
554 **********************************************************************/
555 void Playlist::HandlePopupMenu( HWND hwnd, POINT point )
557 HMENU hMenuTrackPopup;
559 // Create the popup menu.
560 hMenuTrackPopup = CreatePopupMenu();
562 // Append some items.
563 AppendMenu( hMenuTrackPopup, MF_STRING, PopupPlay_Event, _T("Play") );
564 AppendMenu( hMenuTrackPopup, MF_STRING, PopupDel_Event, _T("Delete") );
565 AppendMenu( hMenuTrackPopup, MF_STRING, PopupEna_Event,
566 _T("Toggle enabled") );
567 AppendMenu( hMenuTrackPopup, MF_STRING, PopupInfo_Event, _T("Info") );
569 /* Draw and track the "floating" popup */
570 TrackPopupMenu( hMenuTrackPopup, 0, point.x, point.y, 0, hwnd, NULL );
572 /* Destroy the menu since were are done with it. */
573 DestroyMenu( hMenuTrackPopup );
576 /**********************************************************************
578 **********************************************************************/
579 void Playlist::ShowPlaylist( bool b_show )
581 if( b_show ) Rebuild();
585 /**********************************************************************
586 * Update the playlist
587 **********************************************************************/
588 void Playlist::UpdatePlaylist()
593 b_need_update = false;
596 playlist_t *p_playlist = pl_Hold( p_intf );
597 if( p_playlist == NULL ) return;
599 /* Update the colour of items */
602 if( p_intf->p_sys->i_playing != playlist_CurrentSize( p_playlist ) )
604 // p_playlist->i_index in RED
607 // if exists, p_intf->p_sys->i_playing in BLACK
608 p_intf->p_sys->i_playing = p_playlist->i_current_index;
612 pl_Release( p_intf );
615 /**********************************************************************
616 * Rebuild the playlist
617 **********************************************************************/
618 void Playlist::Rebuild()
620 playlist_t *p_playlist = pl_Hold( p_intf );
621 if( p_playlist == NULL ) return;
624 ListView_GetNextItem( hListView, -1, LVIS_SELECTED | LVNI_ALL );
626 /* Clear the list... */
627 ListView_DeleteAllItems( hListView );
629 /* ...and rebuild it */
631 playlist_item_t * p_root = p_playlist->p_local_onelevel;
632 playlist_item_t * p_child = NULL;
634 for( int i = 0; i < playlist_NodeChildrenCount( p_playlist, p_root ); i++ )
636 p_child = playlist_GetNextLeaf( p_playlist, p_root, p_child, FALSE, FALSE);
643 ListView_InsertItem( hListView, &lv );
644 ListView_SetItemText( hListView, lv.iItem, 0,
645 _FROMMB(p_child->p_input->psz_name) );
647 UpdateItem( p_child->i_id );
652 ListView_SetItemState( hListView, i_focused, LVIS_FOCUSED |
653 LVIS_SELECTED, LVIS_STATEIMAGEMASK )
655 ListView_SetItemState( hListView, i_focused, LVIS_FOCUSED,
656 LVIS_STATEIMAGEMASK );
658 pl_Release( p_intf );
661 /**********************************************************************
662 * Update one playlist item
663 **********************************************************************/
664 void Playlist::UpdateItem( int i )
666 playlist_t *p_playlist = pl_Hold( p_intf );
668 if( p_playlist == NULL ) return;
671 playlist_item_t *p_item = playlist_ItemGetById( p_playlist, i );
676 pl_Release( p_intf );
680 ListView_SetItemText( hListView, i, 0, _FROMMB(p_item->p_input->psz_name) );
682 ListView_SetItemText( hListView, i, 1,
683 _FROMMB( input_item_GetInfo( p_item->p_input,
684 _("General") , _("Author") ) ) );
686 char psz_duration[MSTRTIME_MAX_SIZE];
687 mtime_t dur = input_item_GetDuration( p_item->p_input );
690 if( dur != -1 ) secstotimestr( psz_duration, dur/1000000 );
691 else memcpy( psz_duration , "-:--:--", sizeof("-:--:--") );
693 ListView_SetItemText( hListView, i, 2, _FROMMB(psz_duration) );
695 pl_Release( p_intf );
698 /**********************************************************************
700 **********************************************************************/
701 void Playlist::DeleteItem( int item )
703 playlist_t *p_playlist = pl_Hold( p_intf );
704 if( p_playlist == NULL ) return;
706 playlist_DeleteFromInput( p_playlist, item, FALSE );
707 ListView_DeleteItem( hListView, item );
709 pl_Release( p_intf );
712 /**********************************************************************
714 **********************************************************************/
715 static void OnOpenCB( intf_dialog_args_t *p_arg )
717 intf_thread_t *p_intf = (intf_thread_t *)p_arg->p_arg;
719 if( p_arg->i_results && p_arg->psz_results[0] )
721 playlist_t * p_playlist = pl_Hold( p_intf );
725 playlist_Import( p_playlist, p_arg->psz_results[0] );
726 pl_Release( p_intf );
731 void Playlist::OnOpen()
733 char *psz_filters ="All playlists|*.pls;*.m3u;*.asx;*.b4s|M3U files|*.m3u";
735 intf_dialog_args_t *p_arg =
736 (intf_dialog_args_t *)malloc( sizeof(intf_dialog_args_t) );
737 memset( p_arg, 0, sizeof(intf_dialog_args_t) );
739 p_arg->psz_title = strdup( "Open playlist" );
740 p_arg->psz_extensions = strdup( psz_filters );
741 p_arg->p_arg = p_intf;
742 p_arg->pf_callback = OnOpenCB;
744 p_intf->p_sys->pf_show_dialog( p_intf, INTF_DIALOG_FILE_GENERIC, 0, p_arg);
747 static void OnSaveCB( intf_dialog_args_t *p_arg )
749 intf_thread_t *p_intf = (intf_thread_t *)p_arg->p_arg;
751 if( p_arg->i_results && p_arg->psz_results[0] )
753 playlist_t * p_playlist = pl_Hold( p_intf );
758 char *psz_ext = strrchr( p_arg->psz_results[0], '.' );
760 if( psz_ext && !strcmp( psz_ext, ".pls") )
761 psz_export = "export-pls";
762 else psz_export = "export-m3u";
764 playlist_Export( p_playlist, p_arg->psz_results[0], p_playlist->p_local_onelevel, psz_export );
765 pl_Release( p_intf );
770 void Playlist::OnSave()
772 char *psz_filters ="M3U file|*.m3u|PLS file|*.pls";
774 intf_dialog_args_t *p_arg =
775 (intf_dialog_args_t *)malloc( sizeof(intf_dialog_args_t) );
776 memset( p_arg, 0, sizeof(intf_dialog_args_t) );
778 p_arg->psz_title = strdup( "Save playlist" );
779 p_arg->psz_extensions = strdup( psz_filters );
780 p_arg->b_save = true;
781 p_arg->p_arg = p_intf;
782 p_arg->pf_callback = OnSaveCB;
784 p_intf->p_sys->pf_show_dialog( p_intf, INTF_DIALOG_FILE_GENERIC,
788 /**********************************************************************
789 * Selection functions
790 **********************************************************************/
791 void Playlist::OnDeleteSelection()
793 /* Delete from the end to the beginning, to avoid a shift of indices */
794 for( long item = ((int) ListView_GetItemCount( hListView ) - 1);
797 if( ListView_GetItemState( hListView, item, LVIS_SELECTED ) )
804 void Playlist::OnInvertSelection()
808 for( long item = 0; item < ListView_GetItemCount( hListView ); item++ )
810 iState = ListView_GetItemState( hListView, item, LVIS_STATEIMAGEMASK );
811 ListView_SetItemState( hListView, item, iState ^ LVIS_SELECTED,
812 LVIS_STATEIMAGEMASK );
816 void Playlist::OnEnableSelection()
818 playlist_t *p_playlist = pl_Hold( p_intf );
819 if( p_playlist == NULL ) return;
821 for( long item = ListView_GetItemCount( hListView ) - 1;
824 if( ListView_GetItemState( hListView, item, LVIS_SELECTED ) )
827 playlist_item_t *p_item = playlist_ItemGetById( p_playlist, item );
828 p_item->i_flags ^= PLAYLIST_DBL_FLAG;
833 pl_Release( p_intf );
836 void Playlist::OnDisableSelection()
838 playlist_t *p_playlist = pl_Hold( p_intf );
839 if( p_playlist == NULL ) return;
841 for( long item = ListView_GetItemCount( hListView ) - 1;
844 if( ListView_GetItemState( hListView, item, LVIS_SELECTED ) )
847 playlist_item_t *p_item = playlist_ItemGetById( p_playlist, item );
848 p_item->i_flags |= PLAYLIST_DBL_FLAG;
853 pl_Release( p_intf );
856 void Playlist::OnSelectAll()
858 for( long item = 0; item < ListView_GetItemCount( hListView ); item++ )
860 ListView_SetItemState( hListView, item, LVIS_FOCUSED | LVIS_SELECTED,
861 LVIS_STATEIMAGEMASK );
865 void Playlist::OnActivateItem( int i_item )
867 playlist_t *p_playlist = pl_Hold( p_intf );
868 if( p_playlist == NULL ) return;
870 playlist_Skip( p_playlist, i_item - p_playlist->i_current_index );
872 pl_Release( p_intf );
875 void Playlist::ShowInfos( HWND hwnd, int i_item )
877 playlist_t *p_playlist = pl_Hold( p_intf );
878 if( p_playlist == NULL ) return;
881 playlist_item_t *p_item = playlist_ItemGetById( p_playlist, i_item );
884 ItemInfoDialog *iteminfo_dialog =
885 new ItemInfoDialog( p_intf, this, hInst, p_item );
887 CreateDialogBox( hwnd, iteminfo_dialog );
888 UpdateItem( i_item );
889 delete iteminfo_dialog;
892 pl_Release( p_intf );
895 /********************************************************************
897 ********************************************************************/
898 void Playlist::OnUp()
900 playlist_t *p_playlist = pl_Hold( p_intf );
901 if( p_playlist == NULL ) return;
903 /* We use the first selected item, so find it */
905 ListView_GetNextItem( hListView, -1, LVIS_SELECTED | LVNI_ALL );
907 if( i_item > 0 && i_item < playlist_CurrentSize( p_playlist ) )
909 playlist_Prev( p_playlist );
912 ListView_SetItemState( hListView, i_item - 1, LVIS_FOCUSED,
913 LVIS_STATEIMAGEMASK );
917 ListView_SetItemState( hListView, 0, LVIS_FOCUSED,
918 LVIS_STATEIMAGEMASK );
921 pl_Release( p_intf );
926 void Playlist::OnDown()
928 playlist_t *p_playlist = pl_Hold( p_intf );
929 if( p_playlist == NULL ) return;
931 /* We use the first selected item, so find it */
933 ListView_GetNextItem( hListView, -1, LVIS_SELECTED | LVNI_ALL );
935 if( i_item >= 0 && i_item < playlist_CurrentSize( p_playlist ) - 1 )
937 playlist_Next( p_playlist );
938 ListView_SetItemState( hListView, i_item + 1, LVIS_FOCUSED,
939 LVIS_STATEIMAGEMASK );
941 pl_Release( p_intf );
946 /**********************************************************************
947 * Playlist mode functions
948 **********************************************************************/
949 void Playlist::OnRandom()
952 int bState = SendMessage( hwndTB, TB_GETSTATE, Random_Event, 0 );
953 val.b_bool = (bState & TBSTATE_CHECKED) ? true : false;
955 playlist_t *p_playlist = pl_Hold( p_intf );
956 if( p_playlist == NULL ) return;
958 var_Set( p_playlist , "random", val );
959 pl_Release( p_intf );
962 void Playlist::OnLoop ()
965 int bState = SendMessage( hwndTB, TB_GETSTATE, Loop_Event, 0 );
966 val.b_bool = (bState & TBSTATE_CHECKED) ? true : false;
968 playlist_t *p_playlist = pl_Hold( p_intf );
969 if( p_playlist == NULL ) return;
971 var_Set( p_playlist , "loop", val );
972 pl_Release( p_intf );
975 void Playlist::OnRepeat ()
978 int bState = SendMessage( hwndTB, TB_GETSTATE, Repeat_Event, 0 );
979 val.b_bool = (bState & TBSTATE_CHECKED) ? true : false;
981 playlist_t *p_playlist = pl_Hold( p_intf );
982 if( p_playlist == NULL ) return;
984 var_Set( p_playlist , "repeat", val );
985 pl_Release( p_intf );
988 /********************************************************************
990 ********************************************************************/
991 void Playlist::OnSort( UINT event )
993 playlist_t *p_playlist = pl_Hold( p_intf );
994 if( p_playlist == NULL ) return;
999 playlist_RecursiveNodeSort(p_playlist , p_playlist->p_root_onelevel,
1000 SORT_TITLE, ORDER_NORMAL);
1002 case ID_SORT_RTITLE:
1003 playlist_RecursiveNodeSort(p_playlist , p_playlist->p_root_onelevel,
1004 SORT_TITLE, ORDER_REVERSE );
1006 case ID_SORT_AUTHOR:
1007 playlist_RecursiveNodeSort(p_playlist , p_playlist->p_root_onelevel,
1008 SORT_ARTIST, ORDER_NORMAL);
1010 case ID_SORT_RAUTHOR:
1011 playlist_RecursiveNodeSort(p_playlist , p_playlist->p_root_onelevel,
1012 SORT_ARTIST, ORDER_REVERSE);
1014 case ID_SORT_SHUFFLE:
1015 playlist_RecursiveNodeSort(p_playlist , p_playlist->p_root_onelevel,
1016 SORT_RANDOM, ORDER_NORMAL);
1020 pl_Release( p_intf );
1022 b_need_update = true;
1027 void Playlist::OnColSelect( int iSubItem )
1029 playlist_t *p_playlist = pl_Hold( p_intf );
1030 if( p_playlist == NULL ) return;
1035 if( i_title_sorted != 1 )
1037 playlist_RecursiveNodeSort(p_playlist , p_playlist->p_root_onelevel,
1038 SORT_TITLE, ORDER_NORMAL);
1043 playlist_RecursiveNodeSort(p_playlist , p_playlist->p_root_onelevel,
1044 SORT_TITLE, ORDER_REVERSE );
1045 i_title_sorted = -1;
1049 if( i_author_sorted != 1 )
1051 playlist_RecursiveNodeSort(p_playlist , p_playlist->p_root_onelevel,
1052 SORT_ARTIST, ORDER_NORMAL);
1053 i_author_sorted = 1;
1057 playlist_RecursiveNodeSort(p_playlist , p_playlist->p_root_onelevel,
1058 SORT_ARTIST, ORDER_REVERSE);
1059 i_author_sorted = -1;
1066 pl_Release( p_intf );
1068 b_need_update = true;
1073 /*****************************************************************************
1074 * Popup management functions
1075 *****************************************************************************/
1076 void Playlist::OnPopupPlay()
1079 ListView_GetNextItem( hListView, -1, LVIS_SELECTED | LVNI_ALL );
1081 playlist_t *p_playlist = pl_Hold( p_intf );
1082 if( p_playlist == NULL ) return;
1084 if( i_popup_item != -1 )
1086 playlist_Skip( p_playlist, i_popup_item - p_playlist->i_current_index );
1089 pl_Release( p_intf );
1092 void Playlist::OnPopupDel()
1095 ListView_GetNextItem( hListView, -1, LVIS_SELECTED | LVNI_ALL );
1097 DeleteItem( i_popup_item );
1100 void Playlist::OnPopupEna()
1103 ListView_GetNextItem( hListView, -1, LVIS_SELECTED | LVNI_ALL );
1105 playlist_t *p_playlist = pl_Hold( p_intf );
1106 if( p_playlist == NULL ) return;
1109 playlist_item_t *p_item = playlist_ItemGetById( p_playlist, i_popup_item );
1111 if( !(p_playlist->items.p_elems[i_popup_item]->i_flags & PLAYLIST_DBL_FLAG) )
1112 //playlist_IsEnabled( p_playlist, i_popup_item ) )
1114 p_item->i_flags |= PLAYLIST_DBL_FLAG;
1118 p_item->i_flags ^= PLAYLIST_DBL_FLAG;
1122 pl_Release( p_intf );
1123 UpdateItem( i_popup_item );
1126 void Playlist::OnPopupInfo( HWND hwnd )
1129 ListView_GetNextItem( hListView, -1, LVIS_SELECTED | LVNI_ALL );
1131 ShowInfos( hwnd, i_popup_item );