ml_subclass.cpp 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271
  1. #include <shlwapi.h>
  2. #include "main.h"
  3. #include "../winamp/wa_ipc.h"
  4. #include "CurrentPlaylist.h"
  5. #include "SendTo.h"
  6. #include "Playlist.h"
  7. #include "api__ml_playlists.h"
  8. using namespace Nullsoft::Utility;
  9. WNDPROC ml_wndProc = 0;
  10. static INT_PTR CALLBACK AddPlaylistDialogProc_sc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
  11. {
  12. static wchar_t *title;
  13. switch (uMsg)
  14. {
  15. case WM_INITDIALOG:
  16. title = (wchar_t*)lParam;
  17. PostMessage(hwndDlg, WM_NEXTDLGCTL, (WPARAM)GetDlgItem(hwndDlg, IDC_NAME), TRUE);
  18. break;
  19. case WM_COMMAND:
  20. switch (LOWORD(wParam))
  21. {
  22. case IDOK:
  23. {
  24. wchar_t name[256] = {0};
  25. GetDlgItemText(hwndDlg, IDC_NAME, name, 255);
  26. name[255] = 0;
  27. if (!name[0])
  28. {
  29. wchar_t titleStr[32] = {0};
  30. MessageBox(hwndDlg, WASABI_API_LNGSTRINGW(IDS_ENTER_A_NAME),
  31. WASABI_API_LNGSTRINGW_BUF(IDS_ERROR,titleStr,32), MB_OK);
  32. break;
  33. }
  34. lstrcpyn(title,name,256);
  35. EndDialog(hwndDlg,1);
  36. }
  37. break;
  38. case IDCANCEL:
  39. EndDialog(hwndDlg,0);
  40. break;
  41. }
  42. break;
  43. }
  44. return 0;
  45. }
  46. static void AddPlaylist(mlAddPlaylist *addPlaylist)
  47. {
  48. PlaylistInfo pl;
  49. wchar_t filename[1024+256] = {0}; // use a longer buffer than MAX_PATH here because createPlayListDBFileName needs it
  50. if (addPlaylist->flags & PL_FLAGS_IMPORT)
  51. {
  52. createPlayListDBFileName(filename);
  53. CopyFileW(addPlaylist->filename, filename, FALSE);
  54. }
  55. else
  56. lstrcpynW(filename, addPlaylist->filename, MAX_PATH);
  57. int numItems = 0;
  58. int length = 0;
  59. wchar_t title[256] = {0};
  60. if(addPlaylist->playlistName)
  61. lstrcpynW(title, addPlaylist->playlistName, 256);
  62. else // prompt for name
  63. {
  64. if(WASABI_API_DIALOGBOXPARAMW((playlists_CloudAvailable() ? IDD_ADD_CLOUD_PLAYLIST : IDD_ADD_PLAYLIST),
  65. plugin.hwndLibraryParent, AddPlaylistDialogProc_sc, (LPARAM)title) == 0)
  66. { // the user hit cancel
  67. return;
  68. }
  69. }
  70. if (addPlaylist->numItems == -1 || addPlaylist->length == -1)
  71. {
  72. Playlist temp;
  73. AGAVE_API_PLAYLISTMANAGER->Load(filename, &temp);
  74. numItems = temp.GetNumItems();
  75. for (size_t i = 0;i != numItems;i++)
  76. {
  77. int len = temp.GetItemLengthMilliseconds(i) / 1000;
  78. if (len>=0)
  79. length += len;
  80. }
  81. }
  82. else
  83. {
  84. length = addPlaylist->length;
  85. numItems = addPlaylist->numItems;
  86. }
  87. AddPlaylist(true, title, filename, !!(addPlaylist->flags & PL_FLAG_SHOW), g_config->ReadInt(L"cloud", 1), numItems, length);
  88. }
  89. static void MakePlaylist(mlMakePlaylistV2 *makePlaylist)
  90. {
  91. AutoLockT<api_playlists> lock (AGAVE_API_PLAYLISTS);
  92. switch (makePlaylist->type)
  93. {
  94. case ML_TYPE_FILENAMES:
  95. case ML_TYPE_STREAMNAMES:
  96. AddPlaylistFromFilenames((const char *)makePlaylist->data, makePlaylist->playlistName, makePlaylist->flags);
  97. if (makePlaylist->flags & PL_FLAG_FILL_FILENAME && makePlaylist->size == sizeof(mlMakePlaylistV2))
  98. {
  99. // TODO: not guaranteed to be at the end
  100. size_t last_index = AGAVE_API_PLAYLISTS->GetCount() - 1;
  101. lstrcpynW(makePlaylist->filename, AGAVE_API_PLAYLISTS->GetFilename(last_index), MAX_PATH);
  102. }
  103. return ;
  104. case ML_TYPE_FILENAMESW:
  105. case ML_TYPE_STREAMNAMESW:
  106. AddPlaylistFromFilenamesW((const wchar_t *)makePlaylist->data, makePlaylist->playlistName, makePlaylist->flags);
  107. if (makePlaylist->flags & PL_FLAG_FILL_FILENAME && makePlaylist->size == sizeof(mlMakePlaylistV2))
  108. {
  109. // TODO: not guaranteed to be at the end
  110. size_t last_index = AGAVE_API_PLAYLISTS->GetCount() - 1;
  111. lstrcpynW(makePlaylist->filename, AGAVE_API_PLAYLISTS->GetFilename(last_index), MAX_PATH);
  112. }
  113. return ;
  114. case ML_TYPE_ITEMRECORDLIST:
  115. case ML_TYPE_CDTRACKS:
  116. AddPlaylistFromItemRecordList((itemRecordList *)makePlaylist->data, makePlaylist->playlistName, makePlaylist->flags);
  117. if (makePlaylist->flags & PL_FLAG_FILL_FILENAME && makePlaylist->size == sizeof(mlMakePlaylistV2))
  118. {
  119. // TODO: not guaranteed to be at the end
  120. size_t last_index = AGAVE_API_PLAYLISTS->GetCount() - 1;
  121. lstrcpynW(makePlaylist->filename, AGAVE_API_PLAYLISTS->GetFilename(last_index), MAX_PATH);
  122. }
  123. return ;
  124. case ML_TYPE_ITEMRECORDLISTW:
  125. AddPlaylistFromItemRecordListW((itemRecordListW *)makePlaylist->data, makePlaylist->playlistName, makePlaylist->flags);
  126. if (makePlaylist->flags & PL_FLAG_FILL_FILENAME && makePlaylist->size == sizeof(mlMakePlaylistV2))
  127. {
  128. // TODO: not guaranteed to be at the end
  129. size_t last_index = AGAVE_API_PLAYLISTS->GetCount() - 1;
  130. lstrcpynW(makePlaylist->filename, AGAVE_API_PLAYLISTS->GetFilename(last_index), MAX_PATH);
  131. }
  132. return ;
  133. }
  134. }
  135. static int GetPlaylistInfo(mlPlaylistInfo *info)
  136. {
  137. AutoLockT<api_playlists> lock (AGAVE_API_PLAYLISTS);
  138. size_t num = info->playlistNum;
  139. if (num >= AGAVE_API_PLAYLISTS->GetCount())
  140. return 0;
  141. PlaylistInfo playlist(num);
  142. lstrcpynW(info->filename, playlist.GetFilename(), MAX_PATH);
  143. lstrcpynW(info->playlistName, playlist.GetName(), 128);
  144. info->length = playlist.GetLength();
  145. info->numItems = playlist.GetSize();
  146. return 1;
  147. }
  148. static INT_PTR PlaylistIPC(int msg, INT_PTR param)
  149. {
  150. switch (msg)
  151. {
  152. case ML_IPC_NEWPLAYLIST: playlists_Add((HWND)param); return 1;
  153. case ML_IPC_IMPORTPLAYLIST: Playlist_importFromFile((HWND)param); return 1;
  154. case ML_IPC_SAVEPLAYLIST: CurrentPlaylist_Export((HWND)param); return 1; // TODO: can we guarantee a currently active playlist?
  155. case ML_IPC_IMPORTCURRENTPLAYLIST: Playlist_importFromWinamp(); return 1;
  156. // play/load the playlist passed as param
  157. case ML_IPC_PLAY_PLAYLIST: PlayPlaylist(param); return 1;
  158. case ML_IPC_LOAD_PLAYLIST: LoadPlaylist(param); return 1;
  159. case ML_IPC_GETPLAYLISTWND: return(INT_PTR)activeHWND;
  160. case ML_IPC_PLAYLIST_ADD: AddPlaylist((mlAddPlaylist *)param); return 1;
  161. case ML_IPC_PLAYLIST_MAKE: MakePlaylist((mlMakePlaylistV2 *)param); return 1;
  162. case ML_IPC_PLAYLIST_COUNT: return AGAVE_API_PLAYLISTS->GetCount();
  163. case ML_IPC_PLAYLIST_INFO: return GetPlaylistInfo((mlPlaylistInfo *)param);
  164. }
  165. return 0;
  166. }
  167. extern SendToMenu treeViewSendTo;
  168. INT_PTR CALLBACK MediaLibraryProcedure(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
  169. {
  170. switch (uMsg)
  171. {
  172. case WM_INITMENUPOPUP:
  173. if (treeViewSendTo.InitPopupMenu(wParam))
  174. return 0;
  175. case WM_COMMAND:
  176. {
  177. switch (LOWORD(wParam))
  178. {
  179. case WINAMP_MANAGEPLAYLISTS:
  180. mediaLibrary.SelectTreeItem(playlistsTreeId);
  181. return 1;
  182. case ID_DOSHITMENU_ADDNEWPLAYLIST:
  183. playlists_Add(hwndDlg);
  184. return 1;
  185. }
  186. }
  187. break;
  188. case WM_ML_IPC:
  189. {
  190. INT_PTR res = PlaylistIPC(lParam, wParam);
  191. if (res)
  192. {
  193. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, res);
  194. return TRUE;
  195. }
  196. }
  197. }
  198. return CallWindowProc(ml_wndProc, hwndDlg, uMsg, wParam, lParam);
  199. }
  200. void HookMediaLibrary()
  201. {
  202. ml_wndProc = (WNDPROC)SetWindowLongPtr(plugin.hwndLibraryParent, DWLP_DLGPROC, (LONG_PTR)MediaLibraryProcedure);
  203. }
  204. void UnhookMediaLibrary()
  205. {
  206. SetWindowLongPtr(plugin.hwndLibraryParent, DWLP_DLGPROC, (LONG_PTR)ml_wndProc);
  207. }
  208. #define TREE_PLAYLIST_ID_START 3002
  209. INT_PTR LoadPlaylist(INT_PTR treeId)
  210. {
  211. if (!FindTreeItem(treeId))
  212. return 0;
  213. wchar_t wstr[MAX_PATH+1] = {0};
  214. { // scope for lock
  215. AutoLockT<api_playlists> lock (AGAVE_API_PLAYLISTS);
  216. PlaylistInfo info;
  217. info.Associate(treeId);
  218. playlist_SaveGUID(info.playlist_guid);
  219. memset(wstr, 0, sizeof(wstr)); // easy (but slow) double null terminate
  220. PathCombineW(wstr, g_path, info.GetFilename());
  221. }
  222. SendMessage(plugin.hwndWinampParent, WM_WA_IPC, 0, IPC_DELETE);
  223. enqueueFileWithMetaStructW s;
  224. s.filename = wstr;
  225. s.title = 0;
  226. s.ext = NULL;
  227. s.length = -1;
  228. SendMessage(plugin.hwndWinampParent, WM_WA_IPC, (WPARAM)&s, IPC_PLAYFILEW);
  229. return 1;
  230. }
  231. INT_PTR PlayPlaylist(INT_PTR treeId)
  232. {
  233. if (LoadPlaylist(treeId))
  234. {
  235. SendMessage(plugin.hwndWinampParent, WM_WA_IPC, 0, IPC_STARTPLAY);
  236. return 1;
  237. }
  238. else
  239. return 0;
  240. }