OSDN Git Service

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