1 // SettingsPage.cpp
2
3 #include "StdAfx.h"
4
5 #include <CommCtrl.h>
6
7 // #include "../../../Common/IntToString.h"
8 // #include "../../../Common/StringConvert.h"
9 #include "../../../Common/StringToInt.h"
10
11 #ifndef UNDER_CE
12 #include "../../../Windows/ErrorMsg.h"
13 #include "../../../Windows/MemoryLock.h"
14 #include "../../../Windows/System.h"
15 #endif
16
17 #include "../Explorer/MyMessages.h"
18
19 #include "../Common/ZipRegistry.h"
20
21 #include "HelpUtils.h"
22 #include "LangUtils.h"
23 #include "RegistryUtils.h"
24 #include "SettingsPage.h"
25 #include "SettingsPageRes.h"
26
27 using namespace NWindows;
28
29 #ifdef Z7_LANG
30 static const UInt32 kLangIDs[] =
31 {
32 IDX_SETTINGS_SHOW_DOTS,
33 IDX_SETTINGS_SHOW_REAL_FILE_ICONS,
34 IDX_SETTINGS_SHOW_SYSTEM_MENU,
35 IDX_SETTINGS_FULL_ROW,
36 IDX_SETTINGS_SHOW_GRID,
37 IDX_SETTINGS_SINGLE_CLICK,
38 IDX_SETTINGS_ALTERNATIVE_SELECTION,
39 IDX_SETTINGS_LARGE_PAGES,
40 IDT_MEM_USAGE_EXTRACT
41 // , IDT_COMPRESS_MEMORY
42 };
43 #endif
44
45 #define kSettingsTopic "FM/options.htm#settings"
46
47 extern bool IsLargePageSupported();
48
49 /*
50 static void AddMemSize(UString &res, UInt64 size, bool needRound = false)
51 {
52 char c;
53 unsigned moveBits = 0;
54 if (needRound)
55 {
56 UInt64 rn = 0;
57 if (size >= (1 << 31))
58 rn = (1 << 28) - 1;
59 UInt32 kRound = (1 << 20) - 1;
60 if (rn < kRound)
61 rn = kRound;
62 size += rn;
63 size &= ~rn;
64 }
65 if (size >= ((UInt64)1 << 31) && (size & 0x3FFFFFFF) == 0)
66 { moveBits = 30; c = 'G'; }
67 else
68 { moveBits = 20; c = 'M'; }
69 res.Add_UInt64(size >> moveBits);
70 res.Add_Space();
71 if (moveBits != 0)
72 res += c;
73 res += 'B';
74 }
75
76
77 int CSettingsPage::AddMemComboItem(UInt64 size, UInt64 percents, bool isDefault)
78 {
79 UString sUser;
80 UString sRegistry;
81 if (size == 0)
82 {
83 UString s;
84 s.Add_UInt64(percents);
85 s += '%';
86 if (isDefault)
87 sUser = "* ";
88 else
89 sRegistry = s;
90 sUser += s;
91 }
92 else
93 {
94 AddMemSize(sUser, size);
95 sRegistry = sUser;
96 for (;;)
97 {
98 int pos = sRegistry.Find(L' ');
99 if (pos < 0)
100 break;
101 sRegistry.Delete(pos);
102 }
103 if (!sRegistry.IsEmpty())
104 if (sRegistry.Back() == 'B')
105 sRegistry.DeleteBack();
106 }
107 const int index = (int)_memCombo.AddString(sUser);
108 _memCombo.SetItemData(index, _memLimitStrings.Size());
109 _memLimitStrings.Add(sRegistry);
110 return index;
111 }
112 */
113
OnInit()114 bool CSettingsPage::OnInit()
115 {
116 _initMode = true;
117 _wasChanged = false;
118 _largePages_wasChanged = false;
119 _memx_wasChanged = false;
120 /*
121 _wasChanged_MemLimit = false;
122 _memLimitStrings.Clear();
123 _memCombo.Attach(GetItem(IDC_SETTINGS_MEM));
124 */
125
126 #ifdef Z7_LANG
127 LangSetDlgItems(*this, kLangIDs, Z7_ARRAY_SIZE(kLangIDs));
128 #endif
129
130 CFmSettings st;
131 st.Load();
132
133 CheckButton(IDX_SETTINGS_SHOW_DOTS, st.ShowDots);
134 CheckButton(IDX_SETTINGS_SHOW_REAL_FILE_ICONS, st.ShowRealFileIcons);
135 CheckButton(IDX_SETTINGS_FULL_ROW, st.FullRow);
136 CheckButton(IDX_SETTINGS_SHOW_GRID, st.ShowGrid);
137 CheckButton(IDX_SETTINGS_SINGLE_CLICK, st.SingleClick);
138 CheckButton(IDX_SETTINGS_ALTERNATIVE_SELECTION, st.AlternativeSelection);
139 // CheckButton(IDX_SETTINGS_UNDERLINE, st.Underline);
140
141 CheckButton(IDX_SETTINGS_SHOW_SYSTEM_MENU, st.ShowSystemMenu);
142
143 if (IsLargePageSupported())
144 CheckButton(IDX_SETTINGS_LARGE_PAGES, ReadLockMemoryEnable());
145 else
146 EnableItem(IDX_SETTINGS_LARGE_PAGES, false);
147
148
149 /*
150 NCompression::CMemUse mu;
151 bool needSetCur = NCompression::MemLimit_Load(mu);
152 UInt64 curMemLimit;
153 {
154 AddMemComboItem(0, 90, true);
155 _memCombo.SetCurSel(0);
156 }
157 if (mu.IsPercent)
158 {
159 const int index = AddMemComboItem(0, mu.Val);
160 _memCombo.SetCurSel(index);
161 needSetCur = false;
162 }
163 {
164 _ramSize = (size_t)sizeof(size_t) << 29;
165 _ramSize_Defined = NSystem::GetRamSize(_ramSize);
166 UString s;
167 if (_ramSize_Defined)
168 {
169 s += "/ ";
170 AddMemSize(s, _ramSize, true);
171 }
172 SetItemText(IDT_SETTINGS_MEM_RAM, s);
173
174 curMemLimit = mu.GetBytes(_ramSize);
175
176 // size = 100 << 20; // for debug only;
177 for (unsigned i = (27) * 2;; i++)
178 {
179 UInt64 size = (UInt64)(2 + (i & 1)) << (i / 2);
180 if (i > (20 + sizeof(size_t) * 3 * 1 - 1) * 2)
181 size = (UInt64)(Int64)-1;
182 if (needSetCur && (size >= curMemLimit))
183 {
184 const int index = AddMemComboItem(curMemLimit);
185 _memCombo.SetCurSel(index);
186 needSetCur = false;
187 if (size == curMemLimit)
188 continue;
189 }
190 if (size == (UInt64)(Int64)-1)
191 break;
192 AddMemComboItem(size);
193 }
194 }
195 */
196
197 // EnableSubItems();
198
199
200 {
201 size_t ramSize = (size_t)sizeof(size_t) << 29;
202 const bool ramSize_defined = NWindows::NSystem::GetRamSize(ramSize);
203 // ramSize *= 10; // for debug
204 UInt32 ramSize_GB = (UInt32)(((UInt64)ramSize + (1u << 29)) >> 30);
205 if (ramSize_GB == 0)
206 ramSize_GB = 1;
207 UString s ("GB");
208 if (ramSize_defined)
209 {
210 s += " / ";
211 s.Add_UInt64(ramSize_GB);
212 s += " GB (RAM)";
213 }
214 SetItemText(IDT_SETTINGS_MEM_GB, s);
215
216 const UINT valMin = 1;
217 UINT valMax = 64; // 64GB for RAR7
218 if (ramSize_defined /* && ramSize_GB > valMax */)
219 {
220 const UINT k_max_val = 1u << 14;
221 if (ramSize_GB >= k_max_val)
222 valMax = k_max_val;
223 else if (ramSize_GB > 1)
224 valMax = (UINT)ramSize_GB - 1;
225 else
226 valMax = 1;
227 }
228
229 UInt32 limit = NExtract::Read_LimitGB();
230 if (limit != 0 && limit != (UInt32)(Int32)-1)
231 CheckButton(IDX_SETTINGS_MEM_SET, true);
232 else
233 {
234 limit = 4;
235 EnableSpin(false);
236 }
237 SendItemMessage(IDC_SETTINGS_MEM_SPIN, UDM_SETRANGE, 0, MAKELPARAM(valMax, valMin)); // Sets the controls direction
238 // UDM_SETPOS doesn't set value larger than max value (valMax) of range:
239 SendItemMessage(IDC_SETTINGS_MEM_SPIN, UDM_SETPOS, 0, limit);
240 s.Empty();
241 s.Add_UInt32(limit);
242 SetItemText(IDE_SETTINGS_MEM_SPIN_EDIT, s);
243 }
244
245 _initMode = false;
246 return CPropertyPage::OnInit();
247 }
248
249
EnableSpin(bool enable)250 void CSettingsPage::EnableSpin(bool enable)
251 {
252 EnableItem(IDC_SETTINGS_MEM_SPIN, enable);
253 EnableItem(IDE_SETTINGS_MEM_SPIN_EDIT, enable);
254 }
255
256
257 /*
258 void CSettingsPage::EnableSubItems()
259 {
260 EnableItem(IDX_SETTINGS_UNDERLINE, IsButtonCheckedBool(IDX_SETTINGS_SINGLE_CLICK));
261 }
262 */
263
264 /*
265 static void AddSize_MB(UString &s, UInt64 size)
266 {
267 s.Add_UInt64((size + (1 << 20) - 1) >> 20);
268 s += " MB";
269 }
270 */
271
OnApply()272 LONG CSettingsPage::OnApply()
273 {
274 if (_wasChanged)
275 {
276 CFmSettings st;
277 st.ShowDots = IsButtonCheckedBool(IDX_SETTINGS_SHOW_DOTS);
278 st.ShowRealFileIcons = IsButtonCheckedBool(IDX_SETTINGS_SHOW_REAL_FILE_ICONS);
279 st.FullRow = IsButtonCheckedBool(IDX_SETTINGS_FULL_ROW);
280 st.ShowGrid = IsButtonCheckedBool(IDX_SETTINGS_SHOW_GRID);
281 st.SingleClick = IsButtonCheckedBool(IDX_SETTINGS_SINGLE_CLICK);
282 st.AlternativeSelection = IsButtonCheckedBool(IDX_SETTINGS_ALTERNATIVE_SELECTION);
283 // st.Underline = IsButtonCheckedBool(IDX_SETTINGS_UNDERLINE);
284
285 st.ShowSystemMenu = IsButtonCheckedBool(IDX_SETTINGS_SHOW_SYSTEM_MENU);
286
287 st.Save();
288 _wasChanged = false;
289 }
290
291 #ifndef UNDER_CE
292 if (_largePages_wasChanged)
293 {
294 if (IsLargePageSupported())
295 {
296 const bool enable = IsButtonCheckedBool(IDX_SETTINGS_LARGE_PAGES);
297 NSecurity::EnablePrivilege_LockMemory(enable);
298 SaveLockMemoryEnable(enable);
299 }
300 _largePages_wasChanged = false;
301 }
302 #endif
303
304 if (_memx_wasChanged)
305 {
306 UInt32 val = (UInt32)(Int32)-1;
307 if (IsButtonCheckedBool(IDX_SETTINGS_MEM_SET))
308 {
309 UString s;
310 GetItemText(IDE_SETTINGS_MEM_SPIN_EDIT, s);
311 const wchar_t *end;
312 val = ConvertStringToUInt32(s.Ptr(), &end);
313 if (s.IsEmpty() || *end != 0 || val > (1u << 30))
314 {
315 // L"Incorrect value"
316 ShowErrorMessage(*this, NError::MyFormatMessage(E_INVALIDARG));
317 return PSNRET_INVALID;
318 }
319 }
320 NExtract::Save_LimitGB(val);
321 _memx_wasChanged = false;
322 }
323
324 /*
325 if (_wasChanged_MemLimit)
326 {
327 const unsigned index = (int)_memCombo.GetItemData_of_CurSel();
328 const UString str = _memLimitStrings[index];
329
330 bool needSave = true;
331
332 NCompression::CMemUse mu;
333
334 if (_ramSize_Defined)
335 mu.Parse(str);
336 if (mu.IsDefined)
337 {
338 const UInt64 usage64 = mu.GetBytes(_ramSize);
339 if (_ramSize <= usage64)
340 {
341 UString s2 = LangString(IDT_COMPRESS_MEMORY);
342 if (s2.IsEmpty())
343 GetItemText(IDT_COMPRESS_MEMORY, s2);
344 UString s;
345
346 s += "The selected value is not safe for system performance.";
347 s.Add_LF();
348 s += "The memory consumption for compression operation will exceed RAM size.";
349 s.Add_LF();
350 s.Add_LF();
351 AddSize_MB(s, usage64);
352
353 if (!s2.IsEmpty())
354 {
355 s += " : ";
356 s += s2;
357 }
358
359 s.Add_LF();
360 AddSize_MB(s, _ramSize);
361 s += " : RAM";
362
363 s.Add_LF();
364 s.Add_LF();
365 s += "Are you sure you want set that unsafe value for memory usage?";
366
367 int res = MessageBoxW(*this, s, L"7-Zip", MB_YESNOCANCEL | MB_ICONQUESTION);
368 if (res != IDYES)
369 needSave = false;
370 }
371 }
372
373 if (needSave)
374 {
375 NCompression::MemLimit_Save(str);
376 _wasChanged_MemLimit = false;
377 }
378 else
379 return PSNRET_INVALID_NOCHANGEPAGE;
380 }
381 */
382
383 return PSNRET_NOERROR;
384 }
385
OnNotifyHelp()386 void CSettingsPage::OnNotifyHelp()
387 {
388 ShowHelpWindow(kSettingsTopic);
389 }
390
OnCommand(unsigned code,unsigned itemID,LPARAM param)391 bool CSettingsPage::OnCommand(unsigned code, unsigned itemID, LPARAM param)
392 {
393 if (!_initMode)
394 {
395 if (code == EN_CHANGE && itemID == IDE_SETTINGS_MEM_SPIN_EDIT)
396 {
397 _memx_wasChanged = true;
398 Changed();
399 }
400 /*
401 if (code == CBN_SELCHANGE)
402 {
403 switch (itemID)
404 {
405 case IDC_SETTINGS_MEM:
406 {
407 _wasChanged_MemLimit = true;
408 Changed();
409 break;
410 }
411 }
412 }
413 */
414 }
415 return CPropertyPage::OnCommand(code, itemID, param);
416 }
417
OnButtonClicked(unsigned buttonID,HWND buttonHWND)418 bool CSettingsPage::OnButtonClicked(unsigned buttonID, HWND buttonHWND)
419 {
420 switch (buttonID)
421 {
422 case IDX_SETTINGS_SINGLE_CLICK:
423 /*
424 EnableSubItems();
425 break;
426 */
427 case IDX_SETTINGS_SHOW_DOTS:
428 case IDX_SETTINGS_SHOW_SYSTEM_MENU:
429 case IDX_SETTINGS_SHOW_REAL_FILE_ICONS:
430 case IDX_SETTINGS_FULL_ROW:
431 case IDX_SETTINGS_SHOW_GRID:
432 case IDX_SETTINGS_ALTERNATIVE_SELECTION:
433 _wasChanged = true;
434 break;
435
436 case IDX_SETTINGS_LARGE_PAGES:
437 _largePages_wasChanged = true;
438 break;
439
440 case IDX_SETTINGS_MEM_SET:
441 {
442 _memx_wasChanged = true;
443 EnableSpin(IsButtonCheckedBool(IDX_SETTINGS_MEM_SET));
444 break;
445 }
446
447 default:
448 return CPropertyPage::OnButtonClicked(buttonID, buttonHWND);
449 }
450
451 Changed();
452 return true;
453 }
454