xref: /reactos/dll/win32/browseui/ACLCustomMRU.cpp (revision d09998df)
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 
134