diff options
Diffstat (limited to 'CPP/7zip/FileManager/ViewSettings.cpp')
-rwxr-xr-x | CPP/7zip/FileManager/ViewSettings.cpp | 429 |
1 files changed, 429 insertions, 0 deletions
diff --git a/CPP/7zip/FileManager/ViewSettings.cpp b/CPP/7zip/FileManager/ViewSettings.cpp new file mode 100755 index 00000000..9102cc4e --- /dev/null +++ b/CPP/7zip/FileManager/ViewSettings.cpp @@ -0,0 +1,429 @@ +// ViewSettings.h + +#include "StdAfx.h" + +#include "Common/IntToString.h" +#include "Common/StringConvert.h" + +#include "ViewSettings.h" +#include "Windows/Registry.h" +#include "Windows/Synchronization.h" + +using namespace NWindows; +using namespace NRegistry; + +static const TCHAR *kCUBasePath = TEXT("Software\\7-Zip\\FM"); + +static const TCHAR *kCulumnsKeyName = TEXT("Columns"); + +static const TCHAR *kPositionValueName = TEXT("Position"); +static const TCHAR *kPanelsInfoValueName = TEXT("Panels"); +static const TCHAR *kToolbars = TEXT("Toolbars"); + +static const WCHAR *kPanelPathValueName = L"PanelPath"; +static const TCHAR *kListMode = TEXT("ListMode"); +static const TCHAR *kFolderHistoryValueName = TEXT("FolderHistory"); +static const TCHAR *kFastFoldersValueName = TEXT("FolderShortcuts"); +static const TCHAR *kCopyHistoryValueName = TEXT("CopyHistory"); + +/* +class CColumnInfoSpec +{ + UInt32 PropID; + Byte IsVisible; + UInt32 Width; +}; + +struct CColumnHeader +{ + UInt32 Version; + UInt32 SortID; + Byte Ascending; +}; +*/ + +static const UInt32 kColumnInfoSpecHeader = 12; +static const UInt32 kColumnHeaderSize = 12; + +static const UInt32 kColumnInfoVersion = 1; + +static NSynchronization::CCriticalSection g_RegistryOperationsCriticalSection; + +class CTempOutBufferSpec +{ + CByteBuffer Buffer; + UInt32 Size; + UInt32 Pos; +public: + operator const Byte *() const { return (const Byte *)Buffer; } + void Init(UInt32 dataSize) + { + Buffer.SetCapacity(dataSize); + Size = dataSize; + Pos = 0; + } + void WriteByte(Byte value) + { + if (Pos >= Size) + throw "overflow"; + ((Byte *)Buffer)[Pos++] = value; + } + void WriteUInt32(UInt32 value) + { + for (int i = 0; i < 4; i++) + { + WriteByte((Byte)value); + value >>= 8; + } + } + void WriteBool(bool value) + { + WriteUInt32(value ? 1 : 0); + } +}; + +class CTempInBufferSpec +{ +public: + Byte *Buffer; + UInt32 Size; + UInt32 Pos; + Byte ReadByte() + { + if (Pos >= Size) + throw "overflow"; + return Buffer[Pos++]; + } + UInt32 ReadUInt32() + { + UInt32 value = 0; + for (int i = 0; i < 4; i++) + value |= (((UInt32)ReadByte()) << (8 * i)); + return value; + } + bool ReadBool() + { + return (ReadUInt32() != 0); + } +}; + +void SaveListViewInfo(const UString &id, const CListViewInfo &viewInfo) +{ + const CObjectVector<CColumnInfo> &columns = viewInfo.Columns; + CTempOutBufferSpec buffer; + UInt32 dataSize = kColumnHeaderSize + kColumnInfoSpecHeader * columns.Size(); + buffer.Init(dataSize); + + buffer.WriteUInt32(kColumnInfoVersion); + buffer.WriteUInt32(viewInfo.SortID); + buffer.WriteBool(viewInfo.Ascending); + for(int i = 0; i < columns.Size(); i++) + { + const CColumnInfo &column = columns[i]; + buffer.WriteUInt32(column.PropID); + buffer.WriteBool(column.IsVisible); + buffer.WriteUInt32(column.Width); + } + { + NSynchronization::CCriticalSectionLock lock(g_RegistryOperationsCriticalSection); + CSysString keyName = kCUBasePath; + keyName += kKeyNameDelimiter; + keyName += kCulumnsKeyName; + CKey key; + key.Create(HKEY_CURRENT_USER, keyName); + key.SetValue(GetSystemString(id), (const Byte *)buffer, dataSize); + } +} + +void ReadListViewInfo(const UString &id, CListViewInfo &viewInfo) +{ + viewInfo.Clear(); + CObjectVector<CColumnInfo> &columns = viewInfo.Columns; + CByteBuffer buffer; + UInt32 size; + { + NSynchronization::CCriticalSectionLock lock(g_RegistryOperationsCriticalSection); + CSysString keyName = kCUBasePath; + keyName += kKeyNameDelimiter; + keyName += kCulumnsKeyName; + CKey key; + if(key.Open(HKEY_CURRENT_USER, keyName, KEY_READ) != ERROR_SUCCESS) + return; + if (key.QueryValue(GetSystemString(id), buffer, size) != ERROR_SUCCESS) + return; + } + if (size < kColumnHeaderSize) + return; + CTempInBufferSpec inBuffer; + inBuffer.Size = size; + inBuffer.Buffer = (Byte *)buffer; + inBuffer.Pos = 0; + + + UInt32 version = inBuffer.ReadUInt32(); + if (version != kColumnInfoVersion) + return; + viewInfo.SortID = inBuffer.ReadUInt32(); + viewInfo.Ascending = inBuffer.ReadBool(); + + size -= kColumnHeaderSize; + if (size % kColumnInfoSpecHeader != 0) + return; + int numItems = size / kColumnInfoSpecHeader; + columns.Reserve(numItems); + for(int i = 0; i < numItems; i++) + { + CColumnInfo columnInfo; + columnInfo.PropID = inBuffer.ReadUInt32(); + columnInfo.IsVisible = inBuffer.ReadBool(); + columnInfo.Width = inBuffer.ReadUInt32(); + columns.Add(columnInfo); + } +} + +static const UInt32 kWindowPositionHeaderSize = 5 * 4; +static const UInt32 kPanelsInfoHeaderSize = 3 * 4; + +/* +struct CWindowPosition +{ + RECT Rect; + UInt32 Maximized; +}; + +struct CPanelsInfo +{ + UInt32 NumPanels; + UInt32 CurrentPanel; + UInt32 SplitterPos; +}; +*/ + +void SaveWindowSize(const RECT &rect, bool maximized) +{ + CSysString keyName = kCUBasePath; + CKey key; + NSynchronization::CCriticalSectionLock lock(g_RegistryOperationsCriticalSection); + key.Create(HKEY_CURRENT_USER, keyName); + // CWindowPosition position; + CTempOutBufferSpec buffer; + buffer.Init(kWindowPositionHeaderSize); + buffer.WriteUInt32(rect.left); + buffer.WriteUInt32(rect.top); + buffer.WriteUInt32(rect.right); + buffer.WriteUInt32(rect.bottom); + buffer.WriteBool(maximized); + key.SetValue(kPositionValueName, (const Byte *)buffer, kWindowPositionHeaderSize); +} + +bool ReadWindowSize(RECT &rect, bool &maximized) +{ + CSysString keyName = kCUBasePath; + CKey key; + NSynchronization::CCriticalSectionLock lock(g_RegistryOperationsCriticalSection); + if(key.Open(HKEY_CURRENT_USER, keyName, KEY_READ) != ERROR_SUCCESS) + return false; + CByteBuffer buffer; + UInt32 size; + if (key.QueryValue(kPositionValueName, buffer, size) != ERROR_SUCCESS) + return false; + if (size != kWindowPositionHeaderSize) + return false; + CTempInBufferSpec inBuffer; + inBuffer.Size = size; + inBuffer.Buffer = (Byte *)buffer; + inBuffer.Pos = 0; + rect.left = inBuffer.ReadUInt32(); + rect.top = inBuffer.ReadUInt32(); + rect.right = inBuffer.ReadUInt32(); + rect.bottom = inBuffer.ReadUInt32(); + maximized = inBuffer.ReadBool(); + return true; +} + +void SavePanelsInfo(UInt32 numPanels, UInt32 currentPanel, UInt32 splitterPos) +{ + CSysString keyName = kCUBasePath; + CKey key; + NSynchronization::CCriticalSectionLock lock(g_RegistryOperationsCriticalSection); + key.Create(HKEY_CURRENT_USER, keyName); + + CTempOutBufferSpec buffer; + buffer.Init(kPanelsInfoHeaderSize); + buffer.WriteUInt32(numPanels); + buffer.WriteUInt32(currentPanel); + buffer.WriteUInt32(splitterPos); + key.SetValue(kPanelsInfoValueName, (const Byte *)buffer, kPanelsInfoHeaderSize); +} + +bool ReadPanelsInfo(UInt32 &numPanels, UInt32 ¤tPanel, UInt32 &splitterPos) +{ + CSysString keyName = kCUBasePath; + CKey key; + NSynchronization::CCriticalSectionLock lock(g_RegistryOperationsCriticalSection); + if(key.Open(HKEY_CURRENT_USER, keyName, KEY_READ) != ERROR_SUCCESS) + return false; + CByteBuffer buffer; + UInt32 size; + if (key.QueryValue(kPanelsInfoValueName, buffer, size) != ERROR_SUCCESS) + return false; + if (size != kPanelsInfoHeaderSize) + return false; + CTempInBufferSpec inBuffer; + inBuffer.Size = size; + inBuffer.Buffer = (Byte *)buffer; + inBuffer.Pos = 0; + numPanels = inBuffer.ReadUInt32(); + currentPanel = inBuffer.ReadUInt32(); + splitterPos = inBuffer.ReadUInt32(); + return true; +} + +void SaveToolbarsMask(UInt32 toolbarMask) +{ + CKey key; + key.Create(HKEY_CURRENT_USER, kCUBasePath); + key.SetValue(kToolbars, toolbarMask); +} + +static const UInt32 kDefaultToolbarMask = 8 | 4 | 1; + +UInt32 ReadToolbarsMask() +{ + CKey key; + if(key.Open(HKEY_CURRENT_USER, kCUBasePath, KEY_READ) != ERROR_SUCCESS) + return kDefaultToolbarMask; + UInt32 mask; + if (key.QueryValue(kToolbars, mask) != ERROR_SUCCESS) + return kDefaultToolbarMask; + return mask; +} + + +static UString GetPanelPathName(UInt32 panelIndex) +{ + WCHAR panelString[32]; + ConvertUInt64ToString(panelIndex, panelString); + return UString(kPanelPathValueName) + panelString; +} + + +void SavePanelPath(UInt32 panel, const UString &path) +{ + CKey key; + NSynchronization::CCriticalSectionLock lock(g_RegistryOperationsCriticalSection); + key.Create(HKEY_CURRENT_USER, kCUBasePath); + key.SetValue(GetPanelPathName(panel), path); +} + +bool ReadPanelPath(UInt32 panel, UString &path) +{ + CKey key; + NSynchronization::CCriticalSectionLock lock(g_RegistryOperationsCriticalSection); + if(key.Open(HKEY_CURRENT_USER, kCUBasePath, KEY_READ) != ERROR_SUCCESS) + return false; + return (key.QueryValue(GetPanelPathName(panel), path) == ERROR_SUCCESS); +} + +void SaveListMode(const CListMode &listMode) +{ + CKey key; + key.Create(HKEY_CURRENT_USER, kCUBasePath); + UInt32 t = 0; + for (int i = 0; i < 2; i++) + t |= ((listMode.Panels[i]) & 0xFF) << (i * 8); + key.SetValue(kListMode, t); +} + +void ReadListMode(CListMode &listMode) +{ + CKey key; + listMode.Init(); + if(key.Open(HKEY_CURRENT_USER, kCUBasePath, KEY_READ) != ERROR_SUCCESS) + return; + UInt32 t; + if (key.QueryValue(kListMode, t) != ERROR_SUCCESS) + return; + for (int i = 0; i < 2; i++) + { + listMode.Panels[i] = (t & 0xFF); + t >>= 8; + } +} + + +void SaveStringList(LPCTSTR valueName, const UStringVector &folders) +{ + UInt32 sizeInChars = 0; + int i; + for (i = 0; i < folders.Size(); i++) + sizeInChars += folders[i].Length() + 1; + CBuffer<wchar_t> buffer; + buffer.SetCapacity(sizeInChars); + int pos = 0; + for (i = 0; i < folders.Size(); i++) + { + MyStringCopy((wchar_t *)buffer + pos, (const wchar_t *)folders[i]); + pos += folders[i].Length() + 1; + } + CKey key; + NSynchronization::CCriticalSectionLock lock(g_RegistryOperationsCriticalSection); + key.Create(HKEY_CURRENT_USER, kCUBasePath); + key.SetValue(valueName, buffer, sizeInChars * sizeof(wchar_t)); +} + +void ReadStringList(LPCTSTR valueName, UStringVector &folders) +{ + folders.Clear(); + CKey key; + NSynchronization::CCriticalSectionLock lock(g_RegistryOperationsCriticalSection); + if(key.Open(HKEY_CURRENT_USER, kCUBasePath, KEY_READ) != ERROR_SUCCESS) + return; + CByteBuffer buffer; + UInt32 dataSize; + if (key.QueryValue(valueName, buffer, dataSize) != ERROR_SUCCESS) + return; + if (dataSize % sizeof(wchar_t) != 0) + return; + const wchar_t *data = (const wchar_t *)(const Byte *)buffer; + int sizeInChars = dataSize / sizeof(wchar_t); + UString string; + for (int i = 0; i < sizeInChars; i++) + { + wchar_t c = data[i]; + if (c == L'\0') + { + folders.Add(string); + string.Empty(); + } + else + string += c; + } +} + +void SaveFolderHistory(const UStringVector &folders) + { SaveStringList(kFolderHistoryValueName, folders); } +void ReadFolderHistory(UStringVector &folders) + { ReadStringList(kFolderHistoryValueName, folders); } + +void SaveFastFolders(const UStringVector &folders) + { SaveStringList(kFastFoldersValueName, folders); } +void ReadFastFolders(UStringVector &folders) + { ReadStringList(kFastFoldersValueName, folders); } + +void SaveCopyHistory(const UStringVector &folders) + { SaveStringList(kCopyHistoryValueName, folders); } +void ReadCopyHistory(UStringVector &folders) + { ReadStringList(kCopyHistoryValueName, folders); } + +void AddUniqueStringToHeadOfList(UStringVector &list, + const UString &string) +{ + for(int i = 0; i < list.Size();) + if (string.CompareNoCase(list[i]) == 0) + list.Delete(i); + else + i++; + list.Insert(0, string); +} + |