syncCloudDialog.cpp 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675
  1. #include "main.h"
  2. #include "metadata_utils.h"
  3. #include <strsafe.h>
  4. #include "../playlist/ifc_playlistloadercallback.h"
  5. #include "resource1.h"
  6. #include <shlwapi.h>
  7. #define SYNCCLOUDDIALOG_PROP L"SyncCloudDialogProp"
  8. typedef struct SyncCloudDialog
  9. {
  10. HWND centerWindow;
  11. DeviceView *device;
  12. C_ItemList *libraryList;
  13. C_ItemList *playlistsList;
  14. } SyncCloudDialog;
  15. #define SYNCCLOUDDIALOG(_hwnd) ((SyncCloudDialog*)GetPropW((_hwnd), SYNCCLOUDDIALOG_PROP))
  16. static INT_PTR CALLBACK SyncCloudDialog_DialogProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
  17. INT_PTR SyncCloudDialog_Show(HWND centerWindow, DeviceView *device, C_ItemList *libraryList)
  18. {
  19. SyncCloudDialog param;
  20. param.centerWindow = centerWindow;
  21. param.device = device;
  22. param.libraryList = libraryList;
  23. param.playlistsList = new C_ItemList;
  24. return WASABI_API_DIALOGBOXPARAMW(IDD_CLOUD_SYNC, plugin.hwndLibraryParent, SyncCloudDialog_DialogProc, (LPARAM)&param);
  25. }
  26. static BOOL SyncCloudDialog_FormatSongString(wchar_t *buffer, size_t bufferSize, const wchar_t *artist,
  27. const wchar_t *title, const wchar_t *fileName)
  28. {
  29. HRESULT hr;
  30. if (NULL == buffer)
  31. return FALSE;
  32. if (NULL == title || L'\0' == *title)
  33. {
  34. if (NULL == fileName || L'\0' == *fileName)
  35. {
  36. WASABI_API_LNGSTRINGW_BUF(IDS_UNKNOWN_TRACK, buffer, bufferSize);
  37. hr = S_OK;
  38. }
  39. else
  40. hr = StringCchCopyEx(buffer, bufferSize, fileName, NULL, NULL, STRSAFE_IGNORE_NULLS);
  41. }
  42. else if (NULL == artist || L'\0' == *artist)
  43. {
  44. hr = StringCchCopyEx(buffer, bufferSize, title, NULL, NULL, STRSAFE_IGNORE_NULLS);
  45. }
  46. else
  47. {
  48. hr = StringCchPrintfEx(buffer, bufferSize, NULL, NULL, STRSAFE_IGNORE_NULLS,
  49. L"%s - %s", artist, title);
  50. }
  51. return SUCCEEDED(hr);
  52. }
  53. WORD WGetListboxStringExtent(HWND hList, wchar_t* psz){
  54. WORD wExtent = 0;
  55. HDC hDC = GetDC(hList);
  56. int tab[] = {0};
  57. SelectObject(hDC,(HFONT)SendMessage(hList,WM_GETFONT,0,0));
  58. wExtent = LOWORD(GetTabbedTextExtent(hDC,psz,lstrlen(psz)+1,0,tab));
  59. ReleaseDC(hList,hDC);
  60. return wExtent;
  61. }
  62. DWORD fill_listbox(HWND list, wchar_t* string, DWORD width){
  63. DWORD prev = width;
  64. DWORD dwExtent = WGetListboxStringExtent(list,string);
  65. if(prev < dwExtent){prev = dwExtent;}
  66. return prev;
  67. }
  68. class SyncCloudItemListLoader : public ifc_playlistloadercallback
  69. {
  70. public:
  71. void OnFile(const wchar_t *filename, const wchar_t *title, int lengthInMS, ifc_plentryinfo *info)
  72. {
  73. if(pos < len)
  74. {
  75. if (info)
  76. {
  77. // look at the devices we've already uploaded to vs the destination
  78. const wchar_t * devices = info->GetExtendedInfo(L"cloud_devices");
  79. if (devices)
  80. {
  81. wchar_t* pt = wcstok((wchar_t*)devices, L"*");
  82. while (pt)
  83. {
  84. if (_wtoi(pt) == device_id)
  85. {
  86. done++;
  87. return;
  88. }
  89. pt = wcstok(NULL, L"*");
  90. }
  91. }
  92. }
  93. // check if the file exists, skipping if not
  94. if (PathFileExistsW(filename))
  95. {
  96. __int64 file_size = INVALID_FILE_SIZE;
  97. time_t file_time = 0;
  98. GetFileSizeAndTime(filename, &file_size, &file_time);
  99. if (!(file_size == INVALID_FILE_SIZE || file_size == 0))
  100. {
  101. total_size += file_size;
  102. }
  103. songs[pos].filename = _wcsdup(filename);
  104. pos++;
  105. }
  106. else
  107. {
  108. done++;
  109. }
  110. }
  111. }
  112. int64_t total_size;
  113. int pos, len, done, device_id;
  114. songMapping * songs;
  115. protected:
  116. RECVS_DISPATCH;
  117. };
  118. #define CBCLASS SyncCloudItemListLoader
  119. START_DISPATCH;
  120. VCB(IFC_PLAYLISTLOADERCALLBACK_ONFILE, OnFile)
  121. END_DISPATCH;
  122. #undef CBCLASS
  123. static BOOL SyncCloudDialog_PopulatePlaylistLists(HWND hwnd)
  124. {
  125. SyncCloudDialog *self = SYNCCLOUDDIALOG(hwnd);
  126. if (NULL == self)
  127. return FALSE;
  128. HWND hList = GetDlgItem(hwnd, IDC_LIST_ADD_PL);
  129. if(NULL != hList)
  130. {
  131. DWORD list_width = 0;
  132. SendMessage(hList, WM_SETREDRAW, FALSE, 0L);
  133. SendMessage(hList, LB_RESETCONTENT, FALSE, 0L);
  134. // first collect playlists without metadata
  135. int playlistsnum = SendMessage(plugin.hwndLibraryParent, WM_ML_IPC, 0, ML_IPC_PLAYLIST_COUNT);
  136. for(int i = 0, count = 0; i < playlistsnum; i++)
  137. {
  138. SyncCloudItemListLoader* list = new SyncCloudItemListLoader();
  139. mlPlaylistInfo* playlist = (mlPlaylistInfo*)calloc(sizeof(mlPlaylistInfo),1);
  140. playlist->size = sizeof(mlPlaylistInfo);
  141. playlist->playlistNum = i;
  142. SendMessage(plugin.hwndLibraryParent, WM_ML_IPC, (WPARAM)playlist, ML_IPC_PLAYLIST_INFO);
  143. if (playlist->numItems > 0)
  144. {
  145. wchar_t buf[256] = {0};
  146. list->device_id = self->device->dev->extraActions(DEVICE_GET_CLOUD_DEVICE_ID, 0, 0, 0);
  147. list->total_size = list->pos = list->done = 0;
  148. list->len = playlist->numItems;
  149. list->songs = (songMapping*)calloc(sizeof(songMapping), list->len);
  150. playlistManager->Load(playlist->filename, list);
  151. list->len -= list->done;
  152. if (list->len > 0)
  153. {
  154. if (list->done > 0)
  155. {
  156. StringCchPrintfW(buf, 256, WASABI_API_LNGSTRINGW(IDS_CLOUD_SYNC_PL_SOME), playlist->playlistName, list->done);
  157. }
  158. int pos = SendMessageW(hList, LB_ADDSTRING, 0, (LPARAM)(buf[0] ? buf : playlist->playlistName));
  159. SendMessage(hList, LB_SETITEMDATA, pos, count);
  160. self->playlistsList->Add(list);
  161. count++;
  162. }
  163. else
  164. {
  165. StringCchPrintfW(buf, 256, WASABI_API_LNGSTRINGW(IDS_CLOUD_SYNC_PL_EMPTY), playlist->playlistName);
  166. int pos = SendMessageW(hList, LB_ADDSTRING, 0, (LPARAM)buf);
  167. SendMessage(hList, LB_SETITEMDATA, pos, -1);
  168. }
  169. }
  170. }
  171. SendMessage(hList, WM_SETREDRAW, TRUE, 0L);
  172. SendMessage(hList, LB_SETHORIZONTALEXTENT, list_width, 0L);
  173. }
  174. return TRUE;
  175. }
  176. static BOOL SyncCloudDialog_PopulateTrackLists(HWND hwnd)
  177. {
  178. SyncCloudDialog *self;
  179. HWND hList;
  180. wchar_t buffer[1024] = {0};
  181. int index, count;
  182. self = SYNCCLOUDDIALOG(hwnd);
  183. if (NULL == self)
  184. return FALSE;
  185. hList = GetDlgItem(hwnd, IDC_LIST_ADD);
  186. if(NULL != hList)
  187. {
  188. DWORD list_width = 0;
  189. SendMessage(hList, WM_SETREDRAW, FALSE, 0L);
  190. SendMessage(hList, LB_RESETCONTENT, FALSE, 0L);
  191. count = (NULL != self->libraryList) ? self->libraryList->GetSize() : 0;
  192. if (0 != count)
  193. {
  194. itemRecordW *record;
  195. SendMessage(hList, LB_SETCOUNT , (WPARAM)count, 0L);
  196. for(index = 0; index < count; index++)
  197. {
  198. record = (itemRecordW*)self->libraryList->Get(index);
  199. if (NULL != record &&
  200. FALSE != SyncCloudDialog_FormatSongString(buffer, ARRAYSIZE(buffer),
  201. record->artist, record->title, record->filename))
  202. {
  203. SendMessageW(hList, LB_ADDSTRING, 0, (LPARAM)buffer);
  204. list_width = fill_listbox(hList,buffer,list_width);
  205. }
  206. }
  207. }
  208. SendMessage(hList, WM_SETREDRAW, TRUE, 0L);
  209. SendMessage(hList, LB_SETHORIZONTALEXTENT, list_width, 0L);
  210. }
  211. return TRUE;
  212. }
  213. static int SyncCloudDialog_ReadTransferOptions(SyncCloudDialog *self)
  214. {
  215. if (NULL != self && NULL != self->device && NULL != self->device->config)
  216. {
  217. C_Config *config;
  218. config = self->device->config;
  219. return config->ReadInt(L"CloudSyncMode", 0);
  220. }
  221. return 0;
  222. }
  223. static BOOL SyncCloudDialog_WriteTransferOptions(SyncCloudDialog *self, int mode)
  224. {
  225. if (NULL != self && NULL != self->device && NULL != self->device->config)
  226. {
  227. C_Config *config;
  228. config = self->device->config;
  229. config->WriteInt(L"CloudSyncMode", mode);
  230. return TRUE;
  231. }
  232. return FALSE;
  233. }
  234. static void SyncCloudDialog_UpdateTransferOptions(HWND hwnd, int mode)
  235. {
  236. const int control[] =
  237. {
  238. IDC_CLOUDSYNC_ALL,
  239. IDC_CLOUDSYNC_SEL,
  240. IDC_CLOUDSYNC_NOTSEL
  241. };
  242. const int controls[] =
  243. {
  244. IDS_CLOUD_SYNC_ALL_SONGS,
  245. IDS_CLOUD_SYNC_SEL_SONGS,
  246. IDS_CLOUD_SYNC_NONSEL_SONGS
  247. };
  248. const int controls_pl[] =
  249. {
  250. IDS_CLOUD_SYNC_ALL_PL,
  251. IDS_CLOUD_SYNC_SEL_PL,
  252. IDS_CLOUD_SYNC_NONSEL_PL
  253. };
  254. switch (mode)
  255. {
  256. case 0:
  257. for (int i = 0; i < sizeof(controls_pl)/sizeof(controls_pl[0]); i++)
  258. {
  259. SetDlgItemText(hwnd, control[i], WASABI_API_LNGSTRINGW(controls_pl[i]));
  260. }
  261. ShowWindow(GetDlgItem(hwnd, IDC_LIST_ADD_PL), TRUE);
  262. ShowWindow(GetDlgItem(hwnd, IDC_LIST_ADD), FALSE);
  263. break;
  264. case 1:
  265. for (int i = 0; i < sizeof(controls)/sizeof(controls[0]); i++)
  266. {
  267. SetDlgItemText(hwnd, control[i], WASABI_API_LNGSTRINGW(controls[i]));
  268. }
  269. ShowWindow(GetDlgItem(hwnd, IDC_LIST_ADD_PL), FALSE);
  270. ShowWindow(GetDlgItem(hwnd, IDC_LIST_ADD), TRUE);
  271. break;
  272. }
  273. }
  274. static BOOL SyncCloudDialog_UpdateCaption(HWND hwnd)
  275. {
  276. SyncCloudDialog *self;
  277. HWND captionWindow, hList;
  278. wchar_t buffer[1024] = {0};
  279. self = SYNCCLOUDDIALOG(hwnd);
  280. if (NULL == self)
  281. return FALSE;
  282. captionWindow = GetDlgItem(hwnd, IDC_DETAILS);
  283. if (NULL == captionWindow)
  284. return FALSE;
  285. int mode = SyncCloudDialog_ReadTransferOptions(self);
  286. hList = GetDlgItem(hwnd, (mode ? IDC_LIST_ADD : IDC_LIST_ADD_PL));
  287. if (NULL == hList)
  288. return FALSE;
  289. int64_t total_size = 0, sel_size = 0,
  290. device_size = self->device->dev->getDeviceCapacityAvailable();
  291. int all = (IsDlgButtonChecked(hwnd, IDC_CLOUDSYNC_ALL) == BST_CHECKED);
  292. int sel = (IsDlgButtonChecked(hwnd, IDC_CLOUDSYNC_SEL) == BST_CHECKED);
  293. if (mode)
  294. {
  295. for (int i = 0; i < self->libraryList->GetSize(); i++)
  296. {
  297. if (all || SendMessage(hList, LB_GETSEL, i, 0) != !sel)
  298. {
  299. itemRecordW *record = (itemRecordW *)self->libraryList->Get(i);
  300. total_size += record->filesize * 1024;
  301. sel_size += 1;
  302. }
  303. }
  304. }
  305. else
  306. {
  307. for (int i = 0; i < SendMessage(hList, LB_GETCOUNT, 0, 0); i++)
  308. {
  309. if (all || SendMessage(hList, LB_GETSEL, i, 0) != !sel)
  310. {
  311. int item = SendMessage(hList, LB_GETITEMDATA, i, 0);
  312. if (item != -1)
  313. {
  314. SyncCloudItemListLoader *list = (SyncCloudItemListLoader *)self->playlistsList->Get(item);
  315. total_size += list->total_size;
  316. sel_size += list->len;
  317. }
  318. }
  319. }
  320. }
  321. wchar_t buf[64] = {0}, buf2[64] = {0}, buf3[128] = {0}, buf4[128] = {0},
  322. buffer2[256] = {0}, local_lib[128] = {0};
  323. WASABI_API_LNG->FormattedSizeString(buf, ARRAYSIZE(buf), total_size);
  324. WASABI_API_LNG->FormattedSizeString(buf2, ARRAYSIZE(buf2), device_size);
  325. int64_t over_limit = (total_size - device_size);
  326. if (over_limit > 0)
  327. {
  328. WASABI_API_LNG->FormattedSizeString(buf4, ARRAYSIZE(buf4), over_limit);
  329. }
  330. self->device->GetDisplayName(buf3, ARRAYSIZE(buf3));
  331. int over_size = (device_size > 0 && total_size <= device_size);
  332. // enable the transfer button as applicable
  333. EnableWindow(GetDlgItem(hwnd, IDOK), sel_size && over_size);
  334. WASABI_API_LNGSTRINGW_BUF(IDS_CLOUD_LOCAL_LIBRARY, local_lib, 128);
  335. StringCchPrintf(buffer, ARRAYSIZE(buffer),
  336. WASABI_API_LNGSTRINGW(IDS_CLOUD_TX_X_TO_Y),
  337. local_lib, buf3);
  338. SetWindowText(hwnd, buffer);
  339. StringCchPrintf(buffer, ARRAYSIZE(buffer), WASABI_API_LNGSTRINGW(IDS_CLOUD_TX_HAVE_SELECTED_X), local_lib, buf3, sel_size, buf, buf3, buf2);
  340. if (sel_size && over_limit > 0)
  341. {
  342. StringCchPrintf(buffer2, ARRAYSIZE(buffer2), WASABI_API_LNGSTRINGW(IDS_CLOUD_TX_OVER_LIMIT), buf4, buf3);
  343. StringCchCat(buffer, ARRAYSIZE(buffer), buffer2);
  344. }
  345. else if (!sel_size)
  346. {
  347. StringCchPrintf(buffer, ARRAYSIZE(buffer), WASABI_API_LNGSTRINGW(IDS_CLOUD_TX_NO_SEL), local_lib, buf3);
  348. }
  349. SendMessage(captionWindow, WM_SETTEXT, 0, (LPARAM)buffer);
  350. return TRUE;
  351. }
  352. static void SyncCloudDialog_GenerateList(HWND hwnd)
  353. {
  354. SyncCloudDialog *self;
  355. HWND hList;
  356. self = SYNCCLOUDDIALOG(hwnd);
  357. if (NULL == self)
  358. return;
  359. int mode = SyncCloudDialog_ReadTransferOptions(self);
  360. hList = GetDlgItem(hwnd, (mode ? IDC_LIST_ADD : IDC_LIST_ADD_PL));
  361. if (NULL == hList)
  362. return;
  363. if (mode)
  364. {
  365. if ((IsDlgButtonChecked(hwnd, IDC_CLOUDSYNC_ALL) == BST_UNCHECKED))
  366. {
  367. int sel = (IsDlgButtonChecked(hwnd, IDC_CLOUDSYNC_SEL) == BST_CHECKED),
  368. current = 0, l = self->libraryList->GetSize();
  369. for (int i = 0; i < l; i++)
  370. {
  371. if (SendMessage(hList, LB_GETSEL, i, 0) != !sel)
  372. {
  373. current++;
  374. }
  375. else
  376. {
  377. self->libraryList->Del(current);
  378. }
  379. }
  380. }
  381. }
  382. else
  383. {
  384. // no need for this so clear out
  385. int l = self->libraryList->GetSize();
  386. for (int i = 0; i < l; i++)
  387. {
  388. self->libraryList->Del(0);
  389. }
  390. int all = (IsDlgButtonChecked(hwnd, IDC_CLOUDSYNC_ALL) == BST_CHECKED);
  391. int sel = (IsDlgButtonChecked(hwnd, IDC_CLOUDSYNC_SEL) == BST_CHECKED);
  392. for (int i = 0; i < SendMessage(hList, LB_GETCOUNT, 0, 0); i++)
  393. {
  394. if (all || SendMessage(hList, LB_GETSEL, i, 0) != !sel)
  395. {
  396. int item = SendMessage(hList, LB_GETITEMDATA, i, 0);
  397. if (item != -1)
  398. {
  399. SyncCloudItemListLoader *list = (SyncCloudItemListLoader *)self->playlistsList->Get(item);
  400. if (list)
  401. {
  402. for (int j = 0; j < list->len; j++)
  403. {
  404. songMapping* song = &list->songs[j];
  405. if (song)
  406. {
  407. itemRecordW *result = AGAVE_API_MLDB->GetFile(song->filename);
  408. song->ice = (itemRecordW*)calloc(sizeof(itemRecordW), 1);
  409. if (result)
  410. {
  411. copyRecord(song->ice, result);
  412. AGAVE_API_MLDB->FreeRecord(result);
  413. }
  414. else
  415. {
  416. filenameToItemRecord(song->filename, song->ice); // ugh. Disk intensive.
  417. }
  418. if (song->ice)
  419. {
  420. self->libraryList->Add(song->ice);
  421. }
  422. }
  423. }
  424. }
  425. }
  426. }
  427. }
  428. }
  429. }
  430. typedef enum DeviceSyncPolicy
  431. {
  432. DeviceSyncPolicy_CopyAllTracks = 0,
  433. DeviceSyncPolicy_CopySelTracks = 1,
  434. DeviceSyncPolicy_CopyNotSelTracks = 2,
  435. } DeviceSyncPolicy;
  436. static DeviceSyncPolicy SyncCloudDialog_ReadDeviceSyncPolicy(SyncCloudDialog *self)
  437. {
  438. if (NULL != self && NULL != self->device && NULL != self->device->config)
  439. {
  440. C_Config *config;
  441. config = self->device->config;
  442. return (DeviceSyncPolicy)config->ReadInt(L"CloudSync", (int)DeviceSyncPolicy_CopyAllTracks);
  443. }
  444. return DeviceSyncPolicy_CopyAllTracks;
  445. }
  446. static BOOL SyncCloudDialog_WriteDeviceSyncPolicy(SyncCloudDialog *self, DeviceSyncPolicy policy)
  447. {
  448. if (NULL != self && NULL != self->device && NULL != self->device->config)
  449. {
  450. C_Config *config;
  451. config = self->device->config;
  452. config->WriteInt(L"CloudSync", (int)policy);
  453. return TRUE;
  454. }
  455. return FALSE;
  456. }
  457. static BOOL SyncCloudDialog_SelectDeviceSyncPolicy(HWND hwnd, DeviceSyncPolicy policy)
  458. {
  459. SyncCloudDialog *self;
  460. int policyControl;
  461. const int controls[] =
  462. {
  463. IDC_CLOUDSYNC_ALL,
  464. IDC_CLOUDSYNC_SEL,
  465. IDC_CLOUDSYNC_NOTSEL
  466. };
  467. self = SYNCCLOUDDIALOG(hwnd);
  468. if (NULL == self)
  469. return FALSE;
  470. switch(policy)
  471. {
  472. case DeviceSyncPolicy_CopyAllTracks:
  473. policyControl = IDC_CLOUDSYNC_ALL;
  474. break;
  475. case DeviceSyncPolicy_CopySelTracks:
  476. policyControl = IDC_CLOUDSYNC_SEL;
  477. break;
  478. case DeviceSyncPolicy_CopyNotSelTracks:
  479. policyControl = IDC_CLOUDSYNC_NOTSEL;
  480. break;
  481. default:
  482. return FALSE;
  483. }
  484. CheckRadioButton(hwnd, controls[0], controls[2], policyControl);
  485. return TRUE;
  486. }
  487. static INT_PTR SyncCloudDialog_OnInitDialog(HWND hwnd, HWND focusWindow, LPARAM param)
  488. {
  489. SyncCloudDialog *self;
  490. C_Config *config;
  491. self = (SyncCloudDialog*)param;
  492. if (NULL == self ||
  493. FALSE == SetProp(hwnd, SYNCCLOUDDIALOG_PROP, self))
  494. {
  495. EndDialog(hwnd, -1);
  496. return 0;
  497. }
  498. config = self->device->config;
  499. SyncCloudDialog_SelectDeviceSyncPolicy(hwnd, SyncCloudDialog_ReadDeviceSyncPolicy(self));
  500. if (FALSE != CenterWindow(hwnd, self->centerWindow))
  501. SendMessage(hwnd, DM_REPOSITION, 0, 0L);
  502. int mode = SyncCloudDialog_ReadTransferOptions(self);
  503. SendDlgItemMessageW(hwnd, IDC_TX_MODE, CB_ADDSTRING, 0, (LPARAM)WASABI_API_LNGSTRINGW(IDS_PLAYLISTS));
  504. SendDlgItemMessageW(hwnd, IDC_TX_MODE, CB_ADDSTRING, 0, (LPARAM)WASABI_API_LNGSTRINGW(IDS_SONGS));
  505. SendDlgItemMessageW(hwnd, IDC_TX_MODE, CB_SETCURSEL, (WPARAM)mode, 0);
  506. SyncCloudDialog_UpdateTransferOptions(hwnd, mode);
  507. SyncCloudDialog_PopulateTrackLists(hwnd);
  508. SyncCloudDialog_PopulatePlaylistLists(hwnd);
  509. SyncCloudDialog_UpdateCaption(hwnd);
  510. return 0;
  511. }
  512. static void SyncCloudDialog_OnDestroy(HWND hwnd)
  513. {
  514. RemoveProp(hwnd, SYNCCLOUDDIALOG_PROP);
  515. }
  516. static void SyncCloudDialog_OnCommand(HWND hwnd, INT commandId, INT eventId, HWND controlWindow)
  517. {
  518. SyncCloudDialog *self;
  519. C_Config *config;
  520. self = SYNCCLOUDDIALOG(hwnd);
  521. if (NULL == self)
  522. return;
  523. config = self->device->config;
  524. switch(commandId)
  525. {
  526. case IDC_TX_MODE:
  527. if (CBN_SELCHANGE == eventId)
  528. {
  529. int mode = SendDlgItemMessage(hwnd, commandId, CB_GETCURSEL, 0, 0);
  530. SyncCloudDialog_WriteTransferOptions(self, mode);
  531. SyncCloudDialog_UpdateTransferOptions(hwnd, mode);
  532. SyncCloudDialog_UpdateCaption(hwnd);
  533. }
  534. break;
  535. case IDC_CLOUDSYNC_ALL:
  536. if (BN_CLICKED == eventId)
  537. {
  538. SyncCloudDialog_WriteDeviceSyncPolicy(self, DeviceSyncPolicy_CopyAllTracks);
  539. SyncCloudDialog_SelectDeviceSyncPolicy(hwnd, DeviceSyncPolicy_CopyAllTracks);
  540. SyncCloudDialog_UpdateCaption(hwnd);
  541. }
  542. break;
  543. case IDC_CLOUDSYNC_SEL:
  544. if (BN_CLICKED == eventId)
  545. {
  546. SyncCloudDialog_WriteDeviceSyncPolicy(self, DeviceSyncPolicy_CopySelTracks);
  547. SyncCloudDialog_SelectDeviceSyncPolicy(hwnd, DeviceSyncPolicy_CopySelTracks);
  548. SyncCloudDialog_UpdateCaption(hwnd);
  549. }
  550. break;
  551. case IDC_CLOUDSYNC_NOTSEL:
  552. if (BN_CLICKED == eventId)
  553. {
  554. SyncCloudDialog_WriteDeviceSyncPolicy(self, DeviceSyncPolicy_CopyNotSelTracks);
  555. SyncCloudDialog_SelectDeviceSyncPolicy(hwnd, DeviceSyncPolicy_CopyNotSelTracks);
  556. SyncCloudDialog_UpdateCaption(hwnd);
  557. }
  558. break;
  559. case IDOK:
  560. SyncCloudDialog_GenerateList(hwnd);
  561. EndDialog(hwnd, IDOK);
  562. break;
  563. case IDCANCEL:
  564. EndDialog(hwnd, IDCANCEL);
  565. break;
  566. case IDC_LIST_ADD:
  567. case IDC_LIST_ADD_PL:
  568. if (eventId == LBN_SELCHANGE)
  569. {
  570. SyncCloudDialog_UpdateCaption(hwnd);
  571. }
  572. break;
  573. }
  574. }
  575. static INT_PTR CALLBACK SyncCloudDialog_DialogProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  576. {
  577. switch(uMsg)
  578. {
  579. case WM_INITDIALOG: return SyncCloudDialog_OnInitDialog(hwnd, (HWND)wParam, lParam);
  580. case WM_DESTROY: SyncCloudDialog_OnDestroy(hwnd); return TRUE;
  581. case WM_COMMAND: SyncCloudDialog_OnCommand(hwnd, LOWORD(wParam), HIWORD(wParam), (HWND)lParam); return TRUE;
  582. }
  583. return FALSE;
  584. }