wa_subclass.cpp 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314
  1. #include "main.h"
  2. #include "api__ml_local.h"
  3. #include "resource.h"
  4. #include "../nu/listview.h"
  5. #define WINAMP_FILE_ADDTOLIBRARY 40344
  6. #define WINAMP_FILE_ADDCURRENTPLEDIT 40466
  7. #define WINAMP_SHOWLIBRARY 40379
  8. wchar_t *recent_fn = 0;
  9. static HMENU last_viewmenu = 0;
  10. WORD waMenuID = 0;
  11. extern W_ListView resultlist;
  12. extern volatile int no_lv_update;
  13. void UpdateLocalResultsCache(const wchar_t *filename);
  14. static void onPlayFileTrack()
  15. {
  16. int autoaddplays = g_config->ReadInt(L"autoaddplays", 0);
  17. int trackplays = g_config->ReadInt(L"trackplays", 1);
  18. if (!trackplays && !autoaddplays)
  19. return ;
  20. if (g_table && recent_fn)
  21. {
  22. wchar_t filename2[MAX_PATH] = {0}; // full lfn path if set
  23. EnterCriticalSection(&g_db_cs);
  24. nde_scanner_t s = NDE_Table_CreateScanner(g_table);
  25. int found=FindFileInDatabase(s, MAINTABLE_ID_FILENAME, recent_fn, filename2);
  26. if (found) // if it's in the table already
  27. {
  28. if (trackplays) // if we're tracking plays
  29. {
  30. NDE_Scanner_Edit(s);
  31. nde_field_t f = NDE_Scanner_GetFieldByID(s, MAINTABLE_ID_PLAYCOUNT);
  32. int cnt = f ? NDE_IntegerField_GetValue(f) : 0;
  33. time_t t = time(NULL);
  34. db_setFieldInt(s, MAINTABLE_ID_PLAYCOUNT, ++cnt);
  35. db_setFieldInt(s, MAINTABLE_ID_LASTPLAY, (int)t);
  36. if (asked_for_playcount)
  37. PostMessage(plugin.hwndWinampParent, WM_WA_IPC, 0, IPC_UPDTITLE);
  38. // Issue a wasabi system callback after we have successfully added a file in the ml database
  39. api_mldb::played_info info = {t, cnt};
  40. WASABI_API_SYSCB->syscb_issueCallback(api_mldb::SYSCALLBACK, api_mldb::MLDB_FILE_PLAYED, (size_t)recent_fn, (size_t)&info);
  41. NDE_Scanner_Post(s);
  42. // disabled in 5.65 (was added in 5.64?) as causing
  43. // noticeable ui lockups on sync with large library
  44. // so instead we'll risk it and flush on 50 instead
  45. /*g_table_dirty = 0;
  46. NDE_Table_Sync(g_table);*/
  47. }
  48. NDE_Table_DestroyScanner(g_table, s);
  49. }
  50. else // not found in main table, we are in the main table, time to add if set
  51. {
  52. NDE_Table_DestroyScanner(g_table, s);
  53. if (autoaddplays)
  54. {
  55. int guess = -1, meta = -1, rec = 1;
  56. autoscan_add_directory(recent_fn, &guess, &meta, &rec, 1); // use this folder's guess/meta options
  57. if (guess == -1) guess = g_config->ReadInt(L"guessmode", 0);
  58. if (meta == -1) meta = g_config->ReadInt(L"usemetadata", 1);
  59. addFileToDb(recent_fn, 0, meta, guess, 1, (int)time(NULL));
  60. }
  61. }
  62. if (g_table_dirty > 50)
  63. {
  64. g_table_dirty = 0;
  65. NDE_Table_Sync(g_table);
  66. }
  67. LeaveCriticalSection(&g_db_cs);
  68. }
  69. }
  70. void onStartPlayFileTrack(const wchar_t *filename, bool resume)
  71. {
  72. if (!(wcsstr(filename, L"://") && _wcsnicmp(filename, L"cda://", 6) && _wcsnicmp(filename, L"file://", 7)))
  73. {
  74. int timer = -1, timer1 = -1, timer2 = -1;
  75. KillTimer(plugin.hwndWinampParent, 8081);
  76. if (!resume)
  77. {
  78. free(recent_fn);
  79. recent_fn = _wcsdup(filename);
  80. }
  81. // wait for x seconds
  82. if(g_config->ReadInt(L"trackplays_wait_secs",0))
  83. {
  84. timer1 = g_config->ReadInt(L"trackplays_wait_secs_lim",5)*1000;
  85. }
  86. // wait for x percent of the song (approx to a second)
  87. if(g_config->ReadInt(L"trackplays_wait_percent",0))
  88. {
  89. basicFileInfoStructW bfiW = {0};
  90. bfiW.filename = recent_fn;
  91. SendMessage(plugin.hwndWinampParent, WM_WA_IPC, (WPARAM)&bfiW, IPC_GET_BASIC_FILE_INFOW);
  92. if(bfiW.length > 0)
  93. {
  94. bfiW.length=bfiW.length*1000;
  95. timer2 = (bfiW.length*g_config->ReadInt(L"trackplays_wait_percent_lim",50))/100;
  96. }
  97. }
  98. // decide on which playback option will be the prefered duration (smallest wins)
  99. if(timer1 != -1 && timer2 != -1)
  100. {
  101. if(timer1 > timer2)
  102. {
  103. timer = timer2;
  104. }
  105. if(timer2 > timer1)
  106. {
  107. timer = timer1;
  108. }
  109. }
  110. else if(timer1 == -1 && timer2 != -1)
  111. {
  112. timer = timer2;
  113. }
  114. else if(timer2 == -1 && timer1 != -1)
  115. {
  116. timer = timer1;
  117. }
  118. // if no match or something went wrong then try to ensure the default timer value is used
  119. SetTimer(plugin.hwndWinampParent, 8081, ((timer > 0)? timer : 350), NULL);
  120. }
  121. }
  122. static void FileUpdated(const wchar_t *filename)
  123. {
  124. if (g_table)
  125. {
  126. EnterCriticalSection(&g_db_cs);
  127. int guess = -1, meta = -1, rec = 1;
  128. autoscan_add_directory(filename, &guess, &meta, &rec, 1); // use this folder's guess/meta options
  129. if (guess == -1) guess = g_config->ReadInt(L"guessmode", 0);
  130. if (meta == -1) meta = g_config->ReadInt(L"usemetadata", 1);
  131. addFileToDb(filename, TRUE, meta, guess, 0, 0, true);
  132. LeaveCriticalSection(&g_db_cs);
  133. if (g_table_dirty > 10)
  134. {
  135. g_table_dirty = 0;
  136. EnterCriticalSection(&g_db_cs);
  137. NDE_Table_Sync(g_table);
  138. LeaveCriticalSection(&g_db_cs);
  139. }
  140. if (!no_lv_update)
  141. UpdateLocalResultsCache(filename);
  142. }
  143. ClearCache(filename);
  144. ClearTitleHookCache();
  145. }
  146. LRESULT APIENTRY wa_newWndProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
  147. {
  148. switch (uMsg)
  149. {
  150. case WM_TIMER:
  151. if (recent_fn && wParam == 8081)
  152. {
  153. if (SendMessage(hwndDlg, WM_WA_IPC, 0, IPC_GETOUTPUTTIME) > 350)
  154. {
  155. KillTimer(hwndDlg, 8081);
  156. if (SendMessage(hwndDlg, WM_WA_IPC, 0, IPC_ISPLAYING) == 1)
  157. {
  158. onPlayFileTrack();
  159. }
  160. free(recent_fn);
  161. recent_fn = 0;
  162. }
  163. }
  164. break;
  165. case WM_WA_IPC:
  166. switch (lParam)
  167. {
  168. case IPC_CB_MISC:
  169. if (wParam == IPC_CB_MISC_TITLE)
  170. {
  171. if(!SendMessage(hwndDlg, WM_WA_IPC, 0, IPC_ISPLAYING))
  172. {
  173. KillTimer(hwndDlg, 8081);
  174. }
  175. }
  176. else if (wParam == IPC_CB_MISC_PAUSE)
  177. {
  178. KillTimer(hwndDlg, 8081);
  179. }
  180. else if (wParam == IPC_CB_MISC_UNPAUSE)
  181. {
  182. if (recent_fn) onStartPlayFileTrack(recent_fn, true);
  183. }
  184. break;
  185. case IPC_FILE_TAG_MAY_HAVE_UPDATEDW:
  186. {
  187. wchar_t *filename = (wchar_t *)wParam;
  188. if (filename)
  189. FileUpdated(filename);
  190. }
  191. break;
  192. case IPC_FILE_TAG_MAY_HAVE_UPDATED:
  193. {
  194. char *filename = (char *)wParam;
  195. if (filename)
  196. FileUpdated(AutoWide(filename));
  197. }
  198. break;
  199. case IPC_STOPPLAYING:
  200. {
  201. KillTimer(hwndDlg, 8081);
  202. free(recent_fn);
  203. recent_fn = 0;
  204. }
  205. break;
  206. case IPC_GET_EXTENDED_FILE_INFO_HOOKABLE:
  207. // guessing for metadata for when the library isn't open yet.
  208. if (!g_table && wParam && !m_calling_getfileinfo) return doGuessProc(hwndDlg, uMsg, wParam, lParam);
  209. break;
  210. default:
  211. {
  212. if (lParam == IPC_CLOUD_ENABLED)
  213. {
  214. if (m_curview_hwnd) SendMessage(m_curview_hwnd, WM_APP + 6, 0, 0); //update current view
  215. }
  216. }
  217. break;
  218. }
  219. break;
  220. case WM_INITMENUPOPUP:
  221. {
  222. HMENU hmenuPopup = (HMENU) wParam;
  223. if (hmenuPopup == wa_play_menu)
  224. {
  225. if (last_viewmenu)
  226. {
  227. RemoveMenu(wa_play_menu, waMenuID, MF_BYCOMMAND);
  228. DestroyMenu(last_viewmenu);
  229. last_viewmenu = NULL;
  230. }
  231. mlGetTreeStruct mgts = { 1000, 55000, -1};
  232. last_viewmenu = (HMENU)SendMessage(plugin.hwndLibraryParent, WM_ML_IPC, (WPARAM) & mgts, ML_IPC_GETTREE);
  233. if (last_viewmenu)
  234. {
  235. if (GetMenuItemCount(last_viewmenu) > 0)
  236. {
  237. int count = GetMenuItemCount(wa_play_menu);
  238. MENUITEMINFOW menuItem = {sizeof(MENUITEMINFOW), MIIM_SUBMENU | MIIM_ID | MIIM_TYPE, MFT_STRING, MFS_ENABLED, waMenuID,
  239. last_viewmenu, NULL, NULL, NULL, WASABI_API_LNGSTRINGW(IDS_MEDIA_LIBRARY_VIEW_RESULTS), 0};
  240. InsertMenuItemW(wa_play_menu, count, TRUE, &menuItem);
  241. }
  242. else
  243. {
  244. DestroyMenu(last_viewmenu);
  245. last_viewmenu = 0;
  246. }
  247. }
  248. }
  249. }
  250. break;
  251. case WM_COMMAND:
  252. case WM_SYSCOMMAND:
  253. WORD lowP = LOWORD(wParam);
  254. if (lowP == WINAMP_FILE_ADDTOLIBRARY)
  255. {
  256. if (!plugin.hwndLibraryParent || !IsWindowVisible(plugin.hwndLibraryParent))
  257. {
  258. SendMessage(plugin.hwndWinampParent, WM_COMMAND, MAKEWPARAM(WINAMP_SHOWLIBRARY, 0), 0L);
  259. }
  260. add_to_library(plugin.hwndLibraryParent);
  261. }
  262. else if (lowP == WINAMP_FILE_ADDCURRENTPLEDIT)
  263. {
  264. add_pledit_to_library();
  265. }
  266. else if (uMsg == WM_COMMAND && wParam > 45000 && wParam < 55000)
  267. {
  268. int n = wParam - 45000;
  269. if (m_query_list[n])
  270. {
  271. mediaLibrary.SwitchToPluginView(n);
  272. return 0;
  273. }
  274. }
  275. else if (uMsg == WM_COMMAND && wParam > 55000 && wParam < 65000)
  276. {
  277. int n = wParam - 55000;
  278. if (m_query_list[n])
  279. {
  280. queryItem *item = m_query_list[n];
  281. wchar_t configDir[MAX_PATH] = {0};
  282. PathCombineW(configDir, g_viewsDir, item->metafn);
  283. C_Config viewconf(configDir);
  284. main_playQuery(&viewconf, item->query, 0, 1);
  285. return 0;
  286. }
  287. }
  288. break;
  289. }
  290. return CallWindowProcW(wa_oldWndProc, hwndDlg, uMsg, wParam, lParam);
  291. }