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_SHA1: g_App.CalculateCrc("SHA1"); break;
768 case IDM_SHA256: g_App.CalculateCrc("SHA256"); break;
769 case IDM_BLAKE2SP: g_App.CalculateCrc("BLAKE2sp"); break;
770
771 case IDM_DIFF: g_App.DiffFiles(); break;
772
773 case IDM_VER_EDIT:
774 case IDM_VER_COMMIT:
775 case IDM_VER_REVERT:
776 case IDM_VER_DIFF:
777 g_App.VerCtrl(id); break;
778
779 case IDM_SPLIT: g_App.Split(); break;
780 case IDM_COMBINE: g_App.Combine(); break;
781 case IDM_PROPERTIES: g_App.Properties(); break;
782 case IDM_COMMENT: g_App.Comment(); break;
783 case IDM_CREATE_FOLDER: g_App.CreateFolder(); break;
784 case IDM_CREATE_FILE: g_App.CreateFile(); break;
785 #ifndef UNDER_CE
786 case IDM_LINK: g_App.Link(); break;
787 case IDM_ALT_STREAMS: g_App.OpenAltStreams(); break;
788 #endif
789 default: return false;
790 }
791 return true;
792 }
793
MyBenchmark(bool totalMode)794 static void MyBenchmark(bool totalMode)
795 {
796 CPanel::CDisableTimerProcessing disableTimerProcessing1(g_App.Panels[0]);
797 CPanel::CDisableTimerProcessing disableTimerProcessing2(g_App.Panels[1]);
798 Benchmark(totalMode);
799 }
800
OnMenuCommand(HWND hWnd,unsigned id)801 bool OnMenuCommand(HWND hWnd, unsigned id)
802 {
803 if (ExecuteFileCommand(id))
804 return true;
805
806 switch (id)
807 {
808 // File
809 case IDCLOSE:
810 SendMessage(hWnd, WM_ACTIVATE, MAKEWPARAM(WA_INACTIVE, 0), (LPARAM)hWnd);
811 g_ExitEventLauncher.Exit(false);
812 SendMessage(hWnd, WM_CLOSE, 0, 0);
813 break;
814
815 // Edit
816 /*
817 case IDM_EDIT_CUT:
818 g_App.EditCut();
819 break;
820 case IDM_EDIT_COPY:
821 g_App.EditCopy();
822 break;
823 case IDM_EDIT_PASTE:
824 g_App.EditPaste();
825 break;
826 */
827 case IDM_SELECT_ALL:
828 g_App.SelectAll(true);
829 g_App.Refresh_StatusBar();
830 break;
831 case IDM_DESELECT_ALL:
832 g_App.SelectAll(false);
833 g_App.Refresh_StatusBar();
834 break;
835 case IDM_INVERT_SELECTION:
836 g_App.InvertSelection();
837 g_App.Refresh_StatusBar();
838 break;
839 case IDM_SELECT:
840 g_App.SelectSpec(true);
841 g_App.Refresh_StatusBar();
842 break;
843 case IDM_DESELECT:
844 g_App.SelectSpec(false);
845 g_App.Refresh_StatusBar();
846 break;
847 case IDM_SELECT_BY_TYPE:
848 g_App.SelectByType(true);
849 g_App.Refresh_StatusBar();
850 break;
851 case IDM_DESELECT_BY_TYPE:
852 g_App.SelectByType(false);
853 g_App.Refresh_StatusBar();
854 break;
855
856 //View
857 case IDM_VIEW_LARGE_ICONS:
858 case IDM_VIEW_SMALL_ICONS:
859 case IDM_VIEW_LIST:
860 case IDM_VIEW_DETAILS:
861 {
862 UINT index = id - IDM_VIEW_LARGE_ICONS;
863 if (index < 4)
864 {
865 g_App.SetListViewMode(index);
866 /*
867 CMenu menu;
868 menu.Attach(::GetSubMenu(::GetMenu(hWnd), k_MenuIndex_View));
869 menu.CheckRadioItem(IDM_VIEW_LARGE_ICONS, IDM_VIEW_DETAILS,
870 id, MF_BYCOMMAND);
871 */
872 }
873 break;
874 }
875 case IDM_VIEW_ARANGE_BY_NAME: g_App.SortItemsWithPropID(kpidName); break;
876 case IDM_VIEW_ARANGE_BY_TYPE: g_App.SortItemsWithPropID(kpidExtension); break;
877 case IDM_VIEW_ARANGE_BY_DATE: g_App.SortItemsWithPropID(kpidMTime); break;
878 case IDM_VIEW_ARANGE_BY_SIZE: g_App.SortItemsWithPropID(kpidSize); break;
879 case IDM_VIEW_ARANGE_NO_SORT: g_App.SortItemsWithPropID(kpidNoProperty); break;
880
881 case IDM_OPEN_ROOT_FOLDER: g_App.OpenRootFolder(); break;
882 case IDM_OPEN_PARENT_FOLDER: g_App.OpenParentFolder(); break;
883 case IDM_FOLDERS_HISTORY: g_App.FoldersHistory(); break;
884 case IDM_VIEW_FLAT_VIEW: g_App.ChangeFlatMode(); break;
885 case IDM_VIEW_REFRESH: g_App.RefreshView(); break;
886 case IDM_VIEW_AUTO_REFRESH: g_App.Change_AutoRefresh_Mode(); break;
887
888 // case IDM_VIEW_SHOW_STREAMS: g_App.Change_ShowNtfsStrems_Mode(); break;
889 /*
890 case IDM_VIEW_SHOW_DELETED:
891 {
892 g_App.Change_ShowDeleted();
893 bool isChecked = g_App.ShowDeletedFiles;
894 Save_ShowDeleted(isChecked);
895 }
896 */
897
898 case IDM_VIEW_TWO_PANELS: g_App.SwitchOnOffOnePanel(); break;
899 case IDM_VIEW_STANDARD_TOOLBAR: g_App.SwitchStandardToolbar(); break;
900 case IDM_VIEW_ARCHIVE_TOOLBAR: g_App.SwitchArchiveToolbar(); break;
901
902 case IDM_VIEW_TOOLBARS_SHOW_BUTTONS_TEXT: g_App.SwitchButtonsLables(); break;
903 case IDM_VIEW_TOOLBARS_LARGE_BUTTONS: g_App.SwitchLargeButtons(); break;
904
905 case IDM_VIEW_TIME_UTC:
906 g_Timestamp_Show_UTC = !g_Timestamp_Show_UTC;
907 g_App.RedrawListItems_InPanels();
908 break;
909
910 // Tools
911 case IDM_OPTIONS: OptionsDialog(hWnd, g_hInstance); break;
912
913 case IDM_BENCHMARK: MyBenchmark(false); break;
914 case IDM_BENCHMARK2: MyBenchmark(true); break;
915
916 // Help
917 case IDM_HELP_CONTENTS:
918 ShowHelpWindow(kFMHelpTopic);
919 break;
920 case IDM_ABOUT:
921 {
922 CAboutDialog dialog;
923 dialog.Create(hWnd);
924 break;
925 }
926
927 case IDM_TEMP_DIR:
928 {
929 /*
930 CPanel &panel = g_App.GetFocusedPanel();
931 FString tempPathF;
932 if (NFile::NDir::MyGetTempPath(tempPathF))
933 panel.BindToPathAndRefresh(tempPathF);
934 */
935 MyBrowseForTempFolder(g_HWND);
936 break;
937 }
938
939 default:
940 {
941 if (id >= k_MenuID_OpenBookmark && id <= k_MenuID_OpenBookmark + 9)
942 {
943 g_App.OpenBookmark(id - k_MenuID_OpenBookmark);
944 return true;
945 }
946 else if (id >= k_MenuID_SetBookmark && id <= k_MenuID_SetBookmark + 9)
947 {
948 g_App.SetBookmark(id - k_MenuID_SetBookmark);
949 return true;
950 }
951 else if (id >= k_MenuID_Time && (unsigned)id < k_MenuID_Time + g_App._timestampLevels.Size())
952 {
953 g_App.SetTimestampLevel(g_App._timestampLevels[id - k_MenuID_Time]);
954 return true;
955 }
956 return false;
957 }
958 }
959 return true;
960 }
961