001: /*
002: * ReplacePanel.java
003: *
004: * This file is part of SQL Workbench/J, http://www.sql-workbench.net
005: *
006: * Copyright 2002-2008, Thomas Kellerer
007: * No part of this code maybe reused without the permission of the author
008: *
009: * To contact the author please send an email to: support@sql-workbench.net
010: *
011: */
012: package workbench.gui.components;
013:
014: import java.awt.Component;
015: import java.awt.Dialog;
016: import java.awt.EventQueue;
017: import java.awt.Frame;
018: import java.awt.Window;
019: import java.awt.event.ActionListener;
020: import java.awt.event.WindowListener;
021: import javax.swing.ActionMap;
022: import javax.swing.InputMap;
023: import javax.swing.JComponent;
024: import javax.swing.JDialog;
025: import workbench.gui.WbSwingUtilities;
026: import workbench.gui.actions.EscAction;
027: import workbench.interfaces.Replaceable;
028: import workbench.resource.ResourceMgr;
029: import workbench.resource.Settings;
030: import workbench.util.ExceptionUtil;
031: import workbench.util.StringUtil;
032:
033: /**
034: *
035: * @author support@sql-workbench.net
036: */
037: public class ReplacePanel extends javax.swing.JPanel implements
038: ActionListener, WindowListener {
039: private String settingsKey;
040: private String caseProperty;
041: private String wordProperty;
042: private String selectedProperty;
043: private String regexProperty;
044: private String criteriaProperty;
045: private String replacementProperty;
046:
047: private Replaceable client;
048: private int lastPos = -1;
049: private JDialog dialog;
050: private EscAction escAction;
051:
052: public ReplacePanel(Replaceable aClient) {
053: this (aClient, "workbench.sql.replace", null);
054: }
055:
056: public ReplacePanel(Replaceable aClient, String key,
057: String selectedText) {
058: initComponents();
059: this .client = aClient;
060: settingsKey = key;
061: caseProperty = settingsKey + ".ignoreCase";
062: wordProperty = settingsKey + ".wholeWord";
063: selectedProperty = settingsKey + ".selectedText";
064: regexProperty = settingsKey + ".useRegEx";
065: criteriaProperty = settingsKey + ".criteria";
066: replacementProperty = settingsKey + ".replacement";
067:
068: WbTraversalPolicy policy = new WbTraversalPolicy();
069: policy.addComponent(criteriaTextField);
070: policy.addComponent(this .replaceValueTextField);
071: policy.addComponent(this .ignoreCaseCheckBox);
072: policy.addComponent(this .wordsOnlyCheckBox);
073: policy.addComponent(this .selectedTextCheckBox);
074: policy.addComponent(this .findButton);
075: policy.addComponent(this .replaceNextButton);
076: policy.addComponent(this .replaceAllButton);
077: policy.addComponent(this .closeButton);
078: policy.setDefaultComponent(criteriaTextField);
079: this .setFocusTraversalPolicy(policy);
080:
081: this .findButton.addActionListener(this );
082: this .replaceNextButton.addActionListener(this );
083: this .replaceAllButton.addActionListener(this );
084: this .closeButton.addActionListener(this );
085: this .findNextButton.addActionListener(this );
086:
087: this .replaceNextButton.setEnabled(false);
088: this .findNextButton.setEnabled(false);
089:
090: this .criteriaTextField
091: .addMouseListener(new TextComponentMouseListener());
092: this .replaceValueTextField
093: .addMouseListener(new TextComponentMouseListener());
094: if (selectedText != null) {
095: this .selectedTextCheckBox.setText(selectedText);
096: }
097:
098: this .restoreSettings();
099: }
100:
101: /** This method is called from within the constructor to
102: * initialize the form.
103: * WARNING: Do NOT modify this code. The content of this method is
104: * always regenerated by the Form Editor.
105: */
106: // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
107: private void initComponents() {
108: java.awt.GridBagConstraints gridBagConstraints;
109:
110: criteriaLabel = new javax.swing.JLabel();
111: criteriaTextField = new javax.swing.JTextField();
112: replaceValueTextField = new javax.swing.JTextField();
113: ignoreCaseCheckBox = new javax.swing.JCheckBox();
114: wordsOnlyCheckBox = new javax.swing.JCheckBox();
115: replaceLabel = new javax.swing.JLabel();
116: spacerPanel = new javax.swing.JPanel();
117: findButton = new WbButton();
118: replaceNextButton = new WbButton();
119: replaceAllButton = new WbButton();
120: closeButton = new WbButton();
121: selectedTextCheckBox = new javax.swing.JCheckBox();
122: useRegexCheckBox = new javax.swing.JCheckBox();
123: findNextButton = new WbButton();
124:
125: setLayout(new java.awt.GridBagLayout());
126:
127: criteriaLabel.setLabelFor(criteriaTextField);
128: criteriaLabel.setText(ResourceMgr
129: .getString("LblSearchCriteria"));
130: gridBagConstraints = new java.awt.GridBagConstraints();
131: gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
132: gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
133: gridBagConstraints.insets = new java.awt.Insets(5, 5, 0, 0);
134: add(criteriaLabel, gridBagConstraints);
135:
136: criteriaTextField.setColumns(30);
137: criteriaTextField.setName("searchtext"); // NOI18N
138: gridBagConstraints = new java.awt.GridBagConstraints();
139: gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
140: gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
141: gridBagConstraints.weightx = 1.0;
142: gridBagConstraints.insets = new java.awt.Insets(5, 4, 0, 5);
143: add(criteriaTextField, gridBagConstraints);
144:
145: replaceValueTextField.setColumns(30);
146: replaceValueTextField.setName("replacetext"); // NOI18N
147: replaceValueTextField
148: .addFocusListener(new java.awt.event.FocusAdapter() {
149: public void focusGained(
150: java.awt.event.FocusEvent evt) {
151: replaceValueTextFieldFocusGained(evt);
152: }
153: });
154: gridBagConstraints = new java.awt.GridBagConstraints();
155: gridBagConstraints.gridx = 1;
156: gridBagConstraints.gridy = 1;
157: gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
158: gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
159: gridBagConstraints.insets = new java.awt.Insets(0, 4, 0, 5);
160: add(replaceValueTextField, gridBagConstraints);
161:
162: ignoreCaseCheckBox.setText(ResourceMgr
163: .getString("LblSearchIgnoreCase"));
164: ignoreCaseCheckBox.setToolTipText(ResourceMgr
165: .getDescription("LblSearchIgnoreCase"));
166: ignoreCaseCheckBox.setName("ignorecase"); // NOI18N
167: gridBagConstraints = new java.awt.GridBagConstraints();
168: gridBagConstraints.gridx = 0;
169: gridBagConstraints.gridy = 2;
170: gridBagConstraints.gridwidth = 2;
171: gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
172: gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
173: gridBagConstraints.insets = new java.awt.Insets(0, 5, 0, 5);
174: add(ignoreCaseCheckBox, gridBagConstraints);
175:
176: wordsOnlyCheckBox.setText(ResourceMgr
177: .getString("LblSearchWordsOnly"));
178: wordsOnlyCheckBox.setToolTipText(ResourceMgr
179: .getDescription("LblSearchWordsOnly"));
180: wordsOnlyCheckBox.setName("wordsonly"); // NOI18N
181: gridBagConstraints = new java.awt.GridBagConstraints();
182: gridBagConstraints.gridx = 0;
183: gridBagConstraints.gridy = 3;
184: gridBagConstraints.gridwidth = 2;
185: gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
186: gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
187: gridBagConstraints.insets = new java.awt.Insets(0, 5, 0, 5);
188: add(wordsOnlyCheckBox, gridBagConstraints);
189:
190: replaceLabel.setLabelFor(replaceValueTextField);
191: replaceLabel.setText(ResourceMgr
192: .getString("LblReplaceNewValue"));
193: gridBagConstraints = new java.awt.GridBagConstraints();
194: gridBagConstraints.gridx = 0;
195: gridBagConstraints.gridy = 1;
196: gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
197: gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
198: gridBagConstraints.insets = new java.awt.Insets(0, 5, 0, 0);
199: add(replaceLabel, gridBagConstraints);
200: gridBagConstraints = new java.awt.GridBagConstraints();
201: gridBagConstraints.gridx = 2;
202: gridBagConstraints.gridy = 6;
203: gridBagConstraints.weighty = 1.0;
204: add(spacerPanel, gridBagConstraints);
205:
206: findButton.setText(ResourceMgr.getString("LblFindNow"));
207: findButton.setToolTipText(ResourceMgr
208: .getDescription("LblFindNow"));
209: findButton.setName("findbutton"); // NOI18N
210: gridBagConstraints = new java.awt.GridBagConstraints();
211: gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
212: gridBagConstraints.anchor = java.awt.GridBagConstraints.EAST;
213: gridBagConstraints.insets = new java.awt.Insets(5, 0, 0, 5);
214: add(findButton, gridBagConstraints);
215:
216: replaceNextButton.setText(ResourceMgr
217: .getString("LblReplaceNext"));
218: replaceNextButton.setToolTipText(ResourceMgr
219: .getDescription("LblReplaceNext"));
220: replaceNextButton.setName("replacenextbutton"); // NOI18N
221: gridBagConstraints = new java.awt.GridBagConstraints();
222: gridBagConstraints.gridx = 2;
223: gridBagConstraints.gridy = 2;
224: gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
225: gridBagConstraints.anchor = java.awt.GridBagConstraints.EAST;
226: gridBagConstraints.insets = new java.awt.Insets(2, 0, 0, 5);
227: add(replaceNextButton, gridBagConstraints);
228:
229: replaceAllButton
230: .setText(ResourceMgr.getString("LblReplaceAll"));
231: replaceAllButton.setToolTipText(ResourceMgr
232: .getDescription("LblReplaceAll"));
233: replaceAllButton.setName("replaceallbutton"); // NOI18N
234: gridBagConstraints = new java.awt.GridBagConstraints();
235: gridBagConstraints.gridx = 2;
236: gridBagConstraints.gridy = 3;
237: gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
238: gridBagConstraints.anchor = java.awt.GridBagConstraints.EAST;
239: gridBagConstraints.insets = new java.awt.Insets(2, 0, 0, 5);
240: add(replaceAllButton, gridBagConstraints);
241:
242: closeButton.setText(ResourceMgr.getString("LblClose"));
243: closeButton.setName("closebutton"); // NOI18N
244: gridBagConstraints = new java.awt.GridBagConstraints();
245: gridBagConstraints.gridx = 2;
246: gridBagConstraints.gridy = 5;
247: gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
248: gridBagConstraints.anchor = java.awt.GridBagConstraints.SOUTHEAST;
249: gridBagConstraints.insets = new java.awt.Insets(0, 0, 0, 5);
250: add(closeButton, gridBagConstraints);
251:
252: selectedTextCheckBox.setText(ResourceMgr
253: .getString("LblSelectedTextOnly"));
254: selectedTextCheckBox.setToolTipText(ResourceMgr
255: .getDescription("LblSelectedTextOnly"));
256: selectedTextCheckBox.setName("selectedtext"); // NOI18N
257: gridBagConstraints = new java.awt.GridBagConstraints();
258: gridBagConstraints.gridx = 0;
259: gridBagConstraints.gridy = 5;
260: gridBagConstraints.gridwidth = 2;
261: gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
262: gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
263: gridBagConstraints.insets = new java.awt.Insets(2, 5, 0, 5);
264: add(selectedTextCheckBox, gridBagConstraints);
265:
266: useRegexCheckBox.setText(ResourceMgr
267: .getString("LblSearchRegEx"));
268: useRegexCheckBox.setToolTipText(ResourceMgr
269: .getDescription("LblSearchRegEx"));
270: useRegexCheckBox.setName("regex"); // NOI18N
271: gridBagConstraints = new java.awt.GridBagConstraints();
272: gridBagConstraints.gridx = 0;
273: gridBagConstraints.gridy = 4;
274: gridBagConstraints.gridwidth = 2;
275: gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
276: gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
277: gridBagConstraints.insets = new java.awt.Insets(0, 5, 0, 5);
278: add(useRegexCheckBox, gridBagConstraints);
279:
280: findNextButton.setText(ResourceMgr.getString("LblFindNext"));
281: findNextButton.setToolTipText(ResourceMgr
282: .getDescription("LblFindNext"));
283: findNextButton.setName("findnextbutton"); // NOI18N
284: gridBagConstraints = new java.awt.GridBagConstraints();
285: gridBagConstraints.gridx = 2;
286: gridBagConstraints.gridy = 1;
287: gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
288: gridBagConstraints.anchor = java.awt.GridBagConstraints.EAST;
289: gridBagConstraints.insets = new java.awt.Insets(2, 0, 0, 5);
290: add(findNextButton, gridBagConstraints);
291: }// </editor-fold>//GEN-END:initComponents
292:
293: private void replaceValueTextFieldFocusGained(
294: java.awt.event.FocusEvent evt)//GEN-FIRST:event_replaceValueTextFieldFocusGained
295: {//GEN-HEADEREND:event_replaceValueTextFieldFocusGained
296: // When the popup menu for copy & paste is used, the oppositeComponent()
297: // is the RootPane. In this case we don't want to chage the selection
298: if (!(evt.getOppositeComponent() instanceof javax.swing.JRootPane)) {
299: this .replaceValueTextField.selectAll();
300: }
301: }//GEN-LAST:event_replaceValueTextFieldFocusGained
302:
303: public void showReplaceDialog(Component caller,
304: final String selectedText) {
305: showReplaceDialog(caller, selectedText, ResourceMgr
306: .getString("TxtWindowTitleReplaceText"));
307: }
308:
309: public void showReplaceDialog(Component caller,
310: final String selectedText, String title) {
311: if (this .dialog != null) {
312: this .dialog.setVisible(true);
313: this .dialog.requestFocus();
314: return;
315: }
316: try {
317: Window w = WbSwingUtilities.getWindowAncestor(caller);
318: Frame f = null;
319: this .dialog = null;
320:
321: if (w instanceof Frame) {
322: this .dialog = new JDialog((Frame) w);
323: } else if (w instanceof Dialog) {
324: this .dialog = new JDialog((Dialog) w);
325: }
326: this .dialog.setTitle(title);
327: this .dialog.getContentPane().add(this );
328: this .dialog.pack();
329: this .dialog.setResizable(false);
330: if (!Settings.getInstance().restoreWindowPosition(
331: this .dialog, settingsKey + ".window")) {
332: WbSwingUtilities.center(dialog, w);
333: }
334: this .dialog.addWindowListener(this );
335:
336: boolean hasSelectedText = false;
337:
338: if (!StringUtil.isEmptyString(selectedText)
339: && selectedText.indexOf('\n') == -1
340: && selectedText.indexOf('\r') == -1) {
341: criteriaTextField.setText(selectedText);
342: hasSelectedText = true;
343: }
344:
345: InputMap im = this .dialog.getRootPane().getInputMap(
346: JComponent.WHEN_IN_FOCUSED_WINDOW);
347: ActionMap am = this .dialog.getRootPane().getActionMap();
348:
349: escAction = new EscAction(this );
350: im.put(escAction.getAccelerator(), escAction
351: .getActionName());
352: am.put(escAction.getActionName(), escAction);
353:
354: final boolean criteriaAdded = hasSelectedText;
355:
356: EventQueue.invokeLater(new Runnable() {
357: public void run() {
358: if (criteriaAdded) {
359: replaceValueTextField.selectAll();
360: replaceValueTextField.requestFocus();
361: } else {
362: criteriaTextField.selectAll();
363: criteriaTextField.requestFocus();
364: }
365: }
366: });
367: this .dialog.setVisible(true);
368: } catch (Exception e) {
369: e.printStackTrace();
370: }
371: }
372:
373: public void actionPerformed(java.awt.event.ActionEvent e) {
374: Object source = e.getSource();
375: if (source == this .findButton) {
376: this .findFirst();
377: } else if (source == this .findNextButton) {
378: findNext();
379: } else if (source == this .replaceNextButton) {
380: this .replaceNext();
381: } else if (source == this .replaceAllButton) {
382: this .replaceAll();
383: } else if (source == this .closeButton
384: || e.getActionCommand().equals(
385: escAction.getActionName())) {
386: this .closeWindow();
387: }
388: }
389:
390: private void findNext() {
391: try {
392: this .lastPos = this .client.findNext();
393: this .replaceNextButton.setEnabled(this .lastPos > -1);
394: this .findNextButton.setEnabled(this .lastPos > -1);
395: } catch (Exception e) {
396: WbSwingUtilities.showErrorMessage(this , ExceptionUtil
397: .getDisplay(e));
398: }
399: }
400:
401: private void findFirst() {
402: String toFind = this .criteriaTextField.getText();
403: try {
404: this .lastPos = this .client.findFirst(toFind,
405: this .ignoreCaseCheckBox.isSelected(),
406: this .wordsOnlyCheckBox.isSelected(),
407: this .useRegexCheckBox.isSelected());
408: this .replaceNextButton.setEnabled(this .lastPos > -1);
409: this .findNextButton.setEnabled(this .lastPos > -1);
410: } catch (Exception e) {
411: WbSwingUtilities.showErrorMessage(this , ExceptionUtil
412: .getDisplay(e));
413: }
414: }
415:
416: private void replaceNext() {
417: if (this .lastPos < 0)
418: this .findFirst();
419:
420: if (this .client.replaceCurrent(this .replaceValueTextField
421: .getText(), this .useRegexCheckBox.isSelected())) {
422: this .findNext();
423: } else {
424: this .replaceNextButton.setEnabled(false);
425: }
426: }
427:
428: private void replaceAll() {
429: boolean selected = this .selectedTextCheckBox.isEnabled()
430: && this .selectedTextCheckBox.isSelected();
431: this .client.replaceAll(this .criteriaTextField.getText(),
432: this .replaceValueTextField.getText(), selected,
433: this .ignoreCaseCheckBox.isSelected(),
434: this .wordsOnlyCheckBox.isSelected(),
435: this .useRegexCheckBox.isSelected());
436: }
437:
438: private void closeWindow() {
439: if (this .dialog != null) {
440: this .saveSettings();
441: this .escAction = null;
442: this .dialog.setVisible(false);
443: this .dialog.dispose();
444: this .dialog = null;
445: }
446: }
447:
448: private void saveSettings() {
449: Settings.getInstance().setProperty(caseProperty,
450: Boolean.toString(this .ignoreCaseCheckBox.isSelected()));
451: Settings.getInstance().setProperty(wordProperty,
452: Boolean.toString(this .wordsOnlyCheckBox.isSelected()));
453: Settings.getInstance().setProperty(
454: selectedProperty,
455: Boolean
456: .toString(this .selectedTextCheckBox
457: .isSelected()));
458: Settings.getInstance().setProperty(regexProperty,
459: Boolean.toString(this .useRegexCheckBox.isSelected()));
460: Settings.getInstance().setProperty(criteriaProperty,
461: this .criteriaTextField.getText());
462: Settings.getInstance().setProperty(replacementProperty,
463: this .replaceValueTextField.getText());
464: Settings.getInstance().storeWindowPosition(this .dialog,
465: settingsKey + ".window");
466: }
467:
468: private void restoreSettings() {
469: this .ignoreCaseCheckBox.setSelected(Settings.getInstance()
470: .getBoolProperty(caseProperty, true));
471: this .wordsOnlyCheckBox.setSelected(Settings.getInstance()
472: .getBoolProperty(wordProperty, false));
473: this .selectedTextCheckBox.setSelected(Settings.getInstance()
474: .getBoolProperty(selectedProperty, false));
475: this .useRegexCheckBox.setSelected(Settings.getInstance()
476: .getBoolProperty(regexProperty, true));
477: this .criteriaTextField.setText(Settings.getInstance()
478: .getProperty(criteriaProperty, ""));
479: this .replaceValueTextField.setText(Settings.getInstance()
480: .getProperty(replacementProperty, ""));
481: }
482:
483: public void windowActivated(java.awt.event.WindowEvent e) {
484: }
485:
486: public void windowClosed(java.awt.event.WindowEvent e) {
487: }
488:
489: public void windowClosing(java.awt.event.WindowEvent e) {
490: this .closeWindow();
491: }
492:
493: public void windowDeactivated(java.awt.event.WindowEvent e) {
494: }
495:
496: public void windowDeiconified(java.awt.event.WindowEvent e) {
497: }
498:
499: public void windowIconified(java.awt.event.WindowEvent e) {
500: }
501:
502: public void windowOpened(java.awt.event.WindowEvent e) {
503: }
504:
505: // Variables declaration - do not modify//GEN-BEGIN:variables
506: protected javax.swing.JButton closeButton;
507: protected javax.swing.JLabel criteriaLabel;
508: protected javax.swing.JTextField criteriaTextField;
509: protected javax.swing.JButton findButton;
510: protected javax.swing.JButton findNextButton;
511: protected javax.swing.JCheckBox ignoreCaseCheckBox;
512: protected javax.swing.JButton replaceAllButton;
513: protected javax.swing.JLabel replaceLabel;
514: protected javax.swing.JButton replaceNextButton;
515: protected javax.swing.JTextField replaceValueTextField;
516: protected javax.swing.JCheckBox selectedTextCheckBox;
517: protected javax.swing.JPanel spacerPanel;
518: protected javax.swing.JCheckBox useRegexCheckBox;
519: protected javax.swing.JCheckBox wordsOnlyCheckBox;
520: // End of variables declaration//GEN-END:variables
521:
522: }
|