Main Page | Modules | Class Hierarchy | Class List | Directories | File List | Class Members | File Members | Related Pages

playlist.cpp

00001 /*****************************************************************************
00002  * playlist.cpp : WinCE gui plugin for VLC
00003  *****************************************************************************
00004  * Copyright (C) 2000-2004 the VideoLAN team
00005  * $Id: playlist.cpp 11664 2005-07-09 06:17:09Z courmisch $
00006  *
00007  * Authors: Marodon Cedric <[email protected]>
00008  *          Gildas Bazin <[email protected]>
00009  *
00010  * This program is free software; you can redistribute it and/or modify
00011  * it under the terms of the GNU General Public License as published by
00012  * the Free Software Foundation; either version 2 of the License, or
00013  * (at your option) any later version.
00014  *
00015  * This program is distributed in the hope that it will be useful,
00016  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00017  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018  * GNU General Public License for more details.
00019  *
00020  * You should have received a copy of the GNU General Public License
00021  * along with this program; if not, write to the Free Software
00022  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
00023  *****************************************************************************/
00024 
00025 /*****************************************************************************
00026  * Preamble
00027  *****************************************************************************/
00028 #include <stdlib.h>                                      /* malloc(), free() */
00029 #include <string.h>                                            /* strerror() */
00030 #include <stdio.h>
00031 #include <vlc/vlc.h>
00032 #include <vlc/intf.h>
00033 
00034 #include "wince.h"
00035 
00036 #include <commctrl.h>
00037 #include <commdlg.h>
00038 
00039 #ifndef TEXTMAXBUF
00040 #define TEXTMAXBUF 512 // at least 500
00041 #endif
00042 
00043 #define LONG2POINT(l, pt)  ((pt).x = (SHORT)LOWORD(l), (pt).y = (SHORT)HIWORD(l))
00044 
00045 #define NUMIMAGES     11   // Number of buttons in the toolbar           
00046 #define IMAGEWIDTH    16   // Width of the buttons in the toolbar  
00047 #define IMAGEHEIGHT   16   // Height of the buttons in the toolbar  
00048 #define BUTTONWIDTH   0    // Width of the button images in the toolbar
00049 #define BUTTONHEIGHT  0    // Height of the button images in the toolbar
00050 #define ID_TOOLBAR    2000 // Identifier of the main tool bar
00051 
00052 enum      
00053 {
00054   Infos_Event = 1000,
00055   Up_Event,
00056   Down_Event,
00057   Random_Event,
00058   Loop_Event,
00059   Repeat_Event,
00060   PopupPlay_Event,
00061   PopupDel_Event,
00062   PopupEna_Event,
00063   PopupInfo_Event  
00064 };
00065 
00066 // Help strings
00067 #define HELP_OPENPL _T("Open playlist")
00068 #define HELP_SAVEPL _T("Save playlist")
00069 #define HELP_ADDFILE _T("Add File")
00070 #define HELP_ADDMRL _T("Add MRL")
00071 #define HELP_DELETE _T("Delete selection")
00072 #define HELP_INFOS _T("Item info")
00073 #define HELP_UP _T("Up")
00074 #define HELP_DOWN _T("Down")
00075 #define HELP_RANDOM _T("Random")
00076 #define HELP_LOOP _T("Repeat all")
00077 #define HELP_REPEAT _T("Repeat one")
00078 
00079 // The TBBUTTON structure contains information the toolbar buttons.
00080 static TBBUTTON tbButton2[] =
00081 {
00082   {0, ID_MANAGE_OPENPL,        TBSTATE_ENABLED, TBSTYLE_BUTTON},
00083   {1, ID_MANAGE_SAVEPL,       TBSTATE_ENABLED, TBSTYLE_BUTTON},
00084   {0, 0,              TBSTATE_ENABLED, TBSTYLE_SEP},
00085   {2, ID_MANAGE_ADDFILE,       TBSTATE_ENABLED, TBSTYLE_BUTTON},
00086   {3, ID_MANAGE_ADDMRL,        TBSTATE_ENABLED, TBSTYLE_BUTTON},
00087   {4, ID_SEL_DELETE,       TBSTATE_ENABLED, TBSTYLE_BUTTON},
00088   {0, 0,              TBSTATE_ENABLED, TBSTYLE_SEP},
00089   {5, Infos_Event,      TBSTATE_ENABLED, TBSTYLE_BUTTON},
00090   {0, 0,              TBSTATE_ENABLED, TBSTYLE_SEP},
00091   {6, Up_Event,      TBSTATE_ENABLED, TBSTYLE_BUTTON},
00092   {7, Down_Event,      TBSTATE_ENABLED, TBSTYLE_BUTTON},
00093   {0, 0,              TBSTATE_ENABLED, TBSTYLE_SEP},
00094   {8, Random_Event,      TBSTATE_ENABLED, TBSTYLE_CHECK},
00095   {9, Loop_Event,       TBSTATE_ENABLED, TBSTYLE_CHECK},
00096   {10, Repeat_Event,       TBSTATE_ENABLED, TBSTYLE_CHECK}
00097 };
00098 
00099 // Toolbar ToolTips
00100 TCHAR * szToolTips2[] = 
00101 {
00102     HELP_OPENPL,
00103     HELP_SAVEPL,
00104     HELP_ADDFILE,
00105     HELP_ADDMRL,
00106     HELP_DELETE,
00107     HELP_INFOS,
00108     HELP_UP,
00109     HELP_DOWN,
00110     HELP_RANDOM,
00111     HELP_LOOP,
00112     HELP_REPEAT
00113 };
00114 
00115 /*****************************************************************************
00116  * Event Table.
00117  *****************************************************************************/
00118 
00119 /*****************************************************************************
00120  * Constructor.
00121  *****************************************************************************/
00122 Playlist::Playlist( intf_thread_t *p_intf, CBaseWindow *p_parent,
00123                     HINSTANCE h_inst )
00124   :  CBaseWindow( p_intf, p_parent, h_inst )
00125 {
00126     /* Initializations */
00127     hListView = NULL;
00128     i_title_sorted = 1;
00129     i_author_sorted = 1;
00130 
00131     b_need_update = VLC_TRUE;
00132 }
00133 
00134 /***********************************************************************
00135 FUNCTION: 
00136   CreateMenuBar
00137 
00138 PURPOSE: 
00139   Creates a menu bar.
00140 ***********************************************************************/
00141 static HWND CreateMenuBar( HWND hwnd, HINSTANCE hInst )
00142 {
00143 #ifdef UNDER_CE
00144     SHMENUBARINFO mbi;
00145     memset( &mbi, 0, sizeof(SHMENUBARINFO) );
00146     mbi.cbSize     = sizeof(SHMENUBARINFO);
00147     mbi.hwndParent = hwnd;
00148     mbi.hInstRes   = hInst;
00149     mbi.nToolBarId = IDR_MENUBAR2;
00150 
00151     if( !SHCreateMenuBar( &mbi ) )
00152     {
00153         MessageBox(hwnd, _T("SHCreateMenuBar Failed"), _T("Error"), MB_OK);
00154         return 0;
00155     }
00156 
00157     TBBUTTONINFO tbbi;
00158     tbbi.cbSize = sizeof(tbbi);
00159     tbbi.dwMask = TBIF_LPARAM;
00160 
00161     SendMessage( mbi.hwndMB, TB_GETBUTTONINFO, IDM_MANAGE, (LPARAM)&tbbi );
00162     HMENU hmenu_file = (HMENU)tbbi.lParam;
00163     RemoveMenu( hmenu_file, 0, MF_BYPOSITION );
00164     SendMessage( mbi.hwndMB, TB_GETBUTTONINFO, IDM_SORT, (LPARAM)&tbbi );
00165     HMENU hmenu_sort = (HMENU)tbbi.lParam;
00166     RemoveMenu( hmenu_sort, 0, MF_BYPOSITION );
00167     SendMessage( mbi.hwndMB, TB_GETBUTTONINFO, IDM_SEL, (LPARAM)&tbbi );
00168     HMENU hmenu_sel = (HMENU)tbbi.lParam;
00169     RemoveMenu( hmenu_sel, 0, MF_BYPOSITION );
00170 
00171 #else
00172     HMENU hmenu_file = CreatePopupMenu();
00173     HMENU hmenu_sort = CreatePopupMenu();
00174     HMENU hmenu_sel = CreatePopupMenu();
00175 #endif
00176 
00177     AppendMenu( hmenu_file, MF_STRING, ID_MANAGE_ADDFILE,
00178                 _T("&Add File...") );
00179     AppendMenu( hmenu_file, MF_STRING, ID_MANAGE_ADDDIRECTORY,
00180                 _T("Add Directory...") );
00181     AppendMenu( hmenu_file, MF_STRING, ID_MANAGE_ADDMRL,
00182                 _T("Add MRL...") );
00183     AppendMenu( hmenu_file, MF_SEPARATOR, 0, 0 );
00184     AppendMenu( hmenu_file, MF_STRING, ID_MANAGE_OPENPL,
00185                 _T("Open &Playlist") );
00186     AppendMenu( hmenu_file, MF_STRING, ID_MANAGE_SAVEPL,
00187                 _T("Save Playlist") );
00188 
00189     AppendMenu( hmenu_sort, MF_STRING, ID_SORT_TITLE,
00190                 _T("Sort by &title") );
00191     AppendMenu( hmenu_sort, MF_STRING, ID_SORT_RTITLE,
00192                 _T("&Reverse sort by title") );
00193     AppendMenu( hmenu_sort, MF_SEPARATOR, 0, 0 );
00194     AppendMenu( hmenu_sort, MF_STRING, ID_SORT_AUTHOR,
00195                 _T("Sort by &author") );
00196     AppendMenu( hmenu_sort, MF_STRING, ID_SORT_RAUTHOR,
00197                 _T("Reverse sort by &author") );
00198     AppendMenu( hmenu_sort, MF_SEPARATOR, 0, 0 );
00199     AppendMenu( hmenu_sort, MF_STRING, ID_SORT_SHUFFLE,
00200                 _T("&Shuffle Playlist") );
00201 
00202     AppendMenu( hmenu_sel, MF_STRING, ID_SEL_ENABLE,
00203                 _T("&Enable") );
00204     AppendMenu( hmenu_sel, MF_STRING, ID_SEL_DISABLE,
00205                 _T("&Disable") );
00206     AppendMenu( hmenu_sel, MF_SEPARATOR, 0, 0 );
00207     AppendMenu( hmenu_sel, MF_STRING, ID_SEL_INVERT,
00208                 _T("&Invert") );
00209     AppendMenu( hmenu_sel, MF_STRING, ID_SEL_DELETE,
00210                 _T("D&elete") );
00211     AppendMenu( hmenu_sel, MF_SEPARATOR, 0, 0 );
00212     AppendMenu( hmenu_sel, MF_STRING, ID_SEL_SELECTALL,
00213                 _T("&Select All") );
00214 
00215 
00216 #ifdef UNDER_CE
00217     return mbi.hwndMB;
00218 
00219 #else
00220     HMENU hmenu = CreateMenu();
00221 
00222     AppendMenu( hmenu, MF_POPUP|MF_STRING, (UINT)hmenu_file, _T("Manage") );
00223     AppendMenu( hmenu, MF_POPUP|MF_STRING, (UINT)hmenu_sort, _T("Sort") );
00224     AppendMenu( hmenu, MF_POPUP|MF_STRING, (UINT)hmenu_sel, _T("Selection") );
00225 
00226     SetMenu( hwnd, hmenu );
00227     return hwnd;
00228 
00229 #endif
00230 }
00231 
00232 /***********************************************************************
00233 FUNCTION: 
00234   WndProc
00235 
00236 PURPOSE: 
00237   Processes messages sent to the main window.
00238 ***********************************************************************/
00239 LRESULT Playlist::WndProc( HWND hwnd, UINT msg, WPARAM wp, LPARAM lp )
00240 {
00241     SHINITDLGINFO shidi;
00242     SHMENUBARINFO mbi;
00243     INITCOMMONCONTROLSEX iccex;
00244     RECT rect, rectTB;
00245     DWORD dwStyle;
00246 
00247     int bState;
00248     playlist_t *p_playlist;
00249 
00250     switch( msg )
00251     {
00252     case WM_INITDIALOG: 
00253         shidi.dwMask = SHIDIM_FLAGS;
00254         shidi.dwFlags = SHIDIF_DONEBUTTON | SHIDIF_SIPDOWN |
00255             SHIDIF_FULLSCREENNOMENUBAR;//SHIDIF_SIZEDLGFULLSCREEN;
00256         shidi.hDlg = hwnd;
00257         SHInitDialog( &shidi );
00258 
00259         hwndCB = CreateMenuBar( hwnd, hInst );
00260 
00261         iccex.dwSize = sizeof (INITCOMMONCONTROLSEX);
00262         iccex.dwICC = ICC_BAR_CLASSES;
00263 
00264         // Registers TOOLBAR control classes from the common control dll
00265         InitCommonControlsEx (&iccex);
00266 
00267         //  Create the toolbar control.
00268         dwStyle = WS_VISIBLE | WS_CHILD | TBSTYLE_TOOLTIPS |
00269             WS_EX_OVERLAPPEDWINDOW | CCS_NOPARENTALIGN;
00270 
00271         hwndTB = CreateToolbarEx( hwnd, dwStyle, 0, NUMIMAGES,
00272                                   hInst, IDB_BITMAP3, tbButton2,
00273                                   sizeof (tbButton2) / sizeof (TBBUTTON),
00274                                   BUTTONWIDTH, BUTTONHEIGHT,
00275                                   IMAGEWIDTH, IMAGEHEIGHT, sizeof(TBBUTTON) );
00276         if( !hwndTB ) break;
00277   
00278         // Add ToolTips to the toolbar.
00279         SendMessage( hwndTB, TB_SETTOOLTIPS, (WPARAM) NUMIMAGES,
00280                      (LPARAM)szToolTips2 );
00281 
00282         // Reposition the toolbar.
00283         GetClientRect( hwnd, &rect );
00284         GetWindowRect( hwndTB, &rectTB );
00285         MoveWindow( hwndTB, rect.left, rect.top - 2, rect.right - rect.left, 
00286                     MENU_HEIGHT /*rectTB.bottom - rectTB.top */, TRUE);
00287 
00288         // random, loop, repeat buttons states
00289         vlc_value_t val; 
00290         p_playlist = (playlist_t *)
00291             vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
00292         if( !p_playlist ) break;
00293 
00294         var_Get( p_playlist , "random", &val );
00295         bState = val.b_bool ? TBSTATE_CHECKED : 0;
00296         SendMessage( hwndTB, TB_SETSTATE, Random_Event,
00297                      MAKELONG(bState | TBSTATE_ENABLED, 0) );
00298         var_Get( p_playlist , "loop", &val );
00299         bState = val.b_bool ? TBSTATE_CHECKED : 0;
00300         SendMessage( hwndTB, TB_SETSTATE, Loop_Event,
00301                      MAKELONG(bState | TBSTATE_ENABLED, 0) );
00302         var_Get( p_playlist , "repeat", &val );
00303         bState = val.b_bool ? TBSTATE_CHECKED : 0;
00304         SendMessage( hwndTB, TB_SETSTATE, Repeat_Event,
00305                      MAKELONG(bState | TBSTATE_ENABLED, 0) );
00306         vlc_object_release( p_playlist );
00307 
00308         GetClientRect( hwnd, &rect );
00309         hListView = CreateWindow( WC_LISTVIEW, NULL, WS_VISIBLE | WS_CHILD |
00310             LVS_REPORT | LVS_SHOWSELALWAYS | WS_VSCROLL | WS_HSCROLL,
00311             rect.left, rect.top + 2*(MENU_HEIGHT+1), rect.right - rect.left, 
00312             rect.bottom - ( rect.top + 2*MENU_HEIGHT) - MENU_HEIGHT, 
00313             hwnd, NULL, hInst, NULL );
00314         ListView_SetExtendedListViewStyle( hListView, LVS_EX_FULLROWSELECT );
00315 
00316         LVCOLUMN lv;
00317         lv.mask = LVCF_WIDTH | LVCF_FMT | LVCF_TEXT;
00318         lv.fmt = LVCFMT_LEFT ;
00319         GetClientRect( hwnd, &rect );
00320         lv.cx = 120;
00321         lv.pszText = _T("Name");
00322         lv.cchTextMax = 9;
00323         ListView_InsertColumn( hListView, 0, &lv);
00324         lv.cx = 55;
00325         lv.pszText = _T("Author");
00326         lv.cchTextMax = 9;
00327         ListView_InsertColumn( hListView, 1, &lv);
00328         lv.cx = rect.right - rect.left - 180;
00329         lv.pszText = _T("Duration");
00330         lv.cchTextMax = 9;
00331         ListView_InsertColumn( hListView, 2, &lv);
00332 
00333         SetTimer( hwnd, 1, 500 /*milliseconds*/, NULL );
00334         break;
00335 
00336     case WM_TIMER:
00337         UpdatePlaylist();
00338         break;
00339 
00340     case WM_CLOSE:
00341         EndDialog( hwnd, LOWORD( wp ) );
00342         break;
00343 
00344     case WM_SETFOCUS:
00345         SHSipPreference( hwnd, SIP_DOWN ); 
00346         SHFullScreen( hwnd, SHFS_HIDESIPBUTTON );
00347         break;
00348 
00349     case WM_COMMAND:    
00350         switch( LOWORD(wp) )
00351         {
00352         case IDOK:
00353             EndDialog( hwnd, LOWORD( wp ) );
00354             break;
00355 
00356         case ID_MANAGE_OPENPL:
00357             OnOpen();
00358             b_need_update = VLC_TRUE;
00359             break;
00360 
00361         case ID_MANAGE_SAVEPL:
00362             OnSave();
00363             break;
00364 
00365         case ID_MANAGE_ADDFILE:
00366             p_intf->p_sys->pf_show_dialog( p_intf, INTF_DIALOG_FILE_SIMPLE,
00367                                            0, 0 );
00368             b_need_update = VLC_TRUE;
00369             break;
00370 
00371         case ID_MANAGE_ADDDIRECTORY:
00372             p_intf->p_sys->pf_show_dialog( p_intf, INTF_DIALOG_DIRECTORY,
00373                                            0, 0 );
00374             b_need_update = VLC_TRUE;
00375             break;
00376 
00377         case ID_MANAGE_ADDMRL:
00378             p_intf->p_sys->pf_show_dialog( p_intf, INTF_DIALOG_FILE, 0, 0 );
00379             b_need_update = VLC_TRUE;
00380             break;
00381 
00382         case ID_SEL_DELETE:
00383             OnDeleteSelection();
00384             b_need_update = VLC_TRUE;
00385             break;
00386 
00387         case Infos_Event:
00388             OnPopupInfo( hwnd );
00389             b_need_update = VLC_TRUE;
00390             break;
00391 
00392         case Up_Event:
00393             OnUp();
00394             b_need_update = VLC_TRUE;
00395             break;
00396 
00397         case Down_Event:
00398             OnDown();
00399             b_need_update = VLC_TRUE;
00400             break;
00401 
00402         case Random_Event:
00403             OnRandom();
00404             break;
00405 
00406         case Loop_Event:
00407             OnLoop();
00408             break;
00409 
00410         case Repeat_Event:
00411             OnRepeat();
00412             break;
00413 
00414         case ID_SORT_TITLE:
00415             OnSort( ID_SORT_TITLE );
00416             break;
00417 
00418         case ID_SORT_RTITLE:
00419             OnSort( ID_SORT_RTITLE );
00420             break;
00421 
00422         case ID_SORT_AUTHOR:
00423             OnSort( ID_SORT_AUTHOR );
00424             break;
00425 
00426         case ID_SORT_RAUTHOR:
00427             OnSort( ID_SORT_RAUTHOR );
00428             break;
00429 
00430         case ID_SORT_SHUFFLE:
00431             OnSort( ID_SORT_SHUFFLE );
00432             break;
00433 
00434         case ID_SEL_ENABLE:
00435             OnEnableSelection();
00436             break;
00437 
00438         case ID_SEL_DISABLE:
00439             OnDisableSelection();
00440             break;
00441 
00442         case ID_SEL_INVERT:
00443             OnInvertSelection();
00444             break;
00445 
00446         case ID_SEL_SELECTALL:
00447             OnSelectAll();
00448             break;
00449 
00450         case PopupPlay_Event:
00451             OnPopupPlay();
00452             b_need_update = VLC_TRUE;
00453             break;
00454 
00455         case PopupDel_Event:
00456             OnPopupDel();
00457             b_need_update = VLC_TRUE;
00458             break;
00459 
00460         case PopupEna_Event:
00461             OnPopupEna();
00462             b_need_update = VLC_TRUE;
00463             break;
00464 
00465         case PopupInfo_Event:
00466             OnPopupInfo( hwnd );
00467             b_need_update = VLC_TRUE;
00468             break;
00469 
00470         default:
00471             break;
00472         }
00473         break;
00474 
00475     case WM_NOTIFY:
00476         if( ( ((LPNMHDR)lp)->hwndFrom == hListView ) &&
00477             ( ((LPNMHDR)lp)->code == NM_CUSTOMDRAW ) )
00478         {
00479             SetWindowLong( hwnd, DWL_MSGRESULT,
00480                            (LONG)ProcessCustomDraw(lp) );
00481         }
00482         else if( ( ((LPNMHDR)lp)->hwndFrom == hListView ) &&
00483                  ( ((LPNMHDR)lp)->code == GN_CONTEXTMENU  ) )
00484         {                       
00485             HandlePopupMenu( hwnd, ((PNMRGINFO)lp)->ptAction );
00486         }
00487         else if( ( ((LPNMHDR)lp)->hwndFrom == hListView ) &&
00488                  ( ((LPNMHDR)lp)->code == LVN_COLUMNCLICK  ) )
00489         {
00490             OnColSelect( ((LPNMLISTVIEW)lp)->iSubItem );
00491         }
00492         else if( ( ((LPNMHDR)lp)->hwndFrom == hListView ) &&
00493                  ( ((LPNMHDR)lp)->code == LVN_ITEMACTIVATE  ) )
00494         {
00495             OnActivateItem( ((LPNMLISTVIEW)lp)->iSubItem );
00496         }
00497         break;
00498 
00499     default:
00500          // the message was not processed
00501          // indicate if the base class handled it
00502         break;
00503     }
00504 
00505     return FALSE;
00506 }
00507 
00508 LRESULT Playlist::ProcessCustomDraw( LPARAM lParam )
00509 {
00510     LPNMLVCUSTOMDRAW lplvcd = (LPNMLVCUSTOMDRAW)lParam;
00511 
00512     switch( lplvcd->nmcd.dwDrawStage )
00513     {
00514     case CDDS_PREPAINT : //Before the paint cycle begins
00515         //request notifications for individual listview items
00516         return CDRF_NOTIFYITEMDRAW;
00517 
00518     case CDDS_ITEMPREPAINT: //Before an item is drawn
00519         playlist_t *p_playlist = (playlist_t *)
00520             vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
00521         if( p_playlist == NULL ) return CDRF_DODEFAULT;
00522         if( (int)lplvcd->nmcd.dwItemSpec == p_playlist->i_index )
00523         {
00524             lplvcd->clrText = RGB(255,0,0);
00525             vlc_object_release(p_playlist);
00526             return CDRF_NEWFONT;
00527         }
00528         
00529         playlist_item_t *p_item = playlist_ItemGetByPos( p_playlist,
00530                                         (int)lplvcd->nmcd.dwItemSpec );
00531         if( !p_item )
00532         {
00533             vlc_object_release(p_playlist);
00534             return CDRF_DODEFAULT;
00535         }
00536         if( p_item->b_enabled == VLC_FALSE )
00537         {
00538             lplvcd->clrText = RGB(192,192,192);
00539             vlc_object_release(p_playlist);
00540             return CDRF_NEWFONT;
00541         }
00542     }
00543 
00544     return CDRF_DODEFAULT;
00545 }
00546 
00547 /**********************************************************************
00548  * Handles the display of the "floating" popup
00549  **********************************************************************/
00550 void Playlist::HandlePopupMenu( HWND hwnd, POINT point )
00551 {
00552     HMENU hMenuTrackPopup;
00553 
00554     // Create the popup menu.
00555     hMenuTrackPopup = CreatePopupMenu();
00556 
00557     // Append some items.
00558     AppendMenu( hMenuTrackPopup, MF_STRING, PopupPlay_Event, _T("Play") );
00559     AppendMenu( hMenuTrackPopup, MF_STRING, PopupDel_Event, _T("Delete") );
00560     AppendMenu( hMenuTrackPopup, MF_STRING, PopupEna_Event,
00561                 _T("Toggle enabled") );
00562     AppendMenu( hMenuTrackPopup, MF_STRING, PopupInfo_Event, _T("Info") );
00563 
00564     /* Draw and track the "floating" popup */
00565     TrackPopupMenu( hMenuTrackPopup, 0, point.x, point.y, 0, hwnd, NULL );
00566 
00567     /* Destroy the menu since were are done with it. */
00568     DestroyMenu( hMenuTrackPopup );
00569 }
00570 
00571 /**********************************************************************
00572  * Show the playlist
00573  **********************************************************************/
00574 void Playlist::ShowPlaylist( bool b_show )
00575 {
00576     if( b_show ) Rebuild();
00577     Show( b_show );
00578 }
00579 
00580 /**********************************************************************
00581  * Update the playlist
00582  **********************************************************************/
00583 void Playlist::UpdatePlaylist()
00584 {
00585     if( b_need_update )
00586     {
00587         Rebuild();
00588         b_need_update = VLC_FALSE;
00589     }
00590         
00591     playlist_t *p_playlist = (playlist_t *)
00592         vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
00593     if( p_playlist == NULL ) return;
00594         
00595     /* Update the colour of items */
00596 
00597     vlc_mutex_lock( &p_playlist->object_lock );
00598     if( p_intf->p_sys->i_playing != p_playlist->i_index )
00599     {
00600         // p_playlist->i_index in RED
00601         Rebuild();
00602 
00603         // if exists, p_intf->p_sys->i_playing in BLACK
00604         p_intf->p_sys->i_playing = p_playlist->i_index;
00605     }
00606     vlc_mutex_unlock( &p_playlist->object_lock );
00607 
00608     vlc_object_release( p_playlist );
00609 }
00610 
00611 /**********************************************************************
00612  * Rebuild the playlist
00613  **********************************************************************/
00614 void Playlist::Rebuild()
00615 {
00616     playlist_t *p_playlist = (playlist_t *)
00617         vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
00618     if( p_playlist == NULL ) return;
00619 
00620     int i_focused =
00621         ListView_GetNextItem( hListView, -1, LVIS_SELECTED | LVNI_ALL );
00622 
00623     /* Clear the list... */
00624     ListView_DeleteAllItems( hListView );
00625 
00626     /* ...and rebuild it */
00627     vlc_mutex_lock( &p_playlist->object_lock );
00628     for( int i = 0; i < p_playlist->i_size; i++ )
00629     {
00630         LVITEM lv;
00631         lv.mask = LVIF_TEXT;
00632         lv.pszText = _T("");
00633         lv.cchTextMax = 1;
00634         lv.iSubItem = 0;
00635         lv.iItem = i;
00636         ListView_InsertItem( hListView, &lv );
00637         ListView_SetItemText( hListView, lv.iItem, 0,
00638             _FROMMB(p_playlist->pp_items[i]->input.psz_name) );
00639         UpdateItem( i );
00640     }
00641     vlc_mutex_unlock( &p_playlist->object_lock );
00642 
00643     if ( i_focused )
00644         ListView_SetItemState( hListView, i_focused, LVIS_FOCUSED |
00645                                LVIS_SELECTED, LVIS_STATEIMAGEMASK )
00646     else
00647         ListView_SetItemState( hListView, i_focused, LVIS_FOCUSED,
00648                                LVIS_STATEIMAGEMASK );
00649 
00650     vlc_object_release( p_playlist );
00651 }
00652 
00653 /**********************************************************************
00654  * Update one playlist item
00655  **********************************************************************/
00656 void Playlist::UpdateItem( int i )
00657 {
00658     playlist_t *p_playlist = (playlist_t *)
00659         vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
00660 
00661     if( p_playlist == NULL ) return;
00662 
00663     playlist_item_t *p_item = playlist_ItemGetByPos( p_playlist, i );
00664 
00665     if( !p_item )
00666     {
00667         vlc_object_release(p_playlist);
00668         return;
00669     }
00670 
00671     ListView_SetItemText( hListView, i, 0, _FROMMB(p_item->input.psz_name) );
00672     ListView_SetItemText( hListView, i, 1,
00673                           _FROMMB( vlc_input_item_GetInfo( &p_item->input,
00674                                    _("General") , _("Author") ) ) );
00675 
00676     char psz_duration[MSTRTIME_MAX_SIZE];
00677     mtime_t dur = p_item->input.i_duration;
00678     if( dur != -1 ) secstotimestr( psz_duration, dur/1000000 );
00679     else memcpy( psz_duration , "-:--:--", sizeof("-:--:--") );
00680 
00681     ListView_SetItemText( hListView, i, 3, _FROMMB(psz_duration) );
00682 
00683     vlc_object_release(p_playlist);
00684 }
00685 
00686 /**********************************************************************
00687  * Private functions
00688  **********************************************************************/
00689 void Playlist::DeleteItem( int item )
00690 {
00691     playlist_t *p_playlist = (playlist_t *)
00692         vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
00693     if( p_playlist == NULL ) return;
00694 
00695     playlist_Delete( p_playlist, item );
00696     ListView_DeleteItem( hListView, item );
00697 
00698     vlc_object_release( p_playlist );
00699 }
00700 
00701 /**********************************************************************
00702  * I/O functions
00703  **********************************************************************/
00704 static void OnOpenCB( intf_dialog_args_t *p_arg )
00705 {
00706     intf_thread_t *p_intf = (intf_thread_t *)p_arg->p_arg;
00707 
00708     if( p_arg->i_results && p_arg->psz_results[0] )
00709     {
00710         playlist_t * p_playlist = (playlist_t *)
00711             vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
00712 
00713         if( p_playlist )
00714         {
00715             playlist_Import( p_playlist, p_arg->psz_results[0] );
00716         }
00717 
00718         if( p_playlist ) vlc_object_release( p_playlist );
00719     }
00720 }
00721 
00722 void Playlist::OnOpen()
00723 {
00724     char *psz_filters ="All playlists|*.pls;*.m3u;*.asx;*.b4s|M3U files|*.m3u";
00725 
00726     intf_dialog_args_t *p_arg =
00727         (intf_dialog_args_t *)malloc( sizeof(intf_dialog_args_t) );
00728     memset( p_arg, 0, sizeof(intf_dialog_args_t) );
00729 
00730     p_arg->psz_title = strdup( "Open playlist" );
00731     p_arg->psz_extensions = strdup( psz_filters );
00732     p_arg->p_arg = p_intf;
00733     p_arg->pf_callback = OnOpenCB;
00734 
00735     p_intf->p_sys->pf_show_dialog( p_intf, INTF_DIALOG_FILE_GENERIC, 0, p_arg);
00736 }
00737 
00738 static void OnSaveCB( intf_dialog_args_t *p_arg )
00739 {
00740     intf_thread_t *p_intf = (intf_thread_t *)p_arg->p_arg;
00741 
00742     if( p_arg->i_results && p_arg->psz_results[0] )
00743     {
00744         playlist_t * p_playlist = (playlist_t *)
00745             vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
00746 
00747         if( p_playlist )
00748         {
00749             char *psz_export;
00750             char *psz_ext = strrchr( p_arg->psz_results[0], '.' );
00751 
00752             if( psz_ext && !strcmp( psz_ext, ".pls") )
00753                 psz_export = "export-pls";
00754             else psz_export = "export-m3u";
00755 
00756             playlist_Export( p_playlist, p_arg->psz_results[0], psz_export );
00757         }
00758 
00759         if( p_playlist ) vlc_object_release( p_playlist );
00760     }
00761 }
00762 
00763 void Playlist::OnSave()
00764 {
00765     char *psz_filters ="M3U file|*.m3u|PLS file|*.pls";
00766 
00767     intf_dialog_args_t *p_arg =
00768         (intf_dialog_args_t *)malloc( sizeof(intf_dialog_args_t) );
00769     memset( p_arg, 0, sizeof(intf_dialog_args_t) );
00770 
00771     p_arg->psz_title = strdup( "Save playlist" );
00772     p_arg->psz_extensions = strdup( psz_filters );
00773     p_arg->b_save = VLC_TRUE;
00774     p_arg->p_arg = p_intf;
00775     p_arg->pf_callback = OnSaveCB;
00776 
00777     p_intf->p_sys->pf_show_dialog( p_intf, INTF_DIALOG_FILE_GENERIC,
00778                                    0, p_arg );
00779 }
00780 
00781 /**********************************************************************
00782  * Selection functions
00783  **********************************************************************/
00784 void Playlist::OnDeleteSelection()
00785 {
00786     /* Delete from the end to the beginning, to avoid a shift of indices */
00787     for( long item = ((int) ListView_GetItemCount( hListView ) - 1);
00788          item >= 0; item-- )
00789     {
00790         if( ListView_GetItemState( hListView, item, LVIS_SELECTED ) )
00791         {
00792             DeleteItem( item );
00793         }
00794     }
00795 }
00796 
00797 void Playlist::OnInvertSelection()
00798 {
00799     UINT iState;
00800 
00801     for( long item = 0; item < ListView_GetItemCount( hListView ); item++ )
00802     {
00803         iState = ListView_GetItemState( hListView, item, LVIS_STATEIMAGEMASK );
00804         ListView_SetItemState( hListView, item, iState ^ LVIS_SELECTED,
00805                                LVIS_STATEIMAGEMASK );
00806     }
00807 }
00808 
00809 void Playlist::OnEnableSelection()
00810 {
00811     playlist_t *p_playlist = (playlist_t *)
00812         vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
00813     if( p_playlist == NULL ) return;
00814 
00815     for( long item = ListView_GetItemCount( hListView ) - 1;
00816          item >= 0; item-- )
00817     {
00818         if( ListView_GetItemState( hListView, item, LVIS_SELECTED ) )
00819         {
00820             playlist_item_t *p_item =
00821                 playlist_ItemGetByPos( p_playlist, item );
00822             playlist_Enable( p_playlist, p_item );
00823             UpdateItem( item );
00824         }
00825     }
00826     vlc_object_release( p_playlist);
00827 }
00828 
00829 void Playlist::OnDisableSelection()
00830 {
00831     playlist_t *p_playlist = (playlist_t *)
00832         vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
00833     if( p_playlist == NULL ) return;
00834 
00835     for( long item = ListView_GetItemCount( hListView ) - 1;
00836          item >= 0; item-- )
00837     {
00838         if( ListView_GetItemState( hListView, item, LVIS_SELECTED ) )
00839         {
00840             /*XXX*/
00841             playlist_item_t *p_item =
00842                 playlist_ItemGetByPos( p_playlist, item );
00843             playlist_Disable( p_playlist, p_item );
00844             UpdateItem( item );
00845         }
00846     }
00847     vlc_object_release( p_playlist);
00848 }
00849 
00850 void Playlist::OnSelectAll()
00851 {
00852     for( long item = 0; item < ListView_GetItemCount( hListView ); item++ )
00853     {
00854         ListView_SetItemState( hListView, item, LVIS_FOCUSED | LVIS_SELECTED,
00855                                LVIS_STATEIMAGEMASK );
00856     }
00857 }
00858 
00859 void Playlist::OnActivateItem( int i_item )
00860 {
00861     playlist_t *p_playlist = (playlist_t *)
00862         vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
00863     if( p_playlist == NULL ) return;
00864 
00865     playlist_Goto( p_playlist, i_item );
00866 
00867     vlc_object_release( p_playlist );
00868 }
00869 
00870 void Playlist::ShowInfos( HWND hwnd, int i_item )
00871 {
00872     playlist_t *p_playlist = (playlist_t *)
00873         vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
00874     if( p_playlist == NULL ) return;
00875 
00876     vlc_mutex_lock( &p_playlist->object_lock);
00877     playlist_item_t *p_item = playlist_ItemGetByPos( p_playlist, i_item );
00878     vlc_mutex_unlock( &p_playlist->object_lock );
00879 
00880     if( p_item )
00881     {
00882         ItemInfoDialog *iteminfo_dialog =
00883             new ItemInfoDialog( p_intf, this, hInst, p_item );
00884         CreateDialogBox( hwnd, iteminfo_dialog );                
00885         UpdateItem( i_item );
00886         delete iteminfo_dialog;
00887     }
00888 
00889     vlc_object_release( p_playlist );
00890 }
00891 
00892 /********************************************************************
00893  * Move functions
00894  ********************************************************************/
00895 void Playlist::OnUp()
00896 {
00897     playlist_t *p_playlist = (playlist_t *)
00898         vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
00899     if( p_playlist == NULL ) return;
00900 
00901     /* We use the first selected item, so find it */
00902     long i_item =
00903         ListView_GetNextItem( hListView, -1, LVIS_SELECTED | LVNI_ALL );
00904 
00905     if( i_item > 0 && i_item < p_playlist->i_size )
00906     {
00907         playlist_Move( p_playlist , i_item, i_item - 1);
00908         if( i_item > 1 )
00909         {
00910             ListView_SetItemState( hListView, i_item - 1, LVIS_FOCUSED,
00911                                    LVIS_STATEIMAGEMASK );
00912         }
00913         else
00914         {
00915             ListView_SetItemState( hListView, 0, LVIS_FOCUSED,
00916                                    LVIS_STATEIMAGEMASK );
00917         }
00918     }
00919     vlc_object_release( p_playlist );
00920 
00921     return;
00922 }
00923 
00924 void Playlist::OnDown()
00925 {
00926     playlist_t *p_playlist = (playlist_t *)
00927         vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
00928     if( p_playlist == NULL ) return;
00929 
00930     /* We use the first selected item, so find it */
00931     long i_item =
00932         ListView_GetNextItem( hListView, -1, LVIS_SELECTED | LVNI_ALL );
00933 
00934     if( i_item >= 0 && i_item < p_playlist->i_size - 1 )
00935     {
00936         playlist_Move( p_playlist , i_item, i_item + 2 );
00937         ListView_SetItemState( hListView, i_item + 1, LVIS_FOCUSED,
00938                                LVIS_STATEIMAGEMASK );
00939     }
00940     vlc_object_release( p_playlist );
00941 
00942     return;
00943 }
00944 
00945 /**********************************************************************
00946  * Playlist mode functions
00947  **********************************************************************/
00948 void Playlist::OnRandom()
00949 {
00950     vlc_value_t val;
00951     int bState = SendMessage( hwndTB, TB_GETSTATE, Random_Event, 0 ); 
00952     val.b_bool = (bState & TBSTATE_CHECKED) ? VLC_TRUE : VLC_FALSE;
00953 
00954     playlist_t *p_playlist = (playlist_t *)
00955         vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
00956     if( p_playlist == NULL ) return;
00957 
00958     var_Set( p_playlist , "random", val );
00959     vlc_object_release( p_playlist );
00960 }
00961 
00962 void Playlist::OnLoop ()
00963 {
00964     vlc_value_t val;
00965     int bState = SendMessage( hwndTB, TB_GETSTATE, Loop_Event, 0 ); 
00966     val.b_bool = (bState & TBSTATE_CHECKED) ? VLC_TRUE : VLC_FALSE;
00967 
00968     playlist_t *p_playlist = (playlist_t *)
00969         vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
00970     if( p_playlist == NULL ) return;
00971 
00972     var_Set( p_playlist , "loop", val );
00973     vlc_object_release( p_playlist );
00974 }
00975 
00976 void Playlist::OnRepeat ()
00977 {
00978     vlc_value_t val;
00979     int bState = SendMessage( hwndTB, TB_GETSTATE, Repeat_Event, 0 );  
00980     val.b_bool = (bState & TBSTATE_CHECKED) ? VLC_TRUE : VLC_FALSE;
00981 
00982     playlist_t *p_playlist = (playlist_t *)
00983         vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
00984     if( p_playlist == NULL ) return;
00985 
00986     var_Set( p_playlist , "repeat", val );
00987     vlc_object_release( p_playlist );
00988 }
00989 
00990 /********************************************************************
00991  * Sorting functions
00992  ********************************************************************/
00993 void Playlist::OnSort( UINT event )
00994 {
00995     playlist_t *p_playlist = (playlist_t *)
00996         vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
00997     if( p_playlist == NULL ) return;
00998 
00999     switch( event )
01000     {
01001     case ID_SORT_TITLE:
01002         playlist_SortTitle( p_playlist , ORDER_NORMAL );
01003         break;
01004     case ID_SORT_RTITLE:
01005         playlist_SortTitle( p_playlist , ORDER_REVERSE );
01006         break;
01007     case ID_SORT_AUTHOR:
01008         playlist_SortAuthor(p_playlist , ORDER_NORMAL );
01009         break;
01010     case ID_SORT_RAUTHOR:
01011         playlist_SortAuthor( p_playlist , ORDER_REVERSE );
01012         break;
01013     case ID_SORT_SHUFFLE:
01014         playlist_Sort( p_playlist , SORT_RANDOM, ORDER_NORMAL );
01015         break;
01016     }
01017 
01018     vlc_object_release( p_playlist );
01019 
01020     b_need_update = VLC_TRUE;
01021 
01022     return;
01023 }
01024 
01025 void Playlist::OnColSelect( int iSubItem )
01026 {
01027     playlist_t *p_playlist = (playlist_t *)
01028         vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
01029     if( p_playlist == NULL ) return;
01030 
01031     switch( iSubItem )
01032     {
01033     case 0:
01034         if( i_title_sorted != 1 )
01035         {
01036             playlist_SortTitle( p_playlist, ORDER_NORMAL );
01037             i_title_sorted = 1;
01038         }
01039         else
01040         {
01041             playlist_SortTitle( p_playlist, ORDER_REVERSE );
01042             i_title_sorted = -1;
01043         }
01044         break;
01045     case 1:
01046         if( i_author_sorted != 1 )
01047         {
01048             playlist_SortAuthor( p_playlist, ORDER_NORMAL );
01049             i_author_sorted = 1;
01050         }
01051         else
01052         {
01053             playlist_SortAuthor( p_playlist, ORDER_REVERSE );
01054             i_author_sorted = -1;
01055         }
01056         break;
01057     default:
01058         break;
01059     }
01060 
01061     vlc_object_release( p_playlist );
01062 
01063     b_need_update = VLC_TRUE;
01064 
01065     return;
01066 }
01067 
01068 /*****************************************************************************
01069  * Popup management functions
01070  *****************************************************************************/
01071 void Playlist::OnPopupPlay()
01072 {
01073     int i_popup_item =
01074         ListView_GetNextItem( hListView, -1, LVIS_SELECTED | LVNI_ALL );
01075 
01076     playlist_t *p_playlist = (playlist_t *)
01077         vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
01078     if( p_playlist == NULL ) return;
01079 
01080     if( i_popup_item != -1 )
01081     {
01082         playlist_Goto( p_playlist, i_popup_item );
01083     }
01084 
01085     vlc_object_release( p_playlist );
01086 }
01087 
01088 void Playlist::OnPopupDel()
01089 {
01090     int i_popup_item =
01091         ListView_GetNextItem( hListView, -1, LVIS_SELECTED | LVNI_ALL );
01092 
01093     DeleteItem( i_popup_item );
01094 }
01095 
01096 void Playlist::OnPopupEna()
01097 {
01098     int i_popup_item =
01099         ListView_GetNextItem( hListView, -1, LVIS_SELECTED | LVNI_ALL );
01100 
01101     playlist_t *p_playlist = (playlist_t *)
01102         vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
01103     if( p_playlist == NULL ) return;
01104 
01105     playlist_item_t *p_item =
01106         playlist_ItemGetByPos( p_playlist, i_popup_item );
01107 
01108     if( p_playlist->pp_items[i_popup_item]->b_enabled )
01109         //playlist_IsEnabled( p_playlist, i_popup_item ) )
01110     {
01111         playlist_Disable( p_playlist, p_item );
01112     }
01113     else
01114     {
01115         playlist_Enable( p_playlist, p_item );
01116     }
01117 
01118     vlc_object_release( p_playlist);
01119     UpdateItem( i_popup_item );
01120 }
01121 
01122 void Playlist::OnPopupInfo( HWND hwnd )
01123 {
01124     int i_popup_item =
01125         ListView_GetNextItem( hListView, -1, LVIS_SELECTED | LVNI_ALL );
01126 
01127     ShowInfos( hwnd, i_popup_item );
01128 }

Generated on Tue Dec 20 10:14:43 2005 for vlc-0.8.4a by  doxygen 1.4.2