📄 playlist.cpp
字号:
char dir[MAX_PATH]; if (uMsg == BFFM_INITIALIZED) { strcpy(dir, szCacheDir); SendMessage(hwnd, BFFM_SETSELECTION, TRUE,(LPARAM) dir); } return 0;}static Bool pl_enum_dir_item(void *cbck, char *item_name, char *item_path){ WinGPAC *gpac = GetApp(); Playlist *_this = (Playlist *)cbck; if (gf_term_is_supported_url(gpac->m_term, item_name, 0, 1)) { _this->QueueURL(item_path); } return 0;}static Bool pl_enum_dir_dirs(void *cbck, char *item_name, char *item_path){ gf_enum_directory(item_path, 0, pl_enum_dir_item, cbck, NULL); gf_enum_directory(item_path, 1, pl_enum_dir_dirs, cbck, NULL); return 0;}void Playlist::AddDir(Bool do_recurse) { BROWSEINFO brw; LPMALLOC pMalloc; LPITEMIDLIST ret; char dir[MAX_PATH]; Bool res = 0; if (NOERROR == ::SHGetMalloc(&pMalloc) ) { memset(&brw, 0, sizeof(BROWSEINFO)); brw.hwndOwner = this->GetSafeHwnd(); brw.pszDisplayName = dir; brw.lpszTitle = "Select Directory..."; brw.ulFlags = 0L; brw.lpfn = LocCbck; ret = SHBrowseForFolder(&brw); if (ret != NULL) { if (::SHGetPathFromIDList(ret, dir)) res = 1; pMalloc->Free(ret); } pMalloc->Release(); } if (!res) return; strcpy(szCacheDir, dir); gf_enum_directory(dir, 0, pl_enum_dir_item, this, NULL); if (do_recurse) gf_enum_directory(dir, 1, pl_enum_dir_dirs, this, NULL); m_all_dead_entries=-1; RefreshList();}void Playlist::OnPlAddDir() { AddDir(0);}void Playlist::OnPlAddDirRec() { AddDir(1);}void Playlist::OnPlAddUrl() { COpenUrl url; if (url.DoModal() != IDOK) return; PLEntry *ple = new PLEntry(url.m_url); gf_list_add(m_entries, ple); m_all_dead_entries=-1; RefreshList();}void Playlist::OnPlSave() { Bool save_m3u; char szPath[GF_MAX_PATH]; if (!gf_list_count(m_entries)) return; CFileDialog fd(FALSE,NULL,NULL, OFN_OVERWRITEPROMPT, "M3U Playlists|*.m3u|ShoutCast Playlists|*.pls|"); if (fd.DoModal() != IDOK) return; strcpy(szPath, fd.GetPathName()); strlwr(szPath); save_m3u = (fd.m_ofn.nFilterIndex==1) ? 1 : 0; if (save_m3u) { if (!strstr(szPath, ".m3u")) { strcpy(szPath, fd.GetPathName()); strcat(szPath, ".m3u"); } else { strcpy(szPath, fd.GetPathName()); } } else { if (!strstr(szPath, ".pls")) { strcpy(szPath, fd.GetPathName()); strcat(szPath, ".pls"); } else { strcpy(szPath, fd.GetPathName()); } } Save(szPath, save_m3u);}void Playlist::Save(char *szPath, Bool save_m3u) { FILE *out = fopen(szPath, "wt"); if (!save_m3u) fprintf(out, "[playlist]\nNumberOfEntries=%d\n", gf_list_count(m_entries)); for (u32 i=0; i<gf_list_count(m_entries); i++) { PLEntry *ple = (PLEntry *) gf_list_get(m_entries, i); if (save_m3u) { fprintf(out, "%s\n", ple->m_url); } else { fprintf(out, "File%d=%s\n", i+1, ple->m_url); fprintf(out, "Title%d=%s\n", i+1, ple->m_disp_name); fprintf(out, "Length%d=%d\n", i+1, ple->m_duration ? ple->m_duration : -1); } } if (!save_m3u) fprintf(out, "Version=2\n"); fprintf(out, "\n"); fclose(out);}void Playlist::OnPlOpen() { CFileDialog fd(TRUE,NULL,NULL, OFN_HIDEREADONLY | OFN_FILEMUSTEXIST, "M3U & PLS Playlists|*.m3u;*.pls|M3U Playlists|*.m3u|ShoutCast Playlists|*.pls|"); if (fd.DoModal() != IDOK) return; Clear(); OpenPlayList(fd.GetPathName()); m_cur_entry = 0; Play();}void Playlist::OpenPlayList(CString fileName){ FILE *pl; PLEntry *ple; Bool load_m3u, go; char szLine[GF_MAX_PATH], *sep; char szPath[GF_MAX_PATH]; strcpy(szPath, fileName); sep = strrchr(szPath, '\\'); if (sep) sep[1] = 0; else szPath[0] = 0; pl = fopen(fileName, "rt"); if (!pl) return; ple = NULL; load_m3u = 1; while (!feof(pl)) { fgets(szLine, GF_MAX_PATH, pl); go = 1; while (go) { switch (szLine[strlen(szLine)-1]) { case '\n': case '\r': case ' ': szLine[strlen(szLine)-1] = 0; break; default: go = 0; break; } } if (!strlen(szLine)) continue; if (!stricmp(szLine, "[playlist]")) { load_m3u = 0; } else if (load_m3u) { ple = new PLEntry(szLine, szPath); gf_list_add(m_entries, ple); } else if (!strnicmp(szLine, "file", 4)) { char *st = strchr(szLine, '='); if (!st) ple = NULL; else { ple = new PLEntry(st + 1, szPath); gf_list_add(m_entries, ple); } } else if (ple && !strnicmp(szLine, "Length", 6)) { char *st = strchr(szLine, '='); s32 d = atoi(st + 1); if (d>0) ple->m_duration = d; } else if (ple && !strnicmp(szLine, "Title", 5)) { char *st = strchr(szLine, '='); free(ple->m_disp_name); ple->m_disp_name = strdup(st + 6); } } fclose(pl); m_all_dead_entries=-1; m_cur_entry = -1; RefreshList();}void Playlist::OnRclickFilelist(NMHDR* pNMHDR, LRESULT* pResult) { if (!m_FileList.GetItemCount()) return; CMenu *pPopup = new CMenu(); pPopup->CreatePopupMenu(); if (m_FileList.GetSelectedCount()==1) { pPopup->AppendMenu(MF_STRING | MF_ENABLED, ID_PL_PLAY, "Play"); pPopup->AppendMenu(MF_SEPARATOR, 0, ""); } pPopup->AppendMenu(MF_STRING | MF_ENABLED, ID_PL_SEL_REV, "Inverse Selection"); if (m_FileList.GetSelectedCount()) pPopup->AppendMenu(MF_STRING | MF_ENABLED, ID_PL_REM_FILE, "Remove File(s)"); if (m_FileList.GetItemCount()>1) { pPopup->AppendMenu(MF_SEPARATOR, 0, ""); pPopup->AppendMenu(MF_STRING | MF_ENABLED, ID_PL_SORT_TITLE, "Sort By Title"); pPopup->AppendMenu(MF_STRING | MF_ENABLED, ID_PL_SORT_FILE, "Sort By File Name"); pPopup->AppendMenu(MF_STRING | MF_ENABLED, ID_PL_SORT_DUR, "Sort By Duration"); pPopup->AppendMenu(MF_SEPARATOR, 0, ""); pPopup->AppendMenu(MF_STRING | MF_ENABLED, ID_PL_SORT_REV, "Reverse List"); pPopup->AppendMenu(MF_STRING | MF_ENABLED, ID_PL_RANDOM, "Randomize"); } POINT pt; GetCursorPos(&pt); pPopup->TrackPopupMenu(TPM_RIGHTBUTTON, pt.x, pt.y, this); delete pPopup; *pResult = 0;}void Playlist::OnReverseSelection() { u32 i; POSITION pos = m_FileList.GetFirstSelectedItemPosition(); while (pos != NULL) { int nItem = m_FileList.GetNextSelectedItem(pos); PLEntry *ple = (PLEntry *) m_FileList.GetItemData(nItem); ple->m_bIsSelected = 1; } for (i=0; i<gf_list_count(m_entries); i++) { PLEntry *ple = (PLEntry *) gf_list_get(m_entries, i); ple->m_bIsSelected = !ple->m_bIsSelected; } RefreshList();}void Playlist::OnReverseList(){ u32 count = gf_list_count(m_entries); u32 hcount = count / 2; count--; for (u32 i=0; i<hcount; i++) { PLEntry *ple1 = (PLEntry *) gf_list_get(m_entries, i); PLEntry *ple2 = (PLEntry *) gf_list_get(m_entries, count-i); gf_list_rem(m_entries, i); gf_list_insert(m_entries, ple2, i); gf_list_rem(m_entries, count-i); gf_list_insert(m_entries, ple1, count-i); } RefreshList();}void Playlist::OnRandomize(){ GF_List *new_entries = gf_list_new(); gf_rand_init(0); while (gf_list_count(m_entries)>1) { u32 pos = gf_rand() % (gf_list_count(m_entries)-1); PLEntry *ple = (PLEntry *)gf_list_get(m_entries, pos); gf_list_rem(m_entries, pos); gf_list_add(new_entries, ple); } PLEntry *ple = (PLEntry *)gf_list_get(m_entries, 0); gf_list_rem(m_entries, 0); gf_list_add(new_entries, ple); gf_list_del(m_entries); m_entries = new_entries; m_cur_entry = -1; RefreshList();}void Playlist::Sort(u32 type){ u32 i, j, smallest; if (gf_list_count(m_entries)<=1) return; for (i=0; i<gf_list_count(m_entries)-1; i++) { smallest = i; for (j=i+1; j<gf_list_count(m_entries); j++) { PLEntry *ple2 = (PLEntry *) gf_list_get(m_entries, smallest); PLEntry *ple1 = (PLEntry *) gf_list_get(m_entries, j); s32 test = 0; switch (type) { case 0: test = stricmp(ple1->m_url, ple2->m_url); break; case 1: test = stricmp(ple1->m_disp_name, ple2->m_disp_name); break; case 2: test = ple1->m_duration - ple2->m_duration; break; } if (test<0) smallest = j; } PLEntry *ple = (PLEntry *)gf_list_get(m_entries, smallest); gf_list_rem(m_entries, smallest); gf_list_insert(m_entries, ple, i); } m_cur_entry = -1; RefreshList();}void Playlist::OnSortFile() { Sort(0); }void Playlist::OnSortTitle() { Sort(1); }void Playlist::OnSortDuration() { Sort(2); }Bool Playlist::HasValidEntries(){ u32 nb_dead = 0; if (m_all_dead_entries==-1) { for (u32 i=0; i<gf_list_count(m_entries); i++) { PLEntry *ple = (PLEntry *) gf_list_get(m_entries, i); ple->m_bIsPlaying = 0; if (ple->m_bIsDead) nb_dead ++; } m_all_dead_entries = (nb_dead==gf_list_count(m_entries)) ? 1 : 0; } if (m_all_dead_entries==1) return 0; return 1;}void Playlist::RefreshCurrent(){ if (m_cur_entry==-1) return; PLEntry *ple = (PLEntry *) gf_list_get(m_entries, m_cur_entry); if (ple && ple->m_bIsPlaying) { ple->m_bIsPlaying = 0; UpdateEntry(m_cur_entry); }}void Playlist::Play(){ PLEntry *ple; if (!HasValidEntries()) return; RefreshCurrent(); if (m_cur_entry==-1) m_cur_entry = 0; if (m_cur_entry >= (s32)gf_list_count(m_entries)) { if (!GetApp()->m_Loop) return; m_cur_entry = 0; } ple = (PLEntry *) gf_list_get(m_entries, m_cur_entry); assert(ple); if (ple->m_bIsDead) { m_cur_entry++; Play(); } else { char szPLE[20]; ple->m_bIsPlaying = 1; UpdateEntry(m_cur_entry); sprintf(szPLE, "%d", m_cur_entry); gf_cfg_set_key(GetApp()->m_user.config, "General", "PLEntry", szPLE); GetApp()->m_pMainWnd->PostMessage(WM_OPENURL); }}void Playlist::OnDblclkFilelist(NMHDR* pNMHDR, LRESULT* pResult) { POSITION pos = m_FileList.GetFirstSelectedItemPosition(); RefreshCurrent(); m_cur_entry = m_FileList.GetNextSelectedItem(pos); Play(); *pResult = 0;}void Playlist::OnPlPlay(){ POSITION pos = m_FileList.GetFirstSelectedItemPosition(); RefreshCurrent(); m_cur_entry = m_FileList.GetNextSelectedItem(pos); Play();}void Playlist::Truncate(){ while (m_cur_entry+1 < (s32)gf_list_count(m_entries)) { PLEntry *ple = (PLEntry *) gf_list_get(m_entries, m_cur_entry+1); gf_list_rem(m_entries, m_cur_entry+1); delete ple; } RefreshList();}void Playlist::QueueURL(CString filename){ char *ext = strrchr(filename, '.'); if (ext && (!stricmp(ext, ".m3u") || !stricmp(ext, ".pls")) ) { OpenPlayList(filename); } else { PLEntry *ple = new PLEntry(filename); gf_list_add(m_entries, ple); } m_all_dead_entries=-1;}void Playlist::PlayNext(){ RefreshCurrent(); if (1+m_cur_entry < (s32)gf_list_count(m_entries)) { m_cur_entry++; Play(); }}void Playlist::PlayPrev(){ RefreshCurrent(); if (m_cur_entry>0) { m_cur_entry--; Play(); }}void Playlist::SetDead(){ PLEntry *ple = (PLEntry *) gf_list_get(m_entries, m_cur_entry); if (ple) { ple->m_bIsDead = 1; UpdateEntry(m_cur_entry); m_all_dead_entries=-1; if (ple->m_bIsPlaying) PlayNext(); }}void Playlist::SetDuration(u32 duration){ PLEntry *ple = (PLEntry *) gf_list_get(m_entries, m_cur_entry); if (ple) { ple->m_duration = duration; UpdateEntry(m_cur_entry); }}CString Playlist::GetDisplayName(){ PLEntry *ple = (PLEntry *) gf_list_get(m_entries, m_cur_entry); if (ple) return CString(ple->m_disp_name); return CString("");}CString Playlist::GetURL(){ PLEntry *ple = (PLEntry *) gf_list_get(m_entries, m_cur_entry); if (ple) return CString(ple->m_url); return CString("");}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -