OSDN Git Service

Fix issue #2046: Folder compare omits unique folders from results if they contain...
[winmerge-jp/winmerge-jp.git] / Src / SubstitutionFiltersDlg.cpp
1 /**
2  *  @file SubstitutionFiltersDlg.cpp
3  *
4  *  @brief Implementation of Substitution Filters dialog
5  */ 
6
7 #include "stdafx.h"
8 #include "SubstitutionFiltersList.h"
9 #include "Merge.h"
10 #include "SubstitutionFiltersDlg.h"
11 #include "Constants.h"
12 #include <Poco/Exception.h>
13
14 #ifdef _DEBUG
15 #define new DEBUG_NEW
16 #endif
17
18 /////////////////////////////////////////////////////////////////////////////
19 // CPropLineFilter property page
20
21 IMPLEMENT_DYNAMIC(SubstitutionFiltersDlg, CTrPropertyPage)
22
23 /**
24  * @brief Constructor.
25  */
26 SubstitutionFiltersDlg::SubstitutionFiltersDlg()
27         : CTrPropertyPage(SubstitutionFiltersDlg::IDD)
28         , m_pSubstitutionFiltersList(nullptr)
29 {
30         //{{AFX_DATA_INIT(SubstitutionFiltersFiltersDlg)
31         m_bEnabled = false;
32         //}}AFX_DATA_INIT
33         m_strCaption = theApp.LoadDialogCaption(m_lpszTemplateName).c_str();
34         m_psp.pszTitle = m_strCaption;
35         m_psp.dwFlags |= PSP_USETITLE;
36         m_psp.hIcon = AfxGetApp()->LoadIcon(IDI_SUBSTITUTIONFILTER);
37         m_psp.dwFlags |= PSP_USEHICON;
38 }
39
40 void SubstitutionFiltersDlg::DoDataExchange(CDataExchange* pDX)
41 {
42         CPropertyPage::DoDataExchange(pDX);
43         //{{AFX_DATA_MAP(SubstitutionFiltersFiltersDlg)
44         DDX_Check(pDX, IDC_IGNORED_SUSBSTITUTIONS_ENABLED, m_bEnabled);
45         DDX_Control(pDX, IDC_SUBSTITUTION_FILTERS, m_listFilters);
46         //}}AFX_DATA_MAP
47 }
48
49 BEGIN_MESSAGE_MAP(SubstitutionFiltersDlg, CTrPropertyPage)
50         //{{AFX_MSG_MAP(SubstitutionFiltersFiltersDlg)
51         ON_COMMAND(ID_HELP, OnHelp)
52         ON_BN_CLICKED(IDC_LFILTER_ADDBTN, OnBnClickedAddBtn)
53         ON_BN_CLICKED(IDC_LFILTER_CLEARBTN, OnBnClickedClearBtn)
54         ON_BN_CLICKED(IDC_LFILTER_REMOVEBTN, OnBnClickedRemovebtn)
55         //}}AFX_MSG_MAP
56 END_MESSAGE_MAP()
57
58
59 /////////////////////////////////////////////////////////////////////////////
60 // CPropLineFilter message handlers
61
62 /**
63  * @brief Initialize the dialog.
64  */
65 BOOL SubstitutionFiltersDlg::OnInitDialog()
66 {
67         m_bEnabled = m_pSubstitutionFiltersList->GetEnabled();
68         CTrPropertyPage::OnInitDialog();
69
70         InitList();
71         
72         return TRUE;  // return TRUE unless you set the focus to a control
73                       // EXCEPTION: OCX Property Pages should return FALSE
74 }
75
76 static CString RemoveMnemonic(const String& text)
77 {
78         Poco::RegularExpression re("\\(&.\\)|&|:");
79         std::string textu8 = ucr::toUTF8(text);
80         re.subst(textu8, "", Poco::RegularExpression::RE_GLOBAL);
81         return ucr::toTString(textu8).c_str();
82 }
83
84 void SubstitutionFiltersDlg::InitList()
85 {
86         m_listFilters.SetExtendedStyle(LVS_EX_CHECKBOXES | LVS_EX_FULLROWSELECT | LVS_EX_INFOTIP);
87
88         const int lpx = CClientDC(this).GetDeviceCaps(LOGPIXELSX);
89         auto pointToPixel = [lpx](int point) { return MulDiv(point, lpx, 72); };
90
91         m_listFilters.InsertColumn(0, RemoveMnemonic(_("Fi&nd what:")), LVCFMT_LEFT, pointToPixel(150));
92         m_listFilters.InsertColumn(1, RemoveMnemonic(_("Re&place with:")), LVCFMT_LEFT, pointToPixel(150));
93         m_listFilters.InsertColumn(2, RemoveMnemonic(_("Regular &expression")), LVCFMT_LEFT, pointToPixel(120));
94         m_listFilters.InsertColumn(3, RemoveMnemonic(_("Match &case")), LVCFMT_LEFT, pointToPixel(120));
95         m_listFilters.InsertColumn(4, RemoveMnemonic(_("Match &whole word only")), LVCFMT_LEFT, pointToPixel(120));
96         m_listFilters.SetBooleanValueColumn(2);
97         m_listFilters.SetBooleanValueColumn(3);
98         m_listFilters.SetBooleanValueColumn(4);
99
100         if (m_pSubstitutionFiltersList)
101         {
102                 for (int i = 0; i < (int)m_pSubstitutionFiltersList->GetCount(); i++)
103                 {
104                         const SubstitutionFilter& item = m_pSubstitutionFiltersList->GetAt(i);
105                         m_listFilters.InsertItem(i, item.pattern.c_str());
106                         m_listFilters.SetItemText(i, 1, item.replacement.c_str());
107                         m_listFilters.SetItemBooleanValue(i, 2, item.useRegExp);
108                         m_listFilters.SetItemBooleanValue(i, 3, item.caseSensitive);
109                         m_listFilters.SetItemBooleanValue(i, 4, item.matchWholeWordOnly);
110                         m_listFilters.SetCheck(i, item.enabled);
111                 }
112         }
113 }
114
115 /**
116  * @brief Open help from mainframe when user presses F1.
117  */
118 void SubstitutionFiltersDlg::OnHelp()
119 {
120         theApp.ShowHelp(FilterHelpLocation);
121 }
122
123 /**
124  * @brief Called when Add-button is clicked.
125  */
126 void SubstitutionFiltersDlg::OnBnClickedAddBtn()
127 {
128         int num = m_listFilters.GetItemCount();
129         int ind = m_listFilters.InsertItem(num, _("<Edit here>").c_str());
130         m_listFilters.SetItemText(num, 1, _("<Edit here>").c_str());
131         m_listFilters.SetItemBooleanValue(num, 2, false);
132         m_listFilters.SetItemBooleanValue(num, 3, false);
133         m_listFilters.SetItemBooleanValue(num, 4, false);
134         m_listFilters.SetCheck(num);
135
136         if (ind >= -1)
137         {
138                 m_listFilters.SetItemState(ind, LVIS_SELECTED, LVIS_SELECTED);
139                 m_listFilters.EnsureVisible(ind, FALSE);
140         }
141 }
142
143 /**
144  * @brief Called when Clear-button is clicked.
145  */
146 void SubstitutionFiltersDlg::OnBnClickedClearBtn()
147 {
148         m_listFilters.DeleteAllItems();
149 }
150
151 /**
152  * @brief Save filters to list when exiting the dialog.
153  */
154 BOOL SubstitutionFiltersDlg::OnApply()
155 {
156         m_pSubstitutionFiltersList->Empty();
157
158         for (int i = 0; i < m_listFilters.GetItemCount(); i++)
159         {
160                 String symbolBeforeRename = m_listFilters.GetItemText(i, 0);
161                 String symbolAfterRename = m_listFilters.GetItemText(i, 1);
162                 bool useRegExp = m_listFilters.GetItemBooleanValue(i, 2);
163                 bool caseSensitive = m_listFilters.GetItemBooleanValue(i, 3);
164                 bool matchWholeWordOnly = m_listFilters.GetItemBooleanValue(i, 4);
165                 if (useRegExp)
166                         matchWholeWordOnly = false;
167                 bool enabled = !!m_listFilters.GetCheck(i);
168                 m_pSubstitutionFiltersList->Add(symbolBeforeRename, symbolAfterRename,
169                         useRegExp, caseSensitive, matchWholeWordOnly, enabled);
170         }
171
172         // Test
173         try
174         {
175                 m_pSubstitutionFiltersList->MakeSubstitutionList(true);
176         }
177         catch (Poco::RegularExpressionException& e)
178         {
179                 AfxMessageBox(ucr::toTString(e.message()).c_str(), MB_OK | MB_ICONEXCLAMATION);
180                 return FALSE;
181         }
182
183         m_pSubstitutionFiltersList->SetEnabled(m_bEnabled);
184         AfxGetApp()->WriteProfileInt(_T("Settings"), _T("FilterStartPage"), GetParentSheet()->GetActiveIndex());
185         return TRUE;
186 }
187
188 /**
189  * @brief Sets external filter list.
190  * @param [in] list External filter list.
191  */
192 void SubstitutionFiltersDlg::SetList(SubstitutionFiltersList *list)
193 {
194         m_pSubstitutionFiltersList = list;
195 }
196
197 /**
198  * @brief Called when Remove button is clicked.
199  */
200 void SubstitutionFiltersDlg::OnBnClickedRemovebtn()
201 {
202         int sel = m_listFilters.GetNextItem(-1, LVNI_SELECTED);
203         if (sel != -1)
204         {
205                 m_listFilters.DeleteItem(sel);
206         }
207
208         int newSel = min(m_listFilters.GetItemCount() - 1, sel);
209         if (newSel >= -1)
210         {
211                 m_listFilters.SetItemState(newSel, LVIS_SELECTED, LVIS_SELECTED);
212                 bool bPartialOk = false;
213                 m_listFilters.EnsureVisible(newSel, bPartialOk);
214         }
215 }