📄 playlist.cpp
字号:
// Playlist.cpp : implementation file//#include "stdafx.h"#include "osmo4.h"#include "MainFrm.h"#include "OpenURL.h"#ifdef _DEBUG#define new DEBUG_NEW#undef THIS_FILEstatic char THIS_FILE[] = __FILE__;#endif/////////////////////////////////////////////////////////////////////////////// Playlist dialogPLEntry::PLEntry(CString url, char *path){ if (!path || strrchr(url, '\\') || strstr(url, "://")) { m_url = strdup(url); } else { char szPath[MAX_PATH]; strcpy(szPath, path); strcat(szPath, url); m_url = strdup(szPath); } char *str = strrchr(url, '\\'); if (!str) str = strrchr(url, '/'); if (str && strlen(str+1)) { m_disp_name = strdup(str+1); str = strrchr(m_disp_name, '.'); if (str) str[0] = 0; } else { str = strstr(url, "://"); if (str) { str += 3; m_disp_name = strdup(str); } else { m_disp_name = strdup(url); str = strrchr(m_disp_name, '.'); if (str) str[0] = 0; } } m_duration = 0; m_bIsDead = 0; m_bIsPlaying = 0; m_bIsSelected = 0;}PLEntry::~PLEntry(){ if (m_url) free(m_url); if (m_disp_name) free(m_disp_name);}static char szCacheDir[MAX_PATH];Playlist::Playlist() : CDialog(Playlist::IDD, NULL){ //{{AFX_DATA_INIT(Playlist) //}}AFX_DATA_INIT m_entries = gf_list_new(); m_cur_entry = -1; m_all_dead_entries=-1; GetCurrentDirectory(MAX_PATH, szCacheDir);}Playlist::~Playlist(){ Clear(); gf_list_del(m_entries);}void Playlist::DoDataExchange(CDataExchange* pDX){ CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(Playlist) DDX_Control(pDX, IDC_FILELIST, m_FileList); //}}AFX_DATA_MAP}BEGIN_MESSAGE_MAP(Playlist, CDialog) //{{AFX_MSG_MAP(Playlist) ON_WM_SIZE() ON_COMMAND(ID_PL_ADD_FILE, OnPlAddFile) ON_COMMAND(ID_PL_REM_FILE, OnPlRemFile) ON_COMMAND(ID_PL_UP, OnSelUp) ON_COMMAND(ID_PL_DOWN, OnSelDown) ON_COMMAND(ID_PL_SAVE, OnPlSave) ON_WM_DROPFILES() ON_WM_CLOSE() ON_WM_DESTROY() ON_COMMAND(ID_PL_REM_DEAD, OnPlRemDead) ON_COMMAND(ID_PL_REM_ALL, OnPlRemAll) ON_COMMAND(ID_PL_ADD_DIR, OnPlAddDir) ON_COMMAND(ID_PL_ADD_DIR_REC, OnPlAddDirRec) ON_COMMAND(ID_PL_ADD_URL, OnPlAddUrl) ON_COMMAND(ID_PL_OPEN, OnPlOpen) ON_COMMAND(ID_PL_PLAY, OnPlPlay) ON_COMMAND(ID_PL_SEL_REV, OnReverseSelection) ON_COMMAND(ID_PL_SORT_REV, OnReverseList) ON_COMMAND(ID_PL_RANDOM, OnRandomize) ON_COMMAND(ID_PL_SORT_TITLE, OnSortTitle) ON_COMMAND(ID_PL_SORT_FILE, OnSortFile) ON_COMMAND(ID_PL_SORT_DUR, OnSortDuration) ON_NOTIFY(NM_RCLICK, IDC_FILELIST, OnRclickFilelist) ON_NOTIFY(NM_DBLCLK, IDC_FILELIST, OnDblclkFilelist) //}}AFX_MSG_MAPEND_MESSAGE_MAP()/////////////////////////////////////////////////////////////////////////////// Playlist message handlersBOOL Playlist::OnInitDialog() { UINT buttonArray[50]; TBBUTTONINFO bi; u32 *ba; CDialog::OnInitDialog(); SetIcon(AfxGetApp()->LoadIcon(IDR_MAINFRAME), TRUE); SetIcon(AfxGetApp()->LoadIcon(IDR_MAINFRAME), FALSE); if (!m_toolBar.CreateEx(this, WS_CHILD | CBRS_TOP | CBRS_FLYBY) || !m_toolBar.LoadBitmap(IDR_PLAYLIST)) { TRACE0("Failed to create toolbar\n"); return 0; } ba = &buttonArray[0]; *ba = ID_PL_OPEN; ba++; *ba = ID_PL_SAVE; ba++; *ba = ID_SEPARATOR; ba++; *ba = ID_PL_ADD_FILE; ba++; *ba = ID_PL_REM_FILE; ba++; *ba = ID_SEPARATOR; ba++; *ba = ID_PL_UP; ba++; *ba = ID_PL_DOWN; ba++; *ba = ID_SEPARATOR; ba++; *ba = ID_PL_SORT_FILE; ba++; m_toolBar.SetButtons(buttonArray, 9); m_toolBar.SetButtonInfo(0, ID_PL_OPEN, TBBS_BUTTON, 0); m_toolBar.SetButtonInfo(1, ID_PL_SAVE, TBBS_BUTTON, 1); m_toolBar.SetButtonInfo(2, ID_SEPARATOR, TBBS_SEPARATOR, 0); m_toolBar.SetButtonInfo(3, ID_PL_ADD_FILE, TBBS_DROPDOWN | TBBS_BUTTON, 2); m_toolBar.SetButtonInfo(4, ID_PL_REM_FILE, TBBS_DROPDOWN | TBBS_BUTTON, 3); m_toolBar.SetButtonInfo(5, ID_SEPARATOR, TBBS_SEPARATOR, 0); m_toolBar.SetButtonInfo(6, ID_PL_UP, TBBS_BUTTON, 4); m_toolBar.SetButtonInfo(7, ID_PL_DOWN, TBBS_BUTTON, 5);// m_toolBar.SetButtonInfo(8, ID_SEPARATOR, TBBS_SEPARATOR, 0); m_toolBar.SetButtonInfo(8, ID_PL_SORT_FILE, TBBS_DROPDOWN | TBBS_BUTTON, 6); CToolBarCtrl &ctrl = m_toolBar.GetToolBarCtrl(); ctrl.SetStyle(TBSTYLE_FLAT | TBSTYLE_DROPDOWN); ctrl.SetExtendedStyle(TBSTYLE_EX_DRAWDDARROWS); memset(&bi, 0, sizeof(bi)); bi.cbSize = sizeof(bi); ctrl.GetButtonInfo(3, &bi); bi.fsStyle |= TBSTYLE_DROPDOWN; ctrl.SetButtonInfo(ID_PL_ADD_FILE, &bi); memset(&bi, 0, sizeof(bi)); bi.cbSize = sizeof(bi); ctrl.GetButtonInfo(4, &bi); bi.fsStyle |= TBBS_DROPDOWN | TBSTYLE_DROPDOWN; ctrl.SetButtonInfo(ID_PL_REM_FILE, &bi); memset(&bi, 0, sizeof(bi)); bi.cbSize = sizeof(bi); ctrl.GetButtonInfo(9, &bi); bi.fsStyle |= TBSTYLE_DROPDOWN; ctrl.SetButtonInfo(ID_PL_SORT_FILE, &bi); m_FileList.InsertColumn(0, "", LVCFMT_LEFT, 30, 0); m_FileList.InsertColumn(1, "Title", LVCFMT_LEFT, 200, 1); m_FileList.InsertColumn(2, "Duration", LVCFMT_LEFT, 200, 2); m_toolBar.UpdateWindow(); m_toolBar.ShowWindow(SW_SHOW); SetWindowPos(NULL, 0, 0, 400, 600, SWP_NOZORDER | SWP_NOMOVE); PostMessage(WM_NULL); DragAcceptFiles(); return TRUE; }void Playlist::OnSize(UINT nType, int cx, int cy) { u32 tool_h; CDialog::OnSize(nType, cx, cy); RECT rc; if (!m_toolBar.m_hWnd) return; if (!m_FileList.m_hWnd) return; m_toolBar.GetClientRect(&rc); tool_h = rc.bottom - rc.top; m_toolBar.SetWindowPos(this, 0, 0, cx, tool_h, SWP_NOZORDER); m_FileList.SetWindowPos(this, 0, tool_h, cx, cy-tool_h, SWP_NOZORDER); m_FileList.SetExtendedStyle(m_FileList.GetExtendedStyle() | LVS_EX_FULLROWSELECT); m_FileList.SetColumnWidth(0, 30); m_FileList.SetColumnWidth(2, 60); m_FileList.SetColumnWidth(1, cx-95); }void Playlist::OnDropFiles(HDROP hDropInfo) { u32 i, count; WinGPAC *app = GetApp(); char fileName[MAX_PATH]; count = ::DragQueryFile(hDropInfo, 0xFFFFFFFF, NULL, 0); if (!count) return; for (i=0; i<count; i++) { ::DragQueryFile (hDropInfo, i, fileName, MAX_PATH); QueueURL(fileName); } RefreshList();}BOOL Playlist::OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult) { if (((LPNMHDR)lParam)->code == TBN_DROPDOWN) { RECT rc; POINT pt; CMenu *pPopup = new CMenu(); pPopup->CreatePopupMenu(); m_toolBar.GetWindowRect(&rc); pt.y = rc.bottom; pt.x = rc.left; if ( ((LPNMTOOLBAR)lParam)->iItem == ID_PL_ADD_FILE) { pPopup->AppendMenu(MF_STRING | MF_ENABLED, ID_PL_ADD_DIR, "Directory..."); pPopup->AppendMenu(MF_STRING | MF_ENABLED, ID_PL_ADD_DIR_REC, "Directory and subfolders..."); pPopup->AppendMenu(MF_STRING | MF_ENABLED, ID_PL_ADD_URL, "URL..."); m_toolBar.GetToolBarCtrl().GetItemRect(3, &rc); pt.x += rc.left; } else if ( ((LPNMTOOLBAR)lParam)->iItem == ID_PL_REM_FILE) { pPopup->AppendMenu(MF_STRING | MF_ENABLED, ID_PL_REM_ALL, "Clear"); pPopup->AppendMenu(MF_STRING | MF_ENABLED, ID_PL_REM_DEAD, "Remove dead entries"); m_toolBar.GetToolBarCtrl().GetItemRect(4, &rc); pt.x += rc.left; } else if ( ((LPNMTOOLBAR)lParam)->iItem == ID_PL_SORT_FILE) { pPopup->AppendMenu(MF_STRING | MF_ENABLED, ID_PL_SORT_TITLE, "Sort Files by title"); pPopup->AppendMenu(MF_STRING | MF_ENABLED, ID_PL_SORT_FILE, "Sort Files by filename"); pPopup->AppendMenu(MF_STRING | MF_ENABLED, ID_PL_SORT_DUR, "Sort Files by duration"); pPopup->AppendMenu(MF_SEPARATOR,0); pPopup->AppendMenu(MF_STRING | MF_ENABLED, ID_PL_SORT_REV, "Reverse Playlist"); pPopup->AppendMenu(MF_STRING | MF_ENABLED, ID_PL_RANDOM, "Shuffle Playlist"); m_toolBar.GetToolBarCtrl().GetItemRect(8, &rc); pt.x += rc.left; } pPopup->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, pt.x, pt.y, this); delete pPopup; return FALSE; } return CDialog::OnNotify(wParam, lParam, pResult);}void Playlist::Clear(){ m_FileList.DeleteAllItems(); while (gf_list_count(m_entries)) { PLEntry *ple = (PLEntry *) gf_list_get(m_entries, 0); gf_list_rem(m_entries, 0); delete ple; } m_cur_entry = -1;}void Playlist::ClearButPlaying(){ PLEntry *p; if (m_cur_entry>=0) p = (PLEntry *) gf_list_get(m_entries, m_cur_entry); if (p) gf_list_rem(m_entries, m_cur_entry); Clear(); if (p) { gf_list_add(m_entries, p); m_cur_entry = 0; } RefreshList();}void Playlist::UpdateEntry(u32 i){ char szText[20]; PLEntry *ple = (PLEntry *) gf_list_get(m_entries, i); if (i+1<10) sprintf(szText, "00%d", i+1); else if (i+1<100) sprintf(szText, "0%d", i+1); else sprintf(szText, "%d", i+1); m_FileList.SetItem(i, 0, LVIF_TEXT, szText, 0, 0, 0, 0); CString str; if (ple->m_bIsDead) { str = "!! DEAD !! "; str += ple->m_disp_name; } else if (ple->m_bIsPlaying) { str = ">> "; str += ple->m_disp_name; str += " >>"; } else str = ple->m_disp_name; m_FileList.SetItem(i, 1, LVIF_TEXT, str, 0, 0, 0, 0); if (ple->m_duration) { u32 h = (u32) (ple->m_duration / 3600); u32 m = (u32) (ple->m_duration / 60) - h*60; u32 s = (u32) (ple->m_duration) - h*3600 - m*60; sprintf(szText, "%02d:%02d:%02d", h, m, s); m_FileList.SetItem(i, 2, LVIF_TEXT, szText, 0, 0, 0, 0); } else { m_FileList.SetItem(i, 2, LVIF_TEXT, "Unknown", 0, 0, 0, 0); }}void Playlist::RefreshList(){ u32 i, top_idx; char szPath[GF_MAX_PATH]; top_idx = m_FileList.GetTopIndex(); m_FileList.DeleteAllItems(); for (i=0; i<gf_list_count(m_entries); i++) { PLEntry *ple = (PLEntry *) gf_list_get(m_entries, i); m_FileList.InsertItem(i, ""); m_FileList.SetItemData(i, (u32) ple); UpdateEntry(i); /*in case of sorting*/ if (ple->m_bIsPlaying) m_cur_entry = i; if (ple->m_bIsSelected) { m_FileList.SetItemState(i, LVIS_SELECTED, LVIS_SELECTED); ple->m_bIsSelected = 0; } } if (m_cur_entry >= (s32)gf_list_count(m_entries)) m_cur_entry = gf_list_count(m_entries); else { s32 last_idx = top_idx + m_FileList.GetCountPerPage(); m_FileList.EnsureVisible(top_idx, 0); if (gf_list_count(m_entries)<(u32) last_idx) last_idx = gf_list_count(m_entries); m_FileList.EnsureVisible(last_idx, 1); } strcpy((char *) szPath, GetApp()->szAppPath); strcat(szPath, "gpac_pl.m3u"); Save(szPath, 1);}void Playlist::OnPlAddFile() { WinGPAC *app = GetApp(); CString sFiles = app->GetFileFilter(); CFileDialog fd(TRUE,NULL,NULL, OFN_ALLOWMULTISELECT | OFN_HIDEREADONLY | OFN_FILEMUSTEXIST , sFiles); fd.m_ofn.nMaxFile = 25000; fd.m_ofn.lpstrFile = (char *) malloc(sizeof(char) * fd.m_ofn.nMaxFile); fd.m_ofn.lpstrFile[0] = 0; if (fd.DoModal() == IDOK) { s32 cur = m_FileList.GetItemCount(); POSITION pos = fd.GetStartPosition(); while (pos) { QueueURL(fd.GetNextPathName(pos)); } } free(fd.m_ofn.lpstrFile); m_all_dead_entries=-1; RefreshList();}void Playlist::OnClose() { ShowWindow(SW_HIDE);}void Playlist::OnPlRemFile() { if (!m_FileList.GetSelectedCount()) return; POSITION pos = m_FileList.GetFirstSelectedItemPosition(); while (pos != NULL) { int nItem = m_FileList.GetNextSelectedItem(pos); PLEntry *ple = (PLEntry *) m_FileList.GetItemData(nItem); gf_list_del_item(m_entries, ple); delete ple; } m_all_dead_entries=-1; RefreshList();}void Playlist::OnSelUp() { s32 i; if (!m_FileList.GetSelectedCount()) return; POSITION pos = m_FileList.GetFirstSelectedItemPosition(); int nItem = m_FileList.GetNextSelectedItem(pos); if (nItem==0) return; pos = m_FileList.GetFirstSelectedItemPosition(); while (pos != NULL) { nItem = m_FileList.GetNextSelectedItem(pos); PLEntry *ple = (PLEntry *) m_FileList.GetItemData(nItem); i = gf_list_del_item(m_entries, ple); assert(i>=1); gf_list_insert(m_entries, ple, i-1); ple->m_bIsSelected = 1; } RefreshList();}void Playlist::OnSelDown() { s32 i, nItem; if (!m_FileList.GetSelectedCount()) return; POSITION pos = m_FileList.GetFirstSelectedItemPosition(); while (pos != NULL) nItem = m_FileList.GetNextSelectedItem(pos); if ((u32) nItem + 1 == gf_list_count(m_entries)) return; pos = m_FileList.GetFirstSelectedItemPosition(); while (pos != NULL) { nItem = m_FileList.GetNextSelectedItem(pos); PLEntry *ple = (PLEntry *) m_FileList.GetItemData(nItem); i = gf_list_del_item(m_entries, ple); gf_list_insert(m_entries, ple, i+1); ple->m_bIsSelected = 1; } RefreshList();}void Playlist::OnPlRemAll() { Clear(); RefreshList(); m_cur_entry = -1;}void Playlist::OnPlRemDead() { for (u32 i=0; i<gf_list_count(m_entries); i++) { PLEntry *ple = (PLEntry *) gf_list_get(m_entries, i); if (!ple->m_bIsDead) continue; gf_list_rem(m_entries, i); i--; delete ple; } m_all_dead_entries=-1; RefreshList();}static int CALLBACK LocCbck(HWND hwnd, UINT uMsg, LPARAM lp, LPARAM pData) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -