1 // MediaClassfyDlg.cpp: 实现文件
2 //
3
4 #include "stdafx.h"
5 #include "MusicPlayer2.h"
6 #include "MediaClassifyDlg.h"
7 #include "Playlist.h"
8 #include "InputDlg.h"
9 #include "MusicPlayerCmdHelper.h"
10 #include "PropertyDlg.h"
11 #include "AddToPlaylistDlg.h"
12 #include "SongDataManager.h"
13 #include "Player.h"
14
15
16 // CMediaClassifyDlg 对话框
17
IMPLEMENT_DYNAMIC(CMediaClassifyDlg,CMediaLibTabDlg)18 IMPLEMENT_DYNAMIC(CMediaClassifyDlg, CMediaLibTabDlg)
19
20 CMediaClassifyDlg::CMediaClassifyDlg(CMediaClassifier::ClassificationType type, CWnd* pParent /*=nullptr*/)
21 : CMediaLibTabDlg(IDD_MEDIA_CLASSIFY_DIALOG, pParent), m_type(type),
22 m_classifer(type, theApp.m_media_lib_setting_data.hide_only_one_classification)
23 {
24 if (m_type == CMediaClassifier::CT_ARTIST)
25 m_default_str = theApp.m_str_table.LoadText(L"TXT_EMPTY_ARTIST");
26 else if (m_type == CMediaClassifier::CT_ALBUM)
27 m_default_str = theApp.m_str_table.LoadText(L"TXT_EMPTY_ALBUM");
28 else if (m_type == CMediaClassifier::CT_GENRE)
29 m_default_str = theApp.m_str_table.LoadText(L"TXT_EMPTY_GENRE");
30 else if (m_type == CMediaClassifier::CT_YEAR)
31 m_default_str = theApp.m_str_table.LoadText(L"TXT_EMPTY_YEAR");
32 }
33
~CMediaClassifyDlg()34 CMediaClassifyDlg::~CMediaClassifyDlg()
35 {
36 }
37
RefreshData()38 void CMediaClassifyDlg::RefreshData()
39 {
40 m_classifer.SetHideOnlyOneClassification(theApp.m_media_lib_setting_data.hide_only_one_classification);
41 if (m_initialized)
42 {
43 m_classifer.ClassifyMedia();
44 ShowClassifyList();
45 }
46 }
47
SetLeftListSel(wstring item)48 bool CMediaClassifyDlg::SetLeftListSel(wstring item)
49 {
50 int list_size = static_cast<int>(m_list_data_left.size());
51 item = ListItem(LT_MEDIA_LIB, item, m_type).GetDisplayName(); // 将空item转换为用于显示的<未知xxx>
52 //遍历左侧列表,寻找匹配匹配的项目
53 for (int i = 0; i < list_size; i++)
54 {
55 const wstring& name = m_list_data_left[i][0];
56 if (CCommon::StringCompareNoCase(name, item))
57 {
58 m_classify_list_ctrl.SetCurSel(i);
59 ClassifyListClicked(i);
60 return true;
61 }
62 }
63 //如果在媒体库中设置了“将只有一项的分类归到其他类中”,则要寻找的项目可能在“其他”类中
64 int other_index{ -1 }; //项目在“其他”类中的索引
65 //在“其他”类中寻找
66 auto iter = m_classifer.GetMeidaList().find(STR_OTHER_CLASSIFY_TYPE);
67 if (iter != m_classifer.GetMeidaList().end())
68 {
69 int i = 0;
70 for (const auto& song : iter->second)
71 {
72 if (m_type == CMediaClassifier::CT_ARTIST)
73 {
74 vector<wstring> artist_list;
75 song.GetArtistList(artist_list);
76 if (CCommon::IsItemInVector(artist_list, item))
77 {
78 other_index = i;
79 break;
80 }
81 }
82 else if (m_type == CMediaClassifier::CT_ALBUM)
83 {
84 if (item == song.GetAlbum())
85 {
86 other_index = i;
87 break;
88 }
89 }
90 i++;
91 }
92 }
93
94 if (other_index >= 0)
95 {
96 m_classify_list_ctrl.SetCurSel(m_classify_list_ctrl.GetItemCount() - 1); //在左侧列表中选中“其他”类
97 ClassifyListClicked(m_classify_list_ctrl.GetItemCount() - 1);
98 m_song_list_ctrl.SetCurSel(other_index);
99 return true;
100 }
101 return false;
102 }
103
RefreshSongList()104 void CMediaClassifyDlg::RefreshSongList()
105 {
106 ShowSongList();
107 }
108
ShowClassifyList()109 void CMediaClassifyDlg::ShowClassifyList()
110 {
111 CWaitCursor wait_cursor;
112 auto& media_list{ m_searched ? m_search_result : m_classifer.GetMeidaList() };
113 m_list_data_left.clear();
114 for (const auto& item : media_list)
115 {
116 if (item.first == STR_OTHER_CLASSIFY_TYPE) //跳过“其他”分类
117 continue;
118
119 wstring item_name = item.first;
120 if (item_name.empty())
121 {
122 item_name = m_default_str;
123 }
124
125 CListCtrlEx::RowData row_data;
126 row_data[0] = item_name;
127 row_data[1] = std::to_wstring(item.second.size());
128 m_list_data_left.push_back(std::move(row_data));
129 }
130
131 if (m_type == CMediaClassifier::CT_BITRATE)
132 {
133 //如果类型是比特率,则对其进行自定义排序
134 std::sort(m_list_data_left.begin(), m_list_data_left.end(), [](const CListCtrlEx::RowData& a, const CListCtrlEx::RowData& b)
135 {
136 wstring str_a = a.at(0);
137 wstring str_b = b.at(0);
138
139 auto normalize_string = [](wstring& str)
140 {
141 if (!str.empty() && (str[0] < L'0' || str[0] > L'9'))
142 str = str.substr(1);
143 if (str.size() < 5)
144 str = wstring(5 - str.size(), L'0') + str;
145 };
146
147 normalize_string(str_a);
148 normalize_string(str_b);
149 return str_a < str_b;
150 });
151 }
152
153 //将“其他”分类放到列表的最后面
154 auto iter = media_list.find(STR_OTHER_CLASSIFY_TYPE);
155 if (iter != media_list.end())
156 {
157 CListCtrlEx::RowData row_data;
158 row_data[0] = theApp.m_str_table.LoadText(L"TXT_CLASSIFY_OTHER");
159 row_data[1] = std::to_wstring(iter->second.size());
160 m_list_data_left.push_back(std::move(row_data));
161 }
162 m_classify_list_ctrl.SetListData(&m_list_data_left);
163 }
164
ShowSongList()165 void CMediaClassifyDlg::ShowSongList()
166 {
167 CWaitCursor wait_cursor;
168 auto& media_list{ m_searched ? m_search_result : m_classifer.GetMeidaList() };
169
170 m_list_data_right.clear();
171 m_right_items.clear();
172 int highlight_item{ -1 };
173 int right_index{ 0 };
174 for (int index : m_left_selected_items)
175 {
176 CString str_selected = GetClassifyListSelectedString(index);
177
178 auto iter = media_list.find(wstring(str_selected));
179 if (iter != media_list.end())
180 {
181 for (const auto& item : iter->second)
182 {
183 const SongInfo& song{ CSongDataManager::GetInstance().GetSongInfo3(item) };
184 m_right_items.push_back(song); // 更新显示列表同时存储一份右侧列表SongInfo
185
186 //判断正在播放项
187 if (song.IsSameSong(CPlayer::GetInstance().GetCurrentSongInfo()))
188 highlight_item = right_index;
189
190 CListCtrlEx::RowData row_data;
191 row_data[COL_TITLE] = song.GetTitle();
192 row_data[COL_ARTIST] = song.GetArtist();
193 row_data[COL_ALBUM] = song.GetAlbum();
194 std::wstring track_str;
195 if (song.track != 0)
196 track_str = std::to_wstring(song.track);
197 row_data[COL_TRACK] = track_str;
198 row_data[COL_GENRE] = song.GetGenre();
199 row_data[COL_BITRATE] = (song.bitrate == 0 ? L"-" : std::to_wstring(song.bitrate));
200 row_data[COL_PATH] = song.file_path;
201 m_list_data_right.push_back(std::move(row_data));
202
203 right_index++;
204 }
205 }
206 }
207
208 m_song_list_ctrl.SetListData(&m_list_data_right);
209 if (CPlayer::GetInstance().IsMediaLibMode())
210 {
211 m_song_list_ctrl.SetHightItem(highlight_item);
212 m_song_list_ctrl.EnsureVisible(highlight_item, FALSE);
213 }
214 }
215
GetClassifyListSelectedString(int index) const216 CString CMediaClassifyDlg::GetClassifyListSelectedString(int index) const
217 {
218 CString str_selected = m_classify_list_ctrl.GetItemText(index, 0);
219 if (str_selected == m_default_str.c_str())
220 str_selected.Empty();
221 if (str_selected == theApp.m_str_table.LoadText(L"TXT_CLASSIFY_OTHER").c_str())
222 str_selected = STR_OTHER_CLASSIFY_TYPE;
223 return str_selected;
224 }
225
ClassifyListClicked(int index)226 void CMediaClassifyDlg::ClassifyListClicked(int index)
227 {
228 m_left_selected = true;
229 m_classify_list_ctrl.GetItemSelected(m_left_selected_items); //获取选中的项目
230 if (index < 0)
231 {
232 SetButtonsEnable(false);
233 return;
234 }
235
236 CString str_selected = GetClassifyListSelectedString(index);
237 static size_t last_selected_count = 0;
238 if (last_selected_index != index || last_selected_count != m_left_selected_items.size())
239 {
240 m_classify_selected = str_selected;
241 ShowSongList();
242 last_selected_index = index;
243 last_selected_count = m_left_selected_items.size();
244 }
245 m_right_selected_item = -1; // 点击左侧列表时清空右侧列表选中项
246 m_right_selected_items.clear();
247 m_song_list_ctrl.SelectNone();
248
249 SetButtonsEnable(/*(index >= 0 && index < m_classify_list_ctrl.GetItemCount()) ||*/ !m_left_selected_items.empty());
250
251 }
252
SongListClicked(int index)253 void CMediaClassifyDlg::SongListClicked(int index)
254 {
255 m_left_selected = false;
256 m_right_selected_item = index;
257 m_song_list_ctrl.GetItemSelected(m_right_selected_items);
258 SetButtonsEnable(/*(index >=0 && index < m_song_list_ctrl.GetItemCount()) ||*/ !m_right_selected_items.empty());
259 }
260
IsItemMatchKeyWord(const SongInfo & song,const wstring & key_word)261 bool CMediaClassifyDlg::IsItemMatchKeyWord(const SongInfo& song, const wstring& key_word)
262 {
263 if (m_type == CMediaClassifier::CT_ARTIST)
264 return IsItemMatchKeyWord(song.artist, key_word);
265 else if (m_type == CMediaClassifier::CT_ALBUM)
266 return IsItemMatchKeyWord(song.album, key_word);
267 else if (m_type == CMediaClassifier::CT_GENRE)
268 return IsItemMatchKeyWord(song.genre, key_word);
269 else if (m_type == CMediaClassifier::CT_YEAR)
270 return IsItemMatchKeyWord(song.get_year(), key_word);
271 return false;
272 }
273
IsItemMatchKeyWord(const wstring & str,const wstring & key_word)274 bool CMediaClassifyDlg::IsItemMatchKeyWord(const wstring& str, const wstring& key_word)
275 {
276 return theApp.m_chinese_pingyin_res.IsStringMatchWithPingyin(key_word, str);
277 }
278
QuickSearch(const wstring & key_word)279 void CMediaClassifyDlg::QuickSearch(const wstring& key_word)
280 {
281 m_search_result.clear();
282 std::vector<SongInfo> other_list;
283 for (const auto& item : m_classifer.GetMeidaList())
284 {
285 if (item.first == STR_OTHER_CLASSIFY_TYPE)
286 {
287 for (const auto& song : item.second)
288 {
289 if (IsItemMatchKeyWord(song, key_word))
290 other_list.push_back(song);
291 }
292 }
293 else
294 {
295 if (IsItemMatchKeyWord(item.first, key_word))
296 m_search_result[item.first] = item.second;
297 }
298 }
299 if (!other_list.empty())
300 m_search_result[STR_OTHER_CLASSIFY_TYPE] = other_list;
301 }
302
SetButtonsEnable()303 void CMediaClassifyDlg::SetButtonsEnable()
304 {
305 bool play_enable;
306 if (m_left_selected)
307 play_enable = (m_classify_list_ctrl.GetCurSel() >= 0);
308 else
309 play_enable = (m_song_list_ctrl.GetCurSel() >= 0);
310 SetButtonsEnable(play_enable);
311 }
312
SetButtonsEnable(bool enable)313 void CMediaClassifyDlg::SetButtonsEnable(bool enable)
314 {
315 CWnd* pParent = GetParentWindow();
316 ::SendMessage(pParent->GetSafeHwnd(), WM_PLAY_SELECTED_BTN_ENABLE, WPARAM(enable), 0);
317 }
318
OnTabEntered()319 void CMediaClassifyDlg::OnTabEntered()
320 {
321 SetButtonsEnable();
322 if (!m_initialized)
323 {
324 CWaitCursor wait_cursor;
325 m_classifer.ClassifyMedia();
326 ShowClassifyList();
327
328 //设置左侧列表默认选中项
329 if (CPlayer::GetInstance().IsMediaLibMode())
330 SetLeftListSel(CPlayer::GetInstance().GetMedialibItemName());
331
332 m_initialized = true;
333 }
334 }
335
GetNewPlaylistName() const336 wstring CMediaClassifyDlg::GetNewPlaylistName() const
337 {
338 std::wstring default_name;
339 //如果选中了左侧列表,则添加到新建播放列表时名称自动填上选中项的名称
340 if (m_classify_selected != STR_OTHER_CLASSIFY_TYPE)
341 default_name = m_classify_selected;
342 CCommon::FileNameNormalize(default_name);
343 return default_name;
344 }
345
GetClassificationType() const346 CMediaClassifier::ClassificationType CMediaClassifyDlg::GetClassificationType() const
347 {
348 return m_type;
349 }
350
GetClassificationItemName() const351 std::wstring CMediaClassifyDlg::GetClassificationItemName() const
352 {
353 if (m_left_selected_items.size() > 1) // 左侧列表有多个选中项时返回<其他>
354 return STR_OTHER_CLASSIFY_TYPE;
355 return m_classify_selected;
356 }
357
CalculateClassifyListColumeWidth(std::vector<int> & width)358 void CMediaClassifyDlg::CalculateClassifyListColumeWidth(std::vector<int>& width)
359 {
360 CRect rect;
361 m_classify_list_ctrl.GetWindowRect(rect);
362 width.resize(2);
363
364 width[1] = theApp.DPI(50);
365 width[0] = rect.Width() - width[1] - theApp.DPI(20) - 1;
366 }
367
GetSongsSelected(std::vector<SongInfo> & song_list) const368 void CMediaClassifyDlg::GetSongsSelected(std::vector<SongInfo>& song_list) const
369 {
370 if (m_left_selected)
371 {
372 //如果选中了左侧列表,则把选中分类下的所有曲目的路径添加到song_list中
373 song_list.clear();
374 auto& media_list{ m_searched ? m_search_result : m_classifer.GetMeidaList() };
375 for (int index : m_left_selected_items)
376 {
377 wstring str_selected{ GetClassifyListSelectedString(index) };
378 auto iter = media_list.find(str_selected);
379 if (iter != media_list.end())
380 {
381 for (const auto& item : iter->second)
382 {
383 song_list.push_back(item);
384 }
385 }
386 }
387 }
388 else
389 {
390 CMediaLibTabDlg::GetSongsSelected(song_list);
391 }
392 }
393
GetSongList() const394 const vector<SongInfo>& CMediaClassifyDlg::GetSongList() const
395 {
396 return m_right_items;
397 }
398
GetItemSelected() const399 int CMediaClassifyDlg::GetItemSelected() const
400 {
401 return m_right_selected_item;
402 }
403
GetItemsSelected() const404 const vector<int>& CMediaClassifyDlg::GetItemsSelected() const
405 {
406 return m_right_selected_items;
407 }
408
AfterDeleteFromDisk(const std::vector<SongInfo> & files)409 void CMediaClassifyDlg::AfterDeleteFromDisk(const std::vector<SongInfo>& files)
410 {
411 //删除成功,则刷新列表
412 m_classifer.RemoveFiles(files);
413 ShowSongList();
414 }
415
GetSelectedString() const416 wstring CMediaClassifyDlg::GetSelectedString() const
417 {
418 return m_selected_string;
419 }
420
DoDataExchange(CDataExchange * pDX)421 void CMediaClassifyDlg::DoDataExchange(CDataExchange* pDX)
422 {
423 CMediaLibTabDlg::DoDataExchange(pDX);
424 DDX_Control(pDX, IDC_CLASSIFY_LIST, m_classify_list_ctrl);
425 DDX_Control(pDX, IDC_SONG_LIST, m_song_list_ctrl);
426 DDX_Control(pDX, IDC_MFCEDITBROWSE1, m_search_edit);
427 DDX_Control(pDX, IDC_HSPLITER_STATIC, m_splitter_ctrl);
428 }
429
430
BEGIN_MESSAGE_MAP(CMediaClassifyDlg,CMediaLibTabDlg)431 BEGIN_MESSAGE_MAP(CMediaClassifyDlg, CMediaLibTabDlg)
432 ON_NOTIFY(NM_CLICK, IDC_CLASSIFY_LIST, &CMediaClassifyDlg::OnNMClickClassifyList)
433 ON_NOTIFY(NM_RCLICK, IDC_CLASSIFY_LIST, &CMediaClassifyDlg::OnNMRClickClassifyList)
434 ON_EN_CHANGE(IDC_MFCEDITBROWSE1, &CMediaClassifyDlg::OnEnChangeMfceditbrowse1)
435 ON_MESSAGE(WM_SEARCH_EDIT_BTN_CLICKED, &CMediaClassifyDlg::OnSearchEditBtnClicked)
436 ON_NOTIFY(NM_CLICK, IDC_SONG_LIST, &CMediaClassifyDlg::OnNMClickSongList)
437 ON_NOTIFY(NM_RCLICK, IDC_SONG_LIST, &CMediaClassifyDlg::OnNMRClickSongList)
438 ON_NOTIFY(NM_DBLCLK, IDC_CLASSIFY_LIST, &CMediaClassifyDlg::OnNMDblclkClassifyList)
439 ON_NOTIFY(NM_DBLCLK, IDC_SONG_LIST, &CMediaClassifyDlg::OnNMDblclkSongList)
440 ON_NOTIFY(HDN_ITEMCLICK, 0, &CMediaClassifyDlg::OnHdnItemclickSongList)
441 ON_WM_SIZE()
442 ON_WM_DESTROY()
443 ON_WM_INITMENU()
444 END_MESSAGE_MAP()
445
446
447 // CMediaClassifyDlg 消息处理程序
448
449
450 BOOL CMediaClassifyDlg::OnInitDialog()
451 {
452 CMediaLibTabDlg::OnInitDialog();
453
454 // TODO: 在此添加额外的初始化
455
456 //初始化左侧列表
457 m_classify_list_ctrl.SetExtendedStyle(m_classify_list_ctrl.GetExtendedStyle() | LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES | LVS_EX_LABELTIP);
458 wstring title_name;
459 if (m_type == CMediaClassifier::CT_ARTIST)
460 title_name = theApp.m_str_table.LoadText(L"TXT_ARTIST");
461 else if (m_type == CMediaClassifier::CT_ALBUM)
462 title_name = theApp.m_str_table.LoadText(L"TXT_ALBUM");
463 else if (m_type == CMediaClassifier::CT_GENRE)
464 title_name = theApp.m_str_table.LoadText(L"TXT_GENRE");
465 else if (m_type == CMediaClassifier::CT_YEAR)
466 title_name = theApp.m_str_table.LoadText(L"TXT_YEAR");
467 else if (m_type == CMediaClassifier::CT_TYPE)
468 title_name = theApp.m_str_table.LoadText(L"TXT_FILE_TYPE");
469 else if (m_type == CMediaClassifier::CT_BITRATE)
470 title_name = theApp.m_str_table.LoadText(L"TXT_BITRATE");
471 else if (m_type == CMediaClassifier::CT_RATING)
472 title_name = theApp.m_str_table.LoadText(L"TXT_RATING");
473 CRect rc_classify_list;
474 m_classify_list_ctrl.GetWindowRect(rc_classify_list);
475 std::vector<int> width;
476 CalculateClassifyListColumeWidth(width);
477 m_classify_list_ctrl.InsertColumn(0, title_name.c_str(), LVCFMT_LEFT, width[0]);
478 m_classify_list_ctrl.InsertColumn(1, theApp.m_str_table.LoadText(L"TXT_NUM_OF_TRACK").c_str(), LVCFMT_LEFT, width[1]);
479 //ShowClassifyList();
480
481 //初始化右侧列表
482 m_song_list_ctrl.SetExtendedStyle(m_song_list_ctrl.GetExtendedStyle() | LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES | LVS_EX_LABELTIP);
483 //CRect rc_song_list;
484 //m_song_list_ctrl.GetWindowRect(rc_song_list);
485 m_song_list_ctrl.InsertColumn(0, theApp.m_str_table.LoadText(L"TXT_TITLE").c_str(), LVCFMT_LEFT, theApp.DPI(150));
486 m_song_list_ctrl.InsertColumn(1, theApp.m_str_table.LoadText(L"TXT_ARTIST").c_str(), LVCFMT_LEFT, theApp.DPI(100));
487 m_song_list_ctrl.InsertColumn(2, theApp.m_str_table.LoadText(L"TXT_ALBUM").c_str(), LVCFMT_LEFT, theApp.DPI(150));
488 m_song_list_ctrl.InsertColumn(3, theApp.m_str_table.LoadText(L"TXT_TRACK_NUM").c_str(), LVCFMT_LEFT, theApp.DPI(60));
489 m_song_list_ctrl.InsertColumn(4, theApp.m_str_table.LoadText(L"TXT_GENRE").c_str(), LVCFMT_LEFT, theApp.DPI(100));
490 m_song_list_ctrl.InsertColumn(5, theApp.m_str_table.LoadText(L"TXT_BITRATE").c_str(), LVCFMT_LEFT, theApp.DPI(60));
491 m_song_list_ctrl.InsertColumn(6, theApp.m_str_table.LoadText(L"TXT_FILE_PATH").c_str(), LVCFMT_LEFT, theApp.DPI(600));
492 m_song_list_ctrl.SetCtrlAEnable(true);
493
494 if (m_type == CMediaClassifier::CT_ARTIST)
495 m_search_edit.SetCueBanner(theApp.m_str_table.LoadText(L"TXT_SEARCH_PROMPT_ARTIST").c_str(), TRUE);
496 else if (m_type == CMediaClassifier::CT_ALBUM)
497 m_search_edit.SetCueBanner(theApp.m_str_table.LoadText(L"TXT_SEARCH_PROMPT_ALBUM").c_str(), TRUE);
498 else if (m_type == CMediaClassifier::CT_GENRE)
499 m_search_edit.SetCueBanner(theApp.m_str_table.LoadText(L"TXT_SEARCH_PROMPT_GENRE").c_str(), TRUE);
500 else if (m_type == CMediaClassifier::CT_YEAR)
501 m_search_edit.SetCueBanner(theApp.m_str_table.LoadText(L"TXT_SEARCH_PROMPT_YEAR").c_str(), TRUE);
502 else if (m_type == CMediaClassifier::CT_TYPE)
503 m_search_edit.SetCueBanner(theApp.m_str_table.LoadText(L"TXT_SEARCH_PROMPT_FILE_TYPE").c_str(), TRUE);
504 else if (m_type == CMediaClassifier::CT_BITRATE)
505 m_search_edit.SetCueBanner(theApp.m_str_table.LoadText(L"TXT_SEARCH_PROMPT_BITRATE").c_str(), TRUE);
506 else if (m_type == CMediaClassifier::CT_RATING)
507 m_search_edit.EnableWindow(FALSE);
508 else
509 m_search_edit.SetCueBanner(theApp.m_str_table.LoadText(L"TXT_SEARCH_PROMPT").c_str(), TRUE);
510
511 //初始化分隔条
512 m_splitter_ctrl.AttachCtrlAsLeftPane(IDC_CLASSIFY_LIST);
513 m_splitter_ctrl.AttachCtrlAsLeftPane(IDC_MFCEDITBROWSE1);
514 m_splitter_ctrl.AttachCtrlAsRightPane(IDC_SONG_LIST);
515
516 return TRUE; // return TRUE unless you set the focus to a control
517 // 异常: OCX 属性页应返回 FALSE
518 }
519
520
OnNMClickClassifyList(NMHDR * pNMHDR,LRESULT * pResult)521 void CMediaClassifyDlg::OnNMClickClassifyList(NMHDR* pNMHDR, LRESULT* pResult)
522 {
523 LPNMITEMACTIVATE pNMItemActivate = reinterpret_cast<LPNMITEMACTIVATE>(pNMHDR);
524 // TODO: 在此添加控件通知处理程序代码
525 ClassifyListClicked(pNMItemActivate->iItem);
526 *pResult = 0;
527 }
528
529
OnNMRClickClassifyList(NMHDR * pNMHDR,LRESULT * pResult)530 void CMediaClassifyDlg::OnNMRClickClassifyList(NMHDR* pNMHDR, LRESULT* pResult)
531 {
532 LPNMITEMACTIVATE pNMItemActivate = reinterpret_cast<LPNMITEMACTIVATE>(pNMHDR);
533 // TODO: 在此添加控件通知处理程序代码
534 ClassifyListClicked(pNMItemActivate->iItem);
535 m_selected_string = m_classify_list_ctrl.GetItemText(pNMItemActivate->iItem, pNMItemActivate->iSubItem);
536
537 if (!m_left_selected_items.empty())
538 {
539 //弹出右键菜单
540 CMenu* pMenu = theApp.m_menu_mgr.GetMenu(MenuMgr::LibLeftMenu);
541 ASSERT(pMenu != nullptr);
542 if (pMenu != nullptr)
543 {
544 m_classify_list_ctrl.ShowPopupMenu(pMenu, pNMItemActivate->iItem, this);
545 }
546 }
547
548 *pResult = 0;
549 }
550
551
OnEnChangeMfceditbrowse1()552 void CMediaClassifyDlg::OnEnChangeMfceditbrowse1()
553 {
554 // TODO: 如果该控件是 RICHEDIT 控件,它将不
555 // 发送此通知,除非重写 CMediaLibTabDlg::OnInitDialog()
556 // 函数并调用 CRichEditCtrl().SetEventMask(),
557 // 同时将 ENM_CHANGE 标志“或”运算到掩码中。
558
559 // TODO: 在此添加控件通知处理程序代码
560 CString str;
561 m_search_edit.GetWindowText(str);
562 QuickSearch(wstring(str));
563 m_searched = !str.IsEmpty();
564 ShowClassifyList();
565 m_song_list_ctrl.DeleteAllItems();
566 last_selected_index = -2;
567 }
568
569
OnSearchEditBtnClicked(WPARAM wParam,LPARAM lParam)570 afx_msg LRESULT CMediaClassifyDlg::OnSearchEditBtnClicked(WPARAM wParam, LPARAM lParam)
571 {
572 //点击搜索框中的叉按钮时清除搜索结果
573 if (m_searched)
574 {
575 //清除搜索结果
576 m_searched = false;
577 m_search_edit.SetWindowText(_T(""));
578 ShowClassifyList();
579 m_song_list_ctrl.DeleteAllItems();
580 }
581 return 0;
582 }
583
584
OnNMClickSongList(NMHDR * pNMHDR,LRESULT * pResult)585 void CMediaClassifyDlg::OnNMClickSongList(NMHDR* pNMHDR, LRESULT* pResult)
586 {
587 LPNMITEMACTIVATE pNMItemActivate = reinterpret_cast<LPNMITEMACTIVATE>(pNMHDR);
588 // TODO: 在此添加控件通知处理程序代码
589 SongListClicked(pNMItemActivate->iItem);
590 *pResult = 0;
591 }
592
593
OnNMRClickSongList(NMHDR * pNMHDR,LRESULT * pResult)594 void CMediaClassifyDlg::OnNMRClickSongList(NMHDR* pNMHDR, LRESULT* pResult)
595 {
596 LPNMITEMACTIVATE pNMItemActivate = reinterpret_cast<LPNMITEMACTIVATE>(pNMHDR);
597 // TODO: 在此添加控件通知处理程序代码
598 SongListClicked(pNMItemActivate->iItem);
599 m_selected_string = m_song_list_ctrl.GetItemText(pNMItemActivate->iItem, pNMItemActivate->iSubItem);
600
601 if (!m_right_selected_items.empty())
602 {
603 //弹出右键菜单
604 CMenu* pMenu = theApp.m_menu_mgr.GetMenu(MenuMgr::LibRightMenu);
605 ASSERT(pMenu != nullptr);
606 if (pMenu != nullptr)
607 {
608 m_song_list_ctrl.ShowPopupMenu(pMenu, pNMItemActivate->iItem, this);
609 }
610 }
611
612 *pResult = 0;
613 }
614
615
OnNMDblclkClassifyList(NMHDR * pNMHDR,LRESULT * pResult)616 void CMediaClassifyDlg::OnNMDblclkClassifyList(NMHDR* pNMHDR, LRESULT* pResult)
617 {
618 LPNMITEMACTIVATE pNMItemActivate = reinterpret_cast<LPNMITEMACTIVATE>(pNMHDR);
619 // TODO: 在此添加控件通知处理程序代码
620 OnOK();
621 *pResult = 0;
622 }
623
624
OnNMDblclkSongList(NMHDR * pNMHDR,LRESULT * pResult)625 void CMediaClassifyDlg::OnNMDblclkSongList(NMHDR* pNMHDR, LRESULT* pResult)
626 {
627 LPNMITEMACTIVATE pNMItemActivate = reinterpret_cast<LPNMITEMACTIVATE>(pNMHDR);
628 // TODO: 在此添加控件通知处理程序代码
629 OnOK();
630 *pResult = 0;
631 }
632
633
OnHdnItemclickSongList(NMHDR * pNMHDR,LRESULT * pResult)634 void CMediaClassifyDlg::OnHdnItemclickSongList(NMHDR* pNMHDR, LRESULT* pResult)
635 {
636 LPNMHEADER phdr = reinterpret_cast<LPNMHEADER>(pNMHDR);
637 // TODO: 在此添加控件通知处理程序代码
638
639 if (phdr->hdr.hwndFrom == m_song_list_ctrl.GetHeaderCtrl()->GetSafeHwnd())
640 {
641 static bool ascending = false;
642 ascending = !ascending;
643
644 static int last_item = -1;
645 if (last_item != phdr->iItem)
646 {
647 last_item = phdr->iItem;
648 ascending = true;
649 }
650
651 //对右侧列表排序
652 if (m_left_selected_items.size() == 1) //仅当左侧列表选中了一项时处理
653 {
654 auto& media_list{ m_searched ? m_search_result : m_classifer.GetMeidaList() };
655 auto iter = media_list.find(m_classify_selected);
656 if (iter != media_list.end())
657 {
658 SortMode sort_mode = SM_UNSORT;
659 switch (phdr->iItem)
660 {
661 case CMediaClassifyDlg::COL_TITLE: sort_mode = ascending ? SM_U_TITLE : SM_D_TITLE; break;
662 case CMediaClassifyDlg::COL_ARTIST: sort_mode = ascending ? SM_U_ARTIST : SM_D_ARTIST; break;
663 case CMediaClassifyDlg::COL_ALBUM: sort_mode = ascending ? SM_U_ALBUM : SM_D_ALBUM; break;
664 case CMediaClassifyDlg::COL_TRACK: sort_mode = ascending ? SM_U_TRACK : SM_D_TRACK; break;
665 case CMediaClassifyDlg::COL_GENRE: sort_mode = ascending ? SM_U_GENRE : SM_D_GENRE; break;
666 case CMediaClassifyDlg::COL_BITRATE: sort_mode = ascending ? SM_U_BITRATE : SM_D_BITRATE; break;
667 case CMediaClassifyDlg::COL_PATH: sort_mode = ascending ? SM_U_PATH : SM_D_PATH; break;
668 default: break;
669 }
670 if (sort_mode != SM_UNSORT)
671 {
672 std::sort(iter->second.begin(), iter->second.end(), SongInfo::GetSortFunc(sort_mode));
673 ShowSongList();
674 }
675 }
676 }
677 }
678
679 *pResult = 0;
680 }
681
682
OnSize(UINT nType,int cx,int cy)683 void CMediaClassifyDlg::OnSize(UINT nType, int cx, int cy)
684 {
685 CMediaLibTabDlg::OnSize(nType, cx, cy);
686
687 // TODO: 在此处添加消息处理程序代码
688 if (nType != SIZE_MINIMIZED && m_classify_list_ctrl.m_hWnd)
689 {
690 std::vector<int> width;
691 CalculateClassifyListColumeWidth(width);
692 for (size_t i{}; i < width.size(); i++)
693 m_classify_list_ctrl.SetColumnWidth(i, width[i]);
694 }
695 }
696
697
OnDestroy()698 void CMediaClassifyDlg::OnDestroy()
699 {
700 CMediaLibTabDlg::OnDestroy();
701
702 // TODO: 在此处添加消息处理程序代码
703 m_classifer.ClearResult();
704 }
705
706
OnInitMenu(CMenu * pMenu)707 void CMediaClassifyDlg::OnInitMenu(CMenu* pMenu)
708 {
709 CMediaLibTabDlg::OnInitMenu(pMenu);
710
711 //设置“添加到播放列表”子菜单状态
712 //未选中状态不会弹出右键菜单,因此“添加到播放列表”子菜单全部设置为可用状态
713 for (UINT id = ID_ADD_TO_DEFAULT_PLAYLIST; id < ID_ADD_TO_MY_FAVOURITE + ADD_TO_PLAYLIST_MAX_SIZE + 1; id++)
714 {
715 pMenu->EnableMenuItem(id, MF_BYCOMMAND | MF_ENABLED);
716 }
717 pMenu->EnableMenuItem(ID_ADD_TO_NEW_PLAYLIST, MF_BYCOMMAND | MF_ENABLED);
718 pMenu->EnableMenuItem(ID_ADD_TO_OTHER_PLAYLIST, MF_BYCOMMAND | MF_ENABLED);
719 }
720