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 
25 using namespace NWindows;
26 using namespace NFile;
27 using namespace NName;
28 
29 extern HINSTANCE g_hInstance;
30 
31 static const UInt32 kPathMode_IDs[] =
32 {
33   IDS_EXTRACT_PATHS_FULL,
34   IDS_EXTRACT_PATHS_NO,
35   IDS_EXTRACT_PATHS_ABS
36 };
37 
38 static 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 
49 static const
50   // NExtract::NPathMode::EEnum
51   int
52   kPathModeButtonsVals[] =
53 {
54   NExtract::NPathMode::kFullPaths,
55   NExtract::NPathMode::kNoPaths,
56   NExtract::NPathMode::kAbsPaths
57 };
58 
59 static 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 
75 static 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
91 static const unsigned kHistorySize = 16;
92 #endif
93 
94 #ifndef _SFX
95 
96 // it's used in CompressDialog also
AddComboItems(NControl::CComboBox & combo,const UInt32 * langIDs,unsigned numItems,const int * values,int curVal)97 void 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
GetBoolsVal(const CBoolPair & b1,const CBoolPair & b2)113 bool 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 
CheckButton_TwoBools(UINT id,const CBoolPair & b1,const CBoolPair & b2)120 void CExtractDialog::CheckButton_TwoBools(UINT id, const CBoolPair &b1, const CBoolPair &b2)
121 {
122   CheckButton(id, GetBoolsVal(b1, b2));
123 }
124 
GetButton_Bools(UINT id,CBoolPair & b1,CBoolPair & b2)125 void 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 
OnInit()136 bool 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 += " : ";
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
UpdatePasswordControl()245 void CExtractDialog::UpdatePasswordControl()
246 {
247   _passwordControl.SetPasswordChar(IsShowPasswordChecked() ? 0 : TEXT('*'));
248   UString password;
249   _passwordControl.GetText(password);
250   _passwordControl.SetText(password);
251 }
252 #endif
253 
OnButtonClicked(int buttonID,HWND buttonHWND)254 bool 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 
OnButtonSetPath()275 void 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 
AddUniqueString(UStringVector & list,const UString & s)289 void 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 
OnOK()297 void 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
412 #define kHelpTopic "fm/plugins/7-zip/extract.htm"
OnHelp()413 void CExtractDialog::OnHelp()
414 {
415   ShowHelpWindow(kHelpTopic);
416   CModalDialog::OnHelp();
417 }
418 #endif
419