handleMessage.cpp 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906
  1. #include "main.h"
  2. #include "ml_local.h"
  3. #include "..\..\General\gen_ml/ml.h"
  4. #include "../replicant/nu/ns_wc.h"
  5. #include "../nde/nde.h"
  6. #include "../replicant/nu/AutoWide.h"
  7. #include "../nu/AutoWideFn.h"
  8. #include "editquery.h"
  9. #include <time.h>
  10. int queryEditOther(HWND hwnd, const char *query, const char *viewname, int mode);
  11. extern int m_item_mode;
  12. extern wchar_t m_item_name[256];
  13. extern wchar_t m_item_query[1024];
  14. LRESULT IPC_GetFileRatingW(INT_PTR fileName)
  15. {
  16. int rating = 0;
  17. const wchar_t *filename = (const wchar_t *)fileName;
  18. if (!filename) return 0;
  19. if (g_table)
  20. {
  21. EnterCriticalSection(&g_db_cs);
  22. wchar_t filename2[MAX_PATH] = {0}; // full lfn path if set
  23. nde_scanner_t s = NDE_Table_CreateScanner(g_table);
  24. int found=FindFileInDatabase(s, MAINTABLE_ID_FILENAME, filename, filename2);
  25. if (found)
  26. {
  27. nde_field_t f = NDE_Scanner_GetFieldByID(s, MAINTABLE_ID_RATING);
  28. if (f && NDE_Field_GetType(f) == FIELD_INTEGER)
  29. {
  30. rating = min(5, max(0, NDE_IntegerField_GetValue(f)));
  31. }
  32. }
  33. NDE_Table_DestroyScanner(g_table, s);
  34. LeaveCriticalSection(&g_db_cs);
  35. }
  36. return rating;
  37. }
  38. LRESULT IPC_SetFileRatingW(INT_PTR file_rating)
  39. {
  40. const wchar_t *filename;
  41. int rating;
  42. int found = 0;
  43. file_set_ratingW *data = (file_set_ratingW*)file_rating;
  44. if (!data) return 0;
  45. filename = data->fileName;
  46. rating = min(5, max(0, data->newRating));
  47. if (!filename) return 0;
  48. if (g_table)
  49. {
  50. EnterCriticalSection(&g_db_cs);
  51. wchar_t filename2[MAX_PATH] = {0}; // full lfn path if set
  52. nde_scanner_t s = NDE_Table_CreateScanner(g_table);
  53. int found=FindFileInDatabase(s, MAINTABLE_ID_FILENAME, filename, filename2);
  54. if (!found)
  55. {
  56. int guess = -1, meta = -1, rec = 1;
  57. autoscan_add_directory(filename, &guess, &meta, &rec, 1); // use this folder's guess/meta options
  58. if (guess == -1) guess = g_config->ReadInt(L"guessmode", 0);
  59. if (meta == -1) meta = g_config->ReadInt(L"usemetadata", 1);
  60. addFileToDb(filename, 0, meta, guess, 1, (int)time(NULL));
  61. }
  62. if (filename2[0] && !found)
  63. {
  64. if (NDE_Scanner_LocateFilename(s, MAINTABLE_ID_FILENAME, FIRST_RECORD, filename2)) found = 2;
  65. }
  66. if (!found)
  67. {
  68. if (NDE_Scanner_LocateFilename(s, MAINTABLE_ID_FILENAME, FIRST_RECORD, filename)) found = 1;
  69. }
  70. if (found)
  71. {
  72. NDE_Scanner_Edit(s);
  73. db_setFieldInt(s, MAINTABLE_ID_RATING, rating);
  74. NDE_Scanner_Post(s);
  75. if (g_config->ReadInt(L"writeratings", 0))
  76. {
  77. wchar_t buf[64] = {0};
  78. if (rating > 0)
  79. {
  80. wsprintfW(buf, L"%d", rating);
  81. }
  82. else
  83. buf[0] = 0;
  84. updateFileInfo(filename, DB_FIELDNAME_rating, buf);
  85. SendMessage(plugin.hwndWinampParent, WM_WA_IPC, 0, IPC_WRITE_EXTENDED_FILE_INFO);
  86. }
  87. }
  88. NDE_Table_DestroyScanner(g_table, s);
  89. LeaveCriticalSection(&g_db_cs);
  90. }
  91. return found != 0;
  92. }
  93. LRESULT IPC_GetFileRating(INT_PTR fileName)
  94. {
  95. return IPC_GetFileRatingW((INT_PTR)(wchar_t *)AutoWide((const char *)fileName));
  96. }
  97. LRESULT IPC_SetFileRating(INT_PTR file_rating)
  98. {
  99. file_set_rating *data = (file_set_rating*)file_rating;
  100. if (!data) return 0;
  101. file_set_ratingW dataW;
  102. AutoWide wideFn(data->fileName);
  103. dataW.fileName = wideFn;
  104. dataW.newRating = data->newRating;
  105. return IPC_SetFileRatingW((INT_PTR)&dataW);
  106. }
  107. int m_calling_getfileinfo;
  108. int getFileInfo(const char *filename, char *metadata, char *dest, int len)
  109. {
  110. m_calling_getfileinfo=1;
  111. dest[0]=0;
  112. extendedFileInfoStruct efis={
  113. filename,
  114. metadata,
  115. dest,
  116. len,
  117. };
  118. int r = SendMessage(plugin.hwndWinampParent,WM_WA_IPC,(WPARAM)&efis,IPC_GET_EXTENDED_FILE_INFO); //will return 1 if wa2 supports this IPC call
  119. m_calling_getfileinfo=0;
  120. return r;
  121. }
  122. LRESULT IPC_GetFileInfo(INT_PTR param)
  123. {
  124. if (!param) return 0;
  125. itemRecord *ent = (itemRecord *)param;
  126. if (!ent->filename || ent->filename && !*ent->filename) return 0;
  127. char filename2[MAX_PATH] = {0}; // full lfn path if set
  128. makeFilename2(ent->filename, filename2, ARRAYSIZE(filename2));
  129. if (!g_table) openDb();
  130. // first, check to see if it's in the db
  131. if (g_table)
  132. {
  133. EnterCriticalSection(&g_db_cs);
  134. nde_scanner_t s = NDE_Table_CreateScanner(g_table);
  135. if (NDE_Scanner_LocateFilename(s, MAINTABLE_ID_FILENAME, FIRST_RECORD, (AutoWideFn)(ent->filename)) ||
  136. (filename2[0] && NDE_Scanner_LocateFilename(s, MAINTABLE_ID_FILENAME, FIRST_RECORD, (AutoWideFn)(filename2))))
  137. {
  138. nde_field_t f;
  139. // found it db, yay!
  140. f = NDE_Scanner_GetFieldByID(s, MAINTABLE_ID_TITLE);
  141. if (!ent->title) ent->title = f ? AutoCharDup(NDE_StringField_GetString(f)) : 0;
  142. f = NDE_Scanner_GetFieldByID(s, MAINTABLE_ID_ALBUM);
  143. if (!ent->album) ent->album = f ? AutoCharDup(NDE_StringField_GetString(f)) : 0;
  144. f = NDE_Scanner_GetFieldByID(s, MAINTABLE_ID_ARTIST);
  145. if (!ent->artist) ent->artist = f ? AutoCharDup(NDE_StringField_GetString(f)) : 0;
  146. f = NDE_Scanner_GetFieldByID(s, MAINTABLE_ID_GENRE);
  147. if (!ent->genre) ent->genre = f ? AutoCharDup(NDE_StringField_GetString(f)) : 0;
  148. f = NDE_Scanner_GetFieldByID(s, MAINTABLE_ID_TRACKNB);
  149. if (ent->track <= 0) ent->track = f ? NDE_IntegerField_GetValue(f) : -1;
  150. f = NDE_Scanner_GetFieldByID(s, MAINTABLE_ID_YEAR);
  151. if (ent->year <= 0) ent->year = f ? NDE_IntegerField_GetValue(f) : -1;
  152. f = NDE_Scanner_GetFieldByID(s, MAINTABLE_ID_LENGTH);
  153. if (ent->length <= 0) ent->length = f ? NDE_IntegerField_GetValue(f) : -1;
  154. //ent->extended_info=NULL;//for now
  155. NDE_Table_DestroyScanner(g_table, s);
  156. LeaveCriticalSection(&g_db_cs);
  157. return 0;
  158. }
  159. NDE_Table_DestroyScanner(g_table, s);
  160. LeaveCriticalSection(&g_db_cs);
  161. }
  162. // if not, run the same shit as if we were adding it to the db!
  163. char *fnp = filename2[0] ? filename2 : ent->filename; // fnp is the file we will run through the guesswork
  164. char tmp[1024] = {0, };
  165. if (getFileInfo(fnp, "title", tmp, ARRAYSIZE(tmp) - 1))
  166. {
  167. if (tmp[0] && !ent->title)
  168. {
  169. ent->title = _strdup(tmp);
  170. }
  171. if (!ent->artist)
  172. {
  173. getFileInfo(ent->filename, "artist", tmp, ARRAYSIZE(tmp) - 1);
  174. if (tmp[0])
  175. {
  176. ent->artist = _strdup(tmp);
  177. }
  178. }
  179. if (!ent->album)
  180. {
  181. getFileInfo(ent->filename, "album", tmp, ARRAYSIZE(tmp) - 1);
  182. if (tmp[0])
  183. {
  184. ent->album = _strdup(tmp);
  185. }
  186. }
  187. if (ent->year <= 0)
  188. {
  189. getFileInfo(ent->filename, "year", tmp, ARRAYSIZE(tmp) - 1);
  190. if (tmp[0] && !strstr(tmp, "__") && !strstr(tmp, "/") && !strstr(tmp, "\\") && !strstr(tmp, "."))
  191. {
  192. char *p = tmp;
  193. while (p && *p)
  194. {
  195. if (*p == '_') *p = '0';
  196. p++;
  197. }
  198. int y = atoi(tmp);
  199. if (y != 0) ent->year = y;
  200. }
  201. }
  202. if (!ent->genre)
  203. {
  204. getFileInfo(ent->filename, "genre", tmp, ARRAYSIZE(tmp) - 1);
  205. if (tmp[0])
  206. {
  207. ent->genre = _strdup(tmp);
  208. }
  209. }
  210. if (ent->track <= 0)
  211. {
  212. getFileInfo(ent->filename, "track", tmp, ARRAYSIZE(tmp) - 1);
  213. if (tmp[0])
  214. {
  215. ent->track = atoi(tmp);
  216. }
  217. }
  218. if (ent->length <= 0)
  219. {
  220. getFileInfo(ent->filename, "length", tmp, ARRAYSIZE(tmp) - 1);
  221. if (tmp[0])
  222. {
  223. ent->length = atoi(tmp) / 1000;
  224. }
  225. }
  226. }
  227. if (!ent->title && !ent->artist && !ent->album && !ent->track)
  228. {
  229. int tn = 0;
  230. wchar_t *artist = 0, *album = 0, *title = 0;
  231. wchar_t *guessbuf = guessTitles(AutoWide(filename2[0] ? filename2 : ent->filename), &tn, &artist, &album, &title);
  232. if (guessbuf)
  233. {
  234. if (!ent->title && title)
  235. {
  236. ent->title = AutoCharDup(title);
  237. }
  238. if (!ent->artist && artist)
  239. {
  240. ent->artist = AutoCharDup(artist);
  241. }
  242. if (!ent->album && album)
  243. {
  244. ent->album = AutoCharDup(album);
  245. }
  246. if (ent->track <= 0 && tn)
  247. {
  248. ent->track = tn;
  249. }
  250. free(guessbuf);
  251. }
  252. }
  253. return 0;
  254. }
  255. int m_calling_getfileinfoW;
  256. static int getFileInfoW(const wchar_t *filename, const wchar_t *metadata, wchar_t *dest, int len)
  257. {
  258. m_calling_getfileinfoW=1;
  259. dest[0]=0;
  260. extendedFileInfoStructW efis={
  261. filename,
  262. metadata,
  263. dest,
  264. len,
  265. };
  266. int r = SendMessage(plugin.hwndWinampParent,WM_WA_IPC,(WPARAM)&efis,IPC_GET_EXTENDED_FILE_INFOW); //will return 1 if wa2 supports this IPC call
  267. m_calling_getfileinfoW=0;
  268. return r;
  269. }
  270. LRESULT IPC_GetFileInfoW(INT_PTR param)
  271. {
  272. if (!param) return 0;
  273. itemRecordW *ent = (itemRecordW *)param;
  274. if (!ent->filename || ent->filename && !*ent->filename) return 0;
  275. wchar_t filename2[MAX_PATH] = {0}; // full lfn path if set
  276. makeFilename2W(ent->filename, filename2, ARRAYSIZE(filename2));
  277. if (!g_table) openDb();
  278. // first, check to see if it's in the db
  279. if (g_table)
  280. {
  281. EnterCriticalSection(&g_db_cs);
  282. nde_scanner_t s = NDE_Table_CreateScanner(g_table);
  283. if (NDE_Scanner_LocateFilename(s, MAINTABLE_ID_FILENAME, FIRST_RECORD, ent->filename) ||
  284. (filename2[0] && NDE_Scanner_LocateFilename(s, MAINTABLE_ID_FILENAME, FIRST_RECORD, filename2)))
  285. {
  286. nde_field_t f;
  287. // found it db, yay!
  288. f = NDE_Scanner_GetFieldByID(s, MAINTABLE_ID_TITLE);
  289. if (!ent->title) ent->title = f ? NDE_StringField_GetString(f) : 0;
  290. f = NDE_Scanner_GetFieldByID(s, MAINTABLE_ID_ALBUM);
  291. if (!ent->album) ent->album = f ? NDE_StringField_GetString(f) : 0;
  292. f = NDE_Scanner_GetFieldByID(s, MAINTABLE_ID_ARTIST);
  293. if (!ent->artist) ent->artist = f ? NDE_StringField_GetString(f) : 0;
  294. f = NDE_Scanner_GetFieldByID(s, MAINTABLE_ID_GENRE);
  295. if (!ent->genre) ent->genre = f ? NDE_StringField_GetString(f) : 0;
  296. f = NDE_Scanner_GetFieldByID(s, MAINTABLE_ID_TRACKNB);
  297. if (ent->track <= 0) ent->track = f ? NDE_IntegerField_GetValue(f) : -1;
  298. f = NDE_Scanner_GetFieldByID(s, MAINTABLE_ID_YEAR);
  299. if (ent->year <= 0) ent->year = f ? NDE_IntegerField_GetValue(f) : -1;
  300. f = NDE_Scanner_GetFieldByID(s, MAINTABLE_ID_LENGTH);
  301. if (ent->length <= 0) ent->length = f ? NDE_IntegerField_GetValue(f) : -1;
  302. //ent->extended_info=NULL;//for now
  303. NDE_Table_DestroyScanner(g_table, s);
  304. LeaveCriticalSection(&g_db_cs);
  305. return 0;
  306. }
  307. NDE_Table_DestroyScanner(g_table, s);
  308. LeaveCriticalSection(&g_db_cs);
  309. }
  310. // if not, run the same shit as if we were adding it to the db!
  311. wchar_t *fnp = filename2[0] ? filename2 : ent->filename; // fnp is the file we will run through the guesswork
  312. wchar_t tmp[1024] = {0, };
  313. if (getFileInfoW(fnp, DB_FIELDNAME_title, tmp, ARRAYSIZE(tmp) - 1))
  314. {
  315. if (tmp[0] && !ent->title)
  316. {
  317. ent->title = _wcsdup(tmp);
  318. }
  319. if (!ent->artist)
  320. {
  321. getFileInfoW(ent->filename, DB_FIELDNAME_artist, tmp, ARRAYSIZE(tmp) - 1);
  322. if (tmp[0])
  323. {
  324. ent->artist = _wcsdup(tmp);
  325. }
  326. }
  327. if (!ent->album)
  328. {
  329. getFileInfoW(ent->filename, DB_FIELDNAME_album, tmp, ARRAYSIZE(tmp) - 1);
  330. if (tmp[0])
  331. {
  332. ent->album = _wcsdup(tmp);
  333. }
  334. }
  335. if (ent->year <= 0)
  336. {
  337. getFileInfoW(ent->filename, DB_FIELDNAME_year, tmp, ARRAYSIZE(tmp) - 1);
  338. if (tmp[0] && !wcsstr(tmp, L"__") && !wcsstr(tmp, L"/") && !wcsstr(tmp, L"\\") && !wcsstr(tmp, L"."))
  339. {
  340. wchar_t *p = tmp;
  341. while (p && *p)
  342. {
  343. if (*p == L'_') *p = L'0';
  344. p++;
  345. }
  346. int y = _wtoi(tmp);
  347. if (y != 0) ent->year = y;
  348. }
  349. }
  350. if (!ent->genre)
  351. {
  352. getFileInfoW(ent->filename, DB_FIELDNAME_genre, tmp, ARRAYSIZE(tmp) - 1);
  353. if (tmp[0])
  354. {
  355. ent->genre = _wcsdup(tmp);
  356. }
  357. }
  358. if (ent->track <= 0)
  359. {
  360. getFileInfoW(ent->filename, DB_FIELDNAME_track, tmp, ARRAYSIZE(tmp) - 1);
  361. if (tmp[0])
  362. {
  363. ent->track = _wtoi(tmp);
  364. }
  365. }
  366. if (ent->length <= 0)
  367. {
  368. getFileInfoW(ent->filename, DB_FIELDNAME_length, tmp, ARRAYSIZE(tmp) - 1);
  369. if (tmp[0])
  370. {
  371. ent->length = _wtoi(tmp) / 1000;
  372. }
  373. }
  374. }
  375. if (!ent->title && !ent->artist && !ent->album && !ent->track)
  376. {
  377. int tn = 0;
  378. wchar_t *artist = 0, *album = 0, *title = 0;
  379. wchar_t *guessbuf = guessTitles(filename2[0] ? filename2 : ent->filename, &tn, &artist, &album, &title);
  380. if (guessbuf)
  381. {
  382. if (!ent->title && title)
  383. {
  384. ent->title = _wcsdup(title);
  385. }
  386. if (!ent->artist && artist)
  387. {
  388. ent->artist = _wcsdup(artist);
  389. }
  390. if (!ent->album && album)
  391. {
  392. ent->album = _wcsdup(album);
  393. }
  394. if (ent->track <= 0 && tn)
  395. {
  396. ent->track = tn;
  397. }
  398. free(guessbuf);
  399. }
  400. }
  401. return 0;
  402. }
  403. LRESULT IPC_FreeFileInfo(INT_PTR param)
  404. {
  405. itemRecord *ent = (itemRecord *)param;
  406. if (!param) return 0;
  407. if (ent->album)
  408. {
  409. free(ent->album); ent->album = NULL;
  410. }
  411. if (ent->artist)
  412. {
  413. free(ent->artist); ent->artist = NULL;
  414. }
  415. if (ent->comment)
  416. {
  417. free(ent->comment); ent->comment = NULL;
  418. }
  419. if (ent->genre)
  420. {
  421. free(ent->genre); ent->genre = NULL;
  422. }
  423. if (ent->title)
  424. {
  425. free(ent->title); ent->title = NULL;
  426. }
  427. //if (ent->extended_info) { free(ent->extended_info); ent->extended_info= NULL; }
  428. return 0;
  429. }
  430. LRESULT IPC_FreeFileInfoW(INT_PTR param)
  431. {
  432. itemRecordW *ent = (itemRecordW *)param;
  433. if (!param) return 0;
  434. if (ent->album)
  435. {
  436. free(ent->album); ent->album = NULL;
  437. }
  438. if (ent->artist)
  439. {
  440. free(ent->artist); ent->artist = NULL;
  441. }
  442. if (ent->comment)
  443. {
  444. free(ent->comment); ent->comment = NULL;
  445. }
  446. if (ent->genre)
  447. {
  448. free(ent->genre); ent->genre = NULL;
  449. }
  450. if (ent->title)
  451. {
  452. free(ent->title); ent->title = NULL;
  453. }
  454. //if (ent->extended_info) { free(ent->extended_info); ent->extended_info= NULL; }
  455. return 0;
  456. }
  457. LRESULT IPC_EditView(INT_PTR param)
  458. {
  459. static char dummyNameChar[256];
  460. static char dummyQueryChar[1024];
  461. ml_editview *mev = (ml_editview *)param;
  462. if (mev == NULL) return 0;
  463. if (queryEditOther(mev->dialog_parent, mev->query, mev->name, mev->mode))
  464. {
  465. mev->mode = m_item_mode;
  466. WideCharToMultiByteSZ(CP_ACP, 0, m_item_name, -1, dummyNameChar, 256, 0, 0);
  467. mev->name = dummyNameChar;
  468. WideCharToMultiByteSZ(CP_ACP, 0, m_item_query, -1, dummyQueryChar, 1024, 0, 0);
  469. mev->query = dummyQueryChar;
  470. }
  471. else
  472. {
  473. mev->dialog_parent = NULL;
  474. mev->mode = -1;
  475. mev->name = NULL;
  476. mev->query = NULL;
  477. return 0;
  478. }
  479. return 1;
  480. }
  481. LRESULT IPC_EditQuery(INT_PTR param)
  482. {
  483. static char staticQuery[4096];
  484. ml_editquery *meq = (ml_editquery *)param;
  485. if (meq == NULL) return 0;
  486. wchar_t querybuf[4096] = {0};
  487. const wchar_t *newQuery = editQuery(meq->dialog_parent, AutoWide(meq->query), querybuf, 4096);
  488. WideCharToMultiByteSZ(CP_ACP, 0, newQuery, -1, staticQuery, 4096, 0, 0);
  489. meq->query = staticQuery;
  490. return meq->query != NULL;
  491. }
  492. bool FindFileInDB(nde_scanner_t s, const wchar_t *filename)
  493. {
  494. wchar_t filename2[MAX_PATH] = {0}; // full lfn path if set
  495. return !!FindFileInDatabase(s, MAINTABLE_ID_FILENAME, filename, filename2);
  496. }
  497. INT_PTR HandleIpcMessage(INT_PTR msg, INT_PTR param)
  498. {
  499. switch (msg)
  500. {
  501. /////////////////////// database API
  502. case ML_IPC_DB_RUNQUERYW:
  503. case ML_IPC_DB_RUNQUERY_SEARCHW:
  504. case ML_IPC_DB_RUNQUERY_FILENAMEW:
  505. case ML_IPC_DB_RUNQUERY_INDEXW:
  506. if (!g_table) openDb();
  507. if (param && g_table)
  508. {
  509. mlQueryStructW *p = (mlQueryStructW *)param;
  510. itemRecordListW *obj = &p->results;
  511. int failed = 0;
  512. EnterCriticalSection(&g_db_cs);
  513. nde_scanner_t s = NDE_Table_CreateScanner(g_table);
  514. if (msg == ML_IPC_DB_RUNQUERY_SEARCHW)
  515. {
  516. if (p->query)
  517. {
  518. GayStringW gs;
  519. makeQueryStringFromText(&gs, p->query);
  520. if (gs.Get() && gs.Get()[0]) NDE_Scanner_Query(s, gs.Get());
  521. }
  522. NDE_Scanner_First(s);
  523. }
  524. else if (msg == ML_IPC_DB_RUNQUERY_INDEXW)
  525. {
  526. failed=1;
  527. }
  528. else if (msg == ML_IPC_DB_RUNQUERY_FILENAMEW)
  529. {
  530. failed = 1;
  531. if (p->query)
  532. {
  533. if (NDE_Scanner_LocateFilename(s, MAINTABLE_ID_FILENAME, FIRST_RECORD, p->query))
  534. {
  535. failed = 0;
  536. }
  537. }
  538. }
  539. else
  540. {
  541. if (p->query)
  542. NDE_Scanner_Query(s, p->query);
  543. NDE_Scanner_First(s);
  544. }
  545. if (!failed)
  546. {
  547. int cnt = 0;
  548. do
  549. {
  550. nde_field_t f = NDE_Scanner_GetFieldByID(s, MAINTABLE_ID_FILENAME);
  551. if (!f) break;
  552. allocRecordList(obj, obj->Size + 1);
  553. if (!obj->Alloc) break;
  554. obj->Items[obj->Size].filename = NDE_StringField_GetString(f);
  555. ndestring_retain(obj->Items[obj->Size].filename);
  556. ScannerRefToObjCacheNFNW(s, obj, true);
  557. // this makes 0 give unlimited results, 1 give 1, and so on.
  558. if (++cnt == p->max_results || msg == ML_IPC_DB_RUNQUERY_FILENAMEW
  559. /*|| msg == ML_IPC_DB_RUNQUERY_INDEX*/) break;
  560. }
  561. while (NDE_Scanner_Next(s));
  562. }
  563. NDE_Table_DestroyScanner(g_table, s);
  564. LeaveCriticalSection(&g_db_cs);
  565. compactRecordList(obj);
  566. return failed ? -1 : 1;
  567. }
  568. return -1;
  569. case ML_IPC_DB_RUNQUERY:
  570. case ML_IPC_DB_RUNQUERY_SEARCH:
  571. case ML_IPC_DB_RUNQUERY_FILENAME:
  572. case ML_IPC_DB_RUNQUERY_INDEX:
  573. {
  574. mlQueryStruct *p = (mlQueryStruct*)param;
  575. mlQueryStructW pW;
  576. AutoWide wideQuery(p->query);
  577. pW.query = wideQuery;
  578. pW.max_results = p->max_results;
  579. memset(&pW.results, 0, sizeof(pW.results));
  580. INT_PTR res = HandleIpcMessage(msg+0x1000, (INT_PTR)&pW); // convienently the W messages are 0x1000 higher
  581. itemRecordList *obj = &p->results;
  582. // append new results to old results
  583. for (int i=0;i!=pW.results.Size;i++)
  584. {
  585. allocRecordList(obj, obj->Size + 1);
  586. if (!obj->Alloc) break;
  587. convertRecord(&obj->Items[obj->Size++], &pW.results.Items[i]);
  588. }
  589. freeRecordList(&pW.results);
  590. return res;
  591. }
  592. case ML_IPC_DB_FREEQUERYRESULTS:
  593. if (param)
  594. {
  595. mlQueryStruct *p = (mlQueryStruct*)param;
  596. freeRecordList(&p->results);
  597. return 1;
  598. }
  599. return -1;
  600. case ML_IPC_DB_FREEQUERYRESULTSW:
  601. if (param)
  602. {
  603. mlQueryStructW *p = (mlQueryStructW*)param;
  604. freeRecordList(&p->results);
  605. return 1;
  606. }
  607. return -1;
  608. case ML_IPC_DB_REMOVEITEM:
  609. case ML_IPC_DB_REMOVEITEMW:
  610. if (!g_table) openDb();
  611. if (param && g_table)
  612. {
  613. wchar_t *filename = (((msg == ML_IPC_DB_REMOVEITEMW) ? (wchar_t*)param : AutoWideFn((char*)param)));
  614. int ret = ( RemoveFileFromDB(filename) == 0 ) ? 1 : -2; // Change the return value from the stadard 0 == success, > 0 == fail
  615. return ret;
  616. }
  617. return -1;
  618. case ML_IPC_DB_UPDATEITEMW:
  619. case ML_IPC_DB_ADDORUPDATEITEMW:
  620. if (!g_table) openDb();
  621. if (param && g_table)
  622. {
  623. int ret = 1;
  624. itemRecordW *item = (itemRecordW*)param;
  625. if (!item->filename) return -1;
  626. EnterCriticalSection(&g_db_cs);
  627. nde_scanner_t s = NDE_Table_CreateScanner(g_table);
  628. if (FindFileInDB(s, item->filename))
  629. {
  630. NDE_Scanner_Edit(s);
  631. }
  632. else
  633. {
  634. if (msg == ML_IPC_DB_UPDATEITEMW) ret = -2;
  635. else
  636. {
  637. // new file
  638. NDE_Scanner_New(s);
  639. db_setFieldStringW(s, MAINTABLE_ID_FILENAME, item->filename);
  640. db_setFieldInt(s, MAINTABLE_ID_DATEADDED, (int)time(NULL));
  641. }
  642. }
  643. if (ret == 1)
  644. {
  645. // update applicable members
  646. if (item->title) db_setFieldStringW(s, MAINTABLE_ID_TITLE, item->title);
  647. if (item->album) db_setFieldStringW(s, MAINTABLE_ID_ALBUM, item->album);
  648. if (item->artist) db_setFieldStringW(s, MAINTABLE_ID_ARTIST, item->artist);
  649. if (item->comment) db_setFieldStringW(s, MAINTABLE_ID_COMMENT, item->comment);
  650. if (item->genre) db_setFieldStringW(s, MAINTABLE_ID_GENRE, item->genre);
  651. if (item->albumartist) db_setFieldStringW(s, MAINTABLE_ID_ALBUMARTIST, item->albumartist);
  652. if (item->replaygain_album_gain) db_setFieldStringW(s, MAINTABLE_ID_ALBUMGAIN, item->replaygain_album_gain);
  653. if (item->replaygain_track_gain) db_setFieldStringW(s, MAINTABLE_ID_TRACKGAIN, item->replaygain_track_gain);
  654. if (item->publisher) db_setFieldStringW(s, MAINTABLE_ID_PUBLISHER, item->publisher);
  655. if (item->composer) db_setFieldStringW(s, MAINTABLE_ID_COMPOSER, item->composer);
  656. if (item->category) db_setFieldStringW(s, MAINTABLE_ID_CATEGORY, item->category);
  657. if (item->year >= 0) db_setFieldInt(s, MAINTABLE_ID_YEAR, item->year);
  658. if (item->track >= 0) db_setFieldInt(s, MAINTABLE_ID_TRACKNB, item->track);
  659. if (item->tracks >= 0) db_setFieldInt(s, MAINTABLE_ID_TRACKS, item->tracks);
  660. if (item->length >= 0) db_setFieldInt(s, MAINTABLE_ID_LENGTH, item->length);
  661. if (item->rating >= 0)
  662. {
  663. db_setFieldInt(s, MAINTABLE_ID_RATING, item->rating);
  664. if (g_config->ReadInt(L"writeratings", 0))
  665. {
  666. wchar_t buf[64] = {0};
  667. if (item->rating > 0)
  668. {
  669. wsprintfW(buf, L"%d", item->rating);
  670. }
  671. else
  672. buf[0] = 0;
  673. updateFileInfo(item->filename, DB_FIELDNAME_rating, buf);
  674. SendMessage(plugin.hwndWinampParent, WM_WA_IPC, 0, IPC_WRITE_EXTENDED_FILE_INFO);
  675. }
  676. }
  677. if (item->lastplay >= 0) db_setFieldInt(s, MAINTABLE_ID_LASTPLAY, (int)item->lastplay);
  678. if (item->lastupd >= 0) db_setFieldInt(s, MAINTABLE_ID_LASTUPDTIME, (int)item->lastupd);
  679. if (item->filetime >= 0) db_setFieldInt(s, MAINTABLE_ID_FILETIME, (int)item->filetime);
  680. if (item->filesize >= 0)
  681. {
  682. // changed in 5.64 to use the 'realsize' if it's available, otherwise map to filesize scaled to bytes (was stored as kb previously)
  683. const wchar_t *realsize = getRecordExtendedItem(item, L"realsize");
  684. if (realsize) db_setFieldInt64(s, MAINTABLE_ID_FILESIZE, _wtoi64(realsize));
  685. else db_setFieldInt(s, MAINTABLE_ID_FILESIZE, item->filesize * 1024);
  686. }
  687. if (item->bitrate >= 0) db_setFieldInt(s, MAINTABLE_ID_BITRATE, item->bitrate);
  688. if (item->type >= 0) db_setFieldInt(s, MAINTABLE_ID_TYPE, item->type);
  689. if (item->disc >= 0) db_setFieldInt(s, MAINTABLE_ID_DISC, item->disc);
  690. if (item->discs >= 0) db_setFieldInt(s, MAINTABLE_ID_DISCS, item->discs);
  691. if (item->bpm >= 0) db_setFieldInt(s, MAINTABLE_ID_BPM, item->bpm);
  692. // give a default playcnt of 0 if we're creating a new one and the caller
  693. // didn't specify a playcnt
  694. if (item->playcount >= 0)
  695. db_setFieldInt(s, MAINTABLE_ID_PLAYCOUNT, item->playcount);
  696. else
  697. db_setFieldInt(s, MAINTABLE_ID_PLAYCOUNT, 0);
  698. for (int x = 0; x < NUM_EXTRA_COLSW; x ++)
  699. {
  700. wchar_t *at = getRecordExtendedItem(item, extra_strsW[x]); // can't use _fast here because it's not our itemRecordW
  701. if (at)
  702. {
  703. switch (extra_idsW[x])
  704. {
  705. case MAINTABLE_ID_LOSSLESS:
  706. case MAINTABLE_ID_PODCASTPUBDATE:
  707. case MAINTABLE_ID_ISPODCAST:
  708. case MAINTABLE_ID_WIDTH:
  709. case MAINTABLE_ID_HEIGHT:
  710. if (*at)
  711. db_setFieldInt(s, extra_idsW[x], _wtoi(at));
  712. break;
  713. case MAINTABLE_ID_GRACENOTEFILEID:
  714. case MAINTABLE_ID_GRACENOTEEXTDATA:
  715. case MAINTABLE_ID_PODCASTCHANNEL:
  716. case MAINTABLE_ID_CODEC:
  717. case MAINTABLE_ID_DIRECTOR:
  718. case MAINTABLE_ID_PRODUCER:
  719. db_setFieldStringW(s, extra_idsW[x], at);
  720. break;
  721. }
  722. }
  723. }
  724. NDE_Scanner_Post(s);
  725. g_table_dirty++;
  726. }
  727. NDE_Table_DestroyScanner(g_table, s);
  728. LeaveCriticalSection(&g_db_cs);
  729. return ret;
  730. }
  731. return -1;
  732. case ML_IPC_DB_UPDATEITEM:
  733. case ML_IPC_DB_ADDORUPDATEITEM:
  734. {
  735. itemRecord *item = (itemRecord*)param;
  736. if (!item || !item->filename)
  737. return -1;
  738. itemRecordW wideRecord;
  739. memset(&wideRecord, 0, sizeof(wideRecord));
  740. convertRecord(&wideRecord, item);
  741. INT_PTR res = HandleIpcMessage(msg+0x1000, (INT_PTR)&wideRecord); // unicode message values are convienantly 0x1000 higher here
  742. freeRecord(&wideRecord);
  743. return res;
  744. }
  745. case ML_IPC_DB_UPDATEFILEW:
  746. case ML_IPC_DB_ADDORUPDATEFILEW:
  747. if (!g_table) openDb();
  748. if (param && g_table)
  749. {
  750. LMDB_FILE_ADD_INFOW *fi = (LMDB_FILE_ADD_INFOW *)param;
  751. if (!fi || !fi->fileName) return -1;
  752. int guess = (fi->gues_mode == -1) ? g_config->ReadInt(L"guessmode", 0) : fi->gues_mode;
  753. int meta = (fi->meta_mode == -1) ? g_config->ReadInt(L"usemetadata", 1) : fi->meta_mode;
  754. return addFileToDb(fi->fileName, msg == ML_IPC_DB_UPDATEFILEW ? 1 : 0, meta, guess);
  755. }
  756. return -1;
  757. case ML_IPC_DB_UPDATEFILE:
  758. case ML_IPC_DB_ADDORUPDATEFILE:
  759. if (!g_table) openDb();
  760. if (param && g_table)
  761. {
  762. LMDB_FILE_ADD_INFO *fi = (LMDB_FILE_ADD_INFO*)param;
  763. if (!fi || !fi->fileName) return -1;
  764. int guess = (fi->gues_mode == -1) ? g_config->ReadInt(L"guessmode", 0) : fi->gues_mode;
  765. int meta = (fi->meta_mode == -1) ? g_config->ReadInt(L"usemetadata", 1) : fi->meta_mode;
  766. return addFileToDb(AutoWide(fi->fileName), msg == ML_IPC_DB_UPDATEFILE ? 1 : 0, meta, guess);
  767. }
  768. return -1;
  769. case ML_IPC_DB_SYNCDB:
  770. if (!g_table) openDb();
  771. if (g_table && g_table_dirty)
  772. {
  773. EnterCriticalSection(&g_db_cs);
  774. g_table_dirty = 0;
  775. NDE_Table_Sync(g_table);
  776. LeaveCriticalSection(&g_db_cs);
  777. return 1;
  778. }
  779. return -1;
  780. case ML_IPC_GET_FILE_RATINGW: return IPC_GetFileRatingW(param);
  781. case ML_IPC_SET_FILE_RATINGW: return IPC_SetFileRatingW(param);
  782. case ML_IPC_GET_FILE_RATING: return IPC_GetFileRating(param);
  783. case ML_IPC_SET_FILE_RATING: return IPC_SetFileRating(param);
  784. case ML_IPC_FREEFILEINFO: return IPC_FreeFileInfo(param);
  785. case ML_IPC_FREEFILEINFOW: return IPC_FreeFileInfoW(param);
  786. case ML_IPC_GETFILEINFO: return IPC_GetFileInfo(param);
  787. case ML_IPC_GETFILEINFOW: return IPC_GetFileInfoW(param);
  788. case ML_IPC_PLAY_PLAYLIST:
  789. case ML_IPC_LOAD_PLAYLIST:
  790. {
  791. // play/load the playlist passed as param
  792. queryItem *item = m_query_list[param];
  793. if (item)
  794. {
  795. wchar_t configDir[MAX_PATH] = {0};
  796. PathCombineW(configDir, g_viewsDir, item->metafn);
  797. C_Config viewconf(configDir);
  798. main_playQuery(&viewconf, item->query, 0, msg == ML_IPC_PLAY_PLAYLIST);
  799. }
  800. }
  801. break;
  802. case ML_IPC_EDITVIEW: return IPC_EditView(param);
  803. case ML_IPC_EDITQUERY: return IPC_EditQuery(param);
  804. case ML_IPC_SMARTVIEW_COUNT:
  805. return m_query_list.size();
  806. case ML_IPC_SMARTVIEW_INFO:
  807. if (param)
  808. {
  809. mlSmartViewInfo * v = (mlSmartViewInfo *)param;
  810. if (v->size < sizeof(mlSmartViewInfo)) break;
  811. if (v->smartViewNum >= m_query_list.size()) break;
  812. auto it = m_query_list.begin();
  813. while (v->smartViewNum--)
  814. {
  815. it++;
  816. }
  817. queryItem* q = it->second; //(m_query_list.begin()+v->smartViewNum)->second;
  818. if (!q) break;
  819. if (!q->name || !q->query) break;
  820. v->treeItemId = it->first; //(m_query_list.begin()+v->smartViewNum)->first;
  821. v->iconImgIndex = q->imgIndex;
  822. v->mode = q->mode;
  823. lstrcpynW(v->smartViewName,q->name,sizeof(v->smartViewName)/sizeof(wchar_t));
  824. lstrcpynW(v->smartViewQuery,q->query,sizeof(v->smartViewQuery)/sizeof(wchar_t));
  825. return 1;
  826. }
  827. break;
  828. case ML_IPC_SMARTVIEW_ADD:
  829. if (param)
  830. {
  831. mlSmartViewInfo * v = (mlSmartViewInfo *)param;
  832. if (v->size < sizeof(mlSmartViewInfo)) break;
  833. v->treeItemId = addQueryItem(v->smartViewName,v->smartViewQuery,v->mode,0,NULL,v->iconImgIndex, v->smartViewNum);
  834. saveQueryTree();
  835. return 1;
  836. }
  837. break;
  838. }
  839. return 0;
  840. }