1 /*
2  * Copyright 2005-2007 Gerald Schmidt.
3  *
4  * This file is part of Xml Copy Editor.
5  *
6  * Xml Copy Editor is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version.
10  *
11  * Xml Copy Editor is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with Xml Copy Editor; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
19  */
20 
21 #include <wx/fdrepdlg.h>
22 #include "findreplacepanel.h"
23 #include "nocasecompare.h"
24 #include "xmlcopyeditor.h"
25 
BEGIN_EVENT_TABLE(FindReplacePanel,wxPanel)26 BEGIN_EVENT_TABLE ( FindReplacePanel, wxPanel )
27 	EVT_BUTTON ( ID_FINDREPLACE_FIND_NEXT, FindReplacePanel::OnFindNext )
28 	EVT_BUTTON ( ID_FINDREPLACE_REPLACE, FindReplacePanel::OnReplace )
29 	EVT_BUTTON ( ID_FINDREPLACE_REPLACE_ALL, FindReplacePanel::OnReplaceAll )
30 #if !wxCHECK_VERSION(2,9,0)
31 	EVT_BUTTON ( ID_FINDREPLACE_CLOSE, FindReplacePanel::OnClose )
32 #else
33 	EVT_CHAR_HOOK ( FindReplacePanel::OnCharHook )
34 #endif
35 	EVT_IDLE ( FindReplacePanel::OnIdle )
36 END_EVENT_TABLE()
37 
38 FindReplacePanel::FindReplacePanel (
39     wxWindow *parentParameter,
40     int id,
41     wxFindReplaceData *findDataParameter,
42     bool isReplacePanel,
43     bool isRegexParameter ) : wxPanel ( parentParameter, id )
44 {
45 	parent = parentParameter;
46 	findData = findDataParameter;
47 	incrementalFind = notFoundSet = false;
48 	isRegex = isRegexParameter;
49 
50 	matchCaseMemory = ( findData->GetFlags() ) & wxFR_MATCHCASE;
51 	regexMemory = isRegex;
52 
53 	label1 = new wxStaticText ( this, wxID_ANY, _ ( "Find:" ) );
54 	spacer1 = new wxStaticText ( this, wxID_ANY, _ ( " " ) );
55 	spacer2 = new wxStaticText ( this, wxID_ANY, _ ( " " ) );
56 
57 	int editWidth = 140;
58 	findEdit = new wxTextCtrl (
59 	    this,
60 	    ID_FINDREPLACE_FIND_NEXT,
61 	    _T ( "" ),
62 	    wxDefaultPosition,
63 	    wxSize ( editWidth, -1 )
64 	);
65 	findEdit->SetValue ( findData->GetFindString() );
66 
67 	label2 = new wxStaticText ( this, wxID_ANY, _ ( "Replace with:" ) );
68 	replaceEdit = new wxTextCtrl (
69 	    this,
70 	    ID_FINDREPLACE_REPLACE,
71 	    _T ( "" ),
72 	    wxDefaultPosition,
73 	    wxSize ( editWidth, -1 ) );
74 	replaceEdit->SetValue ( findData->GetReplaceString() );
75 
76 	findNextButton = new wxButton (
77 	    this,
78 	    ID_FINDREPLACE_FIND_NEXT,
79 	    _ ( "Find &Next" ),
80 	    wxDefaultPosition,
81 	    wxDefaultSize,
82 	    wxBU_EXACTFIT | wxNO_BORDER );
83 	replaceButton = new wxButton (
84 	    this,
85 	    ID_FINDREPLACE_REPLACE,
86 	    _ ( "&Replace" ),
87 	    wxDefaultPosition,
88 	    wxDefaultSize,
89 	    wxBU_EXACTFIT | wxNO_BORDER );
90 	replaceAllButton = new wxButton (
91 	    this,
92 	    ID_FINDREPLACE_REPLACE_ALL,
93 	    _ ( "Replace &All" ),
94 	    wxDefaultPosition,
95 	    wxDefaultSize,
96 	    wxBU_EXACTFIT | wxNO_BORDER );
97 
98 	matchCaseBox = new wxCheckBox (
99 	    this,
100 	    ID_FINDREPLACE_MATCH_CASE,
101 	    _ ( "&Match case" ) );
102 	size_t flags = findData->GetFlags();
103 	matchCaseBox->SetValue ( flags & wxFR_MATCHCASE );
104 
105 	regexBox = new wxCheckBox (
106 	    this,
107 	    ID_FINDREPLACE_REGEX,
108 	    _ ( "Re&gex" ) );
109 
110 	int sizerOffset = 2;
111 	sizer = new wxBoxSizer ( wxHORIZONTAL );
112 	sizer->Add ( label1, 0, wxLEFT | wxRIGHT | wxALIGN_CENTER_VERTICAL, sizerOffset );
113 	sizer->Add ( findEdit, 0, wxLEFT | wxRIGHT | wxALIGN_CENTER_VERTICAL, sizerOffset );
114 
115 	sizer->Add ( label2, 0, wxLEFT | wxRIGHT | wxALIGN_CENTER_VERTICAL, sizerOffset );
116 	sizer->Add ( replaceEdit, 0, wxLEFT | wxRIGHT | wxALIGN_CENTER_VERTICAL, sizerOffset );
117 
118 	sizer->Add ( spacer1, 0, wxLEFT | wxRIGHT | wxALIGN_CENTER_VERTICAL, sizerOffset );
119 	sizer->Add ( findNextButton, 0, wxLEFT | wxRIGHT | wxALIGN_CENTER_VERTICAL, sizerOffset );
120 
121 	sizer->Add ( replaceButton, 0, wxLEFT | wxRIGHT | wxALIGN_CENTER_VERTICAL, sizerOffset );
122 	sizer->Add ( replaceAllButton, 0, wxLEFT | wxRIGHT | wxALIGN_CENTER_VERTICAL, sizerOffset );
123 
124 	sizer->Add ( spacer2, 0, wxLEFT | wxRIGHT | wxALIGN_CENTER_VERTICAL, sizerOffset );
125 	sizer->Add ( matchCaseBox, 0, wxLEFT | wxRIGHT | wxALIGN_CENTER_VERTICAL, sizerOffset );
126 	sizer->Add ( regexBox, 0, wxLEFT | wxRIGHT | wxALIGN_CENTER_VERTICAL, sizerOffset );
127 
128 #if !wxCHECK_VERSION(2,9,0)
129 	wxButton *closeButton = new wxButton (
130 	    this,
131 	    ID_FINDREPLACE_CLOSE,
132 	    _ ( "&Close" ),
133 	    wxDefaultPosition,
134 	    wxDefaultSize,
135 	    wxBU_EXACTFIT | wxNO_BORDER );
136 	sizer->Add ( closeButton, 0, wxLEFT | wxRIGHT | wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL, sizerOffset );
137 #endif
138 
139 	this->SetSizer ( sizer );
140 	sizer->SetSizeHints ( this );
141 	sizer->Layout();
142 	this->SetSize ( -1, findNextButton->GetSize().GetHeight() + 10 );
143 
144 	findEditLength = findEdit->GetValue().Length();
145 
146 	if ( !isReplacePanel )
147 	{
148 		label2->Hide();
149 		replaceEdit->Hide();
150 		replaceButton->Hide();
151 		replaceAllButton->Hide();
152 	}
153 
154 	refresh();
155 }
156 
~FindReplacePanel()157 FindReplacePanel::~FindReplacePanel()
158 {}
159 
OnFindNext(wxCommandEvent & event)160 void FindReplacePanel::OnFindNext ( wxCommandEvent& event )
161 {
162 	findData->SetFindString ( findEdit->GetValue() );
163 	findData->SetReplaceString ( replaceEdit->GetValue() );
164 
165 	incrementalFind = false;
166 	size_t flags = 0;
167 	flags |= wxFR_DOWN;
168 	if ( matchCaseBox->GetValue() )
169 		flags |= wxFR_MATCHCASE;
170 	sendFindEvent ( flags );
171 }
172 
OnReplace(wxCommandEvent & event)173 void FindReplacePanel::OnReplace ( wxCommandEvent& event )
174 {
175 	wxFindDialogEvent replaceEvent ( wxEVT_COMMAND_FIND_REPLACE, 0 );
176 	replaceEvent.SetFlags ( wxFR_DOWN );
177 	replaceEvent.SetFindString ( findEdit->GetValue() );
178 	replaceEvent.SetReplaceString ( replaceEdit->GetValue() );
179 #if wxCHECK_VERSION(2,9,0)
180 	parent->ProcessWindowEvent( replaceEvent );
181 #else
182 	parent->ProcessEvent ( replaceEvent );
183 #endif
184 }
185 
OnReplaceAll(wxCommandEvent & event)186 void FindReplacePanel::OnReplaceAll ( wxCommandEvent& event )
187 {
188 	wxFindDialogEvent replaceAllEvent ( wxEVT_COMMAND_FIND_REPLACE_ALL, 0 );
189 	replaceAllEvent.SetFlags ( wxFR_DOWN );
190 	replaceAllEvent.SetFindString ( findEdit->GetValue() );
191 	replaceAllEvent.SetReplaceString ( replaceEdit->GetValue() );
192 #if wxCHECK_VERSION(2,9,0)
193 	parent->ProcessWindowEvent( replaceAllEvent );
194 #else
195 	parent->ProcessEvent ( replaceAllEvent );
196 #endif
197 }
198 
focusOnFind()199 void FindReplacePanel::focusOnFind()
200 {
201 	findEdit->SelectAll();
202 	findEdit->SetFocus();
203 }
204 
OnIdle(wxIdleEvent & event)205 void FindReplacePanel::OnIdle ( wxIdleEvent& event )
206 {
207 	size_t newLength = findEdit->GetValue().Length();
208 
209 	enableButtons ( ( !newLength ) ? false : true );
210 
211 	bool settingsChanged = false;
212 	if ( matchCaseMemory != matchCaseBox->GetValue() ||
213 	        regexMemory != regexBox->GetValue() )
214 	{
215 		settingsChanged = true;
216 		matchCaseMemory = matchCaseBox->GetValue();
217 		regexMemory = regexBox->GetValue();
218 	}
219 
220 	if ( newLength != findEditLength || settingsChanged )
221 	{
222 		incrementalFind = true;
223 
224 		size_t flags = 0;
225 		flags |= wxFR_DOWN;
226 		if ( matchCaseBox->GetValue() )
227 			flags |= wxFR_MATCHCASE;
228 
229 		sendFindEvent ( flags );
230 		findEditLength = newLength;
231 		findData->SetFlags ( flags );
232 	}
233 }
234 
sendFindEvent(size_t flags)235 void FindReplacePanel::sendFindEvent ( size_t flags )
236 {
237 	wxFindDialogEvent findEvent ( wxEVT_COMMAND_FIND_NEXT, 0 );
238 	findEvent.SetFlags ( flags );
239 	findEvent.SetFindString ( findEdit->GetValue() );
240 
241 	MyFrame *frame = ( MyFrame * ) parent;
242 	frame->setStrictScrolling ( true );
243 #if wxCHECK_VERSION(2,9,0)
244 	frame->ProcessWindowEvent(findEvent);
245 #else
246 	frame->ProcessEvent ( findEvent ); // was parent->
247 #endif
248 	frame->setStrictScrolling ( false );
249 
250 	findData->SetFindString ( findEdit->GetValue() );
251 	findData->SetReplaceString ( replaceEdit->GetValue() );
252 }
253 
getIncrementalFind()254 bool FindReplacePanel::getIncrementalFind()
255 {
256 	return incrementalFind;
257 }
258 
refresh()259 void FindReplacePanel::refresh()
260 {
261 	incrementalFind = false;
262 	findEdit->SetValue ( findData->GetFindString() );
263 	replaceEdit->SetValue ( findData->GetReplaceString() );
264 
265 	size_t flags = findData->GetFlags();
266 
267 	bool matchCase;
268 	matchCase = flags & wxFR_MATCHCASE;
269 
270 	matchCaseBox->SetValue ( matchCase );
271 	matchCaseMemory = matchCase;
272 
273 	regexBox->SetValue ( isRegex );
274 	regexMemory = isRegex;
275 }
276 
setReplaceVisible(bool b)277 void FindReplacePanel::setReplaceVisible ( bool b )
278 {
279 	label2->Show ( b );
280 	replaceEdit->Show ( b );
281 	replaceButton->Show ( b );
282 	replaceAllButton->Show ( b );
283 	sizer->Layout();
284 }
285 
flagNotFound(bool b)286 void FindReplacePanel::flagNotFound ( bool b )
287 {
288 	if ( ( notFoundSet && b ) || ( !notFoundSet && !b ) )
289 		return;
290 
291 	notFoundSet = b;
292 }
293 
getRegex()294 bool FindReplacePanel::getRegex()
295 {
296 	return regexBox->GetValue();
297 }
298 
setMatchCase(bool b)299 void FindReplacePanel::setMatchCase ( bool b )
300 {
301 	matchCaseBox->SetValue ( b );
302 }
303 
setRegex(bool b)304 void FindReplacePanel::setRegex ( bool b )
305 {
306 	regexBox->SetValue ( b );
307 }
308 
enableButtons(bool b)309 void FindReplacePanel::enableButtons ( bool b )
310 {
311 	findNextButton->Enable ( b );
312 	replaceButton->Enable ( b );
313 	replaceAllButton->Enable ( b );
314 }
315 
OnCharHook(wxKeyEvent & event)316 void FindReplacePanel::OnCharHook ( wxKeyEvent& event )
317 {
318 	if ( event.GetKeyCode() == WXK_ESCAPE && event.GetModifiers() == 0 )
319 		( ( MyFrame* ) GetParent() )->closeFindReplacePane();
320 	else
321 		event.Skip();
322 }
323 
OnClose(wxCommandEvent & e)324 void FindReplacePanel::OnClose ( wxCommandEvent & e )
325 {
326 	( ( MyFrame* ) GetParent() )->closeFindReplacePane();
327 }
328