1 // ViewSettings.cpp
2
3 #include "StdAfx.h"
4
5 #include "../../../../C/CpuArch.h"
6
7 #include "../../../Common/IntToString.h"
8 #include "../../../Common/StringConvert.h"
9
10 #include "../../../Windows/Registry.h"
11 #include "../../../Windows/Synchronization.h"
12
13 #include "ViewSettings.h"
14
15 using namespace NWindows;
16 using namespace NRegistry;
17
18 #define REG_PATH_FM TEXT("Software") TEXT(STRING_PATH_SEPARATOR) TEXT("7-Zip") TEXT(STRING_PATH_SEPARATOR) TEXT("FM")
19
20 static LPCTSTR const kCUBasePath = REG_PATH_FM;
21 static LPCTSTR const kCulumnsKeyName = REG_PATH_FM TEXT(STRING_PATH_SEPARATOR) TEXT("Columns");
22
23 static LPCTSTR const kPositionValueName = TEXT("Position");
24 static LPCTSTR const kPanelsInfoValueName = TEXT("Panels");
25 static LPCTSTR const kToolbars = TEXT("Toolbars");
26
27 static LPCWSTR const kPanelPathValueName = L"PanelPath";
28
29 static LPCTSTR const kListMode = TEXT("ListMode");
30 static LPCTSTR const kFolderHistoryValueName = TEXT("FolderHistory");
31 static LPCTSTR const kFastFoldersValueName = TEXT("FolderShortcuts");
32 static LPCTSTR const kCopyHistoryValueName = TEXT("CopyHistory");
33
34 static NSynchronization::CCriticalSection g_CS;
35
36 #define Set32(p, v) SetUi32(((Byte *)p), v)
37 #define SetBool(p, v) Set32(p, ((v) ? 1 : 0))
38
39 #define Get32(p, dest) dest = GetUi32((const Byte *)p);
40 #define Get32_LONG(p, dest) dest = (LONG)GetUi32((const Byte *)p);
41 #define GetBool(p, dest) dest = (GetUi32(p) != 0);
42
43 /*
44 struct CColumnHeader
45 {
46 UInt32 Version;
47 UInt32 SortID;
48 UInt32 Ascending; // bool
49 };
50 */
51
52 static const UInt32 kListViewHeaderSize = 3 * 4;
53 static const UInt32 kColumnInfoSize = 3 * 4;
54 static const UInt32 kListViewVersion = 1;
55
Save(const UString & id) const56 void CListViewInfo::Save(const UString &id) const
57 {
58 const UInt32 dataSize = kListViewHeaderSize + kColumnInfoSize * Columns.Size();
59 CByteArr buf(dataSize);
60
61 Set32(buf, kListViewVersion)
62 Set32(buf + 4, SortID)
63 SetBool(buf + 8, Ascending)
64 FOR_VECTOR (i, Columns)
65 {
66 const CColumnInfo &column = Columns[i];
67 Byte *p = buf + kListViewHeaderSize + i * kColumnInfoSize;
68 Set32(p, column.PropID)
69 SetBool(p + 4, column.IsVisible)
70 Set32(p + 8, column.Width)
71 }
72 {
73 NSynchronization::CCriticalSectionLock lock(g_CS);
74 CKey key;
75 key.Create(HKEY_CURRENT_USER, kCulumnsKeyName);
76 key.SetValue(GetSystemString(id), (const Byte *)buf, dataSize);
77 }
78 }
79
Read(const UString & id)80 void CListViewInfo::Read(const UString &id)
81 {
82 Clear();
83 CByteBuffer buf;
84 UInt32 size;
85 {
86 NSynchronization::CCriticalSectionLock lock(g_CS);
87 CKey key;
88 if (key.Open(HKEY_CURRENT_USER, kCulumnsKeyName, KEY_READ) != ERROR_SUCCESS)
89 return;
90 if (key.QueryValue(GetSystemString(id), buf, size) != ERROR_SUCCESS)
91 return;
92 }
93 if (size < kListViewHeaderSize)
94 return;
95 UInt32 version;
96 Get32(buf, version)
97 if (version != kListViewVersion)
98 return;
99 Get32(buf + 4, SortID)
100 GetBool(buf + 8, Ascending)
101
102 IsLoaded = true;
103
104 size -= kListViewHeaderSize;
105 if (size % kColumnInfoSize != 0)
106 return;
107 unsigned numItems = size / kColumnInfoSize;
108 Columns.ClearAndReserve(numItems);
109 for (unsigned i = 0; i < numItems; i++)
110 {
111 CColumnInfo column;
112 const Byte *p = buf + kListViewHeaderSize + i * kColumnInfoSize;
113 Get32(p, column.PropID)
114 GetBool(p + 4, column.IsVisible)
115 Get32(p + 8, column.Width)
116 Columns.AddInReserved(column);
117 }
118 }
119
120
121 /*
122 struct CWindowPosition
123 {
124 RECT Rect;
125 UInt32 Maximized; // bool
126 };
127
128 struct CPanelsInfo
129 {
130 UInt32 NumPanels;
131 UInt32 CurrentPanel;
132 UInt32 SplitterPos;
133 };
134 */
135
136 static const UInt32 kWindowPositionHeaderSize = 5 * 4;
137 static const UInt32 kPanelsInfoHeaderSize = 3 * 4;
138
Save() const139 void CWindowInfo::Save() const
140 {
141 NSynchronization::CCriticalSectionLock lock(g_CS);
142 CKey key;
143 key.Create(HKEY_CURRENT_USER, kCUBasePath);
144 {
145 Byte buf[kWindowPositionHeaderSize];
146 Set32(buf, (UInt32)rect.left)
147 Set32(buf + 4, (UInt32)rect.top)
148 Set32(buf + 8, (UInt32)rect.right)
149 Set32(buf + 12, (UInt32)rect.bottom)
150 SetBool(buf + 16, maximized)
151 key.SetValue(kPositionValueName, buf, kWindowPositionHeaderSize);
152 }
153 {
154 Byte buf[kPanelsInfoHeaderSize];
155 Set32(buf, numPanels)
156 Set32(buf + 4, currentPanel)
157 Set32(buf + 8, splitterPos)
158 key.SetValue(kPanelsInfoValueName, buf, kPanelsInfoHeaderSize);
159 }
160 }
161
QueryBuf(CKey & key,LPCTSTR name,CByteBuffer & buf,UInt32 dataSize)162 static bool QueryBuf(CKey &key, LPCTSTR name, CByteBuffer &buf, UInt32 dataSize)
163 {
164 UInt32 size;
165 return key.QueryValue(name, buf, size) == ERROR_SUCCESS && size == dataSize;
166 }
167
Read(bool & windowPosDefined,bool & panelInfoDefined)168 void CWindowInfo::Read(bool &windowPosDefined, bool &panelInfoDefined)
169 {
170 windowPosDefined = false;
171 panelInfoDefined = false;
172 NSynchronization::CCriticalSectionLock lock(g_CS);
173 CKey key;
174 if (key.Open(HKEY_CURRENT_USER, kCUBasePath, KEY_READ) != ERROR_SUCCESS)
175 return;
176 CByteBuffer buf;
177 if (QueryBuf(key, kPositionValueName, buf, kWindowPositionHeaderSize))
178 {
179 Get32_LONG(buf, rect.left)
180 Get32_LONG(buf + 4, rect.top)
181 Get32_LONG(buf + 8, rect.right)
182 Get32_LONG(buf + 12, rect.bottom)
183 GetBool(buf + 16, maximized)
184 windowPosDefined = true;
185 }
186 if (QueryBuf(key, kPanelsInfoValueName, buf, kPanelsInfoHeaderSize))
187 {
188 Get32(buf, numPanels)
189 Get32(buf + 4, currentPanel)
190 Get32(buf + 8, splitterPos)
191 panelInfoDefined = true;
192 }
193 return;
194 }
195
196
SaveUi32Val(const TCHAR * name,UInt32 value)197 static void SaveUi32Val(const TCHAR *name, UInt32 value)
198 {
199 CKey key;
200 key.Create(HKEY_CURRENT_USER, kCUBasePath);
201 key.SetValue(name, value);
202 }
203
ReadUi32Val(const TCHAR * name,UInt32 & value)204 static bool ReadUi32Val(const TCHAR *name, UInt32 &value)
205 {
206 CKey key;
207 if (key.Open(HKEY_CURRENT_USER, kCUBasePath, KEY_READ) != ERROR_SUCCESS)
208 return false;
209 return key.QueryValue(name, value) == ERROR_SUCCESS;
210 }
211
SaveToolbarsMask(UInt32 toolbarMask)212 void SaveToolbarsMask(UInt32 toolbarMask)
213 {
214 SaveUi32Val(kToolbars, toolbarMask);
215 }
216
217 static const UInt32 kDefaultToolbarMask = ((UInt32)1 << 31) | 8 | 4 | 1;
218
ReadToolbarsMask()219 UInt32 ReadToolbarsMask()
220 {
221 UInt32 mask;
222 if (!ReadUi32Val(kToolbars, mask))
223 return kDefaultToolbarMask;
224 return mask;
225 }
226
227
Save() const228 void CListMode::Save() const
229 {
230 UInt32 t = 0;
231 for (int i = 0; i < 2; i++)
232 t |= ((Panels[i]) & 0xFF) << (i * 8);
233 SaveUi32Val(kListMode, t);
234 }
235
Read()236 void CListMode::Read()
237 {
238 Init();
239 UInt32 t;
240 if (!ReadUi32Val(kListMode, t))
241 return;
242 for (int i = 0; i < 2; i++)
243 {
244 Panels[i] = (t & 0xFF);
245 t >>= 8;
246 }
247 }
248
GetPanelPathName(UInt32 panelIndex)249 static UString GetPanelPathName(UInt32 panelIndex)
250 {
251 UString s (kPanelPathValueName);
252 s.Add_UInt32(panelIndex);
253 return s;
254 }
255
SavePanelPath(UInt32 panel,const UString & path)256 void SavePanelPath(UInt32 panel, const UString &path)
257 {
258 NSynchronization::CCriticalSectionLock lock(g_CS);
259 CKey key;
260 key.Create(HKEY_CURRENT_USER, kCUBasePath);
261 key.SetValue(GetPanelPathName(panel), path);
262 }
263
ReadPanelPath(UInt32 panel,UString & path)264 bool ReadPanelPath(UInt32 panel, UString &path)
265 {
266 NSynchronization::CCriticalSectionLock lock(g_CS);
267 CKey key;
268 if (key.Open(HKEY_CURRENT_USER, kCUBasePath, KEY_READ) != ERROR_SUCCESS)
269 return false;
270 return (key.QueryValue(GetPanelPathName(panel), path) == ERROR_SUCCESS);
271 }
272
273
SaveStringList(LPCTSTR valueName,const UStringVector & folders)274 static void SaveStringList(LPCTSTR valueName, const UStringVector &folders)
275 {
276 NSynchronization::CCriticalSectionLock lock(g_CS);
277 CKey key;
278 key.Create(HKEY_CURRENT_USER, kCUBasePath);
279 key.SetValue_Strings(valueName, folders);
280 }
281
ReadStringList(LPCTSTR valueName,UStringVector & folders)282 static void ReadStringList(LPCTSTR valueName, UStringVector &folders)
283 {
284 folders.Clear();
285 NSynchronization::CCriticalSectionLock lock(g_CS);
286 CKey key;
287 if (key.Open(HKEY_CURRENT_USER, kCUBasePath, KEY_READ) == ERROR_SUCCESS)
288 key.GetValue_Strings(valueName, folders);
289 }
290
SaveFolderHistory(const UStringVector & folders)291 void SaveFolderHistory(const UStringVector &folders)
292 { SaveStringList(kFolderHistoryValueName, folders); }
ReadFolderHistory(UStringVector & folders)293 void ReadFolderHistory(UStringVector &folders)
294 { ReadStringList(kFolderHistoryValueName, folders); }
295
SaveFastFolders(const UStringVector & folders)296 void SaveFastFolders(const UStringVector &folders)
297 { SaveStringList(kFastFoldersValueName, folders); }
ReadFastFolders(UStringVector & folders)298 void ReadFastFolders(UStringVector &folders)
299 { ReadStringList(kFastFoldersValueName, folders); }
300
SaveCopyHistory(const UStringVector & folders)301 void SaveCopyHistory(const UStringVector &folders)
302 { SaveStringList(kCopyHistoryValueName, folders); }
ReadCopyHistory(UStringVector & folders)303 void ReadCopyHistory(UStringVector &folders)
304 { ReadStringList(kCopyHistoryValueName, folders); }
305
AddUniqueStringToHeadOfList(UStringVector & list,const UString & s)306 void AddUniqueStringToHeadOfList(UStringVector &list, const UString &s)
307 {
308 for (unsigned i = 0; i < list.Size();)
309 if (s.IsEqualTo_NoCase(list[i]))
310 list.Delete(i);
311 else
312 i++;
313 list.Insert(0, s);
314 }
315