1 // MyLoadMenu.cpp
2
3 #include "StdAfx.h"
4
5 #include "../../../Windows/FileDir.h"
6 #include "../../../Windows/Menu.h"
7 #include "../../../Windows/TimeUtils.h"
8 #include "../../../Windows/Control/Dialog.h"
9
10 #include "../../PropID.h"
11
12 #include "../Common/CompressCall.h"
13
14 #include "AboutDialog.h"
15 #include "App.h"
16 #include "BrowseDialog2.h"
17 #include "HelpUtils.h"
18 #include "LangUtils.h"
19 #include "MyLoadMenu.h"
20 #include "RegistryUtils.h"
21
22 #include "PropertyNameRes.h"
23 #include "resource.h"
24
25 using namespace NWindows;
26
27 static const UINT k_MenuID_OpenBookmark = 830;
28 static const UINT k_MenuID_SetBookmark = 810;
29 static const UINT k_MenuID_TimePopup = IDM_VIEW_TIME_POPUP;
30 static const UINT k_MenuID_Time = IDM_VIEW_TIME;
31
32 #if 0
33 // static const UINT k_MenuID_Bookmark_Temp = 850;
34 #endif
35
36 extern HINSTANCE g_hInstance;
37
38 #define kFMHelpTopic "FM/index.htm"
39
40 extern void OptionsDialog(HWND hwndOwner, HINSTANCE hInstance);
41
42 enum
43 {
44 k_MenuIndex_File = 0,
45 k_MenuIndex_Edit,
46 k_MenuIndex_View,
47 k_MenuIndex_Bookmarks
48 };
49
50 #ifdef Z7_LANG
51 static const UInt32 k_LangID_TopMenuItems[] =
52 {
53 IDM_FILE,
54 IDM_EDIT,
55 IDM_VIEW,
56 IDM_FAVORITES,
57 IDM_TOOLS,
58 IDM_HELP
59 };
60
61 static const UInt32 k_LangID_Toolbars = IDM_VIEW_TOOLBARS;
62 static const UInt32 k_LangID_AddToFavorites = IDM_ADD_TO_FAVORITES;
63
64 static const CIDLangPair kIDLangPairs[] =
65 {
66 { IDCLOSE, 557 }, // IDM_EXIT
67 { IDM_VIEW_ARANGE_BY_NAME, IDS_PROP_NAME },
68 { IDM_VIEW_ARANGE_BY_TYPE, IDS_PROP_FILE_TYPE },
69 { IDM_VIEW_ARANGE_BY_DATE, IDS_PROP_MTIME },
70 { IDM_VIEW_ARANGE_BY_SIZE, IDS_PROP_SIZE }
71 };
72
FindLangItem(unsigned controlID)73 static int FindLangItem(unsigned controlID)
74 {
75 for (unsigned i = 0; i < Z7_ARRAY_SIZE(kIDLangPairs); i++)
76 if (kIDLangPairs[i].ControlID == controlID)
77 return (int)i;
78 return -1;
79 }
80 #endif
81
GetSortControlID(PROPID propID)82 static unsigned GetSortControlID(PROPID propID)
83 {
84 switch (propID)
85 {
86 case kpidName: return IDM_VIEW_ARANGE_BY_NAME;
87 case kpidExtension: return IDM_VIEW_ARANGE_BY_TYPE;
88 case kpidMTime: return IDM_VIEW_ARANGE_BY_DATE;
89 case kpidSize: return IDM_VIEW_ARANGE_BY_SIZE;
90 case kpidNoProperty: return IDM_VIEW_ARANGE_NO_SORT;
91 }
92 return IDM_VIEW_ARANGE_BY_NAME;
93 // IDM_VIEW_ARANGE_NO_SORT;
94 // return -1;
95 }
96
97 /*
98 #if _MSC_VER > 1400
99 // GetVersion was declared deprecated
100 #pragma warning(disable : 4996)
101 #endif
102
103 static bool g_IsNew_fMask = false;
104 static class CInit_fMask
105 {
106 public:
107 CInit_fMask()
108 {
109 DWORD v = GetVersion();
110 v = ((v & 0xff) << 8) | ((v >> 8) & 0xFF);
111 g_IsNew_fMask = (v > 0x400); // (win98/win2000) or newer
112 }
113 } g_Init_fMask;
114 static UINT Get_fMask_for_String()
115 { return g_IsNew_fMask ? MIIM_STRING : MIIM_TYPE; }
116 static UINT Get_fMask_for_FType_and_String()
117 { return g_IsNew_fMask ? (MIIM_STRING | MIIM_FTYPE) : MIIM_TYPE; }
118 */
119
120 /*
121 We can use new MIIM_STRING / MIIM_FTYPE flags in the following conditions:
122 1) we run at new Windows (win98/win2000) or newer
123 2) also we probably must set MENUITEMINFO::cbSize as sizeof of full
124 (MENUITEMINFO) that was compiled with (WINVER >= 0x0500)
125 But it's simpler to use old MIIM_TYPE without these complex checks.
126 */
127
128 // /*
Get_fMask_for_String()129 static inline UINT Get_fMask_for_String() { return MIIM_TYPE; }
Get_fMask_for_FType_and_String()130 static inline UINT Get_fMask_for_FType_and_String() { return MIIM_TYPE; }
131 // */
132
Is_MenuItem_TimePopup(const CMenuItem & item)133 static bool Is_MenuItem_TimePopup(const CMenuItem &item)
134 {
135 return item.wID == k_MenuID_TimePopup ||
136 item.StringValue.IsPrefixedBy_Ascii_NoCase("20");
137 }
138
139 #ifdef Z7_LANG
MyChangeMenu(HMENU menuLoc,unsigned menuID,unsigned level,unsigned menuIndex)140 static void MyChangeMenu(HMENU menuLoc, unsigned menuID, unsigned level, unsigned menuIndex)
141 {
142 CMenu menu;
143 menu.Attach(menuLoc);
144
145 for (unsigned i = 0;; i++)
146 {
147 CMenuItem item;
148 /* here we can use
149 Get_fMask_for_String() or
150 Get_fMask_for_FType_and_String()
151 We want to change only String of menu item.
152 It's not required to change (fType) of menu item.
153 We can look (fType) to check for SEPARATOR item.
154 But String of separator is empty and (wID == 0).
155 So we can check for SEPARATOR without (fType) requesting.
156 So it's enough to use Get_fMask_for_String() here */
157 item.fMask =
158 Get_fMask_for_String()
159 // Get_fMask_for_FType_and_String()
160 | MIIM_SUBMENU | MIIM_ID;
161 if (!menu.GetItem(i, true, item))
162 break;
163 {
164 UString newString;
165 if (item.hSubMenu)
166 {
167 /* in win10:
168 MENU+POPUP:
169 (wID == item.hSubMenu)
170 MENUEX+POPUP where ID is not set:
171 (wID == 0)
172 MENU+SEPARATOR
173 (wID == 0)
174 */
175 UInt32 langID = item.wID;
176 if (langID >= (1 << 16))
177 {
178 // here we try to exclude the case (wID == item.hSubMenu) if (MENU+POPUP)
179 continue;
180 }
181 if (langID == 0)
182 {
183 if (level == 0)
184 {
185 if (i < Z7_ARRAY_SIZE(k_LangID_TopMenuItems))
186 langID = k_LangID_TopMenuItems[i];
187 }
188 else if (level == 1)
189 {
190 if (menuID == IDM_FAVORITES || (menuID == 0 && menuIndex == k_MenuIndex_Bookmarks))
191 langID = k_LangID_AddToFavorites;
192 else if (menuID == IDM_VIEW || (menuID == 0 && menuIndex == k_MenuIndex_View))
193 {
194 if (Is_MenuItem_TimePopup(item))
195 langID = k_MenuID_TimePopup;
196 else
197 langID = k_LangID_Toolbars;
198 }
199 }
200 }
201 if (langID == k_MenuID_TimePopup)
202 continue;
203 if (langID != k_LangID_AddToFavorites)
204 MyChangeMenu(item.hSubMenu, langID, level + 1, i);
205 if (langID == 0)
206 continue;
207 LangString_OnlyFromLangFile(langID, newString);
208 if (newString.IsEmpty())
209 continue;
210 }
211 else
212 {
213 if (item.fMask & (MIIM_TYPE | MIIM_FTYPE))
214 if (item.IsSeparator())
215 continue;
216 if (item.StringValue.IsEmpty())
217 continue;
218 const int langPos = FindLangItem(item.wID);
219 // we don't need lang change for CRC items!!!
220 const UInt32 langID = langPos >= 0 ? kIDLangPairs[langPos].LangID : item.wID;
221 if (langID == 0)
222 continue;
223
224 if (langID == IDM_OPEN_INSIDE_ONE ||
225 langID == IDM_OPEN_INSIDE_PARSER)
226 {
227 LangString_OnlyFromLangFile(IDM_OPEN_INSIDE, newString);
228 if (newString.IsEmpty())
229 continue;
230 newString.Replace(L"&", L"");
231 const int tabPos = newString.Find(L"\t");
232 if (tabPos >= 0)
233 newString.DeleteFrom(tabPos);
234 newString += (langID == IDM_OPEN_INSIDE_ONE ? " *" : " #");
235 }
236 else if (langID == IDM_BENCHMARK2)
237 {
238 LangString_OnlyFromLangFile(IDM_BENCHMARK, newString);
239 if (newString.IsEmpty())
240 continue;
241 newString.Replace(L"&", L"");
242 const int tabPos = newString.Find(L"\t");
243 if (tabPos >= 0)
244 newString.DeleteFrom(tabPos);
245 newString += " 2";
246 }
247 else
248 {
249 LangString_OnlyFromLangFile(langID, newString);
250 }
251
252 if (newString.IsEmpty())
253 continue;
254
255 const int tabPos = item.StringValue.ReverseFind(L'\t');
256 if (tabPos >= 0)
257 newString += item.StringValue.Ptr(tabPos);
258 }
259
260 {
261 item.StringValue = newString;
262 // we want to change only String
263 item.fMask = Get_fMask_for_String();
264 menu.SetItem(i, true, item);
265 }
266 }
267 }
268 }
269 #endif
270
271 static CMenu g_FileMenu;
272
273 static struct CFileMenuDestroyer
274 {
~CFileMenuDestroyerCFileMenuDestroyer275 ~CFileMenuDestroyer() { if ((HMENU)g_FileMenu) g_FileMenu.Destroy(); }
276 } g_FileMenuDestroyer;
277
278
279 static void CopyMenu(HMENU srcMenuSpec, HMENU destMenuSpec);
280
CopyPopMenu_IfRequired(CMenuItem & item)281 static void CopyPopMenu_IfRequired(CMenuItem &item)
282 {
283 /* if (item.hSubMenu) is defined
284 {
285 - it creates new (popup) menu
286 - it copies menu items from old item.hSubMenu menu to new (popup) menu
287 - it sets item.hSubMenu to handle of created (popup) menu
288 } */
289 if (item.hSubMenu)
290 {
291 CMenu popup;
292 popup.CreatePopup();
293 CopyMenu(item.hSubMenu, popup);
294 item.hSubMenu = popup;
295 }
296 }
297
298 /* destMenuSpec must be non-NULL handle to created empty popup menu */
CopyMenu(HMENU srcMenuSpec,HMENU destMenuSpec)299 static void CopyMenu(HMENU srcMenuSpec, HMENU destMenuSpec)
300 {
301 CMenu srcMenu;
302 srcMenu.Attach(srcMenuSpec);
303 CMenu destMenu;
304 destMenu.Attach(destMenuSpec);
305 unsigned startPos = 0;
306 for (unsigned i = 0;; i++)
307 {
308 CMenuItem item;
309 item.fMask = MIIM_SUBMENU | MIIM_STATE | MIIM_ID | Get_fMask_for_FType_and_String();
310 if (!srcMenu.GetItem(i, true, item))
311 break;
312 CopyPopMenu_IfRequired(item);
313 if (destMenu.InsertItem(startPos, true, item))
314 startPos++;
315 }
316 }
317
318
319 /* use for (needResetMenu):
320 false : for call from program window creation code
321 true : for another calls : (from Options language change)
322 */
MyLoadMenu(bool needResetMenu)323 void MyLoadMenu(bool needResetMenu)
324 {
325 #ifdef UNDER_CE
326
327 const HMENU oldMenu = g_App._commandBar.GetMenu(0);
328 if (oldMenu)
329 ::DestroyMenu(oldMenu);
330 /* BOOL b = */ g_App._commandBar.InsertMenubar(g_hInstance, IDM_MENU, 0);
331 const HMENU baseMenu = g_App._commandBar.GetMenu(0);
332 // if (startInit)
333 // SetIdsForSubMenus(baseMenu, 0, 0);
334 if (!g_LangID.IsEmpty())
335 MyChangeMenu(baseMenu, 0, 0);
336 g_App._commandBar.DrawMenuBar(0);
337
338 #else // UNDER_CE
339
340 const HWND hWnd = g_HWND;
341 bool menuWasChanged = false;
342 /*
343 We must reload to english default menu for at least two cases:
344 - if some submenu was changed (File or another submenu can be changed after menu activating).
345 - for change from non-english lang to another partial non-english lang,
346 where we still need some english strings.
347 But we reload menu to default menu everytime except of program starting stage.
348 That scheme is simpler than complex checks for exact conditions for menu reload.
349 */
350 if (needResetMenu)
351 {
352 const HMENU oldMenu = ::GetMenu(hWnd);
353 const HMENU newMenu = ::LoadMenu(g_hInstance, MAKEINTRESOURCE(IDM_MENU));
354 // docs for SetMenu(): the window is redrawn to reflect the menu change.
355 if (newMenu && ::SetMenu(hWnd, newMenu))
356 ::DestroyMenu(oldMenu);
357 menuWasChanged = true;
358 }
359 const HMENU baseMenu = ::GetMenu(hWnd);
360 // if (startInit)
361 // SetIdsForSubMenus(baseMenu, 0, 0);
362 #ifdef Z7_LANG
363 if (!g_Lang.IsEmpty()) // !g_LangID.IsEmpty() &&
364 {
365 MyChangeMenu(baseMenu, 0, 0, 0);
366 menuWasChanged = true;
367 }
368 #endif
369
370 if (menuWasChanged)
371 ::DrawMenuBar(hWnd);
372
373 #endif // UNDER_CE
374
375 // menuWasChanged = false; // for debug
376 if (menuWasChanged || !(HMENU)g_FileMenu)
377 {
378 if ((HMENU)g_FileMenu)
379 g_FileMenu.Destroy();
380 g_FileMenu.CreatePopup();
381 CopyMenu(::GetSubMenu(baseMenu, k_MenuIndex_File), g_FileMenu);
382 }
383 }
384
OnMenuActivating(HWND,HMENU hMenu,int position)385 void OnMenuActivating(HWND /* hWnd */, HMENU hMenu, int position)
386 {
387 HMENU mainMenu =
388 #ifdef UNDER_CE
389 g_App._commandBar.GetMenu(0);
390 #else
391 ::GetMenu(g_HWND)
392 #endif
393 ;
394
395 if (::GetSubMenu(mainMenu, position) != hMenu)
396 return;
397
398 if (position == k_MenuIndex_File)
399 {
400 CMenu menu;
401 menu.Attach(hMenu);
402 menu.RemoveAllItems();
403 g_App.GetFocusedPanel().CreateFileMenu(hMenu);
404 }
405 else if (position == k_MenuIndex_Edit)
406 {
407 /*
408 CMenu menu;
409 menu.Attach(hMenu);
410 menu.EnableItem(IDM_EDIT_CUT, MF_ENABLED);
411 menu.EnableItem(IDM_EDIT_COPY, MF_ENABLED);
412 menu.EnableItem(IDM_EDIT_PASTE, IsClipboardFormatAvailableHDROP() ? MF_ENABLED : MF_GRAYED);
413 */
414 }
415 else if (position == k_MenuIndex_View)
416 {
417 // View;
418 CMenu menu;
419 menu.Attach(hMenu);
420 menu.CheckRadioItem(
421 IDM_VIEW_LARGE_ICONS, IDM_VIEW_DETAILS,
422 IDM_VIEW_LARGE_ICONS + g_App.GetListViewMode(), MF_BYCOMMAND);
423
424 menu.CheckRadioItem(
425 IDM_VIEW_ARANGE_BY_NAME,
426 IDM_VIEW_ARANGE_NO_SORT,
427 GetSortControlID(g_App.GetSortID()),
428 MF_BYCOMMAND);
429
430 menu.CheckItemByID(IDM_VIEW_TWO_PANELS, g_App.NumPanels == 2);
431 menu.CheckItemByID(IDM_VIEW_FLAT_VIEW, g_App.GetFlatMode());
432 menu.CheckItemByID(IDM_VIEW_ARCHIVE_TOOLBAR, g_App.ShowArchiveToolbar);
433 menu.CheckItemByID(IDM_VIEW_STANDARD_TOOLBAR, g_App.ShowStandardToolbar);
434 menu.CheckItemByID(IDM_VIEW_TOOLBARS_LARGE_BUTTONS, g_App.LargeButtons);
435 menu.CheckItemByID(IDM_VIEW_TOOLBARS_SHOW_BUTTONS_TEXT, g_App.ShowButtonsLables);
436 menu.CheckItemByID(IDM_VIEW_AUTO_REFRESH, g_App.Get_AutoRefresh_Mode());
437 // menu.CheckItemByID(IDM_VIEW_SHOW_STREAMS, g_App.Get_ShowNtfsStrems_Mode());
438 // menu.CheckItemByID(IDM_VIEW_SHOW_DELETED, g_App.ShowDeletedFiles);
439
440 for (unsigned i = 0;; i++)
441 {
442 CMenuItem item;
443 item.fMask = Get_fMask_for_String() | MIIM_SUBMENU | MIIM_ID;
444 item.fType = MFT_STRING;
445 if (!menu.GetItem(i, true, item))
446 break;
447 if (item.hSubMenu && Is_MenuItem_TimePopup(item))
448 {
449 FILETIME ft;
450 NTime::GetCurUtcFileTime(ft);
451
452 {
453 wchar_t s[64];
454 s[0] = 0;
455 if (ConvertUtcFileTimeToString(ft, s, kTimestampPrintLevel_DAY))
456 item.StringValue = s;
457 }
458
459 item.fMask = Get_fMask_for_String() | MIIM_ID;
460 item.fType = MFT_STRING;
461 item.wID = k_MenuID_TimePopup;
462 menu.SetItem(i, true, item);
463
464 CMenu subMenu;
465 subMenu.Attach(menu.GetSubMenu((int)i));
466 subMenu.RemoveAllItems();
467
468 const int k_TimeLevels[] =
469 {
470 kTimestampPrintLevel_DAY,
471 kTimestampPrintLevel_MIN,
472 kTimestampPrintLevel_SEC,
473 // 1,2,3,4,5,6,
474 kTimestampPrintLevel_NTFS,
475 kTimestampPrintLevel_NS
476 };
477
478 unsigned last = k_MenuID_Time;
479 unsigned selectedCommand = 0;
480 g_App._timestampLevels.Clear();
481 unsigned id = k_MenuID_Time;
482
483 for (unsigned k = 0; k < Z7_ARRAY_SIZE(k_TimeLevels); k++)
484 {
485 wchar_t s[64];
486 s[0] = 0;
487 const int timestampLevel = k_TimeLevels[k];
488 if (ConvertUtcFileTimeToString(ft, s, timestampLevel))
489 {
490 if (subMenu.AppendItem(MF_STRING, id, s))
491 {
492 last = id;
493 g_App._timestampLevels.Add(timestampLevel);
494 if (g_App.GetTimestampLevel() == timestampLevel)
495 selectedCommand = id;
496 id++;
497 }
498 }
499 }
500 if (selectedCommand != 0)
501 menu.CheckRadioItem(k_MenuID_Time, last, selectedCommand, MF_BYCOMMAND);
502
503 if (subMenu.AppendItem(MF_STRING, IDM_VIEW_TIME_UTC, L"UTC"))
504 subMenu.CheckItemByID(IDM_VIEW_TIME_UTC, g_Timestamp_Show_UTC);
505 }
506 }
507 }
508 else if (position == k_MenuIndex_Bookmarks)
509 {
510 CMenu menu;
511 menu.Attach(hMenu);
512
513 CMenu subMenu;
514 subMenu.Attach(menu.GetSubMenu(0));
515 subMenu.RemoveAllItems();
516 unsigned i;
517
518 for (i = 0; i < 10; i++)
519 {
520 UString s = LangString(IDS_BOOKMARK);
521 s.Add_Space();
522 const char c = (char)(L'0' + i);
523 s.Add_Char(c);
524 s += "\tAlt+Shift+";
525 s.Add_Char(c);
526 subMenu.AppendItem(MF_STRING, k_MenuID_SetBookmark + i, s);
527 }
528
529 menu.RemoveAllItemsFrom(2);
530
531 for (i = 0; i < 10; i++)
532 {
533 UString s = g_App.AppState.FastFolders.GetString(i);
534 const int kMaxSize = 100;
535 const int kFirstPartSize = kMaxSize / 2;
536 if (s.Len() > kMaxSize)
537 {
538 s.Delete(kFirstPartSize, s.Len() - kMaxSize);
539 s.Insert(kFirstPartSize, L" ... ");
540 }
541 if (s.IsEmpty())
542 s = '-';
543 s += "\tAlt+";
544 s.Add_Char((char)('0' + i));
545 menu.AppendItem(MF_STRING, k_MenuID_OpenBookmark + i, s);
546 }
547 #if 0
548 {
549 FString tempPathF;
550 if (NFile::NDir::MyGetTempPath(tempPathF))
551 {
552 menu.AppendItem(MF_SEPARATOR, 0, (LPCTSTR)NULL);
553 UString s;
554 s = "Temp : ";
555 s += fs2us(tempPathF);
556 menu.AppendItem(MF_STRING, k_MenuID_Bookmark_Temp, s);
557 }
558 }
559 #endif
560 }
561 }
562
563 /*
564 It doesn't help
565 void OnMenuUnActivating(HWND hWnd, HMENU hMenu, int id)
566 {
567 if (::GetSubMenu(::GetMenu(g_HWND), 0) != hMenu)
568 return;
569 }
570 */
571
572 static const unsigned g_Zvc_IDs[] =
573 {
574 IDM_VER_EDIT,
575 IDM_VER_COMMIT,
576 IDM_VER_REVERT,
577 IDM_VER_DIFF
578 };
579
580 static const char * const g_Zvc_Strings[] =
581 {
582 "Ver Edit (&1)"
583 , "Ver Commit"
584 , "Ver Revert"
585 , "Ver Diff (&0)"
586 };
587
Load(HMENU hMenu,unsigned startPos)588 void CFileMenu::Load(HMENU hMenu, unsigned startPos)
589 {
590 CMenu destMenu;
591 destMenu.Attach(hMenu);
592
593 UString diffPath;
594 ReadRegDiff(diffPath);
595
596 unsigned numRealItems = startPos;
597
598 const bool isBigScreen = NControl::IsDialogSizeOK(40, 200, g_HWND);
599
600 for (unsigned i = 0;; i++)
601 {
602 CMenuItem item;
603
604 item.fMask = MIIM_SUBMENU | MIIM_STATE | MIIM_ID | Get_fMask_for_FType_and_String();
605 item.fType = MFT_STRING;
606
607 if (!g_FileMenu.GetItem(i, true, item))
608 break;
609
610 {
611 if (!programMenu && item.wID == IDCLOSE)
612 continue;
613
614 if (item.wID == IDM_DIFF && diffPath.IsEmpty())
615 continue;
616
617 if (item.wID == IDM_OPEN_INSIDE_ONE || item.wID == IDM_OPEN_INSIDE_PARSER)
618 {
619 // We use diff as "super mode" marker for additional commands.
620 /*
621 if (diffPath.IsEmpty())
622 continue;
623 */
624 }
625
626 if (item.wID == IDM_BENCHMARK2)
627 {
628 // We use diff as "super mode" marker for additional commands.
629 if (diffPath.IsEmpty())
630 continue;
631 }
632
633 bool isOneFsFile = (isFsFolder && numItems == 1 && allAreFiles);
634 bool disable = (!isOneFsFile && (item.wID == IDM_SPLIT || item.wID == IDM_COMBINE));
635
636 if (readOnly)
637 {
638 switch (item.wID)
639 {
640 case IDM_RENAME:
641 case IDM_MOVE_TO:
642 case IDM_DELETE:
643 case IDM_COMMENT:
644 case IDM_CREATE_FOLDER:
645 case IDM_CREATE_FILE:
646 disable = true;
647 }
648 }
649
650 if (isHashFolder)
651 {
652 switch (item.wID)
653 {
654 case IDM_OPEN:
655 case IDM_OPEN_INSIDE:
656 case IDM_OPEN_INSIDE_ONE:
657 case IDM_OPEN_INSIDE_PARSER:
658 case IDM_OPEN_OUTSIDE:
659 case IDM_FILE_VIEW:
660 case IDM_FILE_EDIT:
661 // case IDM_RENAME:
662 case IDM_COPY_TO:
663 case IDM_MOVE_TO:
664 // case IDM_DELETE:
665 case IDM_COMMENT:
666 case IDM_CREATE_FOLDER:
667 case IDM_CREATE_FILE:
668 case IDM_LINK:
669 case IDM_DIFF:
670 disable = true;
671 }
672 }
673
674
675 if (item.wID == IDM_LINK && numItems != 1)
676 disable = true;
677
678 if (item.wID == IDM_ALT_STREAMS)
679 disable = !isAltStreamsSupported;
680
681 if (!isBigScreen && (disable || item.IsSeparator()))
682 continue;
683
684 CopyPopMenu_IfRequired(item);
685 if (destMenu.InsertItem(startPos, true, item))
686 {
687 if (disable)
688 destMenu.EnableItem(startPos, MF_BYPOSITION | MF_GRAYED);
689 startPos++;
690 }
691
692 if (!item.IsSeparator())
693 numRealItems = startPos;
694 }
695 }
696
697 UString vercPath;
698 if (!diffPath.IsEmpty() && isFsFolder && allAreFiles && numItems == 1)
699 ReadReg_VerCtrlPath(vercPath);
700
701 if (!vercPath.IsEmpty())
702 {
703 NFile::NFind::CFileInfo fi;
704 if (fi.Find(FilePath) && fi.Size < ((UInt32)1 << 31) && !fi.IsDir())
705 {
706 for (unsigned k = 0; k < Z7_ARRAY_SIZE(g_Zvc_IDs); k++)
707 {
708 const unsigned id = g_Zvc_IDs[k];
709 if (fi.IsReadOnly())
710 {
711 if (id == IDM_VER_COMMIT ||
712 id == IDM_VER_REVERT ||
713 id == IDM_VER_DIFF)
714 continue;
715 }
716 else
717 {
718 if (id == IDM_VER_EDIT)
719 continue;
720 }
721
722 CMenuItem item;
723 UString s (g_Zvc_Strings[k]);
724 if (destMenu.AppendItem(MF_STRING, id, s))
725 {
726 startPos++;
727 numRealItems = startPos;
728 }
729 }
730 }
731 }
732
733 destMenu.RemoveAllItemsFrom(numRealItems);
734 }
735
ExecuteFileCommand(unsigned id)736 bool ExecuteFileCommand(unsigned id)
737 {
738 if (id >= kMenuCmdID_Plugin_Start)
739 {
740 g_App.GetFocusedPanel().InvokePluginCommand(id);
741 g_App.GetFocusedPanel()._sevenZipContextMenu.Release();
742 g_App.GetFocusedPanel()._systemContextMenu.Release();
743 return true;
744 }
745
746 switch (id)
747 {
748 // File
749 case IDM_OPEN: g_App.OpenItem(); break;
750
751 case IDM_OPEN_INSIDE: g_App.OpenItemInside(NULL); break;
752 case IDM_OPEN_INSIDE_ONE: g_App.OpenItemInside(L"*"); break;
753 case IDM_OPEN_INSIDE_PARSER: g_App.OpenItemInside(L"#"); break;
754
755 case IDM_OPEN_OUTSIDE: g_App.OpenItemOutside(); break;
756 case IDM_FILE_VIEW: g_App.EditItem(false); break;
757 case IDM_FILE_EDIT: g_App.EditItem(true); break;
758 case IDM_RENAME: g_App.Rename(); break;
759 case IDM_COPY_TO: g_App.CopyTo(); break;
760 case IDM_MOVE_TO: g_App.MoveTo(); break;
761 case IDM_DELETE: g_App.Delete(!IsKeyDown(VK_SHIFT)); break;
762
763 case IDM_HASH_ALL: g_App.CalculateCrc("*"); break;
764 case IDM_CRC32: g_App.CalculateCrc("CRC32"); break;
765 case IDM_CRC64: g_App.CalculateCrc("CRC64"); break;
766 case IDM_XXH64: g_App.CalculateCrc("XXH64"); break;
767 case IDM_MD5: g_App.CalculateCrc("MD5"); break;
768 case IDM_SHA1: g_App.CalculateCrc("SHA1"); break;
769 case IDM_SHA256: g_App.CalculateCrc("SHA256"); break;
770 case IDM_SHA384: g_App.CalculateCrc("SHA384"); break;
771 case IDM_SHA512: g_App.CalculateCrc("SHA512"); break;
772 case IDM_SHA3_256: g_App.CalculateCrc("SHA3-256"); break;
773 case IDM_BLAKE2SP: g_App.CalculateCrc("BLAKE2sp"); break;
774
775 case IDM_DIFF: g_App.DiffFiles(); break;
776
777 case IDM_VER_EDIT:
778 case IDM_VER_COMMIT:
779 case IDM_VER_REVERT:
780 case IDM_VER_DIFF:
781 g_App.VerCtrl(id); break;
782
783 case IDM_SPLIT: g_App.Split(); break;
784 case IDM_COMBINE: g_App.Combine(); break;
785 case IDM_PROPERTIES: g_App.Properties(); break;
786 case IDM_COMMENT: g_App.Comment(); break;
787 case IDM_CREATE_FOLDER: g_App.CreateFolder(); break;
788 case IDM_CREATE_FILE: g_App.CreateFile(); break;
789 #ifndef UNDER_CE
790 case IDM_LINK: g_App.Link(); break;
791 case IDM_ALT_STREAMS: g_App.OpenAltStreams(); break;
792 #endif
793 default: return false;
794 }
795 return true;
796 }
797
MyBenchmark(bool totalMode)798 static void MyBenchmark(bool totalMode)
799 {
800 CPanel::CDisableTimerProcessing disableTimerProcessing1(g_App.Panels[0]);
801 CPanel::CDisableTimerProcessing disableTimerProcessing2(g_App.Panels[1]);
802 Benchmark(totalMode);
803 }
804
OnMenuCommand(HWND hWnd,unsigned id)805 bool OnMenuCommand(HWND hWnd, unsigned id)
806 {
807 if (ExecuteFileCommand(id))
808 return true;
809
810 switch (id)
811 {
812 // File
813 case IDCLOSE:
814 // SendMessage(hWnd, WM_ACTIVATE, MAKEWPARAM(WA_INACTIVE, 0), (LPARAM)hWnd);
815 // g_ExitEventLauncher.Exit(false);
816 SendMessage(hWnd, WM_CLOSE, 0, 0);
817 break;
818
819 // Edit
820 /*
821 case IDM_EDIT_CUT:
822 g_App.EditCut();
823 break;
824 case IDM_EDIT_COPY:
825 g_App.EditCopy();
826 break;
827 case IDM_EDIT_PASTE:
828 g_App.EditPaste();
829 break;
830 */
831 case IDM_SELECT_ALL:
832 g_App.SelectAll(true);
833 g_App.Refresh_StatusBar();
834 break;
835 case IDM_DESELECT_ALL:
836 g_App.SelectAll(false);
837 g_App.Refresh_StatusBar();
838 break;
839 case IDM_INVERT_SELECTION:
840 g_App.InvertSelection();
841 g_App.Refresh_StatusBar();
842 break;
843 case IDM_SELECT:
844 g_App.SelectSpec(true);
845 g_App.Refresh_StatusBar();
846 break;
847 case IDM_DESELECT:
848 g_App.SelectSpec(false);
849 g_App.Refresh_StatusBar();
850 break;
851 case IDM_SELECT_BY_TYPE:
852 g_App.SelectByType(true);
853 g_App.Refresh_StatusBar();
854 break;
855 case IDM_DESELECT_BY_TYPE:
856 g_App.SelectByType(false);
857 g_App.Refresh_StatusBar();
858 break;
859
860 //View
861 case IDM_VIEW_LARGE_ICONS:
862 case IDM_VIEW_SMALL_ICONS:
863 case IDM_VIEW_LIST:
864 case IDM_VIEW_DETAILS:
865 {
866 UINT index = id - IDM_VIEW_LARGE_ICONS;
867 if (index < 4)
868 {
869 g_App.SetListViewMode(index);
870 /*
871 CMenu menu;
872 menu.Attach(::GetSubMenu(::GetMenu(hWnd), k_MenuIndex_View));
873 menu.CheckRadioItem(IDM_VIEW_LARGE_ICONS, IDM_VIEW_DETAILS,
874 id, MF_BYCOMMAND);
875 */
876 }
877 break;
878 }
879 case IDM_VIEW_ARANGE_BY_NAME: g_App.SortItemsWithPropID(kpidName); break;
880 case IDM_VIEW_ARANGE_BY_TYPE: g_App.SortItemsWithPropID(kpidExtension); break;
881 case IDM_VIEW_ARANGE_BY_DATE: g_App.SortItemsWithPropID(kpidMTime); break;
882 case IDM_VIEW_ARANGE_BY_SIZE: g_App.SortItemsWithPropID(kpidSize); break;
883 case IDM_VIEW_ARANGE_NO_SORT: g_App.SortItemsWithPropID(kpidNoProperty); break;
884
885 case IDM_OPEN_ROOT_FOLDER: g_App.OpenRootFolder(); break;
886 case IDM_OPEN_PARENT_FOLDER: g_App.OpenParentFolder(); break;
887 case IDM_FOLDERS_HISTORY: g_App.FoldersHistory(); break;
888 case IDM_VIEW_FLAT_VIEW: g_App.ChangeFlatMode(); break;
889 case IDM_VIEW_REFRESH: g_App.RefreshView(); break;
890 case IDM_VIEW_AUTO_REFRESH: g_App.Change_AutoRefresh_Mode(); break;
891
892 // case IDM_VIEW_SHOW_STREAMS: g_App.Change_ShowNtfsStrems_Mode(); break;
893 /*
894 case IDM_VIEW_SHOW_DELETED:
895 {
896 g_App.Change_ShowDeleted();
897 bool isChecked = g_App.ShowDeletedFiles;
898 Save_ShowDeleted(isChecked);
899 }
900 */
901
902 case IDM_VIEW_TWO_PANELS: g_App.SwitchOnOffOnePanel(); break;
903 case IDM_VIEW_STANDARD_TOOLBAR: g_App.SwitchStandardToolbar(); break;
904 case IDM_VIEW_ARCHIVE_TOOLBAR: g_App.SwitchArchiveToolbar(); break;
905
906 case IDM_VIEW_TOOLBARS_SHOW_BUTTONS_TEXT: g_App.SwitchButtonsLables(); break;
907 case IDM_VIEW_TOOLBARS_LARGE_BUTTONS: g_App.SwitchLargeButtons(); break;
908
909 case IDM_VIEW_TIME_UTC:
910 g_Timestamp_Show_UTC = !g_Timestamp_Show_UTC;
911 g_App.RedrawListItems_InPanels();
912 break;
913
914 // Tools
915 case IDM_OPTIONS: OptionsDialog(hWnd, g_hInstance); break;
916
917 case IDM_BENCHMARK: MyBenchmark(false); break;
918 case IDM_BENCHMARK2: MyBenchmark(true); break;
919
920 // Help
921 case IDM_HELP_CONTENTS:
922 ShowHelpWindow(kFMHelpTopic);
923 break;
924 case IDM_ABOUT:
925 {
926 CAboutDialog dialog;
927 dialog.Create(hWnd);
928 break;
929 }
930
931 case IDM_TEMP_DIR:
932 {
933 /*
934 CPanel &panel = g_App.GetFocusedPanel();
935 FString tempPathF;
936 if (NFile::NDir::MyGetTempPath(tempPathF))
937 panel.BindToPathAndRefresh(tempPathF);
938 */
939 MyBrowseForTempFolder(g_HWND);
940 break;
941 }
942
943 default:
944 {
945 if (id >= k_MenuID_OpenBookmark && id <= k_MenuID_OpenBookmark + 9)
946 {
947 g_App.OpenBookmark(id - k_MenuID_OpenBookmark);
948 return true;
949 }
950 else if (id >= k_MenuID_SetBookmark && id <= k_MenuID_SetBookmark + 9)
951 {
952 g_App.SetBookmark(id - k_MenuID_SetBookmark);
953 return true;
954 }
955 else if (id >= k_MenuID_Time && (unsigned)id < k_MenuID_Time + g_App._timestampLevels.Size())
956 {
957 g_App.SetTimestampLevel(g_App._timestampLevels[id - k_MenuID_Time]);
958 return true;
959 }
960 return false;
961 }
962 }
963 return true;
964 }
965