mirror of
https://github.com/Xevion/easy7zip.git
synced 2025-12-06 15:14:59 -06:00
430 lines
11 KiB
C++
Executable File
430 lines
11 KiB
C++
Executable File
// 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);
|
|
}
|
|
|