[BROWSEUI] Implement ACLCustomMRU.
[reactos.git] / dll / win32 / browseui / ACLCustomMRU.cpp
1 /*
2 * PROJECT: ReactOS browseui
3 * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
4 * PURPOSE: Custom MRU AutoComplete List
5 * COPYRIGHT: Copyright 2017 Mark Jansen (mark.jansen@reactos.org)
6 */
7
8 #include "precomp.h"
9
10 CACLCustomMRU::CACLCustomMRU()
11 :m_bDirty(false)
12 {
13 }
14
15 CACLCustomMRU::~CACLCustomMRU()
16 {
17 PersistMRU();
18 m_Key.Close();
19 }
20
21 void CACLCustomMRU::PersistMRU()
22 {
23 WCHAR Key[2] = { 0, 0 };
24
25 if (!m_bDirty)
26 return;
27 m_bDirty = false;
28
29 if (m_Key.m_hKey)
30 {
31 m_Key.SetStringValue(L"MRUList", m_MRUList);
32 for (int Index = 0; Index < m_MRUList.GetLength(); ++Index)
33 {
34 Key[0] = Index + 'a';
35 m_Key.SetStringValue(Key, m_MRUData[Index]);
36 }
37 }
38 }
39
40 // *** IACLCustomMRU methods ***
41 HRESULT STDMETHODCALLTYPE CACLCustomMRU::Initialize(LPCWSTR pwszMRURegKey, DWORD dwMax)
42 {
43 LSTATUS Status = m_Key.Create(HKEY_CURRENT_USER, pwszMRURegKey);
44 if (Status != ERROR_SUCCESS)
45 return HRESULT_FROM_WIN32(Status);
46
47 m_MRUData.RemoveAll();
48 dwMax = max(0, dwMax);
49 dwMax = min(29, dwMax);
50 while (dwMax--)
51 m_MRUData.Add(CStringW());
52
53 WCHAR MRUList[40];
54 ULONG nChars = _countof(MRUList);
55
56 Status = m_Key.QueryStringValue(L"MRUList", MRUList, &nChars);
57 if (Status != ERROR_SUCCESS)
58 return S_OK;
59
60 if (nChars > 0 && MRUList[nChars-1] == '\0')
61 nChars--;
62
63 if (nChars > (ULONG)m_MRUData.GetSize())
64 return S_OK;
65
66 for (ULONG n = 0; n < nChars; ++n)
67 {
68 if (MRUList[n] >= 'a' && MRUList[n] <= '}' && m_MRUList.Find(MRUList[n]) < 0)
69 {
70 WCHAR Key[2] = { MRUList[n], NULL };
71 WCHAR Value[MAX_PATH * 2];
72 ULONG nValueChars = _countof(Value);
73
74 m_MRUList += MRUList[n];
75 int Index = MRUList[n] - 'a';
76
77 if (Index < m_MRUData.GetSize())
78 {
79 Status = m_Key.QueryStringValue(Key, Value, &nValueChars);
80 if (Status == ERROR_SUCCESS)
81 {
82 m_MRUData[Index] = CStringW(Value, nValueChars);
83 }
84 }
85 }
86 }
87
88 return S_OK;
89 }
90
91 HRESULT STDMETHODCALLTYPE CACLCustomMRU::AddMRUString(LPCWSTR pwszEntry)
92 {
93 ATLASSERT(m_MRUData.GetSize() <= m_MRUList.GetLength());
94
95 m_bDirty = true;
96
97 CStringW NewElement = pwszEntry;
98 WCHAR Key[2] = { 0, 0 };
99 int Index = m_MRUData.Find(NewElement);
100 if (Index >= 0)
101 {
102 /* Move the key to the front */
103 Key[0] = Index + 'a';
104 m_MRUList.Replace(Key, L"");
105 m_MRUList = Key + m_MRUList;
106 return S_OK;
107 }
108
109 int TotalLen = m_MRUList.GetLength();
110 if (m_MRUData.GetSize() == TotalLen)
111 {
112 /* Find oldest element, move that to the front */
113 Key[0] = m_MRUList[TotalLen-1];
114 m_MRUList = Key + m_MRUList.Left(TotalLen-1);
115 Index = Key[0] - 'a';
116 }
117 else
118 {
119 /* Find the first empty entry */
120 for (Index = 0; Index < m_MRUData.GetSize(); ++Index)
121 {
122 if (m_MRUData[Index].IsEmpty())
123 break;
124 }
125 Key[0] = Index + 'a';
126 m_MRUList = Key + m_MRUList;
127 }
128 m_MRUData[Index] = NewElement;
129
130 PersistMRU();
131 return S_OK;
132 }
133