xref: /aosp_15_r20/external/lzma/CPP/7zip/UI/FileManager/MenuPage.cpp (revision f6dc9357d832569d4d1f5d24eacdb3935a1ae8e6)
1  // MenuPage.cpp
2  
3  #include "StdAfx.h"
4  
5  #include "../Common/ZipRegistry.h"
6  
7  #include "../../../Windows/DLL.h"
8  #include "../../../Windows/ErrorMsg.h"
9  #include "../../../Windows/FileFind.h"
10  
11  #include "../Explorer/ContextMenuFlags.h"
12  #include "../Explorer/RegistryContextMenu.h"
13  #include "../Explorer/resource.h"
14  
15  #include "../FileManager/PropertyNameRes.h"
16  
17  #include "../GUI/ExtractDialogRes.h"
18  
19  #include "FormatUtils.h"
20  #include "HelpUtils.h"
21  #include "LangUtils.h"
22  #include "MenuPage.h"
23  #include "MenuPageRes.h"
24  
25  
26  using namespace NWindows;
27  using namespace NContextMenuFlags;
28  
29  #ifdef Z7_LANG
30  static const UInt32 kLangIDs[] =
31  {
32    IDX_SYSTEM_INTEGRATE_TO_MENU,
33    IDX_SYSTEM_CASCADED_MENU,
34    IDX_SYSTEM_ICON_IN_MENU,
35    IDX_EXTRACT_ELIM_DUP,
36    IDT_SYSTEM_ZONE,
37    IDT_SYSTEM_CONTEXT_MENU_ITEMS
38  };
39  #endif
40  
41  #define kMenuTopic "fm/options.htm#sevenZip"
42  
43  struct CContextMenuItem
44  {
45    unsigned ControlID;
46    UInt32 Flag;
47  };
48  
49  static const CContextMenuItem kMenuItems[] =
50  {
51    { IDS_CONTEXT_OPEN, kOpen },
52    { IDS_CONTEXT_OPEN, kOpenAs },
53    { IDS_CONTEXT_EXTRACT, kExtract },
54    { IDS_CONTEXT_EXTRACT_HERE, kExtractHere },
55    { IDS_CONTEXT_EXTRACT_TO, kExtractTo },
56  
57    { IDS_CONTEXT_TEST, kTest },
58  
59    { IDS_CONTEXT_COMPRESS, kCompress },
60    { IDS_CONTEXT_COMPRESS_TO, kCompressTo7z },
61    { IDS_CONTEXT_COMPRESS_TO, kCompressToZip },
62  
63    #ifndef UNDER_CE
64    { IDS_CONTEXT_COMPRESS_EMAIL, kCompressEmail },
65    { IDS_CONTEXT_COMPRESS_TO_EMAIL, kCompressTo7zEmail },
66    { IDS_CONTEXT_COMPRESS_TO_EMAIL, kCompressToZipEmail },
67    #endif
68  
69    { IDS_PROP_CHECKSUM, kCRC },
70    { IDS_PROP_CHECKSUM, kCRC_Cascaded },
71  };
72  
73  
74  #if !defined(_WIN64)
75  extern bool g_Is_Wow64;
76  #endif
77  
78  #ifndef KEY_WOW64_64KEY
79    #define KEY_WOW64_64KEY (0x0100)
80  #endif
81  
82  #ifndef KEY_WOW64_32KEY
83    #define KEY_WOW64_32KEY (0x0200)
84  #endif
85  
86  
LoadLang_Spec(UString & s,UInt32 id,const char * eng)87  static void LoadLang_Spec(UString &s, UInt32 id, const char *eng)
88  {
89    LangString(id, s);
90    if (s.IsEmpty())
91      s = eng;
92    s.RemoveChar(L'&');
93  }
94  
95  
OnInit()96  bool CMenuPage::OnInit()
97  {
98    _initMode = true;
99  
100    Clear_MenuChanged();
101  
102  #ifdef Z7_LANG
103    LangSetDlgItems(*this, kLangIDs, Z7_ARRAY_SIZE(kLangIDs));
104  #endif
105  
106    #ifdef UNDER_CE
107  
108    HideItem(IDX_SYSTEM_INTEGRATE_TO_MENU);
109    HideItem(IDX_SYSTEM_INTEGRATE_TO_MENU_2);
110  
111    #else
112  
113    {
114      UString s;
115      {
116        CWindow window(GetItem(IDX_SYSTEM_INTEGRATE_TO_MENU));
117        window.GetText(s);
118      }
119      UString bit64 = LangString(IDS_PROP_BIT64);
120      if (bit64.IsEmpty())
121        bit64 = "64-bit";
122      #ifdef _WIN64
123        bit64.Replace(L"64", L"32");
124      #endif
125      s.Add_Space();
126      s.Add_Char('(');
127      s += bit64;
128      s.Add_Char(')');
129      SetItemText(IDX_SYSTEM_INTEGRATE_TO_MENU_2, s);
130    }
131  
132    const FString prefix = NDLL::GetModuleDirPrefix();
133  
134    _dlls[0].ctrl = IDX_SYSTEM_INTEGRATE_TO_MENU;
135    _dlls[1].ctrl = IDX_SYSTEM_INTEGRATE_TO_MENU_2;
136  
137    _dlls[0].wow = 0;
138    _dlls[1].wow =
139        #ifdef _WIN64
140          KEY_WOW64_32KEY
141        #else
142          KEY_WOW64_64KEY
143        #endif
144        ;
145  
146    for (unsigned d = 0; d < 2; d++)
147    {
148      CShellDll &dll = _dlls[d];
149  
150      dll.wasChanged = false;
151  
152      #ifndef _WIN64
153      if (d != 0 && !g_Is_Wow64)
154      {
155        HideItem(dll.ctrl);
156        continue;
157      }
158      #endif
159  
160      FString &path = dll.Path;
161      path = prefix;
162      path += (d == 0 ? "7-zip.dll" :
163          #ifdef _WIN64
164            "7-zip32.dll"
165          #else
166            "7-zip64.dll"
167          #endif
168          );
169  
170  
171      if (!NFile::NFind::DoesFileExist_Raw(path))
172      {
173        path.Empty();
174        EnableItem(dll.ctrl, false);
175      }
176      else
177      {
178        dll.prevValue = CheckContextMenuHandler(fs2us(path), dll.wow);
179        CheckButton(dll.ctrl, dll.prevValue);
180      }
181    }
182  
183    #endif
184  
185  
186    CContextMenuInfo ci;
187    ci.Load();
188  
189    CheckButton(IDX_SYSTEM_CASCADED_MENU, ci.Cascaded.Val);
190    CheckButton(IDX_SYSTEM_ICON_IN_MENU, ci.MenuIcons.Val);
191    CheckButton(IDX_EXTRACT_ELIM_DUP, ci.ElimDup.Val);
192  
193    _listView.Attach(GetItem(IDL_SYSTEM_OPTIONS));
194    _zoneCombo.Attach(GetItem(IDC_SYSTEM_ZONE));
195  
196    {
197      unsigned wz = ci.WriteZone;
198      if (wz == (UInt32)(Int32)-1)
199        wz = 0;
200      for (unsigned i = 0; i <= 3; i++)
201      {
202        unsigned val = i;
203        UString s;
204        if (i == 3)
205        {
206          if (wz < 3)
207            break;
208          val = wz;
209        }
210        else
211        {
212          #define MY_IDYES  406
213          #define MY_IDNO   407
214          if (i == 0)
215            LoadLang_Spec(s, MY_IDNO, "No");
216          else if (i == 1)
217            LoadLang_Spec(s, MY_IDYES, "Yes");
218          else
219            LangString(IDT_ZONE_FOR_OFFICE, s);
220        }
221        if (s.IsEmpty())
222          s.Add_UInt32(val);
223        if (i == 0)
224          s.Insert(0, L"* ");
225        const int index = (int)_zoneCombo.AddString(s);
226        _zoneCombo.SetItemData(index, (LPARAM)val);
227        if (val == wz)
228          _zoneCombo.SetCurSel(index);
229      }
230    }
231  
232  
233    const UInt32 newFlags = LVS_EX_CHECKBOXES | LVS_EX_FULLROWSELECT;
234    _listView.SetExtendedListViewStyle(newFlags, newFlags);
235  
236    _listView.InsertColumn(0, L"", 200);
237  
238    for (unsigned i = 0; i < Z7_ARRAY_SIZE(kMenuItems); i++)
239    {
240      const CContextMenuItem &menuItem = kMenuItems[i];
241  
242      UString s = LangString(menuItem.ControlID);
243      if (menuItem.Flag == kCRC)
244        s = "CRC SHA";
245      else if (menuItem.Flag == kCRC_Cascaded)
246        s = "7-Zip > CRC SHA";
247      if (menuItem.Flag == kOpenAs
248          || menuItem.Flag == kCRC
249          || menuItem.Flag == kCRC_Cascaded)
250        s += " >";
251  
252      switch (menuItem.ControlID)
253      {
254        case IDS_CONTEXT_EXTRACT_TO:
255        {
256          s = MyFormatNew(s, LangString(IDS_CONTEXT_FOLDER));
257          break;
258        }
259        case IDS_CONTEXT_COMPRESS_TO:
260        case IDS_CONTEXT_COMPRESS_TO_EMAIL:
261        {
262          UString s2 = LangString(IDS_CONTEXT_ARCHIVE);
263          switch (menuItem.Flag)
264          {
265            case kCompressTo7z:
266            case kCompressTo7zEmail:
267              s2 += (".7z");
268              break;
269            case kCompressToZip:
270            case kCompressToZipEmail:
271              s2 += (".zip");
272              break;
273          }
274          s = MyFormatNew(s, s2);
275          break;
276        }
277      }
278  
279      const int itemIndex = _listView.InsertItem(i, s);
280      _listView.SetCheckState((unsigned)itemIndex, ((ci.Flags & menuItem.Flag) != 0));
281    }
282  
283    _listView.SetColumnWidthAuto(0);
284    _initMode = false;
285  
286    return CPropertyPage::OnInit();
287  }
288  
289  
290  #ifndef UNDER_CE
291  
ShowMenuErrorMessage(const wchar_t * m,HWND hwnd)292  static void ShowMenuErrorMessage(const wchar_t *m, HWND hwnd)
293  {
294    MessageBoxW(hwnd, m, L"7-Zip", MB_ICONERROR);
295  }
296  
297  #endif
298  
299  
OnApply()300  LONG CMenuPage::OnApply()
301  {
302    #ifndef UNDER_CE
303  
304    for (unsigned d = 2; d != 0;)
305    {
306      d--;
307      CShellDll &dll = _dlls[d];
308      if (dll.wasChanged && !dll.Path.IsEmpty())
309      {
310        const bool newVal = IsButtonCheckedBool(dll.ctrl);
311        const LONG res = SetContextMenuHandler(newVal, fs2us(dll.Path), dll.wow);
312        if (res != ERROR_SUCCESS && (dll.prevValue != newVal || newVal))
313          ShowMenuErrorMessage(NError::MyFormatMessage(res), *this);
314        dll.prevValue = CheckContextMenuHandler(fs2us(dll.Path), dll.wow);
315        CheckButton(dll.ctrl, dll.prevValue);
316        dll.wasChanged = false;
317      }
318    }
319  
320    #endif
321  
322    if (_cascaded_Changed
323        || _menuIcons_Changed
324        || _elimDup_Changed
325        || _writeZone_Changed
326        || _flags_Changed)
327    {
328      CContextMenuInfo ci;
329      ci.Cascaded.Val = IsButtonCheckedBool(IDX_SYSTEM_CASCADED_MENU);
330      ci.Cascaded.Def = _cascaded_Changed;
331  
332      ci.MenuIcons.Val = IsButtonCheckedBool(IDX_SYSTEM_ICON_IN_MENU);
333      ci.MenuIcons.Def = _menuIcons_Changed;
334  
335      ci.ElimDup.Val = IsButtonCheckedBool(IDX_EXTRACT_ELIM_DUP);
336      ci.ElimDup.Def = _elimDup_Changed;
337  
338      {
339        int zoneIndex = (int)_zoneCombo.GetItemData_of_CurSel();
340        if (zoneIndex <= 0)
341          zoneIndex = -1;
342        ci.WriteZone = (UInt32)(Int32)zoneIndex;
343      }
344  
345      ci.Flags = 0;
346  
347      for (unsigned i = 0; i < Z7_ARRAY_SIZE(kMenuItems); i++)
348        if (_listView.GetCheckState(i))
349          ci.Flags |= kMenuItems[i].Flag;
350  
351      ci.Flags_Def = _flags_Changed;
352      ci.Save();
353  
354      Clear_MenuChanged();
355    }
356  
357    // UnChanged();
358  
359    return PSNRET_NOERROR;
360  }
361  
OnNotifyHelp()362  void CMenuPage::OnNotifyHelp()
363  {
364    ShowHelpWindow(kMenuTopic);
365  }
366  
OnButtonClicked(unsigned buttonID,HWND buttonHWND)367  bool CMenuPage::OnButtonClicked(unsigned buttonID, HWND buttonHWND)
368  {
369    switch (buttonID)
370    {
371      #ifndef UNDER_CE
372      case IDX_SYSTEM_INTEGRATE_TO_MENU:
373      case IDX_SYSTEM_INTEGRATE_TO_MENU_2:
374      {
375        for (unsigned d = 0; d < 2; d++)
376        {
377          CShellDll &dll = _dlls[d];
378          if (buttonID == dll.ctrl && !dll.Path.IsEmpty())
379            dll.wasChanged = true;
380        }
381        break;
382      }
383      #endif
384  
385      case IDX_SYSTEM_CASCADED_MENU: _cascaded_Changed = true; break;
386      case IDX_SYSTEM_ICON_IN_MENU: _menuIcons_Changed = true; break;
387      case IDX_EXTRACT_ELIM_DUP: _elimDup_Changed = true; break;
388      // case IDX_EXTRACT_WRITE_ZONE: _writeZone_Changed = true; break;
389  
390      default:
391        return CPropertyPage::OnButtonClicked(buttonID, buttonHWND);
392    }
393  
394    Changed();
395    return true;
396  }
397  
398  
OnCommand(unsigned code,unsigned itemID,LPARAM param)399  bool CMenuPage::OnCommand(unsigned code, unsigned itemID, LPARAM param)
400  {
401    if (code == CBN_SELCHANGE && itemID == IDC_SYSTEM_ZONE)
402    {
403      _writeZone_Changed = true;
404      Changed();
405      return true;
406    }
407    return CPropertyPage::OnCommand(code, itemID, param);
408  }
409  
410  
OnNotify(UINT controlID,LPNMHDR lParam)411  bool CMenuPage::OnNotify(UINT controlID, LPNMHDR lParam)
412  {
413    if (lParam->hwndFrom == HWND(_listView))
414    {
415      switch (lParam->code)
416      {
417        case (LVN_ITEMCHANGED):
418          return OnItemChanged((const NMLISTVIEW *)lParam);
419      }
420    }
421    return CPropertyPage::OnNotify(controlID, lParam);
422  }
423  
424  
OnItemChanged(const NMLISTVIEW * info)425  bool CMenuPage::OnItemChanged(const NMLISTVIEW *info)
426  {
427    if (_initMode)
428      return true;
429    if ((info->uChanged & LVIF_STATE) != 0)
430    {
431      UINT oldState = info->uOldState & LVIS_STATEIMAGEMASK;
432      UINT newState = info->uNewState & LVIS_STATEIMAGEMASK;
433      if (oldState != newState)
434      {
435        _flags_Changed = true;
436        Changed();
437      }
438    }
439    return true;
440  }
441