1// ExtractDialog.cpp
2
3#include "StdAfx.h"
4
5#include "../../../Common/StringConvert.h"
6#include "../../../Common/Wildcard.h"
7
8#include "../../../Windows/FileName.h"
9#include "../../../Windows/FileDir.h"
10#include "../../../Windows/ResourceString.h"
11
12#ifndef Z7_NO_REGISTRY
13#include "../FileManager/HelpUtils.h"
14#endif
15
16
17#include "../FileManager/BrowseDialog.h"
18#include "../FileManager/LangUtils.h"
19#include "../FileManager/resourceGui.h"
20
21#include "ExtractDialog.h"
22#include "ExtractDialogRes.h"
23#include "ExtractRes.h"
24
25using namespace NWindows;
26using namespace NFile;
27using namespace NName;
28
29extern HINSTANCE g_hInstance;
30
31#ifndef Z7_SFX
32
33static const UInt32 kPathMode_IDs[] =
34{
35  IDS_EXTRACT_PATHS_FULL,
36  IDS_EXTRACT_PATHS_NO,
37  IDS_EXTRACT_PATHS_ABS
38};
39
40static const UInt32 kOverwriteMode_IDs[] =
41{
42  IDS_EXTRACT_OVERWRITE_ASK,
43  IDS_EXTRACT_OVERWRITE_WITHOUT_PROMPT,
44  IDS_EXTRACT_OVERWRITE_SKIP_EXISTING,
45  IDS_EXTRACT_OVERWRITE_RENAME,
46  IDS_EXTRACT_OVERWRITE_RENAME_EXISTING
47};
48
49static const
50  // NExtract::NPathMode::EEnum
51  int
52  kPathModeButtonsVals[] =
53{
54  NExtract::NPathMode::kFullPaths,
55  NExtract::NPathMode::kNoPaths,
56  NExtract::NPathMode::kAbsPaths
57};
58
59static const
60  int
61  // NExtract::NOverwriteMode::EEnum
62  kOverwriteButtonsVals[] =
63{
64  NExtract::NOverwriteMode::kAsk,
65  NExtract::NOverwriteMode::kOverwrite,
66  NExtract::NOverwriteMode::kSkip,
67  NExtract::NOverwriteMode::kRename,
68  NExtract::NOverwriteMode::kRenameExisting
69};
70
71#endif
72
73#ifdef Z7_LANG
74
75static const UInt32 kLangIDs[] =
76{
77  IDT_EXTRACT_EXTRACT_TO,
78  IDT_EXTRACT_PATH_MODE,
79  IDT_EXTRACT_OVERWRITE_MODE,
80  // IDX_EXTRACT_ALT_STREAMS,
81  IDX_EXTRACT_NT_SECUR,
82  IDX_EXTRACT_ELIM_DUP,
83  IDG_PASSWORD,
84  IDX_PASSWORD_SHOW
85};
86#endif
87
88// static const int kWildcardsButtonIndex = 2;
89
90#ifndef Z7_NO_REGISTRY
91static const unsigned kHistorySize = 16;
92#endif
93
94#ifndef Z7_SFX
95
96// it's used in CompressDialog also
97void AddComboItems(NControl::CComboBox &combo, const UInt32 *langIDs, unsigned numItems, const int *values, int curVal);
98void AddComboItems(NControl::CComboBox &combo, const UInt32 *langIDs, unsigned numItems, const int *values, int curVal)
99{
100  unsigned curSel = 0;
101  for (unsigned i = 0; i < numItems; i++)
102  {
103    UString s = LangString(langIDs[i]);
104    s.RemoveChar(L'&');
105    const int index = (int)combo.AddString(s);
106    combo.SetItemData(index, (LPARAM)i);
107    if (values[i] == curVal)
108      curSel = i;
109  }
110  combo.SetCurSel(curSel);
111}
112
113// it's used in CompressDialog also
114bool GetBoolsVal(const CBoolPair &b1, const CBoolPair &b2);
115bool GetBoolsVal(const CBoolPair &b1, const CBoolPair &b2)
116{
117  if (b1.Def) return b1.Val;
118  if (b2.Def) return b2.Val;
119  return b1.Val;
120}
121
122void CExtractDialog::CheckButton_TwoBools(UINT id, const CBoolPair &b1, const CBoolPair &b2)
123{
124  CheckButton(id, GetBoolsVal(b1, b2));
125}
126
127void CExtractDialog::GetButton_Bools(UINT id, CBoolPair &b1, CBoolPair &b2)
128{
129  const bool val = IsButtonCheckedBool(id);
130  const bool oldVal = GetBoolsVal(b1, b2);
131  if (val != oldVal)
132    b1.Def = b2.Def = true;
133  b1.Val = b2.Val = val;
134}
135
136#endif
137
138bool CExtractDialog::OnInit()
139{
140  #ifdef Z7_LANG
141  {
142    UString s;
143    LangString_OnlyFromLangFile(IDD_EXTRACT, s);
144    if (s.IsEmpty())
145      GetText(s);
146    if (!ArcPath.IsEmpty())
147    {
148      s += " : ";
149      s += ArcPath;
150    }
151    SetText(s);
152    // LangSetWindowText(*this, IDD_EXTRACT);
153    LangSetDlgItems(*this, kLangIDs, Z7_ARRAY_SIZE(kLangIDs));
154  }
155  #endif
156
157  #ifndef Z7_SFX
158  _passwordControl.Attach(GetItem(IDE_EXTRACT_PASSWORD));
159  _passwordControl.SetText(Password);
160  _passwordControl.SetPasswordChar(TEXT('*'));
161  _pathName.Attach(GetItem(IDE_EXTRACT_NAME));
162  #endif
163
164  #ifdef Z7_NO_REGISTRY
165
166  PathMode = NExtract::NPathMode::kFullPaths;
167  OverwriteMode = NExtract::NOverwriteMode::kAsk;
168
169  #else
170
171  _info.Load();
172
173  if (_info.PathMode == NExtract::NPathMode::kCurPaths)
174    _info.PathMode = NExtract::NPathMode::kFullPaths;
175
176  if (!PathMode_Force && _info.PathMode_Force)
177    PathMode = _info.PathMode;
178  if (!OverwriteMode_Force && _info.OverwriteMode_Force)
179    OverwriteMode = _info.OverwriteMode;
180
181  // CheckButton_TwoBools(IDX_EXTRACT_ALT_STREAMS, AltStreams, _info.AltStreams);
182  CheckButton_TwoBools(IDX_EXTRACT_NT_SECUR,    NtSecurity, _info.NtSecurity);
183  CheckButton_TwoBools(IDX_EXTRACT_ELIM_DUP,    ElimDup,    _info.ElimDup);
184
185  CheckButton(IDX_PASSWORD_SHOW, _info.ShowPassword.Val);
186  UpdatePasswordControl();
187
188  #endif
189
190  _path.Attach(GetItem(IDC_EXTRACT_PATH));
191
192  UString pathPrefix = DirPath;
193
194  #ifndef Z7_SFX
195
196  if (_info.SplitDest.Val)
197  {
198    CheckButton(IDX_EXTRACT_NAME_ENABLE, true);
199    UString pathName;
200    SplitPathToParts_Smart(DirPath, pathPrefix, pathName);
201    if (pathPrefix.IsEmpty())
202      pathPrefix = pathName;
203    else
204      _pathName.SetText(pathName);
205  }
206  else
207    ShowItem_Bool(IDE_EXTRACT_NAME, false);
208
209  #endif
210
211  _path.SetText(pathPrefix);
212
213  #ifndef Z7_NO_REGISTRY
214  for (unsigned i = 0; i < _info.Paths.Size() && i < kHistorySize; i++)
215    _path.AddString(_info.Paths[i]);
216  #endif
217
218  /*
219  if (_info.Paths.Size() > 0)
220    _path.SetCurSel(0);
221  else
222    _path.SetCurSel(-1);
223  */
224
225  #ifndef Z7_SFX
226
227  _pathMode.Attach(GetItem(IDC_EXTRACT_PATH_MODE));
228  _overwriteMode.Attach(GetItem(IDC_EXTRACT_OVERWRITE_MODE));
229
230  AddComboItems(_pathMode, kPathMode_IDs, Z7_ARRAY_SIZE(kPathMode_IDs), kPathModeButtonsVals, PathMode);
231  AddComboItems(_overwriteMode, kOverwriteMode_IDs, Z7_ARRAY_SIZE(kOverwriteMode_IDs), kOverwriteButtonsVals, OverwriteMode);
232
233  #endif
234
235  HICON icon = LoadIcon(g_hInstance, MAKEINTRESOURCE(IDI_ICON));
236  SetIcon(ICON_BIG, icon);
237
238  // CWindow filesWindow = GetItem(IDC_EXTRACT_RADIO_FILES);
239  // filesWindow.Enable(_enableFilesButton);
240
241  NormalizePosition();
242
243  return CModalDialog::OnInit();
244}
245
246#ifndef Z7_SFX
247void CExtractDialog::UpdatePasswordControl()
248{
249  _passwordControl.SetPasswordChar(IsShowPasswordChecked() ? 0 : TEXT('*'));
250  UString password;
251  _passwordControl.GetText(password);
252  _passwordControl.SetText(password);
253}
254#endif
255
256bool CExtractDialog::OnButtonClicked(unsigned buttonID, HWND buttonHWND)
257{
258  switch (buttonID)
259  {
260    case IDB_EXTRACT_SET_PATH:
261      OnButtonSetPath();
262      return true;
263    #ifndef Z7_SFX
264    case IDX_EXTRACT_NAME_ENABLE:
265      ShowItem_Bool(IDE_EXTRACT_NAME, IsButtonCheckedBool(IDX_EXTRACT_NAME_ENABLE));
266      return true;
267    case IDX_PASSWORD_SHOW:
268    {
269      UpdatePasswordControl();
270      return true;
271    }
272    #endif
273  }
274  return CModalDialog::OnButtonClicked(buttonID, buttonHWND);
275}
276
277void CExtractDialog::OnButtonSetPath()
278{
279  UString currentPath;
280  _path.GetText(currentPath);
281  UString title = LangString(IDS_EXTRACT_SET_FOLDER);
282  UString resultPath;
283  if (!MyBrowseForFolder(*this, title, currentPath, resultPath))
284    return;
285  #ifndef Z7_NO_REGISTRY
286  _path.SetCurSel(-1);
287  #endif
288  _path.SetText(resultPath);
289}
290
291void AddUniqueString(UStringVector &list, const UString &s);
292void AddUniqueString(UStringVector &list, const UString &s)
293{
294  FOR_VECTOR (i, list)
295    if (s.IsEqualTo_NoCase(list[i]))
296      return;
297  list.Add(s);
298}
299
300void CExtractDialog::OnOK()
301{
302  #ifndef Z7_SFX
303  int pathMode2 = kPathModeButtonsVals[_pathMode.GetCurSel()];
304  if (PathMode != NExtract::NPathMode::kCurPaths ||
305      pathMode2 != NExtract::NPathMode::kFullPaths)
306    PathMode = (NExtract::NPathMode::EEnum)pathMode2;
307
308  OverwriteMode = (NExtract::NOverwriteMode::EEnum)kOverwriteButtonsVals[_overwriteMode.GetCurSel()];
309
310  // _filesMode = (NExtractionDialog::NFilesMode::EEnum)GetFilesMode();
311
312  _passwordControl.GetText(Password);
313
314  #endif
315
316  #ifndef Z7_NO_REGISTRY
317
318  // GetButton_Bools(IDX_EXTRACT_ALT_STREAMS, AltStreams, _info.AltStreams);
319  GetButton_Bools(IDX_EXTRACT_NT_SECUR,    NtSecurity, _info.NtSecurity);
320  GetButton_Bools(IDX_EXTRACT_ELIM_DUP,    ElimDup,    _info.ElimDup);
321
322  bool showPassword = IsShowPasswordChecked();
323  if (showPassword != _info.ShowPassword.Val)
324  {
325    _info.ShowPassword.Def = true;
326    _info.ShowPassword.Val = showPassword;
327  }
328
329  if (_info.PathMode != pathMode2)
330  {
331    _info.PathMode_Force = true;
332    _info.PathMode = (NExtract::NPathMode::EEnum)pathMode2;
333    /*
334    // we allow kAbsPaths in registry.
335    if (_info.PathMode == NExtract::NPathMode::kAbsPaths)
336      _info.PathMode = NExtract::NPathMode::kFullPaths;
337    */
338  }
339
340  if (!OverwriteMode_Force && _info.OverwriteMode != OverwriteMode)
341    _info.OverwriteMode_Force = true;
342  _info.OverwriteMode = OverwriteMode;
343
344
345  #else
346
347  ElimDup.Val = IsButtonCheckedBool(IDX_EXTRACT_ELIM_DUP);
348
349  #endif
350
351  UString s;
352
353  #ifdef Z7_NO_REGISTRY
354
355  _path.GetText(s);
356
357  #else
358
359  int currentItem = _path.GetCurSel();
360  if (currentItem == CB_ERR)
361  {
362    _path.GetText(s);
363    if (_path.GetCount() >= (int)kHistorySize)
364      currentItem = _path.GetCount() - 1;
365  }
366  else
367    _path.GetLBText(currentItem, s);
368
369  #endif
370
371  s.Trim();
372  NName::NormalizeDirPathPrefix(s);
373
374  #ifndef Z7_SFX
375
376  const bool splitDest = IsButtonCheckedBool(IDX_EXTRACT_NAME_ENABLE);
377  if (splitDest)
378  {
379    UString pathName;
380    _pathName.GetText(pathName);
381    pathName.Trim();
382    s += pathName;
383    NName::NormalizeDirPathPrefix(s);
384  }
385  if (splitDest != _info.SplitDest.Val)
386  {
387    _info.SplitDest.Def = true;
388    _info.SplitDest.Val = splitDest;
389  }
390
391  #endif
392
393  DirPath = s;
394
395  #ifndef Z7_NO_REGISTRY
396  _info.Paths.Clear();
397  #ifndef Z7_SFX
398  AddUniqueString(_info.Paths, s);
399  #endif
400  for (int i = 0; i < _path.GetCount(); i++)
401    if (i != currentItem)
402    {
403      UString sTemp;
404      _path.GetLBText(i, sTemp);
405      sTemp.Trim();
406      AddUniqueString(_info.Paths, sTemp);
407    }
408  _info.Save();
409  #endif
410
411  CModalDialog::OnOK();
412}
413
414#ifndef Z7_NO_REGISTRY
415#define kHelpTopic "fm/plugins/7-zip/extract.htm"
416void CExtractDialog::OnHelp()
417{
418  ShowHelpWindow(kHelpTopic);
419  CModalDialog::OnHelp();
420}
421#endif
422