fileview_menu.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331
  1. #include "./fileview.h"
  2. #include "./fileview_internal.h"
  3. #include "./resource.h"
  4. #include "../nu/menushortcuts.h"
  5. #include <windowsx.h>
  6. #include <strsafe.h>
  7. #define SUBMENU_VIEWMODE 0
  8. #define SUBMENU_OPTIONS 1
  9. #define SUBMENU_ARRANGEBY 2
  10. #define SUBMENU_COLUMNS 3
  11. #define SUBMENU_FILELIST 4
  12. #define SUBMENU_COMMON 5
  13. #define SUBMENU_FILELIST_PLAY 0
  14. #define SUBMENU_FILELIST_VIEWCONTEXT 1
  15. #define SUBMENU_FILELIST_OPCONTEXT 2
  16. static INT MenuCopyEx(HMENU hDest, INT iDstStart, HMENU hSource, INT iSrcStart, INT iSrcCount)
  17. {
  18. if (!hDest || !hSource) return 0;
  19. wchar_t szText[1024] = {0};
  20. INT pos;
  21. MENUITEMINFOW mii = {sizeof(MENUITEMINFOW), };
  22. mii.fMask = MIIM_BITMAP | MIIM_CHECKMARKS | MIIM_DATA | MIIM_FTYPE | MIIM_ID | MIIM_STATE | MIIM_STRING | MIIM_SUBMENU;
  23. mii.dwTypeData = szText;
  24. if (iDstStart < 0) iDstStart = 0;
  25. if (iSrcStart < 0) iSrcStart = 0;
  26. pos = iDstStart;
  27. if ( 0 != iSrcCount)
  28. {
  29. INT c = GetMenuItemCount(hSource);
  30. if (iSrcStart > c) return 0;
  31. if (iSrcCount < 0) iSrcCount = c - iSrcStart;
  32. else if (iSrcCount < (c - iSrcStart)) c = iSrcCount + iSrcStart;
  33. for (int i = iSrcStart; i < c; i++)
  34. {
  35. mii.cch = sizeof(szText)/sizeof(szText[0]);
  36. if (GetMenuItemInfoW(hSource, i, TRUE, &mii))
  37. {
  38. if(InsertMenuItemW(hDest, pos, TRUE, &mii))
  39. {
  40. pos++;
  41. }
  42. }
  43. }
  44. }
  45. else
  46. {
  47. mii.cch = sizeof(szText)/sizeof(szText[0]);
  48. if (GetMenuItemInfoW(hSource, iSrcStart, FALSE, &mii))
  49. {
  50. if (InsertMenuItemW(hDest, pos, TRUE, &mii))
  51. {
  52. pos++;
  53. }
  54. }
  55. }
  56. return pos - iDstStart;
  57. }
  58. static INT MenuCopy(HMENU hDest, INT iDstStart, HMENU hSource)
  59. {
  60. return MenuCopyEx(hDest, iDstStart, hSource, 0, -1);
  61. }
  62. static BOOL MenuInsertSeparator(HMENU hMenu, INT iPos)
  63. {
  64. if (!hMenu) return FALSE;
  65. MENUITEMINFOW mii = {sizeof(MENUITEMINFOW), };
  66. mii.fMask = MIIM_FTYPE;
  67. mii.fType = MFT_SEPARATOR;
  68. return InsertMenuItemW(hMenu, iPos, TRUE, &mii);
  69. }
  70. static BOOL MenuInsertCommonItem(HMENU hMenu, INT iPos, HMENU hViewMenu, UINT itemId)
  71. {
  72. if (!hMenu) return FALSE;
  73. HMENU hCommon = GetSubMenu(hViewMenu, SUBMENU_COMMON);
  74. if (!hCommon) return FALSE;
  75. return (MenuCopyEx(hMenu, iPos, hCommon, itemId, 0) > 0);
  76. }
  77. static HMENU FileViewMenu_GetViewModeMenu(HWND hView, HMENU hViewMenu)
  78. {
  79. HMENU hMenu = GetSubMenu(hViewMenu, SUBMENU_VIEWMODE);
  80. if (!hMenu) return NULL;
  81. UINT style = (FVS_VIEWMASK & FileView_GetStyle(hView));
  82. MENUITEMINFOW mii = {sizeof(MENUITEMINFOW), };
  83. mii.fMask = MIIM_STATE | MIIM_FTYPE;
  84. if (GetMenuItemInfoW(hMenu, ID_FILEVIEW_SETMODE_ICON, FALSE, &mii))
  85. {
  86. mii.fType |= MFT_RADIOCHECK;
  87. mii.fState = (FVS_ICONVIEW == style) ? MFS_CHECKED : MFS_UNCHECKED;
  88. SetMenuItemInfoW(hMenu, ID_FILEVIEW_SETMODE_ICON, FALSE, &mii);
  89. }
  90. if (GetMenuItemInfoW(hMenu, ID_FILEVIEW_SETMODE_LIST, FALSE, &mii))
  91. {
  92. mii.fType |= MFT_RADIOCHECK;
  93. mii.fState = (FVS_LISTVIEW == style) ? MFS_CHECKED : MFS_UNCHECKED;
  94. SetMenuItemInfoW(hMenu, ID_FILEVIEW_SETMODE_LIST, FALSE, &mii);
  95. }
  96. if (GetMenuItemInfoW(hMenu, ID_FILEVIEW_SETMODE_DETAIL, FALSE, &mii))
  97. {
  98. mii.fType |= MFT_RADIOCHECK;
  99. mii.fState = (FVS_DETAILVIEW == style) ? MFS_CHECKED : MFS_UNCHECKED;
  100. SetMenuItemInfoW(hMenu, ID_FILEVIEW_SETMODE_DETAIL, FALSE, &mii);
  101. }
  102. return hMenu;
  103. }
  104. static HMENU FileViewMenu_GetOptionsMenu(HWND hView, HMENU hViewMenu)
  105. {
  106. HMENU hMenu = GetSubMenu(hViewMenu, SUBMENU_OPTIONS);
  107. if (!hMenu) return NULL;
  108. UINT style = FileView_GetStyle(hView);
  109. CheckMenuItem(hMenu, IDM_FILEVIEW_HIDEEXTENSION, MF_BYCOMMAND | ((FVS_HIDEEXTENSION & style) ? MF_CHECKED : MF_UNCHECKED));
  110. CheckMenuItem(hMenu, IDM_FILEVIEW_IGNOREHIDDEN, MF_BYCOMMAND | ((FVS_IGNOREHIDDEN & style) ? MF_CHECKED : MF_UNCHECKED));
  111. CheckMenuItem(hMenu, IDM_FILEVIEW_SHOWAUDIO, MF_BYCOMMAND | ((FVS_SHOWAUDIO & style) ? MF_CHECKED : MF_UNCHECKED));
  112. CheckMenuItem(hMenu, IDM_FILEVIEW_SHOWVIDEO, MF_BYCOMMAND | ((FVS_SHOWVIDEO & style) ? MF_CHECKED : MF_UNCHECKED));
  113. CheckMenuItem(hMenu, IDM_FILEVIEW_SHOWPLAYLIST, MF_BYCOMMAND | ((FVS_SHOWPLAYLIST & style) ? MF_CHECKED : MF_UNCHECKED));
  114. CheckMenuItem(hMenu, IDM_FILEVIEW_SHOWUNKNOWN, MF_BYCOMMAND | ((FVS_SHOWUNKNOWN & style) ? MF_CHECKED : MF_UNCHECKED));
  115. return hMenu;
  116. }
  117. static HMENU FileViewMenu_GetArrangeByMenu(HWND hView, HMENU hViewMenu)
  118. {
  119. HMENU hMenu = GetSubMenu(hViewMenu, SUBMENU_ARRANGEBY);
  120. if (!hMenu) return NULL;
  121. UINT sort = FileView_GetSort(hView);
  122. UINT sortCol = LOWORD(sort);
  123. UINT szColumn[512] = {0};
  124. WCHAR szText[256] = {0};
  125. INT count;
  126. MENUITEMINFOW mii = {sizeof(MENUITEMINFOW), };
  127. mii.fMask = MIIM_ID;
  128. count = GetMenuItemCount(hMenu);
  129. while(count--)
  130. {
  131. if (GetMenuItemInfoW(hMenu, count, TRUE, &mii) &&
  132. mii.wID >= IDM_COLUMN_ARRANGE_MIN && mii.wID <= IDM_COLUMN_ARRANGE_MAX)
  133. {
  134. RemoveMenu(hMenu, count, MF_BYPOSITION);
  135. }
  136. }
  137. mii.fMask = MIIM_STRING | MIIM_STATE | MIIM_ID | MIIM_FTYPE;
  138. mii.fType = MFT_RADIOCHECK;
  139. count = FileView_GetColumnArray(hView, 512, &szColumn);
  140. for (int i = 0; i < count; i++)
  141. {
  142. FileView_GetColumnName(hView, szColumn[i], sizeof(szText)/sizeof(szText[0]), szText);
  143. mii.dwTypeData = szText;
  144. mii.wID = IDM_COLUMN_ARRANGE_MIN + szColumn[i];
  145. mii.fState = (sortCol == szColumn[i]) ? MFS_CHECKED : 0;
  146. InsertMenuItemW(hMenu, i, TRUE, &mii);
  147. }
  148. CheckMenuItem(hMenu, IDM_FILEVIEW_SORTASCENDING, MF_BYCOMMAND | (HIWORD(sort) ? MF_CHECKED : MF_UNCHECKED));
  149. return hMenu;
  150. }
  151. static HMENU FileViewMenu_GetColumnsMenu(HWND hView, HMENU hViewMenu)
  152. {
  153. HMENU hMenu = GetSubMenu(hViewMenu, SUBMENU_COLUMNS);
  154. if (!hMenu) return NULL;
  155. UINT szColumn[512] = {0};
  156. INT count;
  157. MENUITEMINFOW mii = {sizeof(MENUITEMINFOW), };
  158. mii.fMask = MIIM_ID;
  159. count = GetMenuItemCount(hMenu);
  160. while(count--)
  161. {
  162. if (GetMenuItemInfoW(hMenu, count, TRUE, &mii) &&
  163. mii.wID >= IDM_COLUMN_SHOW_MIN && mii.wID <= IDM_COLUMN_SHOW_MAX)
  164. {
  165. RemoveMenu(hMenu, count, MF_BYPOSITION);
  166. }
  167. }
  168. mii.fMask = MIIM_STRING | MIIM_STATE | MIIM_ID;
  169. count = FileView_GetColumnArray(hView, 512, &szColumn);
  170. for (INT i = 0; i < RegisteredColumnsCount; i++)
  171. {
  172. mii.dwTypeData = IS_INTRESOURCE(szRegisteredColumns[i].pszText) ?
  173. WASABI_API_LNGSTRINGW((UINT)(UINT_PTR)szRegisteredColumns[i].pszText) : szRegisteredColumns[i].pszText;
  174. mii.wID = IDM_COLUMN_SHOW_MIN + szRegisteredColumns[i].id;
  175. INT index = 0;
  176. while(index < count && szRegisteredColumns[i].id != szColumn[index]) index++;
  177. mii.fState = (index < count) ? MFS_CHECKED : 0;
  178. if(FVCOLUMN_NAME == szRegisteredColumns[i].id) mii.fState |= MFS_DISABLED;
  179. InsertMenuItemW(hMenu, i, TRUE, &mii);
  180. }
  181. return hMenu;
  182. }
  183. static HMENU FileViewMenu_GetPlayMenu(HWND hView, HMENU hViewMenu)
  184. {
  185. HMENU hMenu = GetSubMenu(hViewMenu, SUBMENU_FILELIST);
  186. if (hMenu) hMenu = GetSubMenu(hMenu, SUBMENU_FILELIST_PLAY);
  187. if (!hMenu) return NULL;
  188. BOOL bEnablePlay = (FileView_GetSelectedCount(hView) &&
  189. (-1 != FileView_GetNextFile(hView, -1, FVNF_PLAYABLE | FVNF_SELECTED)));
  190. MENUITEMINFOW mii = {sizeof(MENUITEMINFOW), };
  191. mii.fMask = MIIM_ID | MIIM_STATE;
  192. mii.fState = (bEnablePlay) ? MFS_ENABLED : MFS_DISABLED;
  193. mii.wID = FileView_GetActionCommand(hView, FVA_PLAY);
  194. SetMenuItemInfoW(hMenu, 0, TRUE, &mii);
  195. mii.wID = mii.wID = FileView_GetActionCommand(hView, FVA_ENQUEUE);
  196. SetMenuItemInfoW(hMenu, 1, TRUE, &mii);
  197. return hMenu;
  198. }
  199. static void FileViewMenu_PopulateFileOpMenu(HMENU hMenu, HWND hView, HMENU hViewMenu)
  200. {
  201. INT c, pos = 0;
  202. c = MenuCopy(hMenu, pos, FileViewMenu_GetPlayMenu(hView, hViewMenu));
  203. pos += c;
  204. if (MenuInsertCommonItem(hMenu, pos, hViewMenu, ID_FILEVIEW_SELECT_ALL) && c)
  205. MenuInsertSeparator(hMenu, pos);
  206. }
  207. static HMENU FileViewMenu_GetFileViewMenu(HWND hView, HMENU hViewMenu)
  208. {
  209. HMENU hMenu = GetSubMenu(hViewMenu, SUBMENU_FILELIST);
  210. if (hMenu) hMenu = GetSubMenu(hMenu, SUBMENU_FILELIST_VIEWCONTEXT);
  211. if (!hMenu) return NULL;
  212. INT c, pos= 0;
  213. c = GetMenuItemCount(hMenu);
  214. while(c--) RemoveMenu(hMenu, c, MF_BYPOSITION);
  215. c = MenuCopyEx(hMenu, pos, hViewMenu, SUBMENU_VIEWMODE, 1);
  216. pos += c;
  217. if (c && MenuInsertSeparator(hMenu, pos)) pos++;
  218. pos += MenuCopyEx(hMenu, pos, hViewMenu, SUBMENU_ARRANGEBY, 1);
  219. if (MenuInsertCommonItem(hMenu, pos, hViewMenu, ID_FILEVIEW_REFRESH)) pos++;
  220. if (MenuInsertSeparator(hMenu, pos)) pos++;
  221. MenuCopyEx(hMenu, pos, hViewMenu, SUBMENU_OPTIONS, 1);
  222. return hMenu;
  223. }
  224. static HMENU FileViewMenu_GetFileOpMenu(HWND hView, HMENU hViewMenu)
  225. {
  226. HMENU hMenu = GetSubMenu(hViewMenu, SUBMENU_FILELIST);
  227. if (hMenu) hMenu = GetSubMenu(hMenu, SUBMENU_FILELIST_OPCONTEXT);
  228. if (!hMenu) return NULL;
  229. INT c, pos = 0;
  230. c = GetMenuItemCount(hMenu);
  231. while(c--) RemoveMenu(hMenu, c, MF_BYPOSITION);
  232. c = MenuCopy(hMenu, pos, FileViewMenu_GetPlayMenu(hView, hViewMenu));
  233. pos += c;
  234. if (MenuInsertCommonItem(hMenu, pos, hViewMenu, ID_FILEVIEW_SELECT_ALL) && c)
  235. MenuInsertSeparator(hMenu, pos);
  236. return hMenu;
  237. }
  238. static HMENU FileViewMenu_GetFileMenu(HWND hView, HMENU hViewMenu)
  239. {
  240. FVHITTEST ht;
  241. GetCursorPos(&ht.pt);
  242. MapWindowPoints(HWND_DESKTOP, hView, &ht.pt, 1);
  243. if (-1 != FileView_HitTest(hView, &ht) && (FVHT_ONFILE & ht.uFlags))
  244. return FileViewMenu_GetFileOpMenu(hView, hViewMenu);
  245. else
  246. return FileViewMenu_GetFileViewMenu(hView, hViewMenu);;
  247. }
  248. HMENU FileViewMenu_Initialize()
  249. {
  250. return WASABI_API_LOADMENUW(IDR_MENU_FILEVIEW);
  251. }
  252. HMENU FileViewMenu_GetSubMenu(HWND hView, HMENU hViewMenu, UINT uMenuType)
  253. {
  254. HMENU hMenu = NULL;
  255. switch(uMenuType)
  256. {
  257. case FVMENU_OPTIONS: hMenu = FileViewMenu_GetOptionsMenu(hView, hViewMenu); break;
  258. case FVMENU_ARRANGEBY: hMenu = FileViewMenu_GetArrangeByMenu(hView, hViewMenu); break;
  259. case FVMENU_COLUMNS: hMenu = FileViewMenu_GetColumnsMenu(hView, hViewMenu); break;
  260. case FVMENU_PLAY: hMenu = FileViewMenu_GetPlayMenu(hView, hViewMenu); break;
  261. case FVMENU_FILECONTEXT: hMenu = FileViewMenu_GetFileMenu(hView, hViewMenu); break;
  262. case FVMENU_FILEVIEWCONTEXT: hMenu = FileViewMenu_GetFileViewMenu(hView, hViewMenu); break;
  263. case FVMENU_FILEOPCONTEXT: hMenu = FileViewMenu_GetFileOpMenu(hView, hViewMenu); break;
  264. case FVMENU_VIEWMODE: hMenu = FileViewMenu_GetViewModeMenu(hView, hViewMenu); break;
  265. }
  266. return hMenu;
  267. }
  268. UINT FileViewMenu_GetMenuType(HWND hView, HMENU hViewMenu, HMENU hMenu)
  269. {
  270. UINT type = ((UINT)-1);
  271. if (hMenu == GetSubMenu(hViewMenu, SUBMENU_VIEWMODE)) type = FVMENU_VIEWMODE;
  272. else if (hMenu == GetSubMenu(hViewMenu, SUBMENU_OPTIONS)) type = FVMENU_OPTIONS;
  273. else if (hMenu == GetSubMenu(hViewMenu, SUBMENU_ARRANGEBY)) type = FVMENU_ARRANGEBY;
  274. else if (hMenu == GetSubMenu(hViewMenu, SUBMENU_COLUMNS)) type = FVMENU_COLUMNS;
  275. else if (hMenu == GetSubMenu(GetSubMenu(hViewMenu, SUBMENU_FILELIST), SUBMENU_FILELIST_PLAY)) type = FVMENU_PLAY;
  276. else if (hMenu == GetSubMenu(GetSubMenu(hViewMenu, SUBMENU_FILELIST), SUBMENU_FILELIST_VIEWCONTEXT)) type = FVMENU_FILEVIEWCONTEXT;
  277. else if (hMenu == GetSubMenu(GetSubMenu(hViewMenu, SUBMENU_FILELIST), SUBMENU_FILELIST_OPCONTEXT)) type = FVMENU_FILEOPCONTEXT;
  278. return type;
  279. }