OSDN Git Service

Improve plugin system (#797) (6)
[winmerge-jp/winmerge-jp.git] / Src / LineFiltersList.cpp
1 /** 
2  * @file  LineFiltersList.cpp
3  *
4  * @brief Implementation for LineFiltersList class.
5  */
6
7 #include "pch.h"
8 #include "LineFiltersList.h"
9 #include <vector>
10 #include <cassert>
11 #include "OptionsMgr.h"
12 #include "UnicodeString.h"
13
14 using std::vector;
15
16 /** @brief Registry key for saving linefilters. */
17 static const TCHAR LineFiltersRegPath[] = _T("LineFilters");
18
19 /**
20  * @brief Default constructor.
21  */
22 LineFiltersList::LineFiltersList()
23 : m_pOptionsMgr(nullptr)
24 {
25 }
26
27 /**
28  * @brief Destructor, empties the list.
29  */
30 LineFiltersList::~LineFiltersList()
31 {
32 }
33
34 /**
35  * @brief Add new filter to the list.
36  * @param [in] filter Filter string to add.
37  * @param [in] enabled Is filter enabled?
38  */
39 void LineFiltersList::AddFilter(const String& filter, bool enabled)
40 {
41         LineFilterItemPtr item(new LineFilterItem());
42         item->enabled = enabled;
43         item->filterStr = filter;
44         m_items.push_back(item);
45 }
46
47 /**
48  * @brief Returns the filter list as one filter string.
49  * This function returns the list of filters as one string that can be
50  * given to regular expression engine as filter. Filter strings in
51  * the list are separated by "|".
52  * @return Filter string.
53  */
54 String LineFiltersList::GetAsString() const
55 {
56         String filter;
57         vector<LineFilterItemPtr>::const_iterator iter = m_items.begin();
58
59         while (iter != m_items.end())
60         {
61                 if ((*iter)->enabled && !(*iter)->filterStr.empty())
62                 {
63                         if (!filter.empty())
64                                 filter += _T("|");
65                         filter += (*iter)->filterStr;
66                 }
67                 ++iter;
68         }
69         return filter;  
70 }
71
72 /**
73  * @brief Return filter from given index.
74  * @param [in] ind Index of filter.
75  * @return Filter item from the index. If the index is beyond table limit,
76  *  return the last item in the list.
77  */
78 const LineFilterItem & LineFiltersList::GetAt(size_t ind) const
79 {
80         if (ind < m_items.size())
81                 return *m_items[ind];
82         else
83                 return *m_items.back();
84 }
85
86 /**
87  * @brief Clone filter list from another list.
88  * This function clones filter list from another list. Current items in the
89  * list are removed and new items added from the given list.
90  * @param [in] list List to clone.
91  */
92 void LineFiltersList::CloneFrom(const LineFiltersList *list)
93 {
94         Empty();
95         size_t count = list->GetCount();
96
97         for (size_t i = 0; i < count; i++)
98         {
99                 const LineFilterItem &item = list->GetAt(i);
100                 AddFilter(item.filterStr, item.enabled);
101         }
102 }
103
104 /**
105  * @brief Compare filter lists.
106  * @param [in] list List to compare.
107  * @return true if lists are identical, false otherwise.
108  */
109 bool LineFiltersList::Compare(const LineFiltersList *list) const
110 {
111         if (list->GetCount() != GetCount())
112                 return false;
113
114         for (size_t i = 0; i < GetCount(); i++)
115         {
116                 const LineFilterItem &item1 = list->GetAt(i);
117                 const LineFilterItem &item2 = GetAt(i);
118
119                 if (item1.enabled != item2.enabled)
120                         return false;
121
122                 if (item1.filterStr != item2.filterStr)
123                         return false;
124         }
125         return true;
126 }
127
128 /**
129  * @brief Read filter list from the options system.
130  * @param [in] pOptionsMgr Pointer to options system.
131  */
132 void LineFiltersList::Initialize(COptionsMgr *pOptionsMgr)
133 {
134         assert(pOptionsMgr != nullptr);
135         String valuename(LineFiltersRegPath);
136
137         m_pOptionsMgr = pOptionsMgr;
138
139         size_t count = m_items.size();
140         valuename += _T("/Values");
141         m_pOptionsMgr->InitOption(valuename, static_cast<int>(count));
142         count = m_pOptionsMgr->GetInt(valuename);
143
144         for (unsigned i = 0; i < count; i++)
145         {
146                 String name = strutils::format(_T("%s/Filter%02u"), LineFiltersRegPath, i);
147                 m_pOptionsMgr->InitOption(name, _T(""));
148                 String filter = m_pOptionsMgr->GetString(name);
149
150                 name = strutils::format(_T("%s/Enabled%02u"), LineFiltersRegPath, i);
151                 m_pOptionsMgr->InitOption(name, (int)true);
152                 int enabled = m_pOptionsMgr->GetInt(name);
153                 bool bEnabled = enabled ? true : false;
154
155                 AddFilter(filter, bEnabled);
156         }
157 }
158
159 /**
160  * @brief Save linefilters to options system.
161  */
162 void LineFiltersList::SaveFilters()
163 {
164         assert(m_pOptionsMgr != nullptr);
165         String valuename(LineFiltersRegPath);
166
167         size_t count = m_items.size();
168         valuename += _T("/Values");
169         m_pOptionsMgr->SaveOption(valuename, static_cast<int>(count));
170
171         for (size_t i = 0; i < count; i++)
172         {
173                 const LineFilterItemPtr& item = m_items[i];
174
175                 String name = strutils::format(_T("%s/Filter%02u"), LineFiltersRegPath, i);
176                 m_pOptionsMgr->InitOption(name, _T(""));
177                 m_pOptionsMgr->SaveOption(name, item->filterStr);
178
179                 name = strutils::format(_T("%s/Enabled%02u"), LineFiltersRegPath, i);
180                 m_pOptionsMgr->InitOption(name, 0);
181                 m_pOptionsMgr->SaveOption(name, (int)item->enabled);
182         }
183
184         // Remove options we don't need anymore
185         // We could have earlier 10 pcs but now we only need 5
186         String filter = strutils::format(_T("%s/Filter%02u"), LineFiltersRegPath, count);
187         int retval1 = m_pOptionsMgr->RemoveOption(filter);
188
189         filter = strutils::format(_T("%s/Enabled%02u"), LineFiltersRegPath, count);
190         int retval2 = m_pOptionsMgr->RemoveOption(filter);
191         
192         while (retval1 == COption::OPT_OK || retval2 == COption::OPT_OK)
193         {
194                 ++count;
195                 filter = strutils::format(_T("%s/Filter%02u"), LineFiltersRegPath, count);
196                 retval1 = m_pOptionsMgr->RemoveOption(filter);
197                 filter = strutils::format(_T("%s/Enabled%02u"), LineFiltersRegPath, count);
198                 retval2 = m_pOptionsMgr->RemoveOption(filter);
199         }
200 }
201
202 /**
203  * @brief Import old-style filter string into new system.
204  * This function imports old-style (2.6.x and earlier) line filters
205  * to new linefilter system. Earlier linefilters were saved as one
206  * string to registry.
207  * @param [in] filters String containing line filters in old-style.
208  */
209 void LineFiltersList::Import(const String& filters)
210 {
211         if (!filters.empty())
212         {
213                 const TCHAR sep[] = _T("\r\n");
214                 TCHAR *p_filters = (TCHAR *)&filters[0];
215                 TCHAR *pfilterNext = nullptr;
216         
217                 // find each regular expression and add to list
218                 TCHAR *token = _tcstok_s(p_filters, sep, &pfilterNext);
219                 while (token != nullptr)
220                 {
221                         AddFilter(token, true);
222                         token = _tcstok_s(nullptr, sep, &pfilterNext);
223                 }
224                 SaveFilters();
225         }
226 }