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