1
2
3
4
5
6
7
8
9
10
11
12
13 package com.eviware.soapui.support.actions;
14
15 import java.awt.BorderLayout;
16 import java.awt.GridLayout;
17 import java.awt.Toolkit;
18 import java.awt.event.ActionEvent;
19
20 import javax.swing.AbstractAction;
21 import javax.swing.Action;
22 import javax.swing.BorderFactory;
23 import javax.swing.ButtonGroup;
24 import javax.swing.JButton;
25 import javax.swing.JCheckBox;
26 import javax.swing.JComboBox;
27 import javax.swing.JDialog;
28 import javax.swing.JLabel;
29 import javax.swing.JPanel;
30 import javax.swing.JRadioButton;
31
32 import com.eviware.soapui.support.UISupport;
33 import com.jgoodies.forms.builder.ButtonBarBuilder;
34
35 /***
36 * Find-and-Replace dialog for a JXmlTextArea
37 *
38 * @author Ole.Matzura
39 */
40
41 public class FindAndReplaceDialog extends AbstractAction {
42 private final FindAndReplaceable target;
43 private JDialog dialog;
44 private JCheckBox caseCheck;
45 private JRadioButton allButton;
46 private JRadioButton selectedLinesButton;
47 private JRadioButton forwardButton;
48 private JRadioButton backwardButton;
49 private JCheckBox wholeWordCheck;
50 private JButton findButton;
51 private JButton replaceButton;
52 private JButton replaceAllButton;
53 private JComboBox findCombo;
54 private JComboBox replaceCombo;
55 private JCheckBox wrapCheck;
56
57 public FindAndReplaceDialog(FindAndReplaceable target) {
58 super("Find / Replace");
59 putValue(Action.ACCELERATOR_KEY, UISupport.getKeyStroke("F3"));
60 this.target = target;
61 }
62
63 public void actionPerformed(ActionEvent e) {
64 show();
65 }
66
67 public void show() {
68 if (dialog == null)
69 buildDialog();
70
71 replaceCombo.setEnabled(target.isEditable());
72 replaceAllButton.setEnabled(target.isEditable());
73 replaceButton.setEnabled(target.isEditable());
74
75 UISupport.showDialog(dialog);
76 findCombo.getEditor().selectAll();
77 findCombo.requestFocus();
78 }
79
80 private void buildDialog() {
81 dialog = new JDialog(UISupport.getMainFrame(), "Find / Replace", false);
82
83 JPanel panel = new JPanel(new BorderLayout());
84 findCombo = new JComboBox();
85 findCombo.setEditable(true);
86 replaceCombo = new JComboBox();
87 replaceCombo.setEditable(true);
88
89
90 GridLayout gridLayout = new GridLayout(2, 2);
91 gridLayout.setVgap(5);
92 JPanel inputPanel = new JPanel(gridLayout);
93 inputPanel.add(new JLabel("Find:"));
94 inputPanel.add(findCombo);
95 inputPanel.add(new JLabel("Replace with:"));
96 inputPanel.add(replaceCombo);
97 inputPanel.setBorder(BorderFactory.createEmptyBorder(8, 8, 8, 8));
98
99
100 ButtonGroup directionGroup = new ButtonGroup();
101 forwardButton = new JRadioButton("Forward", true);
102 forwardButton.setBorder(BorderFactory.createEmptyBorder(3, 3, 3, 3));
103 directionGroup.add(forwardButton);
104 backwardButton = new JRadioButton("Backward");
105 backwardButton.setBorder(BorderFactory.createEmptyBorder(3, 3, 3, 3));
106 directionGroup.add(backwardButton);
107
108 JPanel directionPanel = new JPanel(new GridLayout(2, 1));
109 directionPanel.add(forwardButton);
110 directionPanel.add(backwardButton);
111 directionPanel.setBorder(BorderFactory.createTitledBorder("Direction"));
112
113
114 ButtonGroup scopeGroup = new ButtonGroup();
115 allButton = new JRadioButton("All", true);
116 allButton.setBorder(BorderFactory.createEmptyBorder(3, 3, 3, 3));
117 selectedLinesButton = new JRadioButton("Selected Lines");
118 selectedLinesButton.setBorder(BorderFactory.createEmptyBorder(3, 3, 3,
119 3));
120 scopeGroup.add(allButton);
121 scopeGroup.add(selectedLinesButton);
122
123 JPanel scopePanel = new JPanel(new GridLayout(2, 1));
124 scopePanel.add(allButton);
125 scopePanel.add(selectedLinesButton);
126 scopePanel.setBorder(BorderFactory.createTitledBorder("Scope"));
127
128
129 caseCheck = new JCheckBox("Case Sensitive");
130 caseCheck.setBorder(BorderFactory.createEmptyBorder(3, 3, 3, 3));
131 wholeWordCheck = new JCheckBox("Whole Word");
132 wholeWordCheck.setBorder(BorderFactory.createEmptyBorder(3, 3, 3, 3));
133 wrapCheck = new JCheckBox("Wrap Search");
134 wrapCheck.setBorder(BorderFactory.createEmptyBorder(3, 3, 3, 3));
135 JPanel optionsPanel = new JPanel(new GridLayout(3, 1));
136 optionsPanel.add(caseCheck);
137 optionsPanel.add(wholeWordCheck);
138 optionsPanel.add(wrapCheck);
139 optionsPanel.setBorder(BorderFactory.createTitledBorder("Options"));
140
141
142 JPanel options = new JPanel(new GridLayout(1, 2));
143
144 JPanel radios = new JPanel(new GridLayout(2, 1));
145 radios.add(directionPanel);
146 radios.add(scopePanel);
147
148 options.add(optionsPanel);
149 options.add(radios);
150 options.setBorder(BorderFactory.createEmptyBorder(0, 8, 0, 8));
151
152
153 ButtonBarBuilder builder = new ButtonBarBuilder();
154 findButton = new JButton(new FindAction());
155 builder.addFixed(findButton);
156 builder.addRelatedGap();
157 replaceButton = new JButton(new ReplaceAction());
158 builder.addFixed(replaceButton);
159 builder.addRelatedGap();
160 replaceAllButton = new JButton(new ReplaceAllAction());
161 builder.addFixed(replaceAllButton);
162 builder.addUnrelatedGap();
163 builder.addFixed(new JButton(new CloseAction()));
164 builder.setBorder(BorderFactory.createEmptyBorder(8, 8, 8, 8));
165
166
167 panel.add(inputPanel, BorderLayout.NORTH);
168 panel.add(options, BorderLayout.CENTER);
169 panel.add(builder.getPanel(), BorderLayout.SOUTH);
170
171 dialog.getContentPane().add(panel);
172 dialog.pack();
173 UISupport.initDialogActions(dialog, null, findButton);
174 }
175
176 private int findNext(int pos, String txt, String value) {
177 int ix = forwardButton.isSelected() ? txt.indexOf(value, pos) : txt
178 .lastIndexOf(value, pos);
179
180 if (wholeWordCheck.isSelected()) {
181 while (ix != -1
182 && (ix > 0 && Character.isLetterOrDigit(txt.charAt(ix - 1)))
183 || (ix < txt.length() - value.length() - 1 && Character
184 .isLetterOrDigit(txt.charAt(ix + value.length())))) {
185 ix = findNext(ix, txt, value);
186 }
187 }
188
189 if (ix == -1 && wrapCheck.isSelected()) {
190 if (forwardButton.isSelected() && pos > 0)
191 return findNext(0, txt, value);
192 else if (backwardButton.isSelected() && pos < txt.length() - 1)
193 return findNext(txt.length() - 1, txt, value);
194 }
195
196 if (selectedLinesButton.isSelected()
197 && (ix < target.getSelectionStart() || ix > target
198 .getSelectionEnd()))
199 ix = -1;
200
201 return ix;
202 }
203
204 private class FindAction extends AbstractAction {
205 public FindAction() {
206 super("Find");
207 }
208
209 public void actionPerformed(ActionEvent e) {
210 int pos = target.getCaretPosition();
211 int selstart = target.getSelectionStart();
212 if (selstart < pos && selstart != -1)
213 pos = selstart;
214
215 String txt = target.getText();
216
217 if( findCombo.getSelectedItem() == null ) {
218 return;
219 }
220 String value = findCombo.getSelectedItem().toString();
221 if (value.length() == 0 || pos == txt.length())
222 return;
223
224 if (!caseCheck.isSelected()) {
225 value = value.toUpperCase();
226 txt = txt.toUpperCase();
227 }
228
229 int ix = findNext(pos, txt, value);
230
231 if (ix != -1) {
232 target.select(ix, ix + value.length());
233
234 for (int c = 0; c < findCombo.getItemCount(); c++) {
235 if (findCombo.getItemAt(c).equals(value)) {
236 findCombo.removeItem(c);
237 break;
238 }
239 }
240
241 findCombo.insertItemAt(value, 0);
242 } else
243 Toolkit.getDefaultToolkit().beep();
244 }
245 }
246
247 private class ReplaceAction extends AbstractAction {
248 public ReplaceAction() {
249 super("Replace");
250 }
251
252 public void actionPerformed(ActionEvent e) {
253 if (target.getSelectedText() == null)
254 return;
255
256 String value = replaceCombo.getSelectedItem().toString();
257 int ix = target.getSelectionStart();
258 target.setSelectedText(value);
259 target.select(ix + value.length(), ix);
260
261 for (int c = 0; c < replaceCombo.getItemCount(); c++) {
262 if (replaceCombo.getItemAt(c).equals(value)) {
263 replaceCombo.removeItem(c);
264 break;
265 }
266 }
267
268 replaceCombo.insertItemAt(value, 0);
269 }
270 }
271
272 private class ReplaceAllAction extends AbstractAction {
273 public ReplaceAllAction() {
274 super("Replace All");
275 }
276
277 public void actionPerformed(ActionEvent e) {
278 int pos = target.getCaretPosition();
279 String txt = target.getText();
280
281 if( findCombo.getSelectedItem() == null ) {
282 return;
283 }
284 String value = findCombo.getSelectedItem().toString();
285 if (value.length() == 0 || txt.length() == 0)
286 return;
287 String newValue = replaceCombo.getSelectedItem().toString();
288
289 if (!caseCheck.isSelected()) {
290 if (newValue.equalsIgnoreCase(value))
291 return;
292 value = value.toUpperCase();
293 txt = txt.toUpperCase();
294 } else if (newValue.equals(value))
295 return;
296
297 int ix = findNext(pos, txt, value);
298 int firstIx = ix;
299 int valueInNewValueIx = !caseCheck.isSelected() ? newValue
300 .toUpperCase().indexOf(value) : newValue.indexOf(value);
301
302 while (ix != -1) {
303 System.out.println("found match at " + ix + ", " + firstIx
304 + ", " + valueInNewValueIx);
305 target.select(ix + value.length(), ix);
306
307 target.setSelectedText(newValue);
308 target.select(ix + newValue.length(), ix);
309
310
311 if (ix < firstIx)
312 firstIx += newValue.length() - value.length();
313
314 txt = target.getText();
315 if (!caseCheck.isSelected()) {
316 txt = txt.toUpperCase();
317 }
318
319 if (forwardButton.isSelected()) {
320 ix = findNext(ix + newValue.length(), txt, value);
321 } else {
322 ix = findNext(ix -1, txt, value);
323 }
324 if (wrapCheck.isSelected() && valueInNewValueIx != -1
325 && ix == firstIx + valueInNewValueIx) {
326 break;
327 }
328 }
329 }
330 }
331
332 private class CloseAction extends AbstractAction {
333 public CloseAction() {
334 super("Close");
335 }
336
337 public void actionPerformed(ActionEvent e) {
338 dialog.setVisible(false);
339 }
340 }
341
342 }