001 package nl.cwi.sen1.gui.plugin.editor;
002
003 import java.awt.BorderLayout;
004 import java.awt.Frame;
005 import java.awt.GridBagConstraints;
006 import java.awt.GridBagLayout;
007 import java.awt.Insets;
008 import java.awt.event.ActionEvent;
009 import java.awt.event.ActionListener;
010 import java.awt.event.KeyEvent;
011 import java.awt.event.WindowAdapter;
012 import java.awt.event.WindowEvent;
013 import java.util.ArrayList;
014 import java.util.List;
015
016 import javax.swing.AbstractAction;
017 import javax.swing.ActionMap;
018 import javax.swing.ButtonGroup;
019 import javax.swing.InputMap;
020 import javax.swing.JButton;
021 import javax.swing.JCheckBox;
022 import javax.swing.JComboBox;
023 import javax.swing.JComponent;
024 import javax.swing.JLabel;
025 import javax.swing.JPanel;
026 import javax.swing.JRadioButton;
027 import javax.swing.KeyStroke;
028
029 public class SearchReplaceDialog extends BaseDialog {
030 private EditorPane editor;
031
032 private JRadioButton backwardRadioButton;
033
034 private JCheckBox caseSensitiveCheck;
035
036 private JButton closeButton;
037
038 private ButtonGroup directionButtonGroup;
039
040 private JPanel directionPanel;
041
042 private JButton findButton;
043
044 private JComboBox findCombo;
045
046 private JLabel findLabel;
047
048 private JRadioButton forwardRadioButton;
049
050 private JPanel jPanel1;
051
052 private JPanel mainPanel;
053
054 private JPanel optionsPanel;
055
056 private JButton replaceAllButton;
057
058 private JButton replaceButton;
059
060 private JButton replaceFindButton;
061
062 private JLabel replaceLabel;
063
064 private JComboBox replaceWithCombo;
065
066 private JCheckBox wrapSearchCheck;
067
068 public String getFindText() {
069 String findText = findCombo.getEditor().getItem().toString();
070 return findText;
071 }
072
073 public void setFindText(String findText) {
074 updateComboBox(findCombo, findText);
075 }
076
077 public boolean getFindDirection() {
078 return forwardRadioButton.isSelected();
079 }
080
081 public boolean isCaseSensitiveSearch() {
082 return caseSensitiveCheck.isSelected();
083 }
084
085 public boolean isWrappedSearch() {
086 return wrapSearchCheck.isSelected();
087 }
088
089 public void setVisible(boolean b) {
090 if (b) {
091 String newSearch = editor.getSelectedText();
092 if (newSearch != null && newSearch.length() != 0) {
093 findCombo.insertItemAt(newSearch, 0);
094 findCombo.setSelectedIndex(0);
095 }
096 findCombo.getEditor().selectAll();
097 findCombo.requestFocus();
098 }
099 super.setVisible(b);
100 }
101
102 public SearchReplaceDialog(EditorPane editor, Frame frame) {
103 super(frame);
104 setTitle("Find/Replace");
105 this.editor = editor;
106 initComponents();
107 forwardRadioButton.setSelected(true);
108 wrapSearchCheck.setSelected(true);
109
110 initBindings();
111 }
112
113 private void initBindings() {
114 InputMap inputMap = this.getRootPane().getInputMap(
115 JComponent.WHEN_IN_FOCUSED_WINDOW);
116 inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), "escape");
117 inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0), "enter");
118
119 ActionMap actionMap = this.getRootPane().getActionMap();
120 actionMap.put("escape", new AbstractAction() {
121 public void actionPerformed(ActionEvent evt) {
122 closeButtonActionPerformed();
123 }
124 });
125 actionMap.put("enter", new AbstractAction() {
126 public void actionPerformed(ActionEvent evt) {
127 System.err.println("Enter action performed");
128 findButtonActionPerformed();
129 }
130 });
131
132 findCombo.getEditor().getEditorComponent().addKeyListener(
133 new java.awt.event.KeyAdapter() {
134 public void keyPressed(java.awt.event.KeyEvent e) {
135 if (e.getKeyCode() == KeyEvent.VK_ENTER) {
136 findButtonActionPerformed();
137 e.consume();
138 }
139 }
140 });
141
142 replaceWithCombo.getEditor().getEditorComponent().addKeyListener(
143 new java.awt.event.KeyAdapter() {
144 public void keyPressed(java.awt.event.KeyEvent e) {
145 if (e.getKeyCode() == KeyEvent.VK_ENTER) {
146 findButtonActionPerformed();
147 e.consume();
148 }
149 }
150 });
151 }
152
153 private void initComponents() {
154 GridBagConstraints gridBagConstraints;
155
156 directionButtonGroup = new ButtonGroup();
157 jPanel1 = new JPanel();
158 findButton = new JButton();
159 replaceFindButton = new JButton();
160 replaceButton = new JButton();
161 replaceAllButton = new JButton();
162 closeButton = new JButton();
163 mainPanel = new JPanel();
164 findLabel = new JLabel();
165 replaceLabel = new JLabel();
166 findCombo = new JComboBox();
167 replaceWithCombo = new JComboBox();
168 directionPanel = new JPanel();
169 forwardRadioButton = new JRadioButton();
170 backwardRadioButton = new JRadioButton();
171 optionsPanel = new JPanel();
172 caseSensitiveCheck = new JCheckBox();
173 wrapSearchCheck = new JCheckBox();
174
175 addWindowListener(new WindowAdapter() {
176 public void windowClosing(WindowEvent evt) {
177 closeDialog();
178 }
179 });
180
181 jPanel1.setLayout(new GridBagLayout());
182
183 findButton.setMnemonic('n');
184 findButton.setText("Find");
185 findButton.addActionListener(new ActionListener() {
186 public void actionPerformed(ActionEvent evt) {
187 findButtonActionPerformed();
188 }
189 });
190
191 gridBagConstraints = new GridBagConstraints();
192 gridBagConstraints.fill = GridBagConstraints.HORIZONTAL;
193 gridBagConstraints.anchor = GridBagConstraints.EAST;
194 gridBagConstraints.weightx = 0.5;
195 gridBagConstraints.insets = new Insets(2, 2, 2, 2);
196 jPanel1.add(findButton, gridBagConstraints);
197
198 replaceFindButton.setMnemonic('d');
199 replaceFindButton.setText("Replace/Find");
200 replaceFindButton.addActionListener(new ActionListener() {
201 public void actionPerformed(ActionEvent evt) {
202 replaceFindButtonActionPerformed();
203 }
204 });
205
206 gridBagConstraints = new GridBagConstraints();
207 gridBagConstraints.fill = GridBagConstraints.HORIZONTAL;
208 gridBagConstraints.anchor = GridBagConstraints.WEST;
209 gridBagConstraints.weightx = 0.5;
210 gridBagConstraints.insets = new Insets(2, 2, 2, 2);
211 jPanel1.add(replaceFindButton, gridBagConstraints);
212
213 replaceButton.setMnemonic('R');
214 replaceButton.setText("Replace");
215 replaceButton.addActionListener(new ActionListener() {
216 public void actionPerformed(ActionEvent evt) {
217 replaceButtonActionPerformed();
218 }
219 });
220
221 gridBagConstraints = new GridBagConstraints();
222 gridBagConstraints.gridx = 0;
223 gridBagConstraints.gridy = 1;
224 gridBagConstraints.fill = GridBagConstraints.HORIZONTAL;
225 gridBagConstraints.anchor = GridBagConstraints.EAST;
226 gridBagConstraints.weightx = 0.5;
227 gridBagConstraints.insets = new Insets(2, 2, 2, 2);
228 jPanel1.add(replaceButton, gridBagConstraints);
229
230 replaceAllButton.setMnemonic('A');
231 replaceAllButton.setText("Replace All");
232 replaceAllButton.addActionListener(new ActionListener() {
233 public void actionPerformed(ActionEvent evt) {
234 replaceAllButtonActionPerformed();
235 }
236 });
237
238 gridBagConstraints = new GridBagConstraints();
239 gridBagConstraints.gridx = 1;
240 gridBagConstraints.gridy = 1;
241 gridBagConstraints.fill = GridBagConstraints.HORIZONTAL;
242 gridBagConstraints.anchor = GridBagConstraints.WEST;
243 gridBagConstraints.weightx = 0.5;
244 gridBagConstraints.insets = new Insets(2, 2, 2, 2);
245 jPanel1.add(replaceAllButton, gridBagConstraints);
246
247 closeButton.setText("Close");
248 closeButton.addActionListener(new ActionListener() {
249 public void actionPerformed(ActionEvent evt) {
250 closeButtonActionPerformed();
251 }
252 });
253
254 gridBagConstraints = new GridBagConstraints();
255 gridBagConstraints.gridx = 1;
256 gridBagConstraints.gridy = 2;
257 gridBagConstraints.anchor = GridBagConstraints.NORTHEAST;
258 gridBagConstraints.insets = new Insets(2, 2, 2, 2);
259 jPanel1.add(closeButton, gridBagConstraints);
260
261 getContentPane().add(jPanel1, BorderLayout.SOUTH);
262
263 mainPanel.setLayout(new GridBagLayout());
264
265 findLabel.setText("Find:");
266 gridBagConstraints = new GridBagConstraints();
267 gridBagConstraints.anchor = GridBagConstraints.EAST;
268 gridBagConstraints.insets = new Insets(2, 0, 2, 2);
269 mainPanel.add(findLabel, gridBagConstraints);
270
271 replaceLabel.setText("Replace with:");
272 gridBagConstraints = new GridBagConstraints();
273 gridBagConstraints.gridx = 0;
274 gridBagConstraints.gridy = 1;
275 gridBagConstraints.anchor = GridBagConstraints.EAST;
276 gridBagConstraints.insets = new Insets(2, 0, 2, 2);
277 mainPanel.add(replaceLabel, gridBagConstraints);
278
279 findCombo.setEditable(true);
280 gridBagConstraints = new GridBagConstraints();
281 gridBagConstraints.fill = GridBagConstraints.HORIZONTAL;
282 gridBagConstraints.anchor = GridBagConstraints.WEST;
283 gridBagConstraints.weightx = 1.0;
284 gridBagConstraints.insets = new Insets(2, 2, 2, 2);
285 mainPanel.add(findCombo, gridBagConstraints);
286
287 replaceWithCombo.setEditable(true);
288 gridBagConstraints = new GridBagConstraints();
289 gridBagConstraints.gridx = 1;
290 gridBagConstraints.gridy = 1;
291 gridBagConstraints.fill = GridBagConstraints.HORIZONTAL;
292 gridBagConstraints.anchor = GridBagConstraints.WEST;
293 gridBagConstraints.weightx = 1.0;
294 gridBagConstraints.insets = new Insets(2, 2, 2, 2);
295 mainPanel.add(replaceWithCombo, gridBagConstraints);
296
297 directionPanel.setLayout(new GridBagLayout());
298
299 directionPanel.setBorder(new javax.swing.border.TitledBorder(
300 "Direction"));
301 forwardRadioButton.setText("Forward");
302 directionButtonGroup.add(forwardRadioButton);
303 gridBagConstraints = new GridBagConstraints();
304 gridBagConstraints.anchor = GridBagConstraints.WEST;
305 gridBagConstraints.weightx = 0.5;
306 directionPanel.add(forwardRadioButton, gridBagConstraints);
307
308 backwardRadioButton.setText("Backward");
309 directionButtonGroup.add(backwardRadioButton);
310 gridBagConstraints = new GridBagConstraints();
311 gridBagConstraints.anchor = GridBagConstraints.EAST;
312 gridBagConstraints.weightx = 0.5;
313 directionPanel.add(backwardRadioButton, gridBagConstraints);
314
315 gridBagConstraints = new GridBagConstraints();
316 gridBagConstraints.gridx = 0;
317 gridBagConstraints.gridy = 2;
318 gridBagConstraints.gridwidth = 2;
319 gridBagConstraints.fill = GridBagConstraints.HORIZONTAL;
320 gridBagConstraints.insets = new Insets(2, 2, 2, 2);
321 mainPanel.add(directionPanel, gridBagConstraints);
322
323 optionsPanel.setLayout(new GridBagLayout());
324
325 optionsPanel.setBorder(new javax.swing.border.TitledBorder("Options"));
326 caseSensitiveCheck.setText("Case Sensitive");
327 gridBagConstraints = new GridBagConstraints();
328 gridBagConstraints.anchor = GridBagConstraints.WEST;
329 gridBagConstraints.weightx = 0.5;
330 optionsPanel.add(caseSensitiveCheck, gridBagConstraints);
331
332 wrapSearchCheck.setText("Wrap Search");
333 gridBagConstraints = new GridBagConstraints();
334 gridBagConstraints.anchor = GridBagConstraints.EAST;
335 gridBagConstraints.weightx = 0.5;
336 optionsPanel.add(wrapSearchCheck, gridBagConstraints);
337
338 gridBagConstraints = new GridBagConstraints();
339 gridBagConstraints.gridx = 0;
340 gridBagConstraints.gridy = 3;
341 gridBagConstraints.gridwidth = 2;
342 gridBagConstraints.fill = GridBagConstraints.HORIZONTAL;
343 gridBagConstraints.insets = new Insets(2, 2, 2, 2);
344 mainPanel.add(optionsPanel, gridBagConstraints);
345
346 getContentPane().add(mainPanel, BorderLayout.CENTER);
347
348 pack();
349 }
350
351 private void closeButtonActionPerformed() {
352 this.setVisible(false);
353 }
354
355 private void replaceAllButtonActionPerformed() {
356 String textToFind = getFindText();
357 updateComboBox(findCombo, textToFind);
358 String textToReplaceWith = (String) replaceWithCombo.getSelectedItem();
359 updateComboBox(replaceWithCombo, textToReplaceWith);
360 editor.replaceAll(textToFind, textToReplaceWith,
361 !isCaseSensitiveSearch());
362 }
363
364 private void replaceButtonActionPerformed() {
365 String textToFind = getFindText();
366 String selectedText = editor.getSelectedText();
367
368 if ((isCaseSensitiveSearch() && textToFind.equals(selectedText))
369 || (!isCaseSensitiveSearch() && textToFind
370 .equalsIgnoreCase(selectedText))) {
371 String textToReplaceWith = (String) replaceWithCombo
372 .getSelectedItem();
373
374 if (textToReplaceWith != null) {
375 updateComboBox(replaceWithCombo, textToReplaceWith);
376 int selectionStart = editor.getSelectionStart();
377 editor.replaceSelection(textToReplaceWith);
378 editor.setSelectionStart(selectionStart);
379 editor.setSelectionEnd(selectionStart
380 + textToReplaceWith.length());
381 }
382 }
383 }
384
385 private void findButtonActionPerformed() {
386 String textToFind = getFindText();
387 updateComboBox(findCombo, textToFind);
388 editor.find(textToFind, !isCaseSensitiveSearch(), isWrappedSearch(),
389 getFindDirection());
390 }
391
392 private void replaceFindButtonActionPerformed() {
393 replaceButtonActionPerformed();
394 findButtonActionPerformed();
395 }
396
397 private void updateComboBox(JComboBox combo, String latestEntry) {
398 int numItems = combo.getItemCount();
399 List<String> items = new ArrayList<String>();
400 for (int i = 0; i < numItems; i++) {
401 String current = (String) combo.getItemAt(i);
402 if ((current != null) && !current.equals(latestEntry)) {
403 items.add(current);
404 }
405 }
406 numItems = items.size();
407 combo.removeAllItems();
408 combo.addItem(latestEntry);
409 for (int i = 0; i < numItems; i++) {
410 combo.addItem(items.get(i));
411 }
412 }
413 }