xref: /MusicPlayer2/MusicPlayer2/CSelectPlaylist.cpp (revision 965ce478a79b0d21e8a6e2ade0490efa175855dd)
1 // CSelectPlaylist.cpp: 实现文件
2 //
3 
4 #include "stdafx.h"
5 #include "CSelectPlaylist.h"
6 #include "MusicPlayer2.h"
7 #include "Player.h"
8 #include "Playlist.h"
9 #include "SongDataManager.h"
10 #include "MusicPlayerCmdHelper.h"
11 #include "PlaylistPropertiesDlg.h"
12 #include "CRecentList.h"
13 
14 // CSelectPlaylist 对话框
15 
IMPLEMENT_DYNAMIC(CSelectPlaylistDlg,CMediaLibTabDlg)16 IMPLEMENT_DYNAMIC(CSelectPlaylistDlg, CMediaLibTabDlg)
17 
18 CSelectPlaylistDlg::CSelectPlaylistDlg(CWnd* pParent /*=nullptr*/)
19     : CMediaLibTabDlg(IDD_SELECT_PLAYLIST_DIALOG, pParent)
20     , m_list_cache(LT_PLAYLIST)
21 {
22 
23 }
24 
~CSelectPlaylistDlg()25 CSelectPlaylistDlg::~CSelectPlaylistDlg()
26 {
27 }
28 
RefreshSongList()29 void CSelectPlaylistDlg::RefreshSongList()
30 {
31     ShowSongList();
32 }
33 
AdjustColumnWidth()34 void CSelectPlaylistDlg::AdjustColumnWidth()
35 {
36     vector<int> width;
37     CalculateColumeWidth(width);
38     for (size_t i{}; i < width.size(); i++)
39         m_playlist_ctrl.SetColumnWidth(i, width[i]);
40 }
41 
RefreshTabData()42 void CSelectPlaylistDlg::RefreshTabData()
43 {
44     ShowPathList();
45     ShowSongList();
46 }
47 
SetCurSel(const wstring & playlist_path)48 bool CSelectPlaylistDlg::SetCurSel(const wstring& playlist_path)
49 {
50     if (m_searched)
51         return true;
52     int index = m_list_cache.GetIndex(ListItem{ LT_PLAYLIST, playlist_path });
53     if (index < 0)
54         return false;
55     m_playlist_ctrl.SetCurSel(index);
56     m_playlist_ctrl.EnsureVisible(index, FALSE);
57     LeftListClicked(index);
58     return true;
59 }
60 
DoDataExchange(CDataExchange * pDX)61 void CSelectPlaylistDlg::DoDataExchange(CDataExchange* pDX)
62 {
63     CMediaLibTabDlg::DoDataExchange(pDX);
64     DDX_Control(pDX, IDC_LIST1, m_playlist_ctrl);
65     DDX_Control(pDX, IDC_SEARCH_EDIT, m_search_edit);
66     DDX_Control(pDX, IDC_SONG_LIST, m_song_list_ctrl);
67     DDX_Control(pDX, IDC_HSPLITER_STATIC, m_splitter_ctrl);
68 }
69 
70 
QuickSearch(const wstring & key_words)71 void CSelectPlaylistDlg::QuickSearch(const wstring& key_words)
72 {
73     m_search_result.clear();
74     // 此处不再跳过特殊播放列表,以其显示名称进入搜索
75     for (size_t i{}; i < m_list_cache.size(); ++i)
76         if (theApp.m_chinese_pingyin_res.IsStringMatchWithPingyin(key_words, m_list_cache.at(i).GetDisplayName()))
77             m_search_result.push_back(i);
78 }
79 
ShowSongList()80 void CSelectPlaylistDlg::ShowSongList()
81 {
82     CWaitCursor wait_cursor;
83     m_list_data.clear();
84     int highlight_item{ -1 };
85     if (LeftSelectValid())
86     {
87         const ListItem& list_item = GetSelectedPlaylist();
88         CPlaylistFile playlist_file;
89         playlist_file.LoadFromFile(list_item.path);
90         // 如果是当前播放列表则设置当前播放高亮
91         if (CRecentList::Instance().IsCurrentList(list_item))
92             highlight_item = playlist_file.GetSongIndexInPlaylist(CPlayer::GetInstance().GetCurrentSongInfo());
93         playlist_file.MoveToSongList(m_cur_song_list);
94 
95         CSongDataManager::GetInstance().LoadSongsInfo(m_cur_song_list);  // 从媒体库加载歌曲属性
96         int index{}, totla_time{};
97         for (const SongInfo& song : m_cur_song_list)
98         {
99             CListCtrlEx::RowData row_data;
100             row_data[COL_INDEX] = std::to_wstring(++index);
101             row_data[COL_TITLE] = song.GetTitle();
102             row_data[COL_ARTIST] = song.GetArtist();
103             row_data[COL_ALBUM] = song.GetAlbum();
104             std::wstring track_str;
105             if (song.track != 0)
106                 track_str = std::to_wstring(song.track);
107             row_data[COL_TRACK] = track_str;
108             row_data[COL_GENRE] = song.GetGenre();
109             row_data[COL_BITRATE] = (song.bitrate == 0 ? L"-" : std::to_wstring(song.bitrate));
110             row_data[COL_PATH] = song.file_path;
111             m_list_data.push_back(std::move(row_data));
112 
113             totla_time += song.length().toInt();
114         }
115         // 如果曲目数、总时长有变化那么重新显示左侧列表
116         if (CRecentList::Instance().SetPlaylistTotalInfo(list_item, m_cur_song_list.size(), totla_time))
117             ShowPathList();
118     }
119     m_song_list_ctrl.SetListData(&m_list_data);
120     m_song_list_ctrl.SetHightItem(highlight_item);
121     m_song_list_ctrl.EnsureVisible(highlight_item, FALSE);
122 }
123 
LeftListClicked(int index)124 void CSelectPlaylistDlg::LeftListClicked(int index)
125 {
126     m_left_selected = true;
127     m_left_selected_item = index;
128     m_right_selected_item = -1;         // 点击左侧列表时清空右侧列表选中项
129     m_right_selected_items.clear();
130     m_song_list_ctrl.SelectNone();
131     SetButtonsEnable();
132     ShowSongList();
133 }
134 
SongListClicked(int index)135 void CSelectPlaylistDlg::SongListClicked(int index)
136 {
137     m_left_selected = false;
138     m_right_selected_item = index;
139     m_song_list_ctrl.GetItemSelected(m_right_selected_items);
140     SetButtonsEnable();
141 }
142 
GetSongList() const143 const vector<SongInfo>& CSelectPlaylistDlg::GetSongList() const
144 {
145     return m_cur_song_list;
146 }
147 
GetItemSelected() const148 int CSelectPlaylistDlg::GetItemSelected() const
149 {
150     return m_right_selected_item;
151 }
152 
GetItemsSelected() const153 const vector<int>& CSelectPlaylistDlg::GetItemsSelected() const
154 {
155     return m_right_selected_items;
156 }
157 
AfterDeleteFromDisk(const std::vector<SongInfo> & files)158 void CSelectPlaylistDlg::AfterDeleteFromDisk(const std::vector<SongInfo>& files)
159 {
160     ShowSongList();
161 }
162 
GetSelectedString() const163 wstring CSelectPlaylistDlg::GetSelectedString() const
164 {
165     return m_selected_string;
166 }
167 
OnTabEntered()168 void CSelectPlaylistDlg::OnTabEntered()
169 {
170     if (m_playlist_ctrl.GetCurSel() != -1)
171         m_left_selected_item = m_playlist_ctrl.GetCurSel();     // m_left_selected_item直接存储m_playlist_ctrl的索引
172     SetButtonsEnable();
173 }
174 
InitializeControls()175 bool CSelectPlaylistDlg::InitializeControls()
176 {
177     SetDlgControlText(IDC_NEW_PLAYLIST, L"TXT_LIB_PLAYLIST_NEW_PLAYLIST");
178     SetDlgControlText(IDC_SORT_BUTTON, L"TXT_LIB_PLAYLIST_SORT");
179     // IDC_SEARCH_EDIT
180     // IDC_LIST1
181     // IDC_HSPLITER_STATIC
182     // IDC_SONG_LIST
183 
184     RepositionTextBasedControls({
185         { CtrlTextInfo::L2, IDC_NEW_PLAYLIST, CtrlTextInfo::W32 },
186         { CtrlTextInfo::L1, IDC_SORT_BUTTON, CtrlTextInfo::W32 },
187         { CtrlTextInfo::R1, IDC_SEARCH_EDIT }
188         });
189     return true;
190 }
191 
BEGIN_MESSAGE_MAP(CSelectPlaylistDlg,CMediaLibTabDlg)192 BEGIN_MESSAGE_MAP(CSelectPlaylistDlg, CMediaLibTabDlg)
193     ON_NOTIFY(NM_DBLCLK, IDC_LIST1, &CSelectPlaylistDlg::OnNMDblclkList1)
194     ON_BN_CLICKED(IDC_NEW_PLAYLIST, &CSelectPlaylistDlg::OnBnClickedNewPlaylist)
195     ON_COMMAND(ID_PLAY_PLAYLIST, &CSelectPlaylistDlg::OnPlayPlaylist)
196     ON_COMMAND(ID_RENAME_PLAYLIST, &CSelectPlaylistDlg::OnRenamePlaylist)
197     ON_COMMAND(ID_DELETE_PLAYLIST, &CSelectPlaylistDlg::OnDeletePlaylist)
198     ON_NOTIFY(NM_CLICK, IDC_LIST1, &CSelectPlaylistDlg::OnNMClickList1)
199     ON_NOTIFY(NM_RCLICK, IDC_LIST1, &CSelectPlaylistDlg::OnNMRClickList1)
200     ON_WM_INITMENU()
201     ON_COMMAND(ID_NEW_PLAYLIST, &CSelectPlaylistDlg::OnNewPlaylist)
202     ON_EN_CHANGE(IDC_SEARCH_EDIT, &CSelectPlaylistDlg::OnEnChangeSearchEdit)
203     //ON_BN_CLICKED(IDC_CLEAR_BUTTON, &CSelectPlaylistDlg::OnBnClickedClearButton)
204     ON_MESSAGE(WM_SEARCH_EDIT_BTN_CLICKED, &CSelectPlaylistDlg::OnSearchEditBtnClicked)
205     ON_NOTIFY(NM_CLICK, IDC_SONG_LIST, &CSelectPlaylistDlg::OnNMClickSongList)
206     ON_NOTIFY(NM_RCLICK, IDC_SONG_LIST, &CSelectPlaylistDlg::OnNMRClickSongList)
207     ON_NOTIFY(NM_DBLCLK, IDC_SONG_LIST, &CSelectPlaylistDlg::OnNMDblclkSongList)
208     ON_COMMAND(ID_SAVE_AS_NEW_PLAYLIST, &CSelectPlaylistDlg::OnSaveAsNewPlaylist)
209     ON_COMMAND(ID_PLAYLIST_SAVE_AS, &CSelectPlaylistDlg::OnPlaylistSaveAs)
210     ON_COMMAND(ID_PLAYLIST_FIX_PATH_ERROR, &CSelectPlaylistDlg::OnPlaylistFixPathError)
211     ON_COMMAND(ID_PLAYLIST_BROWSE_FILE, &CSelectPlaylistDlg::OnPlaylistBrowseFile)
212     ON_COMMAND(ID_REMOVE_FROM_PLAYLIST, &CSelectPlaylistDlg::OnRemoveFromPlaylist)
213     ON_BN_CLICKED(IDC_SORT_BUTTON, &CSelectPlaylistDlg::OnBnClickedSortButton)
214     ON_COMMAND(ID_LIB_PLAYLIST_SORT_RECENT_PLAYED, &CSelectPlaylistDlg::OnLibPlaylistSortRecentPlayed)
215     ON_COMMAND(ID_LIB_PLAYLIST_SORT_RECENT_CREATED, &CSelectPlaylistDlg::OnLibPlaylistSortRecentCreated)
216     ON_COMMAND(ID_LIB_PLAYLIST_SORT_NAME, &CSelectPlaylistDlg::OnLibPlaylistSortName)
217     ON_COMMAND(ID_LIB_PLAYLIST_PROPERTIES, &CSelectPlaylistDlg::OnLibPlaylistProperties)
218 END_MESSAGE_MAP()
219 
220 
221 // CSelectPlaylist 消息处理程序
222 
223 
224 BOOL CSelectPlaylistDlg::OnInitDialog()
225 {
226     CMediaLibTabDlg::OnInitDialog();
227 
228     // TODO:  在此添加额外的初始化
229 
230     SetButtonIcon(IDC_NEW_PLAYLIST, IconMgr::IconType::IT_Add);
231     SetButtonIcon(IDC_SORT_BUTTON, IconMgr::IconType::IT_Sort_Mode);
232 
233     //初始化播放列表控件
234     vector<int> width;
235     CalculateColumeWidth(width);
236     m_playlist_ctrl.SetExtendedStyle(m_playlist_ctrl.GetExtendedStyle() | LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES | LVS_EX_LABELTIP);
237     m_playlist_ctrl.InsertColumn(0, theApp.m_str_table.LoadText(L"TXT_SERIAL_NUMBER").c_str(), LVCFMT_LEFT, width[0]);
238     m_playlist_ctrl.InsertColumn(1, theApp.m_str_table.LoadText(L"TXT_PLAYLIST").c_str(), LVCFMT_LEFT, width[1]);
239     m_playlist_ctrl.InsertColumn(2, theApp.m_str_table.LoadText(L"TXT_LAST_PLAYED_TRACK").c_str(), LVCFMT_LEFT, width[2]);
240     m_playlist_ctrl.InsertColumn(3, theApp.m_str_table.LoadText(L"TXT_NUM_OF_TRACK").c_str(), LVCFMT_LEFT, width[3]);
241     m_playlist_ctrl.InsertColumn(4, theApp.m_str_table.LoadText(L"TXT_TOTAL_LENGTH").c_str(), LVCFMT_LEFT, width[4]);
242 
243     ////设置列表控件的提示总是置顶,用于解决如果弹出此窗口的父窗口具有置顶属性时,提示信息在窗口下面的问题
244     //m_playlist_ctrl.GetToolTips()->SetWindowPos(&CWnd::wndTopMost, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
245     //m_Mytip.SetWindowPos(&CWnd::wndTopMost, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
246 
247     //初始化右侧列表
248     m_song_list_ctrl.SetExtendedStyle(m_song_list_ctrl.GetExtendedStyle() | LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES | LVS_EX_LABELTIP);
249     m_song_list_ctrl.InsertColumn(COL_INDEX, theApp.m_str_table.LoadText(L"TXT_SERIAL_NUMBER").c_str(), LVCFMT_LEFT, theApp.DPI(40));
250     m_song_list_ctrl.InsertColumn(COL_TITLE, theApp.m_str_table.LoadText(L"TXT_TITLE").c_str(), LVCFMT_LEFT, theApp.DPI(150));
251     m_song_list_ctrl.InsertColumn(COL_ARTIST, theApp.m_str_table.LoadText(L"TXT_ARTIST").c_str(), LVCFMT_LEFT, theApp.DPI(100));
252     m_song_list_ctrl.InsertColumn(COL_ALBUM, theApp.m_str_table.LoadText(L"TXT_ALBUM").c_str(), LVCFMT_LEFT, theApp.DPI(150));
253     m_song_list_ctrl.InsertColumn(COL_TRACK, theApp.m_str_table.LoadText(L"TXT_TRACK_NUM").c_str(), LVCFMT_LEFT, theApp.DPI(60));
254     m_song_list_ctrl.InsertColumn(COL_GENRE, theApp.m_str_table.LoadText(L"TXT_GENRE").c_str(), LVCFMT_LEFT, theApp.DPI(100));
255     m_song_list_ctrl.InsertColumn(COL_BITRATE, theApp.m_str_table.LoadText(L"TXT_BITRATE").c_str(), LVCFMT_LEFT, theApp.DPI(60));
256     m_song_list_ctrl.InsertColumn(COL_PATH, theApp.m_str_table.LoadText(L"TXT_FILE_PATH").c_str(), LVCFMT_LEFT, theApp.DPI(600));
257     m_song_list_ctrl.SetCtrlAEnable(true);
258 
259     // ShowPathList初始化m_list_cache,需要在其他方法之前
260     ShowPathList();
261     // 初始化时选中正在播放的播放列表
262     m_playlist_ctrl.SetCurSel(m_list_cache.playing_index());
263     m_playlist_ctrl.EnsureVisible(m_list_cache.playing_index(), FALSE);
264     LeftListClicked(m_list_cache.playing_index());
265     // 初始时将焦点设置到搜索框
266     m_search_edit.SetFocus();
267     wstring prompt_str = theApp.m_str_table.LoadText(L"TXT_SEARCH_PROMPT") + L"(F)";
268     m_search_edit.SetCueBanner(prompt_str.c_str(), TRUE);
269 
270     //初始化分隔条
271     m_splitter_ctrl.AttachCtrlAsLeftPane(IDC_LIST1);
272     m_splitter_ctrl.AttachCtrlAsRightPane(IDC_SONG_LIST);
273 
274     return FALSE;  // return TRUE unless you set the focus to a control
275                   // 异常: OCX 属性页应返回 FALSE
276 }
277 
CalculateColumeWidth(vector<int> & width)278 void CSelectPlaylistDlg::CalculateColumeWidth(vector<int>& width)
279 {
280     CRect rect;
281     m_playlist_ctrl.GetWindowRect(rect);
282     width.resize(5);
283 
284     width[2] = width[3] = rect.Width() / 8;
285     width[4] = rect.Width() / 5;
286 
287     width[0] = theApp.DPI(40);
288     width[1] = rect.Width() - width[2] - width[3] - width[4] - width[0] - theApp.DPI(20) - 1;
289 
290 }
291 
ShowPathList()292 void CSelectPlaylistDlg::ShowPathList()
293 {
294     // 更新m_list_cache
295     m_list_cache.reload();
296 
297     m_playlist_ctrl.EnableWindow(TRUE);
298     m_playlist_ctrl.DeleteAllItems();
299     if (!m_searched)        //显示所有项目
300     {
301         for (size_t i{}; i < m_list_cache.size(); ++i)
302         {
303             SetListRowData(i, m_list_cache.at(i));
304         }
305         m_playlist_ctrl.SetHightItem(m_list_cache.playing_index());
306     }
307     else        //只显示搜索结果的曲目
308     {
309         QuickSearch(m_searcher_str);
310         if (m_search_result.empty())
311         {
312             m_playlist_ctrl.InsertItem(0, _T(""));
313             m_playlist_ctrl.SetItemText(0, 1, theApp.m_str_table.LoadText(L"TXT_PLAYLIST_CTRL_NO_RESULT_TO_SHOW").c_str());
314             m_playlist_ctrl.EnableWindow(FALSE);
315             return;
316         }
317         int index{};
318         int highlight_index_searched{ -1 };
319         for (size_t i : m_search_result)
320         {
321             SetListRowData(index, m_list_cache.at(i));
322             if (m_list_cache.playing_index() == i)
323                 highlight_index_searched = index;
324             ++index;
325         }
326         m_playlist_ctrl.SetHightItem(highlight_index_searched);
327     }
328 }
329 
SetListRowData(int index,const ListItem & list_item)330 void CSelectPlaylistDlg::SetListRowData(int index, const ListItem& list_item)
331 {
332     m_playlist_ctrl.InsertItem(index, std::to_wstring(index + 1).c_str());
333     m_playlist_ctrl.SetItemText(index, 1, list_item.GetDisplayName().c_str());
334     m_playlist_ctrl.SetItemText(index, 2, list_item.GetLastTrackDisplayName().c_str());
335     m_playlist_ctrl.SetItemText(index, 3, std::to_wstring(list_item.total_num).c_str());
336     m_playlist_ctrl.SetItemText(index, 4, Time(list_item.total_time).toString3().c_str());
337 }
338 
LeftSelectValid() const339 bool CSelectPlaylistDlg::LeftSelectValid() const
340 {
341     int index{ m_left_selected_item };
342     if (m_searched && index >= 0 && index < static_cast<int>(m_search_result.size()))
343         index = m_search_result[index];
344     return index >= 0 && index < static_cast<int>(m_list_cache.size());
345 }
346 
GetSelectedPlaylist() const347 const ListItem& CSelectPlaylistDlg::GetSelectedPlaylist() const
348 {
349     if (LeftSelectValid())
350         if (m_searched)
351             return m_list_cache.at(m_search_result[m_left_selected_item]);
352         else
353             return m_list_cache.at(m_left_selected_item);
354     static ListItem empty{};
355     return empty;
356 }
357 
SetButtonsEnable()358 void CSelectPlaylistDlg::SetButtonsEnable()
359 {
360     bool enable = SelectedCanPlay();
361     CWnd* pParent = GetParentWindow();
362     ::SendMessage(pParent->GetSafeHwnd(), WM_PLAY_SELECTED_BTN_ENABLE, WPARAM(enable), 0);
363 }
364 
SelectedCanPlay() const365 bool CSelectPlaylistDlg::SelectedCanPlay() const
366 {
367     // 左侧选中不是当前列表或右侧有选中时能够播放(不再要求右侧选中不是当前播放,没有必要)
368     return LeftSelectValid() && (!CRecentList::Instance().IsCurrentList(GetSelectedPlaylist()) || m_right_selected_item >= 0);
369 }
370 
OnNMDblclkList1(NMHDR * pNMHDR,LRESULT * pResult)371 void CSelectPlaylistDlg::OnNMDblclkList1(NMHDR* pNMHDR, LRESULT* pResult)
372 {
373     LPNMITEMACTIVATE pNMItemActivate = reinterpret_cast<LPNMITEMACTIVATE>(pNMHDR);
374     // TODO: 在此添加控件通知处理程序代码
375     LeftListClicked(pNMItemActivate->iItem);
376 
377     OnOK();
378 
379     *pResult = 0;
380 }
381 
382 
OnOK()383 void CSelectPlaylistDlg::OnOK()
384 {
385     // TODO: 在此添加专用代码和/或调用基类
386     if (SelectedCanPlay())
387     {
388         bool ok{};
389         ListItem sel_playlist = GetSelectedPlaylist();
390         // 左侧选中或右侧选中无效则使用之前保存的信息播放选中播放列表,设置play为false,force为false
391         if (m_left_selected || m_right_selected_item < 0 || m_right_selected_item >= static_cast<int>(m_cur_song_list.size()))
392             ok = CPlayer::GetInstance().SetList(sel_playlist);
393         // 否则播放m_right_selected_item指定曲目,设置play为true,force为true
394         else
395         {
396             sel_playlist.SetPlayTrack(m_cur_song_list.at(m_right_selected_item));
397             ok = CPlayer::GetInstance().SetList(sel_playlist, true, true);
398         }
399         if (!ok)
400         {
401             const wstring& info = theApp.m_str_table.LoadText(L"MSG_WAIT_AND_RETRY");
402             MessageBox(info.c_str(), NULL, MB_ICONINFORMATION | MB_OK);
403         }
404         else
405         {
406             CTabDlg::OnOK();
407             CWnd* pParent = GetParentWindow();
408             if (pParent != nullptr)
409                 ::PostMessage(pParent->GetSafeHwnd(), WM_COMMAND, IDOK, 0);
410         }
411     }
412 }
413 
414 
OnBnClickedNewPlaylist()415 void CSelectPlaylistDlg::OnBnClickedNewPlaylist()
416 {
417     CMusicPlayerCmdHelper helper(this);
418     wstring new_path = helper.OnNewPlaylist();
419     if (!new_path.empty())
420     {
421         ShowPathList();
422         if (!m_searched)    // 添加新的播放列表后选中新增的播放列表
423         {
424             int new_index = m_list_cache.GetIndex(ListItem{ LT_PLAYLIST, new_path });
425             m_playlist_ctrl.SetCurSel(new_index);
426             m_playlist_ctrl.EnsureVisible(new_index, FALSE);
427             LeftListClicked(new_index);
428         }
429         else
430         {
431             m_playlist_ctrl.SetCurSel(-1);
432             LeftListClicked(-1);
433         }
434     }
435 }
436 
437 
OnPlayPlaylist()438 void CSelectPlaylistDlg::OnPlayPlaylist()
439 {
440     // TODO: 在此添加命令处理程序代码
441     OnOK();
442 }
443 
444 
OnRenamePlaylist()445 void CSelectPlaylistDlg::OnRenamePlaylist()
446 {
447     // TODO: 在此添加命令处理程序代码
448     if (LeftSelectValid())
449     {
450         CMusicPlayerCmdHelper helper(this);
451         if (helper.OnRenamePlaylist(GetSelectedPlaylist()))
452             ShowPathList();
453     }
454 }
455 
456 
OnDeletePlaylist()457 void CSelectPlaylistDlg::OnDeletePlaylist()
458 {
459     // TODO: 在此添加命令处理程序代码
460     if (LeftSelectValid())
461     {
462         CMusicPlayerCmdHelper helper(this);
463         if (helper.OnDeleteRecentListItem(GetSelectedPlaylist()))
464         {
465             ShowPathList();
466             if (!m_searched)
467             {
468                 m_playlist_ctrl.SetCurSel(m_list_cache.playing_index());
469                 m_playlist_ctrl.EnsureVisible(m_list_cache.playing_index(), FALSE);
470                 LeftListClicked(m_list_cache.playing_index());
471             }
472             else
473             {
474                 m_playlist_ctrl.SetCurSel(-1);
475                 LeftListClicked(-1);
476             }
477         }
478     }
479 }
480 
481 
OnNMClickList1(NMHDR * pNMHDR,LRESULT * pResult)482 void CSelectPlaylistDlg::OnNMClickList1(NMHDR* pNMHDR, LRESULT* pResult)
483 {
484     LPNMITEMACTIVATE pNMItemActivate = reinterpret_cast<LPNMITEMACTIVATE>(pNMHDR);
485     // TODO: 在此添加控件通知处理程序代码
486     LeftListClicked(pNMItemActivate->iItem);
487 
488     *pResult = 0;
489 }
490 
491 
OnNMRClickList1(NMHDR * pNMHDR,LRESULT * pResult)492 void CSelectPlaylistDlg::OnNMRClickList1(NMHDR* pNMHDR, LRESULT* pResult)
493 {
494     LPNMITEMACTIVATE pNMItemActivate = reinterpret_cast<LPNMITEMACTIVATE>(pNMHDR);
495     // TODO: 在此添加控件通知处理程序代码
496     LeftListClicked(pNMItemActivate->iItem);
497     m_selected_string = m_playlist_ctrl.GetItemText(pNMItemActivate->iItem, pNMItemActivate->iSubItem);
498 
499     //弹出右键菜单
500     CMenu* pContextMenu = theApp.m_menu_mgr.GetMenu(MenuMgr::LibPlaylistMenu);
501     m_playlist_ctrl.ShowPopupMenu(pContextMenu, pNMItemActivate->iItem, this);
502 
503     *pResult = 0;
504 }
505 
506 
OnInitMenu(CMenu * pMenu)507 void CSelectPlaylistDlg::OnInitMenu(CMenu* pMenu)
508 {
509     CMediaLibTabDlg::OnInitMenu(pMenu);
510 
511     // TODO: 在此处添加消息处理程序代码
512     bool select_valid{ LeftSelectValid() };
513     wstring sel_playlist_name = CFilePathHelper(GetSelectedPlaylist().path).GetFileName();
514     bool is_spec_playlist = CRecentList::IsSpecPlaylist(GetSelectedPlaylist());
515     bool is_cant_del = CRecentList::IsSpecPlaylist(GetSelectedPlaylist(), CRecentList::PT_DEFAULT) || CRecentList::IsSpecPlaylist(GetSelectedPlaylist(), CRecentList::PT_FAVOURITE);
516     pMenu->EnableMenuItem(ID_RENAME_PLAYLIST, MF_BYCOMMAND | (select_valid && !is_spec_playlist ? MF_ENABLED : MF_GRAYED));
517     pMenu->EnableMenuItem(ID_DELETE_PLAYLIST, MF_BYCOMMAND | (select_valid && !is_cant_del ? MF_ENABLED : MF_GRAYED));
518     pMenu->EnableMenuItem(ID_PLAY_PLAYLIST, MF_BYCOMMAND | (SelectedCanPlay() ? MF_ENABLED : MF_GRAYED));
519     pMenu->EnableMenuItem(ID_SAVE_AS_NEW_PLAYLIST, MF_BYCOMMAND | (select_valid ? MF_ENABLED : MF_GRAYED));
520     pMenu->EnableMenuItem(ID_PLAYLIST_SAVE_AS, MF_BYCOMMAND | (select_valid ? MF_ENABLED : MF_GRAYED));
521     pMenu->EnableMenuItem(ID_PLAYLIST_FIX_PATH_ERROR, MF_BYCOMMAND | (select_valid ? MF_ENABLED : MF_GRAYED));
522     pMenu->EnableMenuItem(ID_PLAYLIST_BROWSE_FILE, MF_BYCOMMAND | (select_valid ? MF_ENABLED : MF_GRAYED));
523 
524     switch (CRecentList::Instance().GetSortMode(LT_PLAYLIST))
525     {
526     case CRecentList::listSortMode::SM_RECENT_PLAYED: pMenu->CheckMenuRadioItem(ID_LIB_PLAYLIST_SORT_RECENT_PLAYED, ID_LIB_PLAYLIST_SORT_NAME, ID_LIB_PLAYLIST_SORT_RECENT_PLAYED, MF_BYCOMMAND | MF_CHECKED); break;
527     case CRecentList::listSortMode::SM_RECENT_CREATED: pMenu->CheckMenuRadioItem(ID_LIB_PLAYLIST_SORT_RECENT_PLAYED, ID_LIB_PLAYLIST_SORT_NAME, ID_LIB_PLAYLIST_SORT_RECENT_CREATED, MF_BYCOMMAND | MF_CHECKED); break;
528     case CRecentList::listSortMode::SM_PATH: pMenu->CheckMenuRadioItem(ID_LIB_PLAYLIST_SORT_RECENT_PLAYED, ID_LIB_PLAYLIST_SORT_NAME, ID_LIB_PLAYLIST_SORT_NAME, MF_BYCOMMAND | MF_CHECKED); break;
529     }
530 
531 }
532 
533 
OnNewPlaylist()534 void CSelectPlaylistDlg::OnNewPlaylist()
535 {
536     // TODO: 在此添加命令处理程序代码
537     OnBnClickedNewPlaylist();
538 }
539 
540 
OnEnChangeSearchEdit()541 void CSelectPlaylistDlg::OnEnChangeSearchEdit()
542 {
543     // TODO:  如果该控件是 RICHEDIT 控件,它将不
544     // 发送此通知,除非重写 CMediaLibTabDlg::OnInitDialog()
545     // 函数并调用 CRichEditCtrl().SetEventMask(),
546     // 同时将 ENM_CHANGE 标志“或”运算到掩码中。
547 
548     // TODO:  在此添加控件通知处理程序代码
549     CString key_word;
550     m_search_edit.GetWindowText(key_word);
551     m_searcher_str = key_word;
552     m_searched = !m_searcher_str.empty();
553     ShowPathList();
554     LeftListClicked(-1);    // 清空所有选中状态及右侧列表
555 }
556 
557 
558 //void CSelectPlaylistDlg::OnBnClickedClearButton()
559 //{
560 //    // TODO: 在此添加控件通知处理程序代码
561 //    if (m_searched)
562 //    {
563 //        //清除搜索结果
564 //        m_searched = false;
565 //        m_search_edit.SetWindowText(_T(""));
566 //        ShowPathList();
567 //        SetHighlightItem();
568 //    }
569 //}
570 
571 
PreTranslateMessage(MSG * pMsg)572 BOOL CSelectPlaylistDlg::PreTranslateMessage(MSG* pMsg)
573 {
574     // TODO: 在此添加专用代码和/或调用基类
575     if (pMsg->message == WM_KEYDOWN && pMsg->hwnd != m_search_edit.GetSafeHwnd())
576     {
577         if (pMsg->wParam == 'F')    //按F键快速查找
578         {
579             m_search_edit.SetFocus();
580             return TRUE;
581         }
582     }
583 
584     //if (pMsg->message == WM_MOUSEMOVE)
585     //    m_Mytip.RelayEvent(pMsg);
586 
587     return CMediaLibTabDlg::PreTranslateMessage(pMsg);
588 }
589 
590 
OnSearchEditBtnClicked(WPARAM wParam,LPARAM lParam)591 afx_msg LRESULT CSelectPlaylistDlg::OnSearchEditBtnClicked(WPARAM wParam, LPARAM lParam)
592 {
593     if (m_searched)
594     {
595         //清除搜索结果
596         m_searched = false;
597         m_search_edit.SetWindowTextW(L"");
598         ShowPathList();
599         m_playlist_ctrl.SetCurSel(m_list_cache.playing_index());
600         m_playlist_ctrl.EnsureVisible(m_list_cache.playing_index(), FALSE);
601         LeftListClicked(m_list_cache.playing_index());
602     }
603     return 0;
604 }
605 
606 
OnNMClickSongList(NMHDR * pNMHDR,LRESULT * pResult)607 void CSelectPlaylistDlg::OnNMClickSongList(NMHDR* pNMHDR, LRESULT* pResult)
608 {
609     LPNMITEMACTIVATE pNMItemActivate = reinterpret_cast<LPNMITEMACTIVATE>(pNMHDR);
610     // TODO: 在此添加控件通知处理程序代码
611     SongListClicked(pNMItemActivate->iItem);
612     *pResult = 0;
613 }
614 
615 
OnNMRClickSongList(NMHDR * pNMHDR,LRESULT * pResult)616 void CSelectPlaylistDlg::OnNMRClickSongList(NMHDR* pNMHDR, LRESULT* pResult)
617 {
618     LPNMITEMACTIVATE pNMItemActivate = reinterpret_cast<LPNMITEMACTIVATE>(pNMHDR);
619     // TODO: 在此添加控件通知处理程序代码
620     SongListClicked(pNMItemActivate->iItem);
621     m_selected_string = m_song_list_ctrl.GetItemText(pNMItemActivate->iItem, pNMItemActivate->iSubItem);
622 
623     if (!m_right_selected_items.empty())
624     {
625         //弹出右键菜单
626         CMenu* pMenu = theApp.m_menu_mgr.GetMenu(MenuMgr::LibPlaylistRightMenu);
627         ASSERT(pMenu != nullptr);
628         if (pMenu != nullptr)
629         {
630             m_song_list_ctrl.ShowPopupMenu(pMenu, pNMItemActivate->iItem, this);
631         }
632     }
633 
634     *pResult = 0;
635 }
636 
637 
OnNMDblclkSongList(NMHDR * pNMHDR,LRESULT * pResult)638 void CSelectPlaylistDlg::OnNMDblclkSongList(NMHDR* pNMHDR, LRESULT* pResult)
639 {
640     LPNMITEMACTIVATE pNMItemActivate = reinterpret_cast<LPNMITEMACTIVATE>(pNMHDR);
641     // TODO: 在此添加控件通知处理程序代码
642 
643     if (m_right_selected_item >= 0 && m_right_selected_item < m_song_list_ctrl.GetItemCount())
644         OnOK();
645     *pResult = 0;
646 }
647 
648 
OnSaveAsNewPlaylist()649 void CSelectPlaylistDlg::OnSaveAsNewPlaylist()
650 {
651     // TODO: 在此添加命令处理程序代码
652     if (LeftSelectValid())
653     {
654         const ListItem& list_item = GetSelectedPlaylist();
655         CMusicPlayerCmdHelper helper(this);
656         wstring new_path = helper.OnNewPlaylist(list_item.path);
657         if (!new_path.empty())
658         {
659             ShowPathList();
660             if (!m_searched)    // 添加新的播放列表后选中新增的播放列表
661             {
662                 int new_index = m_list_cache.GetIndex(ListItem{ LT_PLAYLIST, new_path });
663                 m_playlist_ctrl.SetCurSel(new_index);
664                 m_playlist_ctrl.EnsureVisible(new_index, FALSE);
665                 LeftListClicked(new_index);
666             }
667             else
668             {
669                 m_playlist_ctrl.SetCurSel(-1);
670                 LeftListClicked(-1);
671             }
672         }
673     }
674 }
675 
676 
OnPlaylistSaveAs()677 void CSelectPlaylistDlg::OnPlaylistSaveAs()
678 {
679     // TODO: 在此添加命令处理程序代码
680     if (LeftSelectValid())
681     {
682         CMusicPlayerCmdHelper helper(this);
683         helper.OnPlaylistSaveAs(GetSelectedPlaylist().path);
684     }
685 }
686 
687 
OnPlaylistFixPathError()688 void CSelectPlaylistDlg::OnPlaylistFixPathError()
689 {
690     if (LeftSelectValid())
691     {
692         CMusicPlayerCmdHelper helper(this);
693         if (helper.OnPlaylistFixPathError(GetSelectedPlaylist().path))
694         {
695             ShowSongList();
696         }
697     }
698 }
699 
700 
OnPlaylistBrowseFile()701 void CSelectPlaylistDlg::OnPlaylistBrowseFile()
702 {
703     if (LeftSelectValid())
704     {
705         CString str;
706         str.Format(_T("/select,\"%s\""), GetSelectedPlaylist().path.c_str());
707         ShellExecute(NULL, _T("open"), _T("explorer"), str, NULL, SW_SHOWNORMAL);
708     }
709 }
710 
711 
OnRemoveFromPlaylist()712 void CSelectPlaylistDlg::OnRemoveFromPlaylist()
713 {
714     if (LeftSelectValid())
715     {
716         vector<SongInfo> songs_selected;
717         GetSongsSelected(songs_selected);
718         CMusicPlayerCmdHelper helper;
719         if (helper.OnRemoveFromPlaylist(GetSelectedPlaylist(), songs_selected))
720         {
721             ShowSongList();
722             if (!m_searched)
723             {
724                 m_playlist_ctrl.SetCurSel(m_list_cache.playing_index());
725                 m_playlist_ctrl.EnsureVisible(m_list_cache.playing_index(), FALSE);
726                 LeftListClicked(m_list_cache.playing_index());
727             }
728             else
729             {
730                 m_playlist_ctrl.SetCurSel(-1);
731                 LeftListClicked(-1);
732             }
733         }
734     }
735 }
736 
737 
OnBnClickedSortButton()738 void CSelectPlaylistDlg::OnBnClickedSortButton()
739 {
740     CWnd* pBtn = GetDlgItem(IDC_SORT_BUTTON);
741     CPoint point;
742     if (pBtn != nullptr)
743     {
744         CRect rect;
745         pBtn->GetWindowRect(rect);
746         point.x = rect.left;
747         point.y = rect.bottom;
748         CMenu* pMenu = theApp.m_menu_mgr.GetMenu(MenuMgr::LibPlaylistSortMenu);
749         if (pMenu != NULL)
750             pMenu->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, point.x, point.y, this);
751     }
752 }
753 
754 
OnLibPlaylistSortRecentPlayed()755 void CSelectPlaylistDlg::OnLibPlaylistSortRecentPlayed()
756 {
757     if (CRecentList::Instance().SetSortMode(LT_PLAYLIST, CRecentList::SM_RECENT_PLAYED))
758     {
759         ShowPathList();
760         m_playlist_ctrl.SetCurSel(-1);
761         LeftListClicked(-1);
762         theApp.m_pMainWnd->SendMessage(WM_INIT_ADD_TO_MENU);
763     }
764 }
765 
766 
OnLibPlaylistSortRecentCreated()767 void CSelectPlaylistDlg::OnLibPlaylistSortRecentCreated()
768 {
769     if (CRecentList::Instance().SetSortMode(LT_PLAYLIST, CRecentList::SM_RECENT_CREATED))
770     {
771         ShowPathList();
772         m_playlist_ctrl.SetCurSel(-1);
773         LeftListClicked(-1);
774         theApp.m_pMainWnd->SendMessage(WM_INIT_ADD_TO_MENU);
775     }
776 }
777 
778 
OnLibPlaylistSortName()779 void CSelectPlaylistDlg::OnLibPlaylistSortName()
780 {
781     if (CRecentList::Instance().SetSortMode(LT_PLAYLIST, CRecentList::SM_PATH))
782     {
783         ShowPathList();
784         m_playlist_ctrl.SetCurSel(-1);
785         LeftListClicked(-1);
786         theApp.m_pMainWnd->SendMessage(WM_INIT_ADD_TO_MENU);
787     }
788 }
789 
OnLibPlaylistProperties()790 void CSelectPlaylistDlg::OnLibPlaylistProperties()
791 {
792     CPlaylistPropertiesDlg dlg(GetSelectedPlaylist());
793     dlg.DoModal();
794 }
795