syncDialog.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443
  1. #include "main.h"
  2. #include <strsafe.h>
  3. #define SYNCDIALOG_PROP L"SyncDialogProp"
  4. typedef struct SyncDialog
  5. {
  6. HWND centerWindow;
  7. DeviceView *device;
  8. C_ItemList *libraryList;
  9. C_ItemList *deviceList;
  10. BOOL autofillMode;
  11. } SyncDialog;
  12. #define SYNCDIALOG(_hwnd) ((SyncDialog*)GetPropW((_hwnd), SYNCDIALOG_PROP))
  13. static INT_PTR CALLBACK
  14. SyncDialog_DialogProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
  15. INT_PTR
  16. SyncDialog_Show(HWND centerWindow, DeviceView *device,
  17. C_ItemList *libraryList, C_ItemList *deviceList, BOOL autofillMode)
  18. {
  19. SyncDialog param;
  20. param.centerWindow = centerWindow;
  21. param.device = device;
  22. param.libraryList = libraryList;
  23. param.deviceList = deviceList;
  24. param.autofillMode = autofillMode;
  25. return WASABI_API_DIALOGBOXPARAMW(IDD_SYNC, plugin.hwndLibraryParent, SyncDialog_DialogProc, (LPARAM)&param);
  26. }
  27. static BOOL
  28. SyncDialog_FormatSongString(wchar_t *buffer, size_t bufferSize,
  29. const wchar_t *artist, const wchar_t *title, const wchar_t *fileName)
  30. {
  31. HRESULT hr;
  32. if (NULL == buffer)
  33. return FALSE;
  34. if (NULL == title || L'\0' == *title)
  35. {
  36. if (NULL == fileName || L'\0' == *fileName)
  37. {
  38. WASABI_API_LNGSTRINGW_BUF(IDS_UNKNOWN_TRACK, buffer, bufferSize);
  39. hr = S_OK;
  40. }
  41. else
  42. hr = StringCchCopyEx(buffer, bufferSize, fileName, NULL, NULL, STRSAFE_IGNORE_NULLS);
  43. }
  44. else if (NULL == artist || L'\0' == *artist)
  45. {
  46. hr = StringCchCopyEx(buffer, bufferSize, title, NULL, NULL, STRSAFE_IGNORE_NULLS);
  47. }
  48. else
  49. {
  50. hr = StringCchPrintfEx(buffer, bufferSize, NULL, NULL, STRSAFE_IGNORE_NULLS,
  51. L"%s - %s", artist, title);
  52. }
  53. return SUCCEEDED(hr);
  54. }
  55. static BOOL
  56. SyncDialog_PopulateTrackLists(HWND hwnd)
  57. {
  58. SyncDialog *self;
  59. HWND hList;
  60. wchar_t buffer[1024] = {0};
  61. int index, count;
  62. self = SYNCDIALOG(hwnd);
  63. if (NULL == self)
  64. return FALSE;
  65. hList = GetDlgItem(hwnd, IDC_LIST_ADD);
  66. if(NULL != hList)
  67. {
  68. SendMessage(hList, WM_SETREDRAW, FALSE, 0L);
  69. SendMessage(hList, LB_RESETCONTENT, FALSE, 0L);
  70. count = (NULL != self->libraryList) ? self->libraryList->GetSize() : 0;
  71. if (0 != count)
  72. {
  73. SendMessage(hList, LB_SETCOUNT , (WPARAM)count, 0L);
  74. for(index = 0; index < count; index++)
  75. {
  76. itemRecordW *record = (itemRecordW*)self->libraryList->Get(index);
  77. if (NULL != record &&
  78. FALSE != SyncDialog_FormatSongString(buffer, ARRAYSIZE(buffer),
  79. record->artist, record->title, record->filename))
  80. {
  81. SendMessage(hList, LB_ADDSTRING, 0, (LPARAM)buffer);
  82. }
  83. }
  84. }
  85. SendMessage(hList, WM_SETREDRAW, TRUE, 0L);
  86. }
  87. hList = GetDlgItem(hwnd, IDC_LIST_REMOVE);
  88. if(NULL != hList)
  89. {
  90. SendMessage(hList, WM_SETREDRAW, FALSE, 0L);
  91. SendMessage(hList, LB_RESETCONTENT, FALSE, 0L);
  92. count = (NULL != self->deviceList) ? self->deviceList->GetSize() : 0;
  93. if (0 != count)
  94. {
  95. Device *device;
  96. wchar_t artist[256] = {0}, title[256] = {0};
  97. SendMessage(hList, LB_SETCOUNT , (WPARAM)count, 0L);
  98. device = self->device->dev;
  99. for(index = 0; index < count; index++)
  100. {
  101. songid_t songId = (songid_t)self->deviceList->Get(index);
  102. device->getTrackArtist(songId, artist,ARRAYSIZE(artist));
  103. device->getTrackTitle(songId, title, ARRAYSIZE(title));
  104. if (FALSE != SyncDialog_FormatSongString(buffer, ARRAYSIZE(buffer),
  105. artist, title, NULL))
  106. {
  107. SendMessage(hList, LB_ADDSTRING, 0, (LPARAM)buffer);
  108. }
  109. }
  110. }
  111. SendMessage(hList, WM_SETREDRAW, TRUE, 0L);
  112. }
  113. return TRUE;
  114. }
  115. static BOOL
  116. SyncDialog_UpdateCaption(HWND hwnd)
  117. {
  118. SyncDialog *self;
  119. HWND captionWindow;
  120. int resourceId;
  121. wchar_t buffer[1024] = {0}, format[1024] = {0};
  122. self = SYNCDIALOG(hwnd);
  123. if (NULL == self)
  124. return FALSE;
  125. captionWindow = GetDlgItem(hwnd, IDC_CAPTION);
  126. if (NULL == captionWindow)
  127. return FALSE;
  128. resourceId = (FALSE == self->autofillMode) ?
  129. IDS_X_SONGS_WILL_BE_TRANSFERRED_TO_THE_DEVICE :
  130. IDS_THIS_WILL_ADD_X_SONGS_AND_DELETE_X_SONGS;
  131. WASABI_API_LNGSTRINGW_BUF(resourceId, format, ARRAYSIZE(format));
  132. if (FAILED(StringCchPrintf(buffer, ARRAYSIZE(buffer), format,
  133. self->libraryList->GetSize(), self->deviceList->GetSize())))
  134. {
  135. return FALSE;
  136. }
  137. SendMessage(captionWindow, WM_SETTEXT, 0, (LPARAM)buffer);
  138. return TRUE;
  139. }
  140. typedef enum DeviceSyncPolicy
  141. {
  142. DeviceSyncPolicy_LeaveTracks = 0,
  143. DeviceSyncPolicy_DeleteTracks = 1,
  144. DeviceSyncPolicy_CopyTracks = 2,
  145. } DeviceSyncPolicy;
  146. static BOOL
  147. SyncDialog_GetDeviceSyncPolicyEnabled(SyncDialog *self)
  148. {
  149. if (NULL != self &&
  150. FALSE == self->autofillMode &&
  151. 0 != self->deviceList->GetSize())
  152. {
  153. return TRUE;
  154. }
  155. return FALSE;
  156. }
  157. static DeviceSyncPolicy
  158. SyncDialog_ReadDeviceSyncPolicy(SyncDialog *self)
  159. {
  160. if (FALSE != SyncDialog_GetDeviceSyncPolicyEnabled(self) &&
  161. NULL != self->device &&
  162. NULL != self->device->config)
  163. {
  164. C_Config *config;
  165. config = self->device->config;
  166. return (DeviceSyncPolicy)config->ReadInt(L"TrueSync", (int)DeviceSyncPolicy_LeaveTracks);
  167. }
  168. return DeviceSyncPolicy_LeaveTracks;
  169. }
  170. static BOOL
  171. SyncDialog_WriteDeviceSyncPolicy(SyncDialog *self, DeviceSyncPolicy policy)
  172. {
  173. if (FALSE != SyncDialog_GetDeviceSyncPolicyEnabled(self) &&
  174. NULL != self->device &&
  175. NULL != self->device->config)
  176. {
  177. C_Config *config;
  178. config = self->device->config;
  179. config->WriteInt(L"TrueSync", (int)policy);
  180. return TRUE;
  181. }
  182. return FALSE;
  183. }
  184. static BOOL
  185. SyncDialog_SelectDeviceSyncPolicy(HWND hwnd, DeviceSyncPolicy policy)
  186. {
  187. SyncDialog *self;
  188. HWND hControl;
  189. size_t index;
  190. int policyControl;
  191. int checkMode;
  192. int labelText;
  193. BOOL enableControls;
  194. const int controls[] =
  195. {
  196. IDC_TRUESYNC_LEAVE,
  197. IDC_TRUESYNC_DELETE,
  198. IDC_TRUESYNC_COPY
  199. };
  200. self = SYNCDIALOG(hwnd);
  201. if (NULL == self)
  202. return FALSE;
  203. switch(policy)
  204. {
  205. case DeviceSyncPolicy_LeaveTracks:
  206. policyControl = IDC_TRUESYNC_LEAVE;
  207. labelText = IDS_SONGS_NOT_IN_MEDIA_LIBRARY;
  208. break;
  209. case DeviceSyncPolicy_DeleteTracks:
  210. policyControl = IDC_TRUESYNC_DELETE;
  211. labelText = IDS_SONGS_TO_BE_DELETED;
  212. break;
  213. case DeviceSyncPolicy_CopyTracks:
  214. policyControl = IDC_TRUESYNC_COPY;
  215. labelText = IDS_SONGS_TO_BE_COPIED;
  216. break;
  217. default:
  218. return FALSE;
  219. }
  220. enableControls = SyncDialog_GetDeviceSyncPolicyEnabled(self);
  221. for (index = 0; index < ARRAYSIZE(controls); index++)
  222. {
  223. hControl = GetDlgItem(hwnd, controls[index]);
  224. if (NULL == hControl)
  225. continue;
  226. checkMode = (controls[index] == policyControl) ?
  227. BST_CHECKED :
  228. BST_UNCHECKED;
  229. SendMessage(hControl, BM_SETCHECK, (WPARAM)checkMode, 0L);
  230. EnableWindow(hControl, enableControls);
  231. }
  232. hControl = GetDlgItem(hwnd, IDC_REMOVELABEL);
  233. if (NULL != hControl)
  234. {
  235. wchar_t buffer[256] = {0};
  236. WASABI_API_LNGSTRINGW_BUF(labelText, buffer, ARRAYSIZE(buffer));
  237. SendMessage(hControl, WM_SETTEXT, 0, (LPARAM)buffer);
  238. }
  239. return TRUE;
  240. }
  241. static INT_PTR
  242. SyncDialog_OnInitDialog(HWND hwnd, HWND focusWindow, LPARAM param)
  243. {
  244. SyncDialog *self;
  245. C_Config *config;
  246. self = (SyncDialog*)param;
  247. if (NULL == self ||
  248. FALSE == SetProp(hwnd, SYNCDIALOG_PROP, self))
  249. {
  250. EndDialog(hwnd, -1);
  251. return 0;
  252. }
  253. config = self->device->config;
  254. SyncDialog_UpdateCaption(hwnd);
  255. SyncDialog_SelectDeviceSyncPolicy(hwnd, SyncDialog_ReadDeviceSyncPolicy(self));
  256. if(config->ReadInt(L"syncOnConnect", self->device->SyncConnectionDefault) == (self->autofillMode ? 2:1))
  257. CheckDlgButton(hwnd, IDC_SYNCONCONNECT, BST_CHECKED);
  258. SendMessage(hwnd, WM_COMMAND, MAKEWPARAM(IDC_LESS,0), NULL);
  259. if (FALSE != CenterWindow(hwnd, self->centerWindow))
  260. SendMessage(hwnd, DM_REPOSITION, 0, 0L);
  261. SyncDialog_PopulateTrackLists(hwnd);
  262. return 0;
  263. }
  264. static void
  265. SyncDialog_OnDestroy(HWND hwnd)
  266. {
  267. RemoveProp(hwnd, SYNCDIALOG_PROP);
  268. }
  269. static void
  270. SyncDialog_OnCommand(HWND hwnd, INT commandId, INT eventId, HWND controlWindow)
  271. {
  272. SyncDialog *self;
  273. C_Config *config;
  274. BOOL enableRadios;
  275. self = SYNCDIALOG(hwnd);
  276. if (NULL == self)
  277. return;
  278. config = self->device->config;
  279. enableRadios = ((!self->autofillMode) && self->deviceList->GetSize());
  280. switch(commandId)
  281. {
  282. case IDC_ADD_REMSEL:
  283. case IDC_REM_REMSEL:
  284. case IDC_ADD_CROPSEL:
  285. case IDC_REM_CROPSEL:
  286. {
  287. bool rem = (commandId == IDC_ADD_REMSEL || commandId == IDC_REM_REMSEL);
  288. bool addlist = (commandId == IDC_ADD_REMSEL || commandId == IDC_ADD_CROPSEL);
  289. HWND box = GetDlgItem(hwnd,addlist?IDC_LIST_ADD:IDC_LIST_REMOVE);
  290. C_ItemList * list = addlist?self->libraryList:self->deviceList;
  291. int l=SendMessage(box,LB_GETCOUNT,0,0);
  292. int current=0;
  293. for(int i=0; i<l; ++i)
  294. {
  295. if((SendMessage(box,LB_GETSEL,current,0)!=0) == rem)
  296. {
  297. SendMessage(box,LB_DELETESTRING,current,0);
  298. list->Del(current);
  299. }
  300. else current++;
  301. }
  302. SyncDialog_UpdateCaption(hwnd);
  303. }
  304. break;
  305. case IDC_TRUESYNC_DELETE:
  306. if (BN_CLICKED == eventId)
  307. SyncDialog_SelectDeviceSyncPolicy(hwnd, DeviceSyncPolicy_DeleteTracks);
  308. break;
  309. case IDC_TRUESYNC_COPY:
  310. if (BN_CLICKED == eventId)
  311. SyncDialog_SelectDeviceSyncPolicy(hwnd, DeviceSyncPolicy_CopyTracks);
  312. break;
  313. case IDC_TRUESYNC_LEAVE:
  314. if (BN_CLICKED == eventId)
  315. SyncDialog_SelectDeviceSyncPolicy(hwnd, DeviceSyncPolicy_LeaveTracks);
  316. break;
  317. case IDC_MORE:
  318. case IDC_LESS:
  319. {
  320. bool more = commandId == IDC_MORE;
  321. int show = more?SW_SHOW:SW_HIDE;
  322. int hide = more?SW_HIDE:SW_SHOW;
  323. ShowWindow(GetDlgItem(hwnd,IDCANCEL),hide);
  324. ShowWindow(GetDlgItem(hwnd,IDOK),hide);
  325. ShowWindow(GetDlgItem(hwnd,IDC_MORE),hide);
  326. ShowWindow(GetDlgItem(hwnd,IDC_LESS),show);
  327. ShowWindow(GetDlgItem(hwnd,IDCANCEL2),show);
  328. ShowWindow(GetDlgItem(hwnd,IDOK2),show);
  329. ShowWindow(GetDlgItem(hwnd,IDC_ADDLABEL),show);
  330. ShowWindow(GetDlgItem(hwnd,IDC_REMOVELABEL),show);
  331. ShowWindow(GetDlgItem(hwnd,IDC_LIST_ADD),show);
  332. ShowWindow(GetDlgItem(hwnd,IDC_LIST_REMOVE),show);
  333. RECT r, r1, r2;
  334. GetWindowRect(hwnd,&r);
  335. GetWindowRect(GetDlgItem(hwnd,more?IDC_MORE:IDC_LESS),&r1);
  336. GetWindowRect(GetDlgItem(hwnd,more?IDCANCEL2:IDCANCEL),&r2);
  337. SetWindowPos(hwnd,HWND_TOP,r.left,r.top,
  338. r2.right - r.left + (r1.left - r.left),
  339. r2.bottom - r.top + (r1.left - r.left), 0);
  340. }
  341. break;
  342. case IDOK2:
  343. case IDOK:
  344. config->WriteInt(L"syncOnConnect",IsDlgButtonChecked(hwnd,IDC_SYNCONCONNECT)?(self->autofillMode?2:1):0);
  345. if(enableRadios)
  346. config->WriteInt(L"TrueSync",IsDlgButtonChecked(hwnd,IDC_TRUESYNC_LEAVE)?0:(IsDlgButtonChecked(hwnd,IDC_TRUESYNC_DELETE)?1:2));
  347. EndDialog(hwnd, IDOK);
  348. break;
  349. case IDCANCEL2:
  350. case IDCANCEL:
  351. EndDialog(hwnd, IDCANCEL);
  352. break;
  353. }
  354. }
  355. static INT_PTR CALLBACK
  356. SyncDialog_DialogProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  357. {
  358. switch(uMsg)
  359. {
  360. case WM_INITDIALOG: return SyncDialog_OnInitDialog(hwnd, (HWND)wParam, lParam);
  361. case WM_DESTROY: SyncDialog_OnDestroy(hwnd); return TRUE;
  362. case WM_COMMAND: SyncDialog_OnCommand(hwnd, LOWORD(wParam), HIWORD(wParam), (HWND)lParam); return TRUE;
  363. }
  364. return FALSE;
  365. }