5
#include "Common/IntToString.h"
6
#include "Common/StringConvert.h"
8
#include "ViewSettings.h"
9
#include "Windows/Registry.h"
10
#include "Windows/Synchronization.h"
12
using namespace NWindows;
13
using namespace NRegistry;
15
#define REG_PATH_FM TEXT("Software") TEXT(STRING_PATH_SEPARATOR) TEXT("7-ZIP") TEXT(STRING_PATH_SEPARATOR) TEXT("FM")
17
static const TCHAR *kCUBasePath = REG_PATH_FM;
18
static const TCHAR *kCulumnsKeyName = REG_PATH_FM TEXT(STRING_PATH_SEPARATOR) TEXT("Columns");
20
static const TCHAR *kPositionValueName = TEXT("Position");
21
static const TCHAR *kPanelsInfoValueName = TEXT("Panels");
22
static const TCHAR *kToolbars = TEXT("Toolbars");
24
static const WCHAR *kPanelPathValueName = L"PanelPath";
25
static const TCHAR *kListMode = TEXT("ListMode");
26
static const TCHAR *kFolderHistoryValueName = TEXT("FolderHistory");
27
static const TCHAR *kFastFoldersValueName = TEXT("FolderShortcuts");
28
static const TCHAR *kCopyHistoryValueName = TEXT("CopyHistory");
46
static const UInt32 kColumnInfoSpecHeader = 12;
47
static const UInt32 kColumnHeaderSize = 12;
49
static const UInt32 kColumnInfoVersion = 1;
51
static NSynchronization::CCriticalSection g_RegistryOperationsCriticalSection;
53
class CTempOutBufferSpec
59
operator const Byte *() const { return (const Byte *)Buffer; }
60
void Init(UInt32 dataSize)
62
Buffer.SetCapacity(dataSize);
66
void WriteByte(Byte value)
70
((Byte *)Buffer)[Pos++] = value;
72
void WriteUInt32(UInt32 value)
74
for (int i = 0; i < 4; i++)
76
WriteByte((Byte)value);
80
void WriteBool(bool value)
82
WriteUInt32(value ? 1 : 0);
86
class CTempInBufferSpec
101
for (int i = 0; i < 4; i++)
102
value |= (((UInt32)ReadByte()) << (8 * i));
107
return (ReadUInt32() != 0);
111
void SaveListViewInfo(const UString &id, const CListViewInfo &viewInfo)
113
const CObjectVector<CColumnInfo> &columns = viewInfo.Columns;
114
CTempOutBufferSpec buffer;
115
UInt32 dataSize = kColumnHeaderSize + kColumnInfoSpecHeader * columns.Size();
116
buffer.Init(dataSize);
118
buffer.WriteUInt32(kColumnInfoVersion);
119
buffer.WriteUInt32(viewInfo.SortID);
120
buffer.WriteBool(viewInfo.Ascending);
121
for(int i = 0; i < columns.Size(); i++)
123
const CColumnInfo &column = columns[i];
124
buffer.WriteUInt32(column.PropID);
125
buffer.WriteBool(column.IsVisible);
126
buffer.WriteUInt32(column.Width);
129
NSynchronization::CCriticalSectionLock lock(g_RegistryOperationsCriticalSection);
131
key.Create(HKEY_CURRENT_USER, kCulumnsKeyName);
132
key.SetValue(GetSystemString(id), (const Byte *)buffer, dataSize);
136
void ReadListViewInfo(const UString &id, CListViewInfo &viewInfo)
139
CObjectVector<CColumnInfo> &columns = viewInfo.Columns;
143
NSynchronization::CCriticalSectionLock lock(g_RegistryOperationsCriticalSection);
145
if(key.Open(HKEY_CURRENT_USER, kCulumnsKeyName, KEY_READ) != ERROR_SUCCESS)
147
if (key.QueryValue(GetSystemString(id), buffer, size) != ERROR_SUCCESS)
150
if (size < kColumnHeaderSize)
152
CTempInBufferSpec inBuffer;
153
inBuffer.Size = size;
154
inBuffer.Buffer = (Byte *)buffer;
158
UInt32 version = inBuffer.ReadUInt32();
159
if (version != kColumnInfoVersion)
161
viewInfo.SortID = inBuffer.ReadUInt32();
162
viewInfo.Ascending = inBuffer.ReadBool();
164
size -= kColumnHeaderSize;
165
if (size % kColumnInfoSpecHeader != 0)
167
int numItems = size / kColumnInfoSpecHeader;
168
columns.Reserve(numItems);
169
for(int i = 0; i < numItems; i++)
171
CColumnInfo columnInfo;
172
columnInfo.PropID = inBuffer.ReadUInt32();
173
columnInfo.IsVisible = inBuffer.ReadBool();
174
columnInfo.Width = inBuffer.ReadUInt32();
175
columns.Add(columnInfo);
179
static const UInt32 kWindowPositionHeaderSize = 5 * 4;
180
static const UInt32 kPanelsInfoHeaderSize = 3 * 4;
183
struct CWindowPosition
198
void SaveWindowSize(const RECT &rect, bool maximized)
200
CSysString keyName = kCUBasePath;
202
NSynchronization::CCriticalSectionLock lock(g_RegistryOperationsCriticalSection);
203
key.Create(HKEY_CURRENT_USER, keyName);
204
// CWindowPosition position;
205
CTempOutBufferSpec buffer;
206
buffer.Init(kWindowPositionHeaderSize);
207
buffer.WriteUInt32(rect.left);
208
buffer.WriteUInt32(rect.top);
209
buffer.WriteUInt32(rect.right);
210
buffer.WriteUInt32(rect.bottom);
211
buffer.WriteBool(maximized);
212
key.SetValue(kPositionValueName, (const Byte *)buffer, kWindowPositionHeaderSize);
215
bool ReadWindowSize(RECT &rect, bool &maximized)
217
CSysString keyName = kCUBasePath;
219
NSynchronization::CCriticalSectionLock lock(g_RegistryOperationsCriticalSection);
220
if(key.Open(HKEY_CURRENT_USER, keyName, KEY_READ) != ERROR_SUCCESS)
224
if (key.QueryValue(kPositionValueName, buffer, size) != ERROR_SUCCESS)
226
if (size != kWindowPositionHeaderSize)
228
CTempInBufferSpec inBuffer;
229
inBuffer.Size = size;
230
inBuffer.Buffer = (Byte *)buffer;
232
rect.left = inBuffer.ReadUInt32();
233
rect.top = inBuffer.ReadUInt32();
234
rect.right = inBuffer.ReadUInt32();
235
rect.bottom = inBuffer.ReadUInt32();
236
maximized = inBuffer.ReadBool();
241
void SavePanelsInfo(UInt32 numPanels, UInt32 currentPanel, UInt32 splitterPos)
243
CSysString keyName = kCUBasePath;
245
NSynchronization::CCriticalSectionLock lock(g_RegistryOperationsCriticalSection);
246
key.Create(HKEY_CURRENT_USER, keyName);
248
CTempOutBufferSpec buffer;
249
buffer.Init(kPanelsInfoHeaderSize);
250
buffer.WriteUInt32(numPanels);
251
buffer.WriteUInt32(currentPanel);
252
buffer.WriteUInt32(splitterPos);
253
key.SetValue(kPanelsInfoValueName, (const Byte *)buffer, kPanelsInfoHeaderSize);
256
bool ReadPanelsInfo(UInt32 &numPanels, UInt32 ¤tPanel, UInt32 &splitterPos)
258
CSysString keyName = kCUBasePath;
260
NSynchronization::CCriticalSectionLock lock(g_RegistryOperationsCriticalSection);
261
if(key.Open(HKEY_CURRENT_USER, keyName, KEY_READ) != ERROR_SUCCESS)
265
if (key.QueryValue(kPanelsInfoValueName, buffer, size) != ERROR_SUCCESS)
267
if (size != kPanelsInfoHeaderSize)
269
CTempInBufferSpec inBuffer;
270
inBuffer.Size = size;
271
inBuffer.Buffer = (Byte *)buffer;
273
numPanels = inBuffer.ReadUInt32();
274
currentPanel = inBuffer.ReadUInt32();
275
splitterPos = inBuffer.ReadUInt32();
279
void SaveToolbarsMask(UInt32 toolbarMask)
282
key.Create(HKEY_CURRENT_USER, kCUBasePath);
283
key.SetValue(kToolbars, toolbarMask);
286
static const UInt32 kDefaultToolbarMask = 8 | 4 | 1;
288
UInt32 ReadToolbarsMask()
291
if(key.Open(HKEY_CURRENT_USER, kCUBasePath, KEY_READ) != ERROR_SUCCESS)
292
return kDefaultToolbarMask;
294
if (key.QueryValue(kToolbars, mask) != ERROR_SUCCESS)
295
return kDefaultToolbarMask;
300
static UString GetPanelPathName(UInt32 panelIndex)
302
WCHAR panelString[32];
303
ConvertUInt64ToString(panelIndex, panelString);
304
return UString(kPanelPathValueName) + panelString;
308
void SavePanelPath(UInt32 panel, const UString &path)
311
NSynchronization::CCriticalSectionLock lock(g_RegistryOperationsCriticalSection);
312
key.Create(HKEY_CURRENT_USER, kCUBasePath);
313
key.SetValue(GetPanelPathName(panel), path);
316
bool ReadPanelPath(UInt32 panel, UString &path)
319
NSynchronization::CCriticalSectionLock lock(g_RegistryOperationsCriticalSection);
320
if(key.Open(HKEY_CURRENT_USER, kCUBasePath, KEY_READ) != ERROR_SUCCESS)
322
return (key.QueryValue(GetPanelPathName(panel), path) == ERROR_SUCCESS);
325
void SaveListMode(const CListMode &listMode)
328
key.Create(HKEY_CURRENT_USER, kCUBasePath);
330
for (int i = 0; i < 2; i++)
331
t |= ((listMode.Panels[i]) & 0xFF) << (i * 8);
332
key.SetValue(kListMode, t);
335
void ReadListMode(CListMode &listMode)
339
if(key.Open(HKEY_CURRENT_USER, kCUBasePath, KEY_READ) != ERROR_SUCCESS)
342
if (key.QueryValue(kListMode, t) != ERROR_SUCCESS)
344
for (int i = 0; i < 2; i++)
346
listMode.Panels[i] = (t & 0xFF);
352
void SaveStringList(LPCTSTR valueName, const UStringVector &folders)
354
UInt32 sizeInChars = 0;
356
for (i = 0; i < folders.Size(); i++)
357
sizeInChars += folders[i].Length() + 1;
358
CBuffer<wchar_t> buffer;
359
buffer.SetCapacity(sizeInChars);
361
for (i = 0; i < folders.Size(); i++)
363
MyStringCopy((wchar_t *)buffer + pos, (const wchar_t *)folders[i]);
364
pos += folders[i].Length() + 1;
367
NSynchronization::CCriticalSectionLock lock(g_RegistryOperationsCriticalSection);
368
key.Create(HKEY_CURRENT_USER, kCUBasePath);
369
key.SetValue(valueName, buffer, sizeInChars * sizeof(wchar_t));
372
void ReadStringList(LPCTSTR valueName, UStringVector &folders)
376
NSynchronization::CCriticalSectionLock lock(g_RegistryOperationsCriticalSection);
377
if(key.Open(HKEY_CURRENT_USER, kCUBasePath, KEY_READ) != ERROR_SUCCESS)
381
if (key.QueryValue(valueName, buffer, dataSize) != ERROR_SUCCESS)
383
if (dataSize % sizeof(wchar_t) != 0)
385
const wchar_t *data = (const wchar_t *)(const Byte *)buffer;
386
int sizeInChars = dataSize / sizeof(wchar_t);
388
for (int i = 0; i < sizeInChars; i++)
401
void SaveFolderHistory(const UStringVector &folders)
402
{ SaveStringList(kFolderHistoryValueName, folders); }
403
void ReadFolderHistory(UStringVector &folders)
404
{ ReadStringList(kFolderHistoryValueName, folders); }
406
void SaveFastFolders(const UStringVector &folders)
407
{ SaveStringList(kFastFoldersValueName, folders); }
408
void ReadFastFolders(UStringVector &folders)
409
{ ReadStringList(kFastFoldersValueName, folders); }
411
void SaveCopyHistory(const UStringVector &folders)
412
{ SaveStringList(kCopyHistoryValueName, folders); }
413
void ReadCopyHistory(UStringVector &folders)
414
{ ReadStringList(kCopyHistoryValueName, folders); }
416
void AddUniqueStringToHeadOfList(UStringVector &list,
417
const UString &string)
419
for(int i = 0; i < list.Size();)
420
if (string.CompareNoCase(list[i]) == 0)
424
list.Insert(0, string);