5 #include "Common/IntToString.h"
\r
6 #include "Common/StringConvert.h"
\r
8 #include "ViewSettings.h"
\r
9 #include "Windows/Registry.h"
\r
10 #include "Windows/Synchronization.h"
\r
12 using namespace NWindows;
\r
13 using namespace NRegistry;
\r
15 #define REG_PATH_FM TEXT("Software") TEXT(STRING_PATH_SEPARATOR) TEXT("7-Zip") TEXT(STRING_PATH_SEPARATOR) TEXT("FM")
\r
17 static const TCHAR *kCUBasePath = REG_PATH_FM;
\r
18 static const TCHAR *kCulumnsKeyName = REG_PATH_FM TEXT(STRING_PATH_SEPARATOR) TEXT("Columns");
\r
20 static const TCHAR *kPositionValueName = TEXT("Position");
\r
21 static const TCHAR *kPanelsInfoValueName = TEXT("Panels");
\r
22 static const TCHAR *kToolbars = TEXT("Toolbars");
\r
24 static const WCHAR *kPanelPathValueName = L"PanelPath";
\r
25 static const TCHAR *kListMode = TEXT("ListMode");
\r
26 static const TCHAR *kFolderHistoryValueName = TEXT("FolderHistory");
\r
27 static const TCHAR *kFastFoldersValueName = TEXT("FolderShortcuts");
\r
28 static const TCHAR *kCopyHistoryValueName = TEXT("CopyHistory");
\r
31 class CColumnInfoSpec
\r
38 struct CColumnHeader
\r
46 static const UInt32 kColumnInfoSpecHeader = 12;
\r
47 static const UInt32 kColumnHeaderSize = 12;
\r
49 static const UInt32 kColumnInfoVersion = 1;
\r
51 static NSynchronization::CCriticalSection g_CS;
\r
53 class CTempOutBufferSpec
\r
59 operator const Byte *() const { return (const Byte *)Buffer; }
\r
60 void Init(UInt32 dataSize)
\r
62 Buffer.SetCapacity(dataSize);
\r
66 void WriteByte(Byte value)
\r
70 ((Byte *)Buffer)[Pos++] = value;
\r
72 void WriteUInt32(UInt32 value)
\r
74 for (int i = 0; i < 4; i++)
\r
76 WriteByte((Byte)value);
\r
80 void WriteBool(bool value)
\r
82 WriteUInt32(value ? 1 : 0);
\r
86 class CTempInBufferSpec
\r
96 return Buffer[Pos++];
\r
101 for (int i = 0; i < 4; i++)
\r
102 value |= (((UInt32)ReadByte()) << (8 * i));
\r
107 return (ReadUInt32() != 0);
\r
111 void SaveListViewInfo(const UString &id, const CListViewInfo &viewInfo)
\r
113 const CObjectVector<CColumnInfo> &columns = viewInfo.Columns;
\r
114 CTempOutBufferSpec buffer;
\r
115 UInt32 dataSize = kColumnHeaderSize + kColumnInfoSpecHeader * columns.Size();
\r
116 buffer.Init(dataSize);
\r
118 buffer.WriteUInt32(kColumnInfoVersion);
\r
119 buffer.WriteUInt32(viewInfo.SortID);
\r
120 buffer.WriteBool(viewInfo.Ascending);
\r
121 for(int i = 0; i < columns.Size(); i++)
\r
123 const CColumnInfo &column = columns[i];
\r
124 buffer.WriteUInt32(column.PropID);
\r
125 buffer.WriteBool(column.IsVisible);
\r
126 buffer.WriteUInt32(column.Width);
\r
129 NSynchronization::CCriticalSectionLock lock(g_CS);
\r
131 key.Create(HKEY_CURRENT_USER, kCulumnsKeyName);
\r
132 key.SetValue(GetSystemString(id), (const Byte *)buffer, dataSize);
\r
136 void ReadListViewInfo(const UString &id, CListViewInfo &viewInfo)
\r
139 CObjectVector<CColumnInfo> &columns = viewInfo.Columns;
\r
140 CByteBuffer buffer;
\r
143 NSynchronization::CCriticalSectionLock lock(g_CS);
\r
145 if (key.Open(HKEY_CURRENT_USER, kCulumnsKeyName, KEY_READ) != ERROR_SUCCESS)
\r
147 if (key.QueryValue(GetSystemString(id), buffer, size) != ERROR_SUCCESS)
\r
150 if (size < kColumnHeaderSize)
\r
152 CTempInBufferSpec inBuffer;
\r
153 inBuffer.Size = size;
\r
154 inBuffer.Buffer = (Byte *)buffer;
\r
158 UInt32 version = inBuffer.ReadUInt32();
\r
159 if (version != kColumnInfoVersion)
\r
161 viewInfo.SortID = inBuffer.ReadUInt32();
\r
162 viewInfo.Ascending = inBuffer.ReadBool();
\r
164 size -= kColumnHeaderSize;
\r
165 if (size % kColumnInfoSpecHeader != 0)
\r
167 int numItems = size / kColumnInfoSpecHeader;
\r
168 columns.Reserve(numItems);
\r
169 for(int i = 0; i < numItems; i++)
\r
171 CColumnInfo columnInfo;
\r
172 columnInfo.PropID = inBuffer.ReadUInt32();
\r
173 columnInfo.IsVisible = inBuffer.ReadBool();
\r
174 columnInfo.Width = inBuffer.ReadUInt32();
\r
175 columns.Add(columnInfo);
\r
179 static const UInt32 kWindowPositionHeaderSize = 5 * 4;
\r
180 static const UInt32 kPanelsInfoHeaderSize = 3 * 4;
\r
183 struct CWindowPosition
\r
192 UInt32 CurrentPanel;
\r
193 UInt32 SplitterPos;
\r
197 void SaveWindowSize(const RECT &rect, bool maximized)
\r
199 CSysString keyName = kCUBasePath;
\r
200 NSynchronization::CCriticalSectionLock lock(g_CS);
\r
202 key.Create(HKEY_CURRENT_USER, keyName);
\r
203 // CWindowPosition position;
\r
204 CTempOutBufferSpec buffer;
\r
205 buffer.Init(kWindowPositionHeaderSize);
\r
206 buffer.WriteUInt32(rect.left);
\r
207 buffer.WriteUInt32(rect.top);
\r
208 buffer.WriteUInt32(rect.right);
\r
209 buffer.WriteUInt32(rect.bottom);
\r
210 buffer.WriteBool(maximized);
\r
211 key.SetValue(kPositionValueName, (const Byte *)buffer, kWindowPositionHeaderSize);
\r
214 bool ReadWindowSize(RECT &rect, bool &maximized)
\r
216 CSysString keyName = kCUBasePath;
\r
217 NSynchronization::CCriticalSectionLock lock(g_CS);
\r
219 if (key.Open(HKEY_CURRENT_USER, keyName, KEY_READ) != ERROR_SUCCESS)
\r
221 CByteBuffer buffer;
\r
223 if (key.QueryValue(kPositionValueName, buffer, size) != ERROR_SUCCESS)
\r
225 if (size != kWindowPositionHeaderSize)
\r
227 CTempInBufferSpec inBuffer;
\r
228 inBuffer.Size = size;
\r
229 inBuffer.Buffer = (Byte *)buffer;
\r
231 rect.left = inBuffer.ReadUInt32();
\r
232 rect.top = inBuffer.ReadUInt32();
\r
233 rect.right = inBuffer.ReadUInt32();
\r
234 rect.bottom = inBuffer.ReadUInt32();
\r
235 maximized = inBuffer.ReadBool();
\r
239 void SavePanelsInfo(UInt32 numPanels, UInt32 currentPanel, UInt32 splitterPos)
\r
241 CSysString keyName = kCUBasePath;
\r
242 NSynchronization::CCriticalSectionLock lock(g_CS);
\r
244 key.Create(HKEY_CURRENT_USER, keyName);
\r
246 CTempOutBufferSpec buffer;
\r
247 buffer.Init(kPanelsInfoHeaderSize);
\r
248 buffer.WriteUInt32(numPanels);
\r
249 buffer.WriteUInt32(currentPanel);
\r
250 buffer.WriteUInt32(splitterPos);
\r
251 key.SetValue(kPanelsInfoValueName, (const Byte *)buffer, kPanelsInfoHeaderSize);
\r
254 bool ReadPanelsInfo(UInt32 &numPanels, UInt32 ¤tPanel, UInt32 &splitterPos)
\r
256 CSysString keyName = kCUBasePath;
\r
257 NSynchronization::CCriticalSectionLock lock(g_CS);
\r
259 if (key.Open(HKEY_CURRENT_USER, keyName, KEY_READ) != ERROR_SUCCESS)
\r
261 CByteBuffer buffer;
\r
263 if (key.QueryValue(kPanelsInfoValueName, buffer, size) != ERROR_SUCCESS)
\r
265 if (size != kPanelsInfoHeaderSize)
\r
267 CTempInBufferSpec inBuffer;
\r
268 inBuffer.Size = size;
\r
269 inBuffer.Buffer = (Byte *)buffer;
\r
271 numPanels = inBuffer.ReadUInt32();
\r
272 currentPanel = inBuffer.ReadUInt32();
\r
273 splitterPos = inBuffer.ReadUInt32();
\r
277 void SaveToolbarsMask(UInt32 toolbarMask)
\r
280 key.Create(HKEY_CURRENT_USER, kCUBasePath);
\r
281 key.SetValue(kToolbars, toolbarMask);
\r
284 static const UInt32 kDefaultToolbarMask = ((UInt32)1 << 31) | 8 | 4 | 1;
\r
286 UInt32 ReadToolbarsMask()
\r
289 if (key.Open(HKEY_CURRENT_USER, kCUBasePath, KEY_READ) != ERROR_SUCCESS)
\r
290 return kDefaultToolbarMask;
\r
292 if (key.QueryValue(kToolbars, mask) != ERROR_SUCCESS)
\r
293 return kDefaultToolbarMask;
\r
298 static UString GetPanelPathName(UInt32 panelIndex)
\r
300 WCHAR panelString[16];
\r
301 ConvertUInt32ToString(panelIndex, panelString);
\r
302 return UString(kPanelPathValueName) + panelString;
\r
306 void SavePanelPath(UInt32 panel, const UString &path)
\r
308 NSynchronization::CCriticalSectionLock lock(g_CS);
\r
310 key.Create(HKEY_CURRENT_USER, kCUBasePath);
\r
311 key.SetValue(GetPanelPathName(panel), path);
\r
314 bool ReadPanelPath(UInt32 panel, UString &path)
\r
316 NSynchronization::CCriticalSectionLock lock(g_CS);
\r
318 if (key.Open(HKEY_CURRENT_USER, kCUBasePath, KEY_READ) != ERROR_SUCCESS)
\r
320 return (key.QueryValue(GetPanelPathName(panel), path) == ERROR_SUCCESS);
\r
323 void SaveListMode(const CListMode &listMode)
\r
326 key.Create(HKEY_CURRENT_USER, kCUBasePath);
\r
328 for (int i = 0; i < 2; i++)
\r
329 t |= ((listMode.Panels[i]) & 0xFF) << (i * 8);
\r
330 key.SetValue(kListMode, t);
\r
333 void ReadListMode(CListMode &listMode)
\r
337 if (key.Open(HKEY_CURRENT_USER, kCUBasePath, KEY_READ) != ERROR_SUCCESS)
\r
340 if (key.QueryValue(kListMode, t) != ERROR_SUCCESS)
\r
342 for (int i = 0; i < 2; i++)
\r
344 listMode.Panels[i] = (t & 0xFF);
\r
350 static void SaveStringList(LPCTSTR valueName, const UStringVector &folders)
\r
352 NSynchronization::CCriticalSectionLock lock(g_CS);
\r
354 key.Create(HKEY_CURRENT_USER, kCUBasePath);
\r
355 key.SetValue_Strings(valueName, folders);
\r
358 static void ReadStringList(LPCTSTR valueName, UStringVector &folders)
\r
361 NSynchronization::CCriticalSectionLock lock(g_CS);
\r
363 if (key.Open(HKEY_CURRENT_USER, kCUBasePath, KEY_READ) == ERROR_SUCCESS)
\r
364 key.GetValue_Strings(valueName, folders);
\r
367 void SaveFolderHistory(const UStringVector &folders)
\r
368 { SaveStringList(kFolderHistoryValueName, folders); }
\r
369 void ReadFolderHistory(UStringVector &folders)
\r
370 { ReadStringList(kFolderHistoryValueName, folders); }
\r
372 void SaveFastFolders(const UStringVector &folders)
\r
373 { SaveStringList(kFastFoldersValueName, folders); }
\r
374 void ReadFastFolders(UStringVector &folders)
\r
375 { ReadStringList(kFastFoldersValueName, folders); }
\r
377 void SaveCopyHistory(const UStringVector &folders)
\r
378 { SaveStringList(kCopyHistoryValueName, folders); }
\r
379 void ReadCopyHistory(UStringVector &folders)
\r
380 { ReadStringList(kCopyHistoryValueName, folders); }
\r
382 void AddUniqueStringToHeadOfList(UStringVector &list, const UString &s)
\r
384 for (int i = 0; i < list.Size();)
\r
385 if (s.CompareNoCase(list[i]) == 0)
\r