Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/kornelski/7z.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to '7zip/FileManager/ViewSettings.cpp')
-rwxr-xr-x7zip/FileManager/ViewSettings.cpp344
1 files changed, 344 insertions, 0 deletions
diff --git a/7zip/FileManager/ViewSettings.cpp b/7zip/FileManager/ViewSettings.cpp
new file mode 100755
index 00000000..5955bf10
--- /dev/null
+++ b/7zip/FileManager/ViewSettings.cpp
@@ -0,0 +1,344 @@
+// ViewSettings.h
+
+#include "StdAfx.h"
+
+#include "Common/IntToString.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 TCHAR *kPanelPathValueName = TEXT("PanelPath");
+static const TCHAR *kFolderHistoryValueName = TEXT("FolderHistory");
+static const TCHAR *kFastFoldersValueName = TEXT("FolderShortcuts");
+static const TCHAR *kCopyHistoryValueName = TEXT("CopyHistory");
+
+
+#pragma pack( push, PragmaColumnInfoSpec)
+#pragma pack( push, 1)
+
+class CColumnInfoSpec
+{
+ UINT32 PropID;
+ BYTE IsVisible;
+ UINT32 Width;
+public:
+ void GetFromColumnInfo(const CColumnInfo &aSrc)
+ {
+ PropID = aSrc.PropID;
+ IsVisible = aSrc.IsVisible ? 1: 0;
+ Width = aSrc.Width;
+ }
+ void PutColumnInfo(CColumnInfo &aDest)
+ {
+ aDest.PropID = PropID;
+ aDest.IsVisible = (IsVisible != 0);
+ aDest.Width = Width;
+ }
+};
+
+struct CColumnHeader
+{
+ UINT32 Version;
+ // UINT32 SortIndex;
+ UINT32 SortID;
+ BYTE Ascending;
+};
+
+#pragma pack(pop)
+#pragma pack(pop, PragmaColumnInfoSpec)
+
+static const UINT32 kColumnInfoVersion = 0;
+
+static NSynchronization::CCriticalSection g_RegistryOperationsCriticalSection;
+
+void SaveListViewInfo(const CSysString &id, const CListViewInfo &viewInfo)
+{
+ const CObjectVector<CColumnInfo> &columns = viewInfo.Columns;
+ CByteBuffer buffer;
+ UINT32 dataSize = sizeof(CColumnHeader) + sizeof(CColumnInfoSpec) * columns.Size();
+ buffer.SetCapacity(dataSize);
+ BYTE *dataPointer = (BYTE *)buffer;
+ CColumnHeader &columnHeader = *(CColumnHeader *)dataPointer;
+ columnHeader.Version = kColumnInfoVersion;
+
+ // columnHeader.SortIndex = viewInfo.SortIndex;
+ columnHeader.SortID = viewInfo.SortID;
+
+ columnHeader.Ascending = viewInfo.Ascending ? 1 : 0;
+ CColumnInfoSpec *destItems = (CColumnInfoSpec *)(dataPointer + sizeof(CColumnHeader));
+ for(int i = 0; i < columns.Size(); i++)
+ {
+ CColumnInfoSpec &columnInfoSpec = destItems[i];
+ columnInfoSpec.GetFromColumnInfo(columns[i]);
+ }
+ {
+ NSynchronization::CCriticalSectionLock lock(g_RegistryOperationsCriticalSection);
+ CSysString keyName = kCUBasePath;
+ keyName += kKeyNameDelimiter;
+ keyName += kCulumnsKeyName;
+ CKey key;
+ key.Create(HKEY_CURRENT_USER, keyName);
+ key.SetValue(id, dataPointer, dataSize);
+ }
+}
+
+void ReadListViewInfo(const CSysString &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(id, buffer, size) != ERROR_SUCCESS)
+ return;
+ }
+ if (size < sizeof(CColumnHeader))
+ return;
+ BYTE *dataPointer = (BYTE *)buffer;
+ const CColumnHeader &columnHeader = *(CColumnHeader*)dataPointer;
+ if (columnHeader.Version != kColumnInfoVersion)
+ return;
+ viewInfo.Ascending = (columnHeader.Ascending != 0);
+
+ // viewInfo.SortIndex = columnHeader.SortIndex;
+ viewInfo.SortID = columnHeader.SortID;
+
+ size -= sizeof(CColumnHeader);
+ if (size % sizeof(CColumnHeader) != 0)
+ return;
+ int numItems = size / sizeof(CColumnInfoSpec);
+ CColumnInfoSpec *specItems = (CColumnInfoSpec *)(dataPointer + sizeof(CColumnHeader));;
+ columns.Reserve(numItems);
+ for(int i = 0; i < numItems; i++)
+ {
+ CColumnInfo columnInfo;
+ specItems[i].PutColumnInfo(columnInfo);
+ columns.Add(columnInfo);
+ }
+}
+
+#pragma pack( push, PragmaWindowPosition)
+#pragma pack( push, 1)
+
+struct CWindowPosition
+{
+ RECT Rect;
+ UINT32 Maximized;
+};
+
+struct CPanelsInfo
+{
+ UINT32 NumPanels;
+ UINT32 CurrentPanel;
+ UINT32 SplitterPos;
+};
+
+#pragma pack(pop)
+#pragma pack(pop, PragmaWindowPosition)
+
+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;
+ position.Rect = rect;
+ position.Maximized = maximized ? 1: 0;
+ key.SetValue(kPositionValueName, &position, sizeof(position));
+}
+
+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 != sizeof(CWindowPosition))
+ return false;
+ const CWindowPosition &position = *(const CWindowPosition *)(const BYTE *)buffer;
+ rect = position.Rect;
+ maximized = (position.Maximized != 0);
+ 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);
+ CPanelsInfo block;
+ block.NumPanels = numPanels;
+ block.CurrentPanel = currentPanel;
+ block.SplitterPos = splitterPos;
+ key.SetValue(kPanelsInfoValueName, &block, sizeof(block));
+}
+
+bool ReadPanelsInfo(UINT32 &numPanels, UINT32 &currentPanel, 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 != sizeof(CPanelsInfo))
+ return false;
+ const CPanelsInfo &block = *(const CPanelsInfo *)(const BYTE *)buffer;
+ numPanels = block.NumPanels;
+ currentPanel = block.CurrentPanel;
+ splitterPos = block.SplitterPos;
+ return true;
+}
+
+void SaveToolbarsMask(UINT32 toolbarMask)
+{
+ CKey key;
+ key.Create(HKEY_CURRENT_USER, kCUBasePath);
+ key.SetValue(kToolbars, toolbarMask);
+}
+
+static const 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 CSysString GetPanelPathName(UINT32 panelIndex)
+{
+ TCHAR panelString[32];
+ ConvertUINT64ToString(panelIndex, panelString);
+ return CSysString(kPanelPathValueName) + panelString;
+}
+
+
+void SavePanelPath(UINT32 panel, const CSysString &path)
+{
+ CSysString keyName = kCUBasePath;
+ CKey key;
+ NSynchronization::CCriticalSectionLock lock(g_RegistryOperationsCriticalSection);
+ key.Create(HKEY_CURRENT_USER, keyName);
+ key.SetValue(GetPanelPathName(panel), path);
+}
+
+bool ReadPanelPath(UINT32 panel, CSysString &path)
+{
+ CSysString keyName = kCUBasePath;
+ CKey key;
+ NSynchronization::CCriticalSectionLock lock(g_RegistryOperationsCriticalSection);
+ if(key.Open(HKEY_CURRENT_USER, keyName, KEY_READ) != ERROR_SUCCESS)
+ return false;
+ return (key.QueryValue(GetPanelPathName(panel), path) == ERROR_SUCCESS);
+}
+
+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 aPos = 0;
+ for (i = 0; i < folders.Size(); i++)
+ {
+ wcscpy(buffer + aPos, folders[i]);
+ aPos += 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.CollateNoCase(list[i]) == 0)
+ list.Delete(i);
+ else
+ i++;
+ list.Insert(0, string);
+}
+