view_data.cpp 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675
  1. #include "main.h"
  2. #include <windowsx.h>
  3. #include "resource.h"
  4. #include "../winamp/wa_ipc.h"
  5. #include "../nu/DialogSkinner.h"
  6. #include "../nu/menushortcuts.h"
  7. #include "./commandbar.h"
  8. #include "./copyfiles.h"
  9. #include "./settings.h"
  10. #include <shlwapi.h>
  11. #include <strsafe.h>
  12. #define IDT_NOTIFYINFO 1985
  13. #define IDT_UPDATESTATUS 1986
  14. #define DELAY_NOTIFYINFO 200
  15. #define DELAY_UPDATESTATUS 5
  16. #define IDC_FILEVIEW 10000
  17. #define DATAVIEW_PROPW L"DATAVIEW"
  18. #define STRCOMP_INVARIANT MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT)
  19. typedef struct _DATAVIEW
  20. {
  21. CHAR cLetter;
  22. WCHAR szSongInfoCache[MAX_PATH];
  23. } DATAVIEW;
  24. static INT_PTR WINAPI DlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
  25. INT_PTR WINAPI DataCmdBar_DialogProc(HWND hdlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
  26. static void CALLBACK DataViewTimer_OnNotifyInfoElapsed(HWND hdlg, UINT uMsg, UINT_PTR idEvent, DWORD dwTime);
  27. static void CALLBACK DataViewTimer_OnStatusUpdateElapsed(HWND hdlg, UINT uMsg, UINT_PTR idEvent, DWORD dwTime);
  28. HWND CreateCdDataViewWindow(HWND hwndParent, CHAR cLetter)
  29. {
  30. return WASABI_API_CREATEDIALOGPARAMW(IDD_VIEW_CDROM_DATA, hwndParent, DlgProc, (LPARAM)cLetter);
  31. }
  32. #define GetDataView(__hwnd) ((DATAVIEW*)GetPropW(__hwnd, DATAVIEW_PROPW))
  33. static void DataView_NotifyInfoWindow(HWND hdlg, INT iFile, BOOL bForceRefresh)
  34. {
  35. DATAVIEW *pdv = GetDataView(hdlg);
  36. HWND hParent = GetParent(hdlg);
  37. if (hParent)
  38. {
  39. wchar_t szPath[MAX_PATH], *pszPath;
  40. szPath[0] = L'\0';
  41. if (-1 != iFile)
  42. {
  43. HWND hfv = GetDlgItem(hdlg, IDC_FILEVIEW);
  44. if (hfv)
  45. {
  46. if (FileView_GetCurrentPath(hfv, szPath, ARRAYSIZE(szPath)) &&
  47. S_OK == StringCchCatW(szPath, ARRAYSIZE(szPath), L"\\"))
  48. {
  49. FVITEM item;
  50. item.mask = FVIF_TEXT | FVIF_TYPE;
  51. INT l = lstrlenW(szPath);
  52. pszPath = szPath + l;
  53. item.cchTextMax = l;
  54. item.pszText = pszPath;
  55. item.cchTextMax = ARRAYSIZE(szPath) - item.cchTextMax;
  56. if (!FileView_GetFile(hfv, iFile, &item) || FVFT_AUDIO != item.wType) szPath[0] = L'\0';
  57. else if (item.pszText != szPath) StringCchCopy(szPath, ARRAYSIZE(szPath), item.pszText);
  58. }
  59. else szPath[0] = L'\0';
  60. }
  61. }
  62. if (pdv && !bForceRefresh &&
  63. CSTR_EQUAL == CompareString(STRCOMP_INVARIANT, NORM_IGNORECASE, pdv->szSongInfoCache, -1, szPath, -1))
  64. {
  65. return;
  66. }
  67. SendMessageW(hParent, WM_SHOWFILEINFO, (WPARAM)((bForceRefresh) ? WISF_FORCE : WISF_NORMAL), (LPARAM)szPath);
  68. if (pdv) StringCchPrintfW(pdv->szSongInfoCache, sizeof(pdv->szSongInfoCache)/sizeof(pdv->szSongInfoCache[0]), szPath);
  69. }
  70. }
  71. static void DataViewStatus_UpdateText(HWND hdlg)
  72. {
  73. WCHAR szStatus[256] = {0};
  74. HWND hFileView = GetDlgItem(hdlg, IDC_FILEVIEW);
  75. HWND hbar = ViewContainer_GetCmdBar(GetParent(hdlg));
  76. if (!hbar) return;
  77. if (hFileView)
  78. FileView_GetStatusText(hFileView, szStatus, sizeof(szStatus)/sizeof(szStatus[0]));
  79. DataView_NotifyInfoWindow(hdlg, -1, FALSE);
  80. SetWindowTextW(hbar, szStatus);
  81. }
  82. typedef struct _COLUMN
  83. {
  84. INT id;
  85. INT width;
  86. } COLUMN;
  87. static COLUMN defaultColumns[] =
  88. {
  89. { FVCOLUMN_NAME, 200 },
  90. { FVCOLUMN_SIZE, 82 },
  91. { FVCOLUMN_TYPE, 64 },
  92. { FVCOLUMN_MODIFIED, 140 },
  93. { FVCOLUMN_EXTENSION, 64 },
  94. };
  95. static LPTSTR DataView_ColumnsToStr(LPTSTR pszText, size_t cchTextMax, COLUMN *pColumns, INT count)
  96. {
  97. if (!pszText || cchTextMax < 1) return NULL;
  98. pszText[0] = TEXT('\0');
  99. if (!pColumns) return pszText;
  100. LPTSTR pc = pszText;
  101. for(int i = 0; i < count; i++)
  102. {
  103. HRESULT hr = StringCchPrintfEx(pc, cchTextMax, &pc, &cchTextMax, STRSAFE_IGNORE_NULLS,
  104. TEXT("%c(%d, %d)"), ((0 == i) ? TEXT(' ') : TEXT(',')), pColumns[i].id, pColumns[i].width);
  105. if (S_OK != hr) return NULL;
  106. }
  107. return pszText;
  108. }
  109. static void DataView_LoadFileViewColumns(HWND hdlg)
  110. {
  111. UINT szColumns[256] = {0};
  112. HWND hctrl = GetDlgItem(hdlg, IDC_FILEVIEW);
  113. if (!hctrl) return;
  114. INT count = FileView_GetColumnArray(hctrl, ARRAYSIZE(szColumns), szColumns);
  115. for (int i = count-1; i >= 0; i--) FileView_DeleteColumn(hctrl, szColumns[i]);
  116. TCHAR szColumnList[4096] = {0};
  117. if (S_OK != Settings_ReadValue(C_DATAVIEW, DVF_COLUMNLIST, szColumnList, sizeof(szColumnList)) ||
  118. TEXT('\0') == *szColumnList)
  119. {
  120. DataView_ColumnsToStr(szColumnList, ARRAYSIZE(szColumnList), defaultColumns, ARRAYSIZE(defaultColumns));
  121. }
  122. for (LPCTSTR pc = szColumnList, pBlock = NULL; TEXT('\0') != *pc; pc++)
  123. {
  124. if (TEXT('(') == *pc) pBlock = (pc + 1);
  125. else if (TEXT(')') == *pc)
  126. {
  127. if (pBlock && pBlock != pc)
  128. {
  129. FVCOLUMN fvc;
  130. fvc.mask = 0;
  131. while (TEXT(' ') == *pBlock && pBlock != pc) pBlock++;
  132. if (pBlock != pc)
  133. {
  134. fvc.id = StrToInt(pBlock);
  135. while (TEXT(',') != *pBlock && pBlock != pc) pBlock++;
  136. if (pBlock != pc)
  137. {
  138. while ((TEXT(',') == *pBlock || TEXT(' ') == *pBlock) && pBlock != pc) pBlock++;
  139. if (pBlock != pc)
  140. {
  141. fvc.width = StrToInt(pBlock);
  142. if (fvc.width > 0) fvc.mask |= FVCF_WIDTH;
  143. }
  144. }
  145. FileView_InsertColumn(hctrl, &fvc);
  146. }
  147. }
  148. pBlock = NULL;
  149. }
  150. }
  151. INT orderBy, orderAsc;
  152. Settings_GetInt(C_DATAVIEW, DVF_ORDERBY, &orderBy);
  153. Settings_GetBool(C_DATAVIEW, DVF_ORDERASC, &orderAsc);
  154. FileView_SetSort(hctrl, orderBy, orderAsc);
  155. }
  156. static void DataView_SaveFileViewColumns(HWND hdlg)
  157. {
  158. UINT szOrder[256] = {0};
  159. COLUMN szColumns[256] = {0};
  160. TCHAR szBuffer[1024] = {0};
  161. HWND hctrl = GetDlgItem(hdlg, IDC_FILEVIEW);
  162. if (!hctrl) return;
  163. INT count = FileView_GetColumnArray(hctrl, ARRAYSIZE(szOrder), szOrder);
  164. for (int i = 0; i < count; i++)
  165. {
  166. szColumns[i].id = szOrder[i];
  167. szColumns[i].width = FileView_GetColumnWidth(hctrl, szOrder[i]);
  168. }
  169. DataView_ColumnsToStr(szBuffer, ARRAYSIZE(szBuffer), szColumns, count);
  170. Settings_SetString(C_DATAVIEW, DVF_COLUMNLIST, szBuffer);
  171. DWORD sort = FileView_GetSort(hctrl);
  172. Settings_SetInt(C_DATAVIEW, DVF_ORDERBY, LOWORD(sort));
  173. Settings_SetBool(C_DATAVIEW, DVF_ORDERASC, HIWORD(sort));
  174. }
  175. static UINT DataView_ReadFileViewStyle()
  176. {
  177. UINT style = 0;
  178. INT nVal;
  179. style = FVS_DETAILVIEW;
  180. if (S_OK == Settings_GetInt(C_DATAVIEW, DVF_VIEWMODE, &nVal))
  181. {
  182. switch(nVal)
  183. {
  184. case FVS_ICONVIEW:
  185. case FVS_LISTVIEW:
  186. style = nVal;
  187. break;
  188. }
  189. }
  190. if (S_OK == Settings_GetInt(C_DATAVIEW, DVF_SHOWAUDIO, &nVal) && nVal) style |= FVS_SHOWAUDIO;
  191. if (S_OK == Settings_GetInt(C_DATAVIEW, DVF_SHOWVIDEO, &nVal) && nVal) style |= FVS_SHOWVIDEO;
  192. if (S_OK == Settings_GetInt(C_DATAVIEW, DVF_SHOWPLAYLIST, &nVal) && nVal) style |= FVS_SHOWPLAYLIST;
  193. if (S_OK == Settings_GetInt(C_DATAVIEW, DVF_SHOWUNKNOWN, &nVal) && nVal) style |= FVS_SHOWUNKNOWN;
  194. if (S_OK == Settings_GetInt(C_DATAVIEW, DVF_HIDEEXTENSION, &nVal) && nVal) style |= FVS_HIDEEXTENSION;
  195. if (S_OK == Settings_GetInt(C_DATAVIEW, DVF_IGNOREHIDDEN, &nVal) && nVal) style |= FVS_IGNOREHIDDEN;
  196. if (S_OK == Settings_GetInt(C_GLOBAL, GF_ENQUEUEBYDEFAULT, &nVal) && nVal)
  197. style |= FVS_ENQUEUE;
  198. return style;
  199. }
  200. static void DataView_SaveFileViewStyle(UINT uStyle)
  201. {
  202. Settings_SetInt(C_DATAVIEW, DVF_VIEWMODE, (FVS_VIEWMASK & uStyle));
  203. Settings_SetBool(C_DATAVIEW, DVF_SHOWAUDIO, (FVS_SHOWAUDIO & uStyle));
  204. Settings_SetBool(C_DATAVIEW, DVF_SHOWVIDEO, (FVS_SHOWVIDEO & uStyle));
  205. Settings_SetBool(C_DATAVIEW, DVF_SHOWPLAYLIST, (FVS_SHOWPLAYLIST & uStyle));
  206. Settings_SetBool(C_DATAVIEW, DVF_SHOWUNKNOWN, (FVS_SHOWUNKNOWN & uStyle));
  207. Settings_SetBool(C_DATAVIEW, DVF_HIDEEXTENSION, (FVS_HIDEEXTENSION & uStyle));
  208. Settings_SetBool(C_DATAVIEW, DVF_IGNOREHIDDEN, (FVS_IGNOREHIDDEN & uStyle));
  209. }
  210. static BOOL DataView_OnInitDialog(HWND hdlg, HWND hwndFocus, LPARAM lParam)
  211. {
  212. RECT rc;
  213. HWND hctrl;
  214. DATAVIEW *pdv = (DATAVIEW*)calloc(1, sizeof(DATAVIEW));
  215. if (pdv)
  216. {
  217. pdv->cLetter = (CHAR)lParam;
  218. pdv->szSongInfoCache[0] = L'\0';
  219. SetPropW(hdlg, DATAVIEW_PROPW, pdv);
  220. }
  221. GetClientRect(hdlg, &rc);
  222. MLSkinWindow2(plugin.hwndLibraryParent, hdlg, SKINNEDWND_TYPE_AUTO, SWS_USESKINFONT | SWS_USESKINCOLORS | SWS_USESKINCURSORS);
  223. MLFILEVIEWCREATESTRUCT fvcs;
  224. fvcs.hwndParent = hdlg;
  225. fvcs.hwndInsertAfter = hdlg;
  226. fvcs.fStyle = DataView_ReadFileViewStyle();
  227. fvcs.x = 0;
  228. fvcs.y = 0;
  229. fvcs.cx = rc.right - rc.left;
  230. fvcs.cy = rc.bottom - rc.top - 4;
  231. hctrl = (HWND)SENDMLIPC(plugin.hwndLibraryParent, ML_IPC_CREATEFILEVIEW, (WPARAM)&fvcs);
  232. if (hctrl)
  233. {
  234. wchar_t szRoot[] = L"x:";
  235. if (pdv) szRoot[0] = pdv->cLetter;
  236. //szRoot[0] = L'C';
  237. FileView_SetRoot(hctrl, szRoot);
  238. SetWindowLongPtrW(hctrl, GWLP_ID, IDC_FILEVIEW);
  239. DataView_LoadFileViewColumns(hdlg);
  240. SetWindowLongPtrW(hctrl, GWL_STYLE, GetWindowLongPtrW(hctrl, GWL_STYLE) | WS_VISIBLE);
  241. INT nPos;
  242. if (S_OK == Settings_GetInt(C_DATAVIEW, DVF_DIVIDERPOS, &nPos))
  243. FileView_SetDividerPos(hctrl, nPos, FVRF_NOREDRAW);
  244. }
  245. ViewContainer_CreateCmdBar(GetParent(hdlg), hdlg, IDD_COMMANDBAR_DATA, DataCmdBar_DialogProc, (ULONG_PTR)hctrl);
  246. DataView_NotifyInfoWindow(hdlg, -1, TRUE); // ignore cache
  247. SendMessage(hdlg, WM_COMMAND, MAKEWPARAM(ID_DRIVE_MODE_CHANGED, 0), 0L);
  248. TCHAR szRoot[MAX_PATH] = {0};
  249. if (hctrl && S_OK == Settings_ReadString(C_DATAVIEW, DVF_LASTFOLDER, szRoot, ARRAYSIZE(szRoot)))
  250. FileView_SetCurrentPath(hctrl, szRoot, TRUE);
  251. return FALSE;
  252. }
  253. static void DataView_OnDestroy(HWND hdlg)
  254. {
  255. KillTimer(hdlg, IDT_NOTIFYINFO);
  256. DataView_NotifyInfoWindow(hdlg, -1, FALSE);
  257. HWND hView = GetDlgItem(hdlg, IDC_FILEVIEW);
  258. if (hView)
  259. {
  260. WCHAR szRoot[MAX_PATH] = {0};
  261. FileView_GetCurrentPath(hView, szRoot, ARRAYSIZE(szRoot));
  262. Settings_SetString(C_DATAVIEW, DVF_LASTFOLDER, szRoot);
  263. DataView_SaveFileViewColumns(hdlg);
  264. DataView_SaveFileViewStyle(FileView_GetStyle(hView));
  265. Settings_SetInt(C_DATAVIEW, DVF_DIVIDERPOS, FileView_GetDividerPos(hView));
  266. }
  267. DATAVIEW *pdv = GetDataView(hdlg);
  268. if (pdv)
  269. {
  270. RemovePropW(hdlg, DATAVIEW_PROPW);
  271. free(pdv);
  272. }
  273. ViewContainer_DestroyCmdBar(GetParent(hdlg));
  274. }
  275. static void CALLBACK DataViewTimer_OnStatusUpdateElapsed(HWND hdlg, UINT uMsg, UINT_PTR idEvent, DWORD dwTime)
  276. {
  277. KillTimer(hdlg, idEvent);
  278. DataViewStatus_UpdateText(hdlg);
  279. BOOL enablePlay = FALSE;
  280. HWND hctrl = GetDlgItem(hdlg, IDC_FILEVIEW);
  281. if (hctrl && FileView_GetSelectedCount(hctrl) > 0)
  282. {
  283. enablePlay = (-1 != FileView_GetNextFile(hctrl, -1, FVNF_PLAYABLE | FVNF_SELECTED));
  284. }
  285. HWND hbar = ViewContainer_GetCmdBar(GetParent(hdlg));
  286. if (hbar)
  287. {
  288. if (NULL != (hctrl = GetDlgItem(hbar, IDC_BTN_PLAYEX))) EnableWindow(hctrl, enablePlay);
  289. if (NULL != (hctrl = GetDlgItem(hbar, IDC_BTN_COPY))) EnableWindow(hctrl, enablePlay);
  290. }
  291. }
  292. static void CALLBACK DataViewTimer_OnNotifyInfoElapsed(HWND hdlg, UINT uMsg, UINT_PTR idEvent, DWORD dwTime)
  293. {
  294. KillTimer(hdlg, IDT_NOTIFYINFO);
  295. HWND hFileView = GetDlgItem(hdlg, IDC_FILEVIEW);
  296. INT iFile = -1;
  297. if (hFileView)
  298. {
  299. iFile = FileView_GetSelectedCount(hFileView);
  300. if (1 != iFile) iFile = -1;
  301. else iFile = FileView_GetNextFile(hFileView, -1, FVNF_FOCUSED);
  302. }
  303. DataView_NotifyInfoWindow(hdlg, iFile, FALSE);
  304. }
  305. static void DataView_OnWindowPosChanged(HWND hdlg, WINDOWPOS *pwp)
  306. {
  307. if (0 == (SWP_NOSIZE & pwp->flags))
  308. {
  309. HWND hctrl;
  310. RECT rc, rw;
  311. GetClientRect(hdlg, &rc);
  312. hctrl = GetDlgItem(hdlg, IDC_FILEVIEW);
  313. if (hctrl && GetWindowRect(hctrl, &rw))
  314. {
  315. MapWindowPoints(HWND_DESKTOP, hdlg, (POINT*)&rw, 2);
  316. SetWindowPos(hctrl, NULL, 0, 0, rc.right - rc.left, rc.bottom - rc.top,
  317. SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOMOVE | ((SWP_NOREDRAW | SWP_NOCOPYBITS) & pwp->flags));
  318. }
  319. }
  320. }
  321. static void DataView_OnCopySelection(HWND hdlg)
  322. {
  323. LPWSTR *ppszFiles = NULL;
  324. ULONGLONG *pFSizes;
  325. INT count, iFile;
  326. size_t cchPath, cchFile;
  327. WCHAR szPath[MAX_PATH] = {0};
  328. FVITEM file = {0};
  329. HWND hctrl = GetDlgItem(hdlg, IDC_FILEVIEW);
  330. if (!hctrl) return;
  331. count = FileView_GetSelectedCount(hctrl);
  332. if (count < 1) return;
  333. if (!FileView_GetCurrentPath(hctrl, szPath, sizeof(szPath)/sizeof(szPath[0])) ||
  334. S_OK != StringCchLengthW(szPath, sizeof(szPath)/sizeof(szPath[0]), &cchPath)) return;
  335. ppszFiles = (LPWSTR*)CoTaskMemAlloc(sizeof(LPWSTR)*count);
  336. pFSizes = (ULONGLONG*)CoTaskMemAlloc(sizeof(ULONGLONG)*count);
  337. if (!ppszFiles || !pFSizes)
  338. {
  339. if (ppszFiles) CoTaskMemFree(ppszFiles);
  340. if (pFSizes) CoTaskMemFree(pFSizes);
  341. return;
  342. }
  343. iFile = -1;
  344. count = 0;
  345. file.mask = FVIF_TEXT | FVIF_SIZE;
  346. TCHAR szBuffer[MAX_PATH] = {0};
  347. while (-1 != (iFile = FileView_GetNextFile(hctrl, iFile, FVNF_SELECTED | FVNF_PLAYABLE)))
  348. {
  349. file.pszText = szBuffer;
  350. file.cchTextMax = ARRAYSIZE(szBuffer);
  351. if (FileView_GetFile(hctrl, iFile, &file))
  352. {
  353. cchFile = (file.pszText) ? lstrlenW(file.pszText) : 0;
  354. if (cchFile)
  355. {
  356. pFSizes[count] = (ULONGLONG)(((__int64)file.dwSizeHigh << 32) | file.dwSizeLow);
  357. ppszFiles[count] = (LPWSTR)CoTaskMemAlloc(sizeof(WCHAR)*(cchPath + cchFile + 4));
  358. if (ppszFiles[count])
  359. {
  360. PathCombineW(ppszFiles[count], szPath, file.pszText);
  361. count++;
  362. }
  363. }
  364. }
  365. }
  366. if (!MLDisc_CopyFiles(hdlg, ppszFiles, pFSizes, count))
  367. {
  368. if (ppszFiles)
  369. {
  370. for (int i = 0; i < count; i++) CoTaskMemFree(ppszFiles[i]);
  371. CoTaskMemFree(ppszFiles);
  372. }
  373. if (pFSizes) CoTaskMemFree(pFSizes);
  374. }
  375. }
  376. static void DataView_OnDriveModeChanged(HWND hdlg)
  377. {
  378. DATAVIEW *pdv = GetDataView(hdlg);
  379. if (!pdv) return;
  380. HWND hbar;
  381. if (NULL != (hbar = ViewContainer_GetCmdBar(GetParent(hdlg))))
  382. {
  383. HWND hctrl;
  384. if (NULL != (hctrl = GetDlgItem(hbar, IDC_BTN_EJECT)))
  385. {
  386. UINT cMode = DriveManager_GetDriveMode(pdv->cLetter);
  387. EnableWindow(hctrl, (DM_MODE_READY == cMode));
  388. }
  389. }
  390. }
  391. static void DataView_OnCommand(HWND hdlg, INT eventId, INT ctrlId, HWND hwndCtrl)
  392. {
  393. switch(ctrlId)
  394. {
  395. case ID_COPY_SELECTION:
  396. DataView_OnCopySelection(hdlg);
  397. break;
  398. case ID_DRIVE_MODE_CHANGED:
  399. DataView_OnDriveModeChanged(hdlg);
  400. break;
  401. }
  402. }
  403. static void FileView_OnFolderChanged(HWND hdlg, NMHDR *phdr)
  404. {
  405. DataView_NotifyInfoWindow(hdlg, -1, FALSE);
  406. SetTimer(hdlg, IDT_UPDATESTATUS, DELAY_UPDATESTATUS, DataViewTimer_OnStatusUpdateElapsed);
  407. }
  408. static void FileView_OnStatusChanged(HWND hdlg, NMHDR *phdr)
  409. {
  410. SetTimer(hdlg, IDT_UPDATESTATUS, DELAY_UPDATESTATUS, DataViewTimer_OnStatusUpdateElapsed);
  411. }
  412. static void FileView_OnFileStateChanged(HWND hdlg, NMFVSTATECHANGED *pnmsc)
  413. {
  414. SetTimer(hdlg, IDT_UPDATESTATUS, DELAY_UPDATESTATUS, DataViewTimer_OnStatusUpdateElapsed);
  415. SetTimer(hdlg, IDT_NOTIFYINFO, DELAY_NOTIFYINFO, DataViewTimer_OnNotifyInfoElapsed);
  416. }
  417. static void FileView_OnDoubleClick(HWND hdlg, NMFVFILEACTIVATE *pnma)
  418. {
  419. if (-1 == pnma->iFile) return;
  420. HWND hctrl = GetDlgItem(hdlg, IDC_FILEVIEW);
  421. if (!hctrl) return;
  422. SendMessageW(hctrl, WM_COMMAND,
  423. MAKEWPARAM(FileView_GetActionCommand(hctrl, (FVS_ENQUEUE & (FileView_GetStyle(hctrl)) ? FVA_ENQUEUE : FVA_PLAY)), 0), 0L);
  424. }
  425. static void FileView_OnUninitOptionsMenu(HWND hdlg, HMENU hMenu, UINT uCommand)
  426. {
  427. HWND hParent = GetParent(hdlg);
  428. if (!hMenu || !hParent || !ViewContainer_GetMiniInfoEnabled(hParent)) return;
  429. INT index = GetMenuItemCount(hMenu);
  430. MENUITEMINFOW mii = { sizeof(MENUITEMINFOW), };
  431. mii.fMask = MIIM_ID;
  432. while (index--)
  433. {
  434. if (GetMenuItemInfoW(hMenu, index, TRUE, &mii) && ID_MINIINFO_SHOW == mii.wID)
  435. {
  436. if (DeleteMenu(hMenu, index, MF_BYPOSITION))
  437. DeleteMenu(hMenu, --index, MF_BYPOSITION);
  438. break;
  439. }
  440. }
  441. }
  442. static void FileView_OnInitOptionsMenu(HWND hdlg, HMENU hMenu)
  443. {
  444. INT index;
  445. HWND hParent;
  446. hParent = GetParent(hdlg);
  447. if (!hMenu || !hParent || !ViewContainer_GetMiniInfoEnabled(hParent)) return;
  448. MENUITEMINFOW mii = { sizeof(MENUITEMINFOW), };
  449. index = GetMenuItemCount(hMenu);
  450. mii.fMask = MIIM_TYPE;
  451. mii.fType = MFT_SEPARATOR;
  452. if (InsertMenuItemW(hMenu, index, TRUE, &mii))
  453. {
  454. wchar_t szText[1024] = {0};
  455. WASABI_API_LNGSTRINGW_BUF(IDS_SHOW_INFO, szText, sizeof(szText)/sizeof(szText[0]));
  456. if (WASABI_API_APP)
  457. {
  458. HACCEL szAccel[24] = {0};
  459. INT c = WASABI_API_APP->app_getAccelerators(GetParent(hdlg), szAccel, sizeof(szAccel)/sizeof(szAccel[0]), FALSE);
  460. AppendShortcutText(szText, sizeof(szText)/sizeof(szText[0]), ID_MINIINFO_SHOW, szAccel, c, MSF_REPLACE);
  461. }
  462. index++;
  463. mii.fMask = MIIM_STRING | MIIM_STATE | MIIM_ID;
  464. mii.dwTypeData = szText;
  465. mii.wID = ID_MINIINFO_SHOW;
  466. mii.fState = (ViewContainer_GetMiniInfoVisible(hParent)) ? MFS_CHECKED : MFS_UNCHECKED;
  467. InsertMenuItemW(hMenu, index, TRUE, &mii);
  468. }
  469. }
  470. static void FileView_OnInitFileContextMenu(HWND hdlg, HMENU hMenu, HWND hView)
  471. {
  472. HWND hbar = ViewContainer_GetCmdBar(GetParent(hdlg));
  473. HWND hButton = (hbar) ? GetDlgItem(hbar, IDC_BTN_COPY) : NULL;
  474. if (!hButton) return;
  475. wchar_t szText[1024] = {0};
  476. GetWindowTextW(hButton, szText, sizeof(szText)/sizeof(szText[0]));
  477. if (WASABI_API_APP)
  478. {
  479. HACCEL szAccel[24] = {0};
  480. INT c = WASABI_API_APP->app_getAccelerators(GetParent(hdlg), szAccel, sizeof(szAccel)/sizeof(szAccel[0]), FALSE);
  481. AppendShortcutText(szText, sizeof(szText)/sizeof(szText[0]), ID_COPY_SELECTION, szAccel, c, MSF_REPLACE);
  482. }
  483. MENUITEMINFOW mii = { sizeof(MENUITEMINFOW), };
  484. mii.fMask = MIIM_STRING | MIIM_STATE | MIIM_ID;
  485. mii.dwTypeData = szText;
  486. mii.wID = ID_COPY_SELECTION; // TODO: make id uniqueue
  487. mii.fState = (IsWindowEnabled(hButton)) ? MFS_ENABLED : MFS_DISABLED;
  488. InsertMenuItemW(hMenu, 2, TRUE, &mii);
  489. }
  490. static BOOL FileView_OnInitMenu(HWND hdlg, NMFVMENU *pnm)
  491. {
  492. switch(pnm->uMenuType)
  493. {
  494. case FVMENU_OPTIONS: FileView_OnInitOptionsMenu(hdlg, pnm->hMenu); break;
  495. case FVMENU_FILEOPCONTEXT: FileView_OnInitFileContextMenu(hdlg, pnm->hMenu, pnm->hdr.hwndFrom); break;
  496. }
  497. return FALSE;
  498. }
  499. static void FileView_OnUninitMenu(HWND hdlg, NMFVMENU *pnm)
  500. {
  501. switch(pnm->uMenuType)
  502. {
  503. case FVMENU_OPTIONS: FileView_OnUninitOptionsMenu(hdlg, pnm->hMenu, pnm->uCommand); break;
  504. case FVMENU_FILEOPCONTEXT: DeleteMenu(pnm->hMenu, ID_COPY_SELECTION, MF_BYCOMMAND); break;
  505. }
  506. }
  507. static BOOL FileView_OnMenuCommand(HWND hdlg, NMFVMENU *pnm)
  508. {
  509. switch(pnm->uCommand)
  510. {
  511. case ID_MINIINFO_SHOW:
  512. SendMessageW(GetParent(hdlg), WM_COMMAND, MAKEWPARAM(ID_MINIINFO_SHOW, 0), 0L);
  513. return TRUE;
  514. case ID_COPY_SELECTION:
  515. SendMessageW(hdlg, WM_COMMAND, MAKEWPARAM(ID_COPY_SELECTION, 0), 0L);
  516. return TRUE;
  517. }
  518. return FALSE;
  519. }
  520. static INT_PTR DataView_OnNotify(HWND hdlg, INT ctrlId, NMHDR *phdr)
  521. {
  522. switch(phdr->idFrom)
  523. {
  524. case IDC_FILEVIEW:
  525. switch(phdr->code)
  526. {
  527. case FVN_FOLDERCHANGED: FileView_OnFolderChanged(hdlg, phdr); break;
  528. case FVN_STATECHANGED: FileView_OnFileStateChanged(hdlg, (NMFVSTATECHANGED*)phdr); break;
  529. case FVN_STATUSCHANGED: FileView_OnStatusChanged(hdlg, phdr); break;
  530. case NM_DBLCLK: FileView_OnDoubleClick(hdlg, (NMFVFILEACTIVATE*)phdr); break;
  531. case FVN_INITMENU: return FileView_OnInitMenu(hdlg, (NMFVMENU*)phdr);
  532. case FVN_UNINITMENU: FileView_OnUninitMenu(hdlg, (NMFVMENU*)phdr); break;
  533. case FVN_MENUCOMMAND: return FileView_OnMenuCommand(hdlg, (NMFVMENU*)phdr);
  534. }
  535. break;
  536. }
  537. return 0;
  538. }
  539. static void DataView_OnQueryInfo(HWND hdlg)
  540. {
  541. KillTimer(hdlg, IDT_NOTIFYINFO);
  542. DataView_NotifyInfoWindow(hdlg, -1, TRUE);
  543. SetTimer(hdlg, IDT_NOTIFYINFO, DELAY_NOTIFYINFO, DataViewTimer_OnNotifyInfoElapsed);
  544. }
  545. static void DataView_OnDisplayChange(HWND hdlg)
  546. {
  547. HWND hctrl = GetDlgItem(hdlg, IDC_FILEVIEW);
  548. if (!hctrl) return;
  549. BOOL bVal;
  550. Settings_GetBool(C_GLOBAL, GF_ENQUEUEBYDEFAULT, &bVal);
  551. FileView_SetStyle(hctrl, (bVal) ? FVS_ENQUEUE : 0L, FVS_ENQUEUE);
  552. }
  553. static INT_PTR WINAPI DlgProc(HWND hdlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
  554. {
  555. switch (uMsg)
  556. {
  557. case WM_INITDIALOG: return DataView_OnInitDialog(hdlg, (HWND)wParam, lParam);
  558. case WM_DESTROY: DataView_OnDestroy(hdlg); break;
  559. case WM_WINDOWPOSCHANGED: DataView_OnWindowPosChanged(hdlg, (WINDOWPOS*)lParam); return TRUE;
  560. case WM_COMMAND: DataView_OnCommand(hdlg, HIWORD(wParam), LOWORD(wParam), (HWND)lParam); break;
  561. case WM_NOTIFY: MSGRESULT(hdlg, DataView_OnNotify(hdlg, (INT)wParam, (LPNMHDR) lParam));
  562. case WM_QUERYFILEINFO: DataView_OnQueryInfo(hdlg); break;
  563. case WM_DISPLAYCHANGE: DataView_OnDisplayChange(hdlg); break;
  564. }
  565. return 0;
  566. }