1
0

FileInfoDialog.cpp 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831
  1. #include "Main.h"
  2. #include "FileInfoDialog.h"
  3. #include "WMInformation.h"
  4. #include "resource.h"
  5. #include "../nu/AutoChar.h"
  6. #include "WMDRMModule.h"
  7. #include "WMPlaylist.h"
  8. // blah! commented out a load of shit because we can't have the advanced pane edit data cause wma sucks.
  9. class Info
  10. {
  11. public:
  12. Info(const wchar_t *filename);
  13. ~Info();
  14. //bool Save(HWND parent);
  15. int Error();
  16. int GetNumMetadataItems();
  17. void EnumMetadata(int n,wchar_t *key,int keylen, wchar_t *val, int vallen);
  18. //void RemoveMetadata(wchar_t * key);
  19. //void RemoveMetadata(int n);
  20. //void SetMetadata(wchar_t *key, wchar_t *val);
  21. //void SetMetadata(int n, wchar_t *key, wchar_t *val);
  22. //void SetTag(int n,wchar_t *key); // changes the key name
  23. private:
  24. WMInformation wminfo;
  25. const wchar_t *filename;
  26. };
  27. Info::Info(const wchar_t *filename) : wminfo(filename), filename(filename)
  28. {
  29. }
  30. Info::~Info()
  31. {
  32. }
  33. /*
  34. bool Info::Save(HWND parent)
  35. {
  36. if (!wminfo.MakeWritable(filename))
  37. {
  38. wchar_t title[64] = {0};
  39. if (activePlaylist.IsMe(filename) && mod.playing)
  40. {
  41. // TODO: this is a race condition. we might have stopped in between the above if () and now...
  42. int outTime = mod.GetOutputTime();
  43. winamp.PressStop();
  44. wminfo.MakeWritable(filename);
  45. SendMessage(parent,WM_USER+1,0,0);
  46. //WriteEditBoxes();
  47. wminfo.Flush();
  48. wminfo.MakeReadOnly(filename);
  49. mod.startAtMilliseconds=outTime;
  50. winamp.PressPlay();
  51. return true;
  52. }
  53. else if (!wminfo.MakeReadOnly(filename))
  54. MessageBox(parent, WASABI_API_LNGSTRINGW(IDS_UNABLE_TO_WRITE_TO_FILE_DOES_FILE_EXIST),
  55. WASABI_API_LNGSTRINGW_BUF(IDS_UNABLE_TO_WRITE_TO_FILE,title,64), MB_OK);
  56. else
  57. MessageBox(parent, WASABI_API_LNGSTRINGW(IDS_UNABLE_TO_WRITE_TO_FILE_MAY_NOT_HAVE_ACCESS),
  58. WASABI_API_LNGSTRINGW_BUF(IDS_UNABLE_TO_WRITE_TO_FILE,title,64), MB_OK);
  59. return false;
  60. }
  61. SendMessage(parent,WM_USER+1,0,0);
  62. //WriteEditBoxes();
  63. if (!wminfo.Flush())
  64. {
  65. wchar_t* title = WASABI_API_LNGSTRINGW(IDS_SAVE_FAILED);
  66. MessageBox(NULL, title, title, MB_OK);
  67. }
  68. wminfo.MakeReadOnly(filename);
  69. return true;
  70. }
  71. */
  72. int Info::Error()
  73. {
  74. return wminfo.ErrorOpening();
  75. }
  76. int Info::GetNumMetadataItems()
  77. {
  78. return wminfo.GetNumberAttributes();
  79. }
  80. void Info::EnumMetadata(int n,wchar_t *key,int keylen, wchar_t *val, int vallen)
  81. {
  82. if(keylen) key[0]=0;
  83. if(vallen) val[0]=0;
  84. wminfo.GetAttribute(n, key, keylen, val, vallen);
  85. }
  86. /*
  87. void Info::RemoveMetadata(wchar_t * key)
  88. {
  89. wminfo.DeleteAttribute(key);
  90. }
  91. void Info::RemoveMetadata(int n)
  92. {
  93. wchar_t key[256] = {0};
  94. EnumMetadata(n,key,256,NULL,0);
  95. if(key[0])
  96. RemoveMetadata(key);
  97. }
  98. void Info::SetMetadata(wchar_t *key, wchar_t *val)
  99. {
  100. wminfo.SetAttribute(key,val);
  101. }
  102. void Info::SetTag(int n, wchar_t *key)
  103. { // changes the key name
  104. wchar_t val[2048]=L"";
  105. wchar_t oldkey[256]=L"";
  106. EnumMetadata(n,oldkey,256,val,2048);
  107. RemoveMetadata(oldkey);
  108. wminfo.SetAttribute(key,val);
  109. }
  110. */
  111. bool WMTagToWinampTag(wchar_t * tag, int len)
  112. {
  113. const wchar_t *f = GetAlias_rev(tag);
  114. if(f)
  115. {
  116. lstrcpyn(tag,f,len);
  117. return true;
  118. }
  119. return false;
  120. }
  121. bool WinampTagToWMTag(wchar_t * tag, int len)
  122. {
  123. const wchar_t *f = GetAlias(tag);
  124. if(f)
  125. {
  126. lstrcpyn(tag,f,len);
  127. return true;
  128. }
  129. return false;
  130. }
  131. static INT_PTR CALLBACK ChildProc_Advanced(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) {
  132. static int ismychange=0;
  133. switch(msg)
  134. {
  135. case WM_NOTIFYFORMAT:
  136. return NFR_UNICODE;
  137. case WM_INITDIALOG:
  138. {
  139. //SetWindowLongPtr(hwndDlg,GWLP_USERDATA,lParam);
  140. HWND hwndlist = GetDlgItem(hwndDlg,IDC_LIST);
  141. ListView_SetExtendedListViewStyle(hwndlist, LVS_EX_FULLROWSELECT);
  142. LVCOLUMN lvc = {0, };
  143. lvc.mask = LVCF_TEXT|LVCF_WIDTH;
  144. lvc.pszText = WASABI_API_LNGSTRINGW(IDS_NAME);
  145. lvc.cx = 82;
  146. ListView_InsertColumn(hwndlist, 0, &lvc);
  147. lvc.pszText = WASABI_API_LNGSTRINGW(IDS_VALUE);
  148. lvc.cx = 160;
  149. ListView_InsertColumn(hwndlist, 1, &lvc);
  150. Info *info = (Info *)lParam;
  151. int n = info->GetNumMetadataItems();
  152. for(int i=0; i<n; i++) {
  153. wchar_t key[512] = {0};
  154. wchar_t value[2048] = {0};
  155. info->EnumMetadata(i,key,512,value,2048);
  156. if(key[0]) {
  157. LVITEMW lvi={LVIF_TEXT,i,0};
  158. lvi.pszText = key;
  159. SendMessage(hwndlist,LVM_INSERTITEMW,0,(LPARAM)&lvi);
  160. lvi.iSubItem=1;
  161. lvi.pszText = value;
  162. SendMessage(hwndlist,LVM_SETITEMW,0,(LPARAM)&lvi);
  163. }
  164. }
  165. ListView_SetColumnWidth(hwndlist,0,LVSCW_AUTOSIZE);
  166. ListView_SetColumnWidth(hwndlist,1,LVSCW_AUTOSIZE);
  167. //SetDlgItemTextW(hwndDlg,IDC_NAME,L"");
  168. //SetDlgItemTextW(hwndDlg,IDC_VALUE,L"");
  169. //EnableWindow(GetDlgItem(hwndDlg,IDC_NAME),FALSE);
  170. //EnableWindow(GetDlgItem(hwndDlg,IDC_VALUE),FALSE);
  171. //EnableWindow(GetDlgItem(hwndDlg,IDC_BUTTON_DEL),FALSE);
  172. delete info;
  173. }
  174. break;
  175. case WM_DESTROY:
  176. {
  177. HWND hwndlist = GetDlgItem(hwndDlg,IDC_LIST);
  178. ListView_DeleteAllItems(hwndlist);
  179. while(ListView_DeleteColumn(hwndlist,0));
  180. Info * info = (Info*)GetWindowLongPtr(hwndDlg,GWLP_USERDATA);
  181. if(info) delete info;
  182. }
  183. break;
  184. /*
  185. case WM_USER+1:
  186. {
  187. Info *info = (Info *)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
  188. info->wminfo.ClearAllAttributes();
  189. wchar_t key[100] = {0}, value[2048] = {0};
  190. HWND hlist = GetDlgItem(hwndDlg,IDC_LIST);
  191. int n = ListView_GetItemCount(hlist);
  192. for(int i=0; i<n; i++)
  193. {
  194. key[0]=value[0]=0;
  195. LVITEMW lvi={LVIF_TEXT,i,0};
  196. lvi.pszText=key;
  197. lvi.cchTextMax=100;
  198. SendMessage(hlist,LVM_GETITEMW,0,(LPARAM)&lvi);
  199. lvi.iSubItem = 1;
  200. lvi.pszText = value;
  201. lvi.cchTextMax=2048;
  202. SendMessage(hlist,LVM_GETITEMW,0,(LPARAM)&lvi);
  203. if(key[0])
  204. info->SetMetadata(key,value);
  205. }
  206. }
  207. break;
  208. */
  209. case WM_USER:
  210. if(wParam && lParam && !ismychange)
  211. {
  212. wchar_t * value = (wchar_t*)lParam;
  213. wchar_t tag[100] = {0};
  214. lstrcpynW(tag,(wchar_t*)wParam,100);
  215. WinampTagToWMTag(tag,100);
  216. /*
  217. Info *info = (Info *)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
  218. if(!*value) info->RemoveMetadata(tag);
  219. else info->SetMetadata(tag,value);
  220. */
  221. HWND hlist = GetDlgItem(hwndDlg,IDC_LIST);
  222. int n = ListView_GetItemCount(hlist);
  223. for(int i=0; i<n; i++)
  224. {
  225. wchar_t key[100]=L"";
  226. LVITEMW lvi={LVIF_TEXT,i,0};
  227. lvi.pszText=key;
  228. lvi.cchTextMax=100;
  229. SendMessage(hlist,LVM_GETITEMW,0,(LPARAM)&lvi);
  230. if(!_wcsicmp(key,tag))
  231. {
  232. lvi.iSubItem = 1;
  233. lvi.pszText = value;
  234. SendMessage(hlist,LVM_SETITEMW,0,(LPARAM)&lvi);
  235. if(!*value)
  236. ListView_DeleteItem(hlist,i);
  237. /*
  238. else if(ListView_GetItemState(hlist,i,LVIS_SELECTED))
  239. SetDlgItemTextW(hwndDlg,IDC_VALUE,value);
  240. */
  241. return 0;
  242. }
  243. }
  244. // bew hew, not found
  245. LVITEMW lvi={0,0x7FFFFFF0,0};
  246. n = SendMessage(hlist,LVM_INSERTITEMW,0,(LPARAM)&lvi);
  247. lvi.mask = LVIF_TEXT;
  248. lvi.iItem = n;
  249. lvi.iSubItem = 0;
  250. lvi.pszText = tag;
  251. SendMessage(hlist,LVM_SETITEMW,0,(LPARAM)&lvi);
  252. lvi.iSubItem = 1;
  253. lvi.pszText = value;
  254. SendMessage(hlist,LVM_SETITEMW,0,(LPARAM)&lvi);
  255. }
  256. break;
  257. /*
  258. case WM_NOTIFY:
  259. {
  260. LPNMHDR l=(LPNMHDR)lParam;
  261. if(l->idFrom==IDC_LIST && l->code == LVN_ITEMCHANGED) {
  262. LPNMLISTVIEW lv=(LPNMLISTVIEW)lParam;
  263. if(lv->uNewState & LVIS_SELECTED) {
  264. int n = lv->iItem;
  265. LVITEMW lvi={LVIF_TEXT,lv->iItem,0};
  266. wchar_t key[100] = {0};
  267. wchar_t value[1024] = {0};
  268. lvi.pszText=key;
  269. lvi.cchTextMax=100;
  270. SendMessage(l->hwndFrom,LVM_GETITEMW,0,(LPARAM)&lvi);
  271. lvi.pszText=value;
  272. lvi.cchTextMax=1024;
  273. lvi.iSubItem=1;
  274. SendMessage(l->hwndFrom,LVM_GETITEMW,0,(LPARAM)&lvi);
  275. SetDlgItemTextW(hwndDlg,IDC_NAME,key);
  276. SetDlgItemTextW(hwndDlg,IDC_VALUE,value);
  277. sel = n;
  278. EnableWindow(GetDlgItem(hwndDlg,IDC_NAME),TRUE);
  279. EnableWindow(GetDlgItem(hwndDlg,IDC_VALUE),TRUE);
  280. EnableWindow(GetDlgItem(hwndDlg,IDC_BUTTON_DEL),TRUE);
  281. }
  282. if(lv->uOldState & LVIS_SELECTED) {
  283. int n = lv->iItem;
  284. sel = -1;
  285. SetDlgItemTextW(hwndDlg,IDC_NAME,L"");
  286. SetDlgItemTextW(hwndDlg,IDC_VALUE,L"");
  287. EnableWindow(GetDlgItem(hwndDlg,IDC_NAME),FALSE);
  288. EnableWindow(GetDlgItem(hwndDlg,IDC_VALUE),FALSE);
  289. EnableWindow(GetDlgItem(hwndDlg,IDC_BUTTON_DEL),FALSE);
  290. }
  291. }
  292. }
  293. break;
  294. */
  295. case WM_COMMAND:
  296. switch(LOWORD(wParam)) {
  297. case IDOK:
  298. {
  299. //Info * info = (Info*)GetWindowLongPtr(hwndDlg,GWLP_USERDATA);
  300. //info->Save(hwndDlg);
  301. }
  302. break;
  303. /*
  304. case IDC_NAME:
  305. case IDC_VALUE:
  306. if(HIWORD(wParam) == EN_CHANGE && sel>=0) {
  307. wchar_t key[100] = {0};
  308. wchar_t value[1024] = {0};
  309. LVITEMW lvi={LVIF_TEXT,sel,0};
  310. GetDlgItemTextW(hwndDlg,IDC_NAME,key,100);
  311. GetDlgItemTextW(hwndDlg,IDC_VALUE,value,1024);
  312. lvi.pszText=key;
  313. lvi.cchTextMax=100;
  314. SendMessage(GetDlgItem(hwndDlg,IDC_LIST),LVM_SETITEMW,0,(LPARAM)&lvi);
  315. lvi.pszText=value;
  316. lvi.cchTextMax=1024;
  317. lvi.iSubItem=1;
  318. SendMessage(GetDlgItem(hwndDlg,IDC_LIST),LVM_SETITEMW,0,(LPARAM)&lvi);
  319. WMTagToWinampTag(key,100);
  320. ismychange=1;
  321. SendMessage(GetParent(hwndDlg),WM_USER,(WPARAM)key,(WPARAM)value);
  322. ismychange=0;
  323. }
  324. else if(HIWORD(wParam) == EN_KILLFOCUS && sel>=0) {
  325. wchar_t key[100] = {0};
  326. wchar_t value[1024] = {0};
  327. GetDlgItemTextW(hwndDlg,IDC_NAME,key,100);
  328. GetDlgItemTextW(hwndDlg,IDC_VALUE,value,1024);
  329. Info *info = (Info *)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
  330. wchar_t oldkey[100]=L"";
  331. bool newitem=true;
  332. if(sel < info->GetNumMetadataItems()) {
  333. info->EnumMetadata(sel,oldkey,100,0,0);
  334. newitem=false;
  335. }
  336. if(!newitem && wcscmp(oldkey,key)) { // key changed
  337. info->SetTag(sel,key);
  338. } else {
  339. info->SetMetadata(key,value);
  340. }
  341. WMTagToWinampTag(key,100);
  342. ismychange=1;
  343. SendMessage(GetParent(hwndDlg),WM_USER,(WPARAM)key,(WPARAM)value);
  344. ismychange=0;
  345. }
  346. break;
  347. case IDC_BUTTON_DEL:
  348. if(sel >= 0) {
  349. wchar_t tag[100] = {0};
  350. GetDlgItemTextW(hwndDlg,IDC_NAME,tag,100);
  351. SetDlgItemTextW(hwndDlg,IDC_NAME,L"");
  352. SetDlgItemTextW(hwndDlg,IDC_VALUE,L"");
  353. EnableWindow(GetDlgItem(hwndDlg,IDC_NAME),FALSE);
  354. EnableWindow(GetDlgItem(hwndDlg,IDC_VALUE),FALSE);
  355. EnableWindow(GetDlgItem(hwndDlg,IDC_BUTTON_DEL),FALSE);
  356. Info *info = (Info *)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
  357. if(sel < info->GetNumMetadataItems())
  358. info->RemoveMetadata(sel);
  359. ListView_DeleteItem(GetDlgItem(hwndDlg,IDC_LIST),sel);
  360. sel=-1;
  361. WMTagToWinampTag(tag,100);
  362. ismychange=1;
  363. SendMessage(GetParent(hwndDlg),WM_USER,(WPARAM)tag,(WPARAM)L"");
  364. ismychange=0;
  365. }
  366. break;
  367. case IDC_BUTTON_DELALL:
  368. ListView_DeleteAllItems(GetDlgItem(hwndDlg,IDC_LIST));
  369. SetDlgItemTextW(hwndDlg,IDC_NAME,L"");
  370. SetDlgItemTextW(hwndDlg,IDC_VALUE,L"");
  371. EnableWindow(GetDlgItem(hwndDlg,IDC_NAME),FALSE);
  372. EnableWindow(GetDlgItem(hwndDlg,IDC_VALUE),FALSE);
  373. EnableWindow(GetDlgItem(hwndDlg,IDC_BUTTON_DEL),FALSE);
  374. sel=-1;
  375. {
  376. Info *info = (Info *)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
  377. int n = info->GetNumMetadataItems();
  378. while(n>0) {
  379. --n;
  380. wchar_t tag[100] = {0};
  381. info->EnumMetadata(n,tag,100,0,0);
  382. WMTagToWinampTag(tag,100);
  383. ismychange=0;
  384. SendMessage(GetParent(hwndDlg),WM_USER,(WPARAM)tag,(WPARAM)L"");
  385. ismychange=1;
  386. info->RemoveMetadata(n);
  387. }
  388. }
  389. break;
  390. case IDC_BUTTON_ADD:
  391. {
  392. HWND hwndlist = GetDlgItem(hwndDlg,IDC_LIST);
  393. LVITEMW lvi={0,0x7FFFFFF0,0};
  394. int n = SendMessage(hwndlist,LVM_INSERTITEMW,0,(LPARAM)&lvi);
  395. ListView_SetItemState(hwndlist,n,LVIS_SELECTED,LVIS_SELECTED);
  396. }
  397. break;
  398. */
  399. }
  400. break;
  401. }
  402. return 0;
  403. }
  404. extern "C"
  405. {
  406. // return 1 if you want winamp to show it's own file info dialogue, 0 if you want to show your own (via In_Module.InfoBox)
  407. // if returning 1, remember to implement winampGetExtendedFileInfo("formatinformation")!
  408. __declspec(dllexport) int winampUseUnifiedFileInfoDlg(const wchar_t * fn)
  409. {
  410. return 1;
  411. }
  412. // should return a child window of 513x271 pixels (341x164 in msvc dlg units), or return NULL for no tab.
  413. // Fill in name (a buffer of namelen characters), this is the title of the tab (defaults to "Advanced").
  414. // filename will be valid for the life of your window. n is the tab number. This function will first be
  415. // called with n == 0, then n == 1 and so on until you return NULL (so you can add as many tabs as you like).
  416. // The window you return will recieve WM_COMMAND, IDOK/IDCANCEL messages when the user clicks OK or Cancel.
  417. // when the user edits a field which is duplicated in another pane, do a SendMessage(GetParent(hwnd),WM_USER,(WPARAM)L"fieldname",(LPARAM)L"newvalue");
  418. // this will be broadcast to all panes (including yours) as a WM_USER.
  419. __declspec(dllexport) HWND winampAddUnifiedFileInfoPane(int n, const wchar_t * filename, HWND parent, wchar_t *name, size_t namelen)
  420. {
  421. if(n == 0) { // add first pane
  422. //SetPropW(parent,L"INBUILT_NOWRITEINFO", (HANDLE)1);
  423. Info *info = new Info(filename);
  424. if(info->Error())
  425. {
  426. delete info;
  427. return NULL;
  428. }
  429. return WASABI_API_CREATEDIALOGPARAMW(IDD_INFO,parent,ChildProc_Advanced,(LPARAM)info);
  430. }
  431. return NULL;
  432. }
  433. };
  434. /* CUT> we're now using the unified file info dlg. I'll leave this commented out incase we want to do an advanced tab later on.
  435. #define CREATEDIALOGBOX DialogBoxParam
  436. #define CLOSEDIALOGBOX(x) EndDialog(x, 0)
  437. extern WMDRM mod;
  438. enum
  439. {
  440. AttributeColumn = 0,
  441. ValueColumn = 1,
  442. };
  443. void FileInfoDialog::FillAttributeList()
  444. {
  445. attributeList.Clear();
  446. WORD attrCount = wmInfo->GetNumberAttributes();
  447. wchar_t attrName[32768] = {0}, value[32768] = {0};
  448. int pos=0;
  449. for (WORD i = 0;i != attrCount;i++)
  450. {
  451. wmInfo->GetAttribute(i, attrName, 32768, value, 32768);
  452. // if (!AttributeInStandardEditor(attrName.c_str()))
  453. attributeList.InsertItem(pos, (wchar_t *)attrName, 0);
  454. attributeList.SetItemText(pos, 1, (wchar_t *)value);
  455. pos++;
  456. }
  457. attributeList.AutoColumnWidth(1);
  458. }
  459. void FileInfoDialog::FillEditBoxes()
  460. {
  461. wchar_t temp[32768] = {0};
  462. wmInfo->GetAttribute(g_wszWMAuthor, temp, 32768);
  463. SetWindowText(GetDlgItem(fileInfoHWND, IDC_EDIT_ARTIST), temp);
  464. wmInfo->GetAttribute(g_wszWMTitle, temp, 32768);
  465. SetWindowText(GetDlgItem(fileInfoHWND, IDC_EDIT_TITLE), temp);
  466. wmInfo->GetAttribute(g_wszWMAlbumTitle, temp, 32768);
  467. SetWindowText(GetDlgItem(fileInfoHWND, IDC_EDIT_ALBUM), temp);
  468. wmInfo->GetAttribute(g_wszWMDescription, temp, 32768);
  469. SetWindowText(GetDlgItem(fileInfoHWND, IDC_EDIT_COMMENTS), temp);
  470. wmInfo->GetAttribute(g_wszWMGenre, temp, 32768);
  471. SetWindowText(GetDlgItem(fileInfoHWND, IDC_EDIT_GENRE), temp);
  472. wmInfo->GetAttribute(g_wszWMYear, temp, 32768);
  473. SetWindowText(GetDlgItem(fileInfoHWND, IDC_EDIT_YEAR), temp);
  474. wmInfo->GetAttribute(g_wszWMTrackNumber, temp, 32768);
  475. SetWindowText(GetDlgItem(fileInfoHWND, IDC_EDIT_TRACK), temp);
  476. wmInfo->GetAttribute(g_wszWMPublisher, temp, 32768);
  477. SetWindowText(GetDlgItem(fileInfoHWND, IDC_EDIT_PUBLISHER), temp);
  478. wmInfo->GetAttribute(g_wszWMAlbumArtist, temp, 32768);
  479. SetWindowText(GetDlgItem(fileInfoHWND, IDC_EDIT_ALBUMARTIST), temp);
  480. }
  481. void FileInfoDialog::Init(HWND _hwnd)
  482. {
  483. fileInfoHWND = _hwnd;
  484. attributeList.setwnd(GetDlgItem(fileInfoHWND, IDC_METADATALIST));
  485. attributeList.AddCol(WASABI_API_LNGSTRINGW(IDS_ATTRIBUTE), 150);
  486. attributeList.AddCol(WASABI_API_LNGSTRINGW(IDS_VALUE), 1);
  487. attributeList.AutoColumnWidth(1);
  488. if (fileNameToShow)
  489. SetWindowText(GetDlgItem(fileInfoHWND, IDC_FILENAME), fileNameToShow);
  490. else
  491. SetWindowText(GetDlgItem(fileInfoHWND, IDC_FILENAME), fileName);
  492. FillEditBoxes();
  493. FillAttributeList();
  494. if (wmInfo->NonWritable())
  495. {
  496. EnableWindow(GetDlgItem(fileInfoHWND, IDC_APPLY), FALSE);
  497. EnableWindow(GetDlgItem(fileInfoHWND, IDC_REVERT), FALSE);
  498. EnableWindow(GetDlgItem(fileInfoHWND, IDOK), FALSE);
  499. SetDlgItemText(fileInfoHWND, IDCANCEL, WASABI_API_LNGSTRINGW(IDS_CLOSE));
  500. SendMessage(GetDlgItem(fileInfoHWND, IDC_EDIT_TITLE), EM_SETREADONLY, TRUE, 0);
  501. SendMessage(GetDlgItem(fileInfoHWND, IDC_EDIT_ARTIST), EM_SETREADONLY, TRUE, 0);
  502. SendMessage(GetDlgItem(fileInfoHWND, IDC_EDIT_ALBUM), EM_SETREADONLY, TRUE, 0);
  503. SendMessage(GetDlgItem(fileInfoHWND, IDC_EDIT_COMMENTS), EM_SETREADONLY, TRUE, 0);
  504. SendMessage(GetDlgItem(fileInfoHWND, IDC_EDIT_GENRE), EM_SETREADONLY, TRUE, 0);
  505. SendMessage(GetDlgItem(fileInfoHWND, IDC_EDIT_YEAR), EM_SETREADONLY, TRUE, 0);
  506. SendMessage(GetDlgItem(fileInfoHWND, IDC_EDIT_TRACK), EM_SETREADONLY, TRUE, 0);
  507. SendMessage(GetDlgItem(fileInfoHWND, IDC_EDIT_PUBLISHER), EM_SETREADONLY, TRUE, 0);
  508. SendMessage(GetDlgItem(fileInfoHWND, IDC_EDIT_ALBUMARTIST), EM_SETREADONLY, TRUE, 0);
  509. }
  510. SetFocus(GetDlgItem(fileInfoHWND, IDCANCEL));
  511. SendMessage(fileInfoHWND, DM_SETDEFID, GetDlgCtrlID(GetDlgItem(fileInfoHWND, IDCANCEL)),0);
  512. }
  513. void FileInfoDialog::Revert()
  514. {
  515. FillEditBoxes();
  516. FillAttributeList();
  517. }
  518. BOOL FileInfoDialog::MetadataList_Notify(NMHDR *header)
  519. {
  520. switch (header->code)
  521. {
  522. case LVN_ITEMCHANGED:
  523. {
  524. LPNMLISTVIEW lvNotif = (LPNMLISTVIEW)header;
  525. if ((lvNotif->uOldState & LVIS_SELECTED)
  526. && !(lvNotif->uNewState & LVIS_SELECTED))
  527. {
  528. EnableWindow(GetDlgItem(fileInfoHWND, IDC_EDIT),0);
  529. EnableWindow(GetDlgItem(fileInfoHWND, IDC_DELETE), 0);
  530. }
  531. if (lvNotif->uNewState & LVIS_SELECTED)
  532. {
  533. if (lvNotif->iItem != -1)
  534. {
  535. EnableWindow(GetDlgItem(fileInfoHWND, IDC_EDIT),1);
  536. EnableWindow(GetDlgItem(fileInfoHWND, IDC_DELETE), 1);
  537. }
  538. }
  539. }
  540. break;
  541. }
  542. return 0;
  543. }
  544. bool FileInfoDialog::AttributeInStandardEditor(const wchar_t *attrName)
  545. {
  546. return (!wcscmp(attrName, g_wszWMTitle)
  547. ||!wcscmp(attrName, g_wszWMAuthor)
  548. ||!wcscmp(attrName, g_wszWMAlbumTitle)
  549. ||!wcscmp(attrName, g_wszWMDescription)
  550. ||!wcscmp(attrName, g_wszWMGenre)
  551. ||!wcscmp(attrName, g_wszWMYear)
  552. ||!wcscmp(attrName, g_wszWMTrackNumber)
  553. ||!wcscmp(attrName, g_wszWMPublisher)
  554. || !wcscmp(attrName, g_wszWMAlbumArtist));
  555. }
  556. void FileInfoDialog::WriteEditBoxHelper(const wchar_t attrName[], DWORD IDC, wchar_t *&temp, int &size)
  557. {
  558. int thisSize = GetWindowTextLength(GetDlgItem(fileInfoHWND, IDC))+1;
  559. if (thisSize && thisSize>size)
  560. {
  561. if (temp)
  562. delete[] temp;
  563. temp = new wchar_t[thisSize];
  564. size=thisSize;
  565. }
  566. GetWindowText(GetDlgItem(fileInfoHWND, IDC), temp, size);
  567. wmInfo->SetAttribute(attrName, temp);
  568. }
  569. void FileInfoDialog::WriteEditBoxes()
  570. {
  571. wchar_t *temp=0;
  572. int thisSize=0;
  573. int size=0;
  574. WriteEditBoxHelper(g_wszWMTitle, IDC_EDIT_TITLE, temp, size);
  575. WriteEditBoxHelper(g_wszWMAuthor, IDC_EDIT_ARTIST, temp, size);
  576. WriteEditBoxHelper(g_wszWMAlbumTitle, IDC_EDIT_ALBUM, temp, size);
  577. WriteEditBoxHelper(g_wszWMDescription, IDC_EDIT_COMMENTS, temp, size);
  578. WriteEditBoxHelper(g_wszWMGenre, IDC_EDIT_GENRE, temp, size);
  579. WriteEditBoxHelper(g_wszWMYear, IDC_EDIT_YEAR, temp, size);
  580. WriteEditBoxHelper(g_wszWMTrackNumber, IDC_EDIT_TRACK, temp, size);
  581. WriteEditBoxHelper(g_wszWMPublisher, IDC_EDIT_PUBLISHER, temp, size);
  582. WriteEditBoxHelper(g_wszWMAlbumArtist, IDC_EDIT_ALBUMARTIST, temp, size);
  583. }
  584. void FileInfoDialog::WriteAttributeListA()
  585. {
  586. int attributeTextLength=0, valueTextLength=0;
  587. char *attribute=0, *value=0;
  588. size_t numAttrs = attributeList.GetCount();
  589. for (size_t i=0;i!=numAttrs;i++)
  590. {
  591. int textLength;
  592. textLength = attributeList.GetTextLength(i, 0);
  593. if (textLength>attributeTextLength)
  594. {
  595. if (attribute)
  596. delete[] attribute;
  597. attribute = new char[textLength];
  598. attributeTextLength=textLength;
  599. }
  600. attributeList.GetText(i, 0, attribute, attributeTextLength);
  601. textLength = attributeList.GetTextLength(i, 0);
  602. if (textLength>valueTextLength)
  603. {
  604. if (value)
  605. delete[] value;
  606. value = new char[textLength];
  607. valueTextLength=textLength;
  608. }
  609. attributeList.GetText(i, 0, value, valueTextLength);
  610. }
  611. }
  612. void FileInfoDialog::WriteAttributeList()
  613. {
  614. int attributeTextLength=0, valueTextLength=0;
  615. wchar_t *attribute=0, *value=0;
  616. size_t numAttrs = attributeList.GetCount();
  617. for (size_t i=0;i!=numAttrs;i++)
  618. {
  619. int textLength;
  620. textLength = attributeList.GetTextLength(i, 0);
  621. if (textLength>attributeTextLength)
  622. {
  623. if (attribute)
  624. delete[] attribute;
  625. attribute = new wchar_t[textLength];
  626. attributeTextLength=textLength;
  627. }
  628. attributeList.GetText(i, 0, attribute, attributeTextLength);
  629. textLength = attributeList.GetTextLength(i, 0);
  630. if (textLength>valueTextLength)
  631. {
  632. if (value)
  633. delete[] value;
  634. value = new wchar_t[textLength];
  635. valueTextLength=textLength;
  636. }
  637. attributeList.GetText(i, 0, value, valueTextLength);
  638. }
  639. }
  640. bool FileInfoDialog::Apply()
  641. {
  642. edited=true;
  643. if (!wmInfo->MakeWritable(fileName))
  644. {
  645. wchar_t title[64] = {0};
  646. if (activePlaylist.IsMe(fileName) && mod.playing)
  647. {
  648. // TODO: this is a race condition. we might have stopped in between the above if () and now...
  649. int outTime = mod.GetOutputTime();
  650. winamp.PressStop();
  651. wmInfo->MakeWritable(fileName);
  652. WriteEditBoxes();
  653. wmInfo->Flush();
  654. wmInfo->MakeReadOnly(fileName);
  655. mod.startAtMilliseconds=outTime;
  656. winamp.PressPlay();
  657. return true;
  658. }
  659. else if (!wmInfo->MakeReadOnly(fileName))
  660. MessageBox(fileInfoHWND, WASABI_API_LNGSTRINGW(IDS_UNABLE_TO_WRITE_TO_FILE_DOES_FILE_EXIST),
  661. WASABI_API_LNGSTRINGW_BUF(IDS_UNABLE_TO_WRITE_TO_FILE,title,64), MB_OK);
  662. else
  663. MessageBox(fileInfoHWND, WASABI_API_LNGSTRINGW(IDS_UNABLE_TO_WRITE_TO_FILE_MAY_NOT_HAVE_ACCESS),
  664. WASABI_API_LNGSTRINGW_BUF(IDS_UNABLE_TO_WRITE_TO_FILE,title,64), MB_OK);
  665. return false;
  666. }
  667. WriteEditBoxes();
  668. if (!wmInfo->Flush())
  669. {
  670. wchar_t* title = WASABI_API_LNGSTRINGW(IDS_SAVE_FAILED);
  671. MessageBox(NULL, title, title, MB_OK);
  672. }
  673. wmInfo->MakeReadOnly(fileName);
  674. return true;
  675. }
  676. BOOL FileInfoDialog::OnOk()
  677. {
  678. if (Apply())
  679. CLOSEDIALOGBOX(fileInfoHWND);
  680. return 0;
  681. }
  682. BOOL FileInfoDialog::OnCancel()
  683. {
  684. CLOSEDIALOGBOX(fileInfoHWND);
  685. return 0;
  686. }
  687. INT_PTR WINAPI FileInfoDialog::FileInfoProc(HWND wnd, UINT msg, WPARAM wp, LPARAM lp)
  688. {
  689. FileInfoDialog *fileInfoDialog = (FileInfoDialog *)GetWindowLongPtr(wnd, GWLP_USERDATA);
  690. switch (msg)
  691. {
  692. case WM_NOTIFYFORMAT:
  693. return NFR_UNICODE;
  694. case WM_NOTIFY:
  695. {
  696. LPNMHDR l = (LPNMHDR)lp;
  697. if (l->hwndFrom == GetDlgItem(wnd, IDC_METADATALIST))
  698. return fileInfoDialog->MetadataList_Notify(l);
  699. }
  700. break;
  701. case WM_INITDIALOG:
  702. SetWindowLongPtr(wnd, GWLP_USERDATA, (LONG_PTR)lp);
  703. fileInfoDialog = (FileInfoDialog *)lp;
  704. fileInfoDialog->Init(wnd);
  705. return FALSE;
  706. case WM_DESTROY:
  707. if (fileInfoDialog)
  708. {
  709. //delete fileInfoDialog;
  710. //fileInfoDialog=0;
  711. SetWindowLongPtr(wnd, GWLP_USERDATA, 0);
  712. }
  713. break;
  714. case WM_COMMAND:
  715. switch (LOWORD(wp))
  716. {
  717. case IDC_REVERT:
  718. fileInfoDialog->Revert();
  719. break;
  720. case IDCANCEL:
  721. return fileInfoDialog->OnCancel();
  722. break;
  723. case IDOK:
  724. return fileInfoDialog->OnOk();
  725. break;
  726. case IDC_APPLY:
  727. fileInfoDialog->Apply();
  728. break;
  729. }
  730. break;
  731. }
  732. return 0;
  733. }
  734. FileInfoDialog::FileInfoDialog(HINSTANCE _hInstance, HWND parent,const wchar_t *_fileName)
  735. : wmInfo(0),hInstance(_hInstance),fileName(0),fileNameToShow(0), edited(false)
  736. {
  737. if (activePlaylist.IsMe(_fileName))
  738. {
  739. fileName = _wcsdup(activePlaylist.GetFileName());
  740. fileNameToShow = _wcsdup(_fileName);
  741. }
  742. else
  743. fileName = _wcsdup(_fileName);
  744. wmInfo = new WMInformation(fileName);
  745. CREATEDIALOGBOX(hInstance, MAKEINTRESOURCE(IDD_FILEINFO), parent, FileInfoProc, (LPARAM)this);
  746. }
  747. FileInfoDialog::~FileInfoDialog()
  748. {
  749. delete wmInfo;
  750. wmInfo=0;
  751. free(fileName);
  752. free(fileNameToShow);
  753. }
  754. bool FileInfoDialog::WasEdited()
  755. {
  756. return edited;
  757. }
  758. */