0001: /*
0002: * SearchDialog.java - Search and replace dialog
0003: * :tabSize=8:indentSize=8:noTabs=false:
0004: * :folding=explicit:collapseFolds=1:
0005: *
0006: * Copyright (C) 1998, 2004 Slava Pestov
0007: *
0008: * This program is free software; you can redistribute it and/or
0009: * modify it under the terms of the GNU General Public License
0010: * as published by the Free Software Foundation; either version 2
0011: * of the License, or any later version.
0012: *
0013: * This program is distributed in the hope that it will be useful,
0014: * but WITHOUT ANY WARRANTY; without even the implied warranty of
0015: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
0016: * GNU General Public License for more details.
0017: *
0018: * You should have received a copy of the GNU General Public License
0019: * along with this program; if not, write to the Free Software
0020: * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
0021: */
0022:
0023: package org.gjt.sp.jedit.search;
0024:
0025: //{{{ Imports
0026: import javax.swing.border.*;
0027: import javax.swing.*;
0028:
0029: import java.awt.*;
0030: import java.awt.event.*;
0031: import java.util.HashMap;
0032: import java.util.Map;
0033:
0034: import org.gjt.sp.jedit.browser.VFSBrowser;
0035: import org.gjt.sp.jedit.gui.*;
0036: import org.gjt.sp.jedit.io.*;
0037: import org.gjt.sp.jedit.msg.SearchSettingsChanged;
0038: import org.gjt.sp.jedit.*;
0039:
0040: //}}}
0041:
0042: /**
0043: * Search and replace dialog.
0044: * @author Slava Pestov
0045: * @version $Id: SearchDialog.java 10828 2007-10-06 22:37:21Z shlomy $
0046: */
0047: public class SearchDialog extends EnhancedDialog implements EBComponent {
0048: //{{{ Constants
0049: /**
0050: * Default file set.
0051: * @since jEdit 3.2pre2
0052: */
0053: public static final int CURRENT_BUFFER = 0;
0054: public static final int ALL_BUFFERS = 1;
0055: public static final int DIRECTORY = 2;
0056:
0057: //}}}
0058:
0059: //{{{ getSearchDialog() method
0060: public static SearchDialog getSearchDialog(View view) {
0061: if (Debug.DISABLE_SEARCH_DIALOG_POOL)
0062: return new SearchDialog(view);
0063: else {
0064:
0065: SearchDialog searchDialog = viewHash.get(view);
0066: if (searchDialog == null) {
0067: searchDialog = new SearchDialog(view);
0068: viewHash.put(view, searchDialog);
0069: }
0070: return searchDialog;
0071: }
0072: } //}}}
0073:
0074: //{{{ preloadSearchDialog() method
0075: /**
0076: * Preloads the search dialog for the given for so that it can be
0077: * quickly displayed later.
0078: *
0079: * @param view the view from which you want to preload the SearchDialog
0080: * @since jEdit 4.2pre3
0081: * @deprecated no reason to use this method anymore now we have JIT compiler
0082: */
0083: @Deprecated
0084: public static void preloadSearchDialog(View view) {
0085: if (Debug.DISABLE_SEARCH_DIALOG_POOL)
0086: return;
0087:
0088: SearchDialog dialog = new SearchDialog(view);
0089: viewHash.put(view, dialog);
0090: } //}}}
0091:
0092: //{{{ showSearchDialog() method
0093: /**
0094: * Displays a search and replace dialog box, reusing an existing one
0095: * if necessary.
0096: * @param view The view
0097: * @param searchString The search string
0098: * @param searchIn One of CURRENT_BUFFER, ALL_BUFFERS, or DIRECTORY
0099: * @since jEdit 4.0pre6
0100: */
0101: public static void showSearchDialog(View view, String searchString,
0102: int searchIn) {
0103: final SearchDialog dialog = getSearchDialog(view);
0104:
0105: dialog.setSearchString(searchString, searchIn);
0106:
0107: // ugly workaround
0108: if (OperatingSystem.isUnix() && !OperatingSystem.isMacOS())
0109: dialog.setVisible(false);
0110:
0111: // I'm not sure if calling requestFocus() is strictly necessary
0112: // (focus looks fine without this, on Linux at least), but
0113: // it doesn't hurt to leave it here.
0114: SwingUtilities.invokeLater(new Runnable() {
0115: public void run() {
0116: dialog.toFront();
0117: dialog.requestFocus();
0118: // Ensure that the dialog gets the focus. Just bringing
0119: // it to front just not necessarily give it the focus.
0120: dialog.find.requestFocus();
0121: // Given that the dialog has the focus, set the focus
0122: // to the 'find' field.
0123: }
0124: });
0125: dialog.setVisible(true);
0126: } //}}}
0127:
0128: //{{{ setSearchString() method
0129: /**
0130: * Sets the search string.
0131: *
0132: * @param searchString The search string
0133: * @param searchIn One of {@link #CURRENT_BUFFER}, {@link #ALL_BUFFERS}, or {@link #DIRECTORY}
0134: * @since jEdit 4.0pre5
0135: */
0136: public void setSearchString(String searchString, int searchIn) {
0137: find.setText(null);
0138: replace.setText(null);
0139:
0140: if (searchString == null)
0141: searchCurrentBuffer.setSelected(true);
0142: else {
0143: if (searchString.indexOf('\n') == -1) {
0144: if (SearchAndReplace.getRegexp()) {
0145: find.setText(SearchAndReplace.escapeRegexp(
0146: searchString, true));
0147: } else
0148: find.setText(searchString);
0149: find.selectAll();
0150: searchCurrentBuffer.setSelected(true);
0151: } else if (searchIn == CURRENT_BUFFER) {
0152: searchSelection.setSelected(true);
0153: hyperSearch.setSelected(true);
0154: }
0155: }
0156:
0157: if (searchIn == CURRENT_BUFFER) {
0158: if (!searchSelection.isSelected()) {
0159: // might be already selected, see above.
0160: searchCurrentBuffer.setSelected(true);
0161:
0162: /* this property is only loaded and saved if
0163: * the 'current buffer' file set is selected.
0164: * otherwise, it defaults to on. */
0165: hyperSearch
0166: .setSelected(jEdit
0167: .getBooleanProperty("search.hypersearch.toggle"));
0168: }
0169: } else if (searchIn == ALL_BUFFERS) {
0170: searchAllBuffers.setSelected(true);
0171: hyperSearch.setSelected(true);
0172: } else if (searchIn == DIRECTORY) {
0173: SearchFileSet fileset = SearchAndReplace.getSearchFileSet();
0174:
0175: if (fileset instanceof DirectoryListSet) {
0176: filter.setText(((DirectoryListSet) fileset)
0177: .getFileFilter());
0178: directory.setText(((DirectoryListSet) fileset)
0179: .getDirectory());
0180: searchSubDirectories
0181: .setSelected(((DirectoryListSet) fileset)
0182: .isRecursive());
0183: }
0184:
0185: hyperSearch.setSelected(true);
0186: searchDirectory.setSelected(true);
0187: }
0188:
0189: updateEnabled();
0190: } //}}}
0191:
0192: //{{{ ok() method
0193: public void ok() {
0194: try {
0195: setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
0196:
0197: if (!save(false))
0198: return;
0199:
0200: if (searchSelection.isSelected()
0201: && view.getTextArea().getSelectionCount() == 0) {
0202: GUIUtilities.error(view, "search-no-selection", null);
0203: return;
0204: }
0205:
0206: if (hyperSearch.isSelected()
0207: || searchSelection.isSelected()) {
0208: if (SearchAndReplace.hyperSearch(view, searchSelection
0209: .isSelected()))
0210: closeOrKeepDialog();
0211: } else {
0212: if (SearchAndReplace.find(view))
0213: closeOrKeepDialog();
0214: else {
0215: toFront();
0216: requestFocus();
0217: find.requestFocus();
0218: }
0219: }
0220: } finally {
0221: setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
0222: }
0223: } //}}}
0224:
0225: //{{{ cancel() method
0226: public void cancel() {
0227: save(true);
0228: GUIUtilities.saveGeometry(this , "search");
0229: setVisible(false);
0230: } //}}}
0231:
0232: //{{{ handleMessage() method
0233: public void handleMessage(EBMessage msg) {
0234: if (msg instanceof SearchSettingsChanged) {
0235: if (!saving)
0236: load();
0237: }
0238: } //}}}
0239:
0240: //{{{ dispose() method
0241: public void dispose() {
0242: EditBus.removeFromBus(this );
0243: viewHash.remove(view);
0244: super .dispose();
0245: } //}}}
0246:
0247: //{{{ Private members
0248:
0249: private static final Map<View, SearchDialog> viewHash = new HashMap<View, SearchDialog>();
0250:
0251: //{{{ Instance variables
0252: private final View view;
0253:
0254: // fields
0255: private HistoryTextArea find, replace;
0256:
0257: private JRadioButton stringReplace, beanShellReplace;
0258:
0259: // search settings
0260: private JCheckBox keepDialog, ignoreCase, regexp, hyperSearch,
0261: wrap;
0262: private JRadioButton searchBack, searchForward;
0263: private JRadioButton searchSelection, searchCurrentBuffer,
0264: searchAllBuffers, searchDirectory;
0265:
0266: // multifile settings
0267: private HistoryTextField filter, directory;
0268: private JCheckBox searchSubDirectories;
0269: private JCheckBox skipBinaryFiles;
0270: private JCheckBox skipHidden;
0271:
0272: private JButton choose;
0273: private JButton synchronize;
0274:
0275: // buttons
0276: private JButton findBtn, /* replaceBtn, */replaceAndFindBtn,
0277: replaceAllBtn, closeBtn;
0278:
0279: private boolean saving;
0280:
0281: //}}}
0282:
0283: //{{{ SearchDialog constructor
0284: /**
0285: * Creates a new search and replace dialog box.
0286: * @param view The view
0287: */
0288: private SearchDialog(View view) {
0289: super (view, jEdit.getProperty("search.title"), false);
0290:
0291: this .view = view;
0292:
0293: JPanel content = new JPanel(new BorderLayout());
0294: content.setBorder(new EmptyBorder(0, 12, 12, 12));
0295: setContentPane(content);
0296:
0297: JPanel centerPanel = new JPanel(new BorderLayout());
0298: centerPanel.add(BorderLayout.CENTER, createFieldPanel());
0299: centerPanel
0300: .add(BorderLayout.SOUTH, createSearchSettingsPanel());
0301: content.add(BorderLayout.CENTER, centerPanel);
0302: content.add(BorderLayout.SOUTH, createMultiFilePanel());
0303:
0304: content.add(BorderLayout.EAST, createButtonsPanel());
0305:
0306: pack();
0307: jEdit.unsetProperty("search.width");
0308: jEdit.unsetProperty("search.d-width");
0309: jEdit.unsetProperty("search.height");
0310: jEdit.unsetProperty("search.d-height");
0311: GUIUtilities.loadGeometry(this , "search");
0312:
0313: load();
0314:
0315: EditBus.addToBus(this );
0316: } //}}}
0317:
0318: //{{{ createFindLabelAndField() method
0319: private void createFindLabelAndField(JPanel fieldPanel,
0320: GridBagConstraints cons) {
0321: JLabel label = new JLabel(jEdit.getProperty("search.find"));
0322:
0323: label.setDisplayedMnemonic(jEdit.getProperty(
0324: "search.find.mnemonic").charAt(0));
0325: find = new HistoryTextArea("find");
0326: find.setColumns(25);
0327: find.setToolTipText(jEdit.getProperty("search.find.tooltip"));
0328: label.setToolTipText(jEdit.getProperty("search.find.tooltip"));
0329: label.setLabelFor(find);
0330: label.setBorder(new EmptyBorder(12, 0, 2, 0));
0331:
0332: cons.gridx = 0;
0333: cons.weightx = 0.0;
0334: cons.weighty = 0.0;
0335: fieldPanel.add(label, cons);
0336: cons.gridy++;
0337: cons.weightx = 1.0;
0338: cons.weighty = 1.0;
0339: fieldPanel.add(new JScrollPane(find), cons);
0340: cons.gridy++;
0341: } //}}}
0342:
0343: //{{{ createReplaceLabelAndField() method
0344: private void createReplaceLabelAndField(JPanel fieldPanel,
0345: GridBagConstraints cons) {
0346: JLabel label = new JLabel(jEdit.getProperty("search.replace"));
0347: label.setDisplayedMnemonic(jEdit.getProperty(
0348: "search.replace.mnemonic").charAt(0));
0349: label.setBorder(new EmptyBorder(12, 0, 0, 0));
0350:
0351: cons.gridx = 0;
0352: cons.weightx = 0.0;
0353: cons.weighty = 0.0;
0354: fieldPanel.add(label, cons);
0355: cons.gridy++;
0356:
0357: ButtonGroup grp = new ButtonGroup();
0358: ReplaceActionHandler replaceActionHandler = new ReplaceActionHandler();
0359:
0360: // we use a custom JRadioButton subclass that returns
0361: // false for isFocusTraversable() so that the user can
0362: // tab from the search field to the replace field with
0363: // one keystroke
0364:
0365: stringReplace = new MyJRadioButton(jEdit
0366: .getProperty("search.string-replace-btn"));
0367: stringReplace.addActionListener(replaceActionHandler);
0368: grp.add(stringReplace);
0369: cons.gridwidth = 1;
0370: fieldPanel.add(stringReplace, cons);
0371: cons.gridx++;
0372: cons.insets = new Insets(0, 12, 0, 0);
0373:
0374: beanShellReplace = new MyJRadioButton(jEdit
0375: .getProperty("search.beanshell-replace-btn"));
0376: beanShellReplace.addActionListener(replaceActionHandler);
0377: grp.add(beanShellReplace);
0378: fieldPanel.add(beanShellReplace, cons);
0379: cons.gridx = 0;
0380: cons.gridwidth = 2;
0381: cons.insets = new Insets(0, 0, 0, 0);
0382:
0383: replace = new HistoryTextArea("replace");
0384: replace
0385: .setToolTipText(jEdit
0386: .getProperty("search.find.tooltip"));
0387: label.setLabelFor(replace);
0388:
0389: cons.gridx = 0;
0390: cons.gridy++;
0391: cons.weightx = 1.0;
0392: cons.weighty = 1.0;
0393: fieldPanel.add(new JScrollPane(replace), cons);
0394: cons.gridy++;
0395: } //}}}
0396:
0397: //{{{ createFieldPanel() method
0398: private JPanel createFieldPanel() {
0399: JPanel fieldPanel = new JPanel(new GridBagLayout());
0400: fieldPanel.setBorder(new EmptyBorder(0, 0, 12, 12));
0401:
0402: GridBagConstraints cons = new GridBagConstraints();
0403: cons.fill = GridBagConstraints.BOTH;
0404: cons.gridy = 0;
0405: cons.gridwidth = 2;
0406:
0407: createFindLabelAndField(fieldPanel, cons);
0408: createReplaceLabelAndField(fieldPanel, cons);
0409:
0410: return fieldPanel;
0411: } //}}}
0412:
0413: //{{{ createSearchSettingsPanel() method
0414: private JPanel createSearchSettingsPanel() {
0415: JPanel searchSettings = new JPanel(new VariableGridLayout(
0416: VariableGridLayout.FIXED_NUM_COLUMNS, 3));
0417: searchSettings.setBorder(new EmptyBorder(0, 0, 12, 12));
0418:
0419: SettingsActionHandler actionHandler = new SettingsActionHandler();
0420: ButtonGroup fileset = new ButtonGroup();
0421: ButtonGroup direction = new ButtonGroup();
0422:
0423: searchSettings.add(new JLabel(jEdit
0424: .getProperty("search.fileset")));
0425:
0426: searchSettings.add(new JLabel(jEdit
0427: .getProperty("search.settings")));
0428:
0429: searchSettings.add(new JLabel(jEdit
0430: .getProperty("search.direction")));
0431:
0432: searchSelection = new JRadioButton(jEdit
0433: .getProperty("search.selection"));
0434: searchSelection.setMnemonic(jEdit.getProperty(
0435: "search.selection.mnemonic").charAt(0));
0436: fileset.add(searchSelection);
0437: searchSettings.add(searchSelection);
0438: searchSelection.addActionListener(actionHandler);
0439:
0440: keepDialog = new JCheckBox(jEdit.getProperty("search.keep"));
0441: keepDialog.setMnemonic(jEdit
0442: .getProperty("search.keep.mnemonic").charAt(0));
0443: searchSettings.add(keepDialog);
0444:
0445: searchBack = new JRadioButton(jEdit.getProperty("search.back"));
0446: searchBack.setMnemonic(jEdit
0447: .getProperty("search.back.mnemonic").charAt(0));
0448: direction.add(searchBack);
0449: searchSettings.add(searchBack);
0450: searchBack.addActionListener(actionHandler);
0451:
0452: searchCurrentBuffer = new JRadioButton(jEdit
0453: .getProperty("search.current"));
0454: searchCurrentBuffer.setMnemonic(jEdit.getProperty(
0455: "search.current.mnemonic").charAt(0));
0456: fileset.add(searchCurrentBuffer);
0457: searchSettings.add(searchCurrentBuffer);
0458: searchCurrentBuffer.addActionListener(actionHandler);
0459:
0460: ignoreCase = new JCheckBox(jEdit.getProperty("search.case"));
0461: ignoreCase.setMnemonic(jEdit
0462: .getProperty("search.case.mnemonic").charAt(0));
0463: searchSettings.add(ignoreCase);
0464: ignoreCase.addActionListener(actionHandler);
0465:
0466: searchForward = new JRadioButton(jEdit
0467: .getProperty("search.forward"));
0468: searchForward.setMnemonic(jEdit.getProperty(
0469: "search.forward.mnemonic").charAt(0));
0470: direction.add(searchForward);
0471: searchSettings.add(searchForward);
0472: searchForward.addActionListener(actionHandler);
0473:
0474: searchAllBuffers = new JRadioButton(jEdit
0475: .getProperty("search.all"));
0476: searchAllBuffers.setMnemonic(jEdit.getProperty(
0477: "search.all.mnemonic").charAt(0));
0478: fileset.add(searchAllBuffers);
0479: searchSettings.add(searchAllBuffers);
0480: searchAllBuffers.addActionListener(actionHandler);
0481:
0482: regexp = new JCheckBox(jEdit.getProperty("search.regexp"));
0483: regexp.setMnemonic(jEdit.getProperty("search.regexp.mnemonic")
0484: .charAt(0));
0485: searchSettings.add(regexp);
0486: regexp.addActionListener(actionHandler);
0487:
0488: wrap = new JCheckBox(jEdit.getProperty("search.wrap"));
0489: wrap.setMnemonic(jEdit.getProperty("search.wrap.mnemonic")
0490: .charAt(0));
0491: searchSettings.add(wrap);
0492: wrap.addActionListener(actionHandler);
0493:
0494: searchDirectory = new JRadioButton(jEdit
0495: .getProperty("search.directory"));
0496: searchDirectory.setMnemonic(jEdit.getProperty(
0497: "search.directory.mnemonic").charAt(0));
0498: fileset.add(searchDirectory);
0499: searchSettings.add(searchDirectory);
0500: searchDirectory.addActionListener(actionHandler);
0501:
0502: hyperSearch = new JCheckBox(jEdit
0503: .getProperty("search.hypersearch"));
0504: hyperSearch.setMnemonic(jEdit.getProperty(
0505: "search.hypersearch.mnemonic").charAt(0));
0506: searchSettings.add(hyperSearch);
0507: hyperSearch.addActionListener(actionHandler);
0508:
0509: return searchSettings;
0510: } //}}}
0511:
0512: //{{{ createMultiFilePanel() method
0513: private JPanel createMultiFilePanel() {
0514: JPanel multifile = new JPanel();
0515:
0516: GridBagLayout layout = new GridBagLayout();
0517: multifile.setLayout(layout);
0518:
0519: GridBagConstraints cons = new GridBagConstraints();
0520: cons.gridy = cons.gridwidth = cons.gridheight = 1;
0521: cons.anchor = GridBagConstraints.WEST;
0522: cons.fill = GridBagConstraints.HORIZONTAL;
0523:
0524: MultiFileActionHandler actionListener = new MultiFileActionHandler();
0525: filter = new HistoryTextField("search.filter");
0526:
0527: filter.setToolTipText(jEdit.getProperty("glob.tooltip"));
0528: filter.addActionListener(actionListener);
0529:
0530: cons.insets = new Insets(0, 0, 3, 0);
0531:
0532: JLabel label = new JLabel(jEdit
0533: .getProperty("search.filterField"),
0534: SwingConstants.RIGHT);
0535: label.setBorder(new EmptyBorder(0, 0, 0, 12));
0536: label.setDisplayedMnemonic(jEdit.getProperty(
0537: "search.filterField.mnemonic").charAt(0));
0538: label.setLabelFor(filter);
0539: cons.weightx = 0.0;
0540: layout.setConstraints(label, cons);
0541: multifile.add(label);
0542:
0543: cons.gridwidth = 2;
0544: cons.insets = new Insets(0, 0, 3, 6);
0545: cons.weightx = 1.0;
0546: layout.setConstraints(filter, cons);
0547: multifile.add(filter);
0548:
0549: cons.gridwidth = 1;
0550: cons.weightx = 0.0;
0551: cons.insets = new Insets(0, 0, 3, 0);
0552:
0553: synchronize = new JButton(jEdit
0554: .getProperty("search.synchronize"));
0555: synchronize.setMnemonic(jEdit.getProperty(
0556: "search.synchronize.mnemonic").charAt(0));
0557: synchronize.addActionListener(actionListener);
0558: layout.setConstraints(synchronize, cons);
0559: multifile.add(synchronize);
0560:
0561: cons.gridy++;
0562:
0563: directory = new HistoryTextField("search.directory");
0564: directory.setColumns(25);
0565: directory.addActionListener(actionListener);
0566:
0567: label = new JLabel(jEdit.getProperty("search.directoryField"),
0568: SwingConstants.RIGHT);
0569: label.setBorder(new EmptyBorder(0, 0, 0, 12));
0570:
0571: label.setDisplayedMnemonic(jEdit.getProperty(
0572: "search.directoryField.mnemonic").charAt(0));
0573: label.setLabelFor(directory);
0574: cons.insets = new Insets(0, 0, 3, 0);
0575: cons.weightx = 0.0;
0576: layout.setConstraints(label, cons);
0577: multifile.add(label);
0578:
0579: cons.insets = new Insets(0, 0, 3, 6);
0580: cons.weightx = 1.0;
0581: cons.gridwidth = 2;
0582: layout.setConstraints(directory, cons);
0583: multifile.add(directory);
0584:
0585: choose = new JButton(jEdit.getProperty("search.choose"));
0586: choose.setMnemonic(jEdit.getProperty("search.choose.mnemonic")
0587: .charAt(0));
0588: cons.insets = new Insets(0, 0, 3, 0);
0589: cons.weightx = 0.0;
0590: cons.gridwidth = 1;
0591: layout.setConstraints(choose, cons);
0592: multifile.add(choose);
0593: choose.addActionListener(actionListener);
0594:
0595: cons.insets = new Insets(0, 0, 0, 0);
0596: cons.gridy++;
0597: cons.gridwidth = 3;
0598:
0599: JPanel dirCheckBoxPanel = new JPanel();
0600: searchSubDirectories = new JCheckBox(jEdit
0601: .getProperty("search.subdirs"));
0602: String mnemonic = jEdit.getProperty("search.subdirs.mnemonic");
0603: searchSubDirectories.setMnemonic(mnemonic.charAt(0));
0604: searchSubDirectories.setSelected(jEdit
0605: .getBooleanProperty("search.subdirs.toggle"));
0606: skipHidden = new JCheckBox(jEdit
0607: .getProperty("search.skipHidden"));
0608: skipHidden.setSelected(jEdit.getBooleanProperty(
0609: "search.skipHidden.toggle", true));
0610: skipBinaryFiles = new JCheckBox(jEdit
0611: .getProperty("search.skipBinary"));
0612: skipBinaryFiles.setSelected(jEdit.getBooleanProperty(
0613: "search.skipBinary.toggle", true));
0614: dirCheckBoxPanel.add(searchSubDirectories);
0615: dirCheckBoxPanel.add(skipHidden);
0616: dirCheckBoxPanel.add(skipBinaryFiles);
0617:
0618: cons.insets = new Insets(0, 0, 0, 0);
0619: cons.gridy++;
0620: cons.gridwidth = 4;
0621: layout.setConstraints(dirCheckBoxPanel, cons);
0622:
0623: multifile.add(dirCheckBoxPanel);
0624:
0625: return multifile;
0626: } //}}}
0627:
0628: //{{{ createButtonsPanel() method
0629: private Box createButtonsPanel() {
0630: Box box = new Box(BoxLayout.Y_AXIS);
0631:
0632: ButtonActionHandler actionHandler = new ButtonActionHandler();
0633:
0634: box.add(Box.createVerticalStrut(12));
0635:
0636: JPanel grid = new JPanel(new GridLayout(5, 1, 0, 12));
0637:
0638: findBtn = new JButton(jEdit.getProperty("search.findBtn"));
0639: /* findBtn.setMnemonic(jEdit.getProperty("search.findBtn.mnemonic")
0640: .charAt(0)); */
0641: getRootPane().setDefaultButton(findBtn);
0642: grid.add(findBtn);
0643: findBtn.addActionListener(actionHandler);
0644:
0645: /* replaceBtn = new JButton(jEdit.getProperty("search.replaceBtn"));
0646: replaceBtn.setMnemonic(jEdit.getProperty("search.replaceBtn.mnemonic")
0647: .charAt(0));
0648: grid.add(replaceBtn);
0649: replaceBtn.addActionListener(actionHandler); */
0650:
0651: replaceAndFindBtn = new JButton(jEdit
0652: .getProperty("search.replaceAndFindBtn"));
0653: replaceAndFindBtn.setMnemonic(jEdit.getProperty(
0654: "search.replaceAndFindBtn.mnemonic").charAt(0));
0655: grid.add(replaceAndFindBtn);
0656: replaceAndFindBtn.addActionListener(actionHandler);
0657:
0658: replaceAllBtn = new JButton(jEdit
0659: .getProperty("search.replaceAllBtn"));
0660: replaceAllBtn.setMnemonic(jEdit.getProperty(
0661: "search.replaceAllBtn.mnemonic").charAt(0));
0662: grid.add(replaceAllBtn);
0663: replaceAllBtn.addActionListener(actionHandler);
0664:
0665: closeBtn = new JButton(jEdit.getProperty("common.close"));
0666: grid.add(closeBtn);
0667: closeBtn.addActionListener(actionHandler);
0668:
0669: grid.setMaximumSize(grid.getPreferredSize());
0670:
0671: box.add(grid);
0672: box.add(Box.createGlue());
0673:
0674: return box;
0675: } //}}}
0676:
0677: //{{{ updateEnabled() method
0678: private void updateEnabled() {
0679: wrap.setEnabled(!hyperSearch.isSelected()
0680: && !searchSelection.isSelected());
0681:
0682: boolean reverseEnabled = !hyperSearch.isSelected()
0683: && searchCurrentBuffer.isSelected()
0684: && !regexp.isSelected();
0685: searchBack.setEnabled(reverseEnabled);
0686: searchForward.setEnabled(reverseEnabled);
0687: if (!reverseEnabled)
0688: searchForward.setSelected(true);
0689:
0690: filter.setEnabled(searchAllBuffers.isSelected()
0691: || searchDirectory.isSelected());
0692:
0693: boolean searchDirs = searchDirectory.isSelected();
0694: directory.setEnabled(searchDirs);
0695: choose.setEnabled(searchDirs);
0696: searchSubDirectories.setEnabled(searchDirs);
0697: skipHidden.setEnabled(searchDirs);
0698: skipBinaryFiles.setEnabled(searchDirs);
0699:
0700: synchronize.setEnabled(searchAllBuffers.isSelected()
0701: || searchDirectory.isSelected());
0702:
0703: findBtn.setEnabled(!searchSelection.isSelected()
0704: || hyperSearch.isSelected());
0705: replaceAndFindBtn.setEnabled(!hyperSearch.isSelected()
0706: && !searchSelection.isSelected());
0707: } //}}}
0708:
0709: //{{{ save() method
0710: /**
0711: * @param cancel If true, we don't bother the user with warning messages
0712: */
0713: private boolean save(boolean cancel) {
0714: try {
0715: // prevents us from handling SearchSettingsChanged
0716: // as a result of below
0717: saving = true;
0718: SearchAndReplace.setIgnoreCase(ignoreCase.isSelected());
0719: SearchAndReplace.setRegexp(regexp.isSelected());
0720: SearchAndReplace.setReverseSearch(searchBack.isSelected());
0721: SearchAndReplace.setAutoWrapAround(wrap.isSelected());
0722: jEdit.setBooleanProperty("search.subdirs.toggle",
0723: searchSubDirectories.isSelected());
0724: jEdit.setBooleanProperty("search.skipHidden.toggle",
0725: skipHidden.isSelected());
0726: jEdit.setBooleanProperty("search.skipBinary.toggle",
0727: skipBinaryFiles.isSelected());
0728:
0729: String filter = this .filter.getText();
0730: this .filter.addCurrentToHistory();
0731: if (filter.length() == 0)
0732: filter = "*";
0733:
0734: SearchFileSet fileset = SearchAndReplace.getSearchFileSet();
0735:
0736: boolean recurse = searchSubDirectories.isSelected();
0737:
0738: if (searchSelection.isSelected())
0739: fileset = new CurrentBufferSet();
0740: else if (searchCurrentBuffer.isSelected()) {
0741: fileset = new CurrentBufferSet();
0742:
0743: jEdit.setBooleanProperty("search.hypersearch.toggle",
0744: hyperSearch.isSelected());
0745: } else if (searchAllBuffers.isSelected())
0746: fileset = new AllBufferSet(filter);
0747: else if (searchDirectory.isSelected()) {
0748: String directory = this .directory.getText();
0749: this .directory.addCurrentToHistory();
0750: directory = MiscUtilities.constructPath(view
0751: .getBuffer().getDirectory(), directory);
0752:
0753: if ((VFSManager.getVFSForPath(directory)
0754: .getCapabilities() & VFS.LOW_LATENCY_CAP) == 0) {
0755: if (cancel)
0756: return false;
0757:
0758: int retVal = GUIUtilities.confirm(this ,
0759: "remote-dir-search", null,
0760: JOptionPane.YES_NO_OPTION,
0761: JOptionPane.WARNING_MESSAGE);
0762: if (retVal != JOptionPane.YES_OPTION)
0763: return false;
0764: }
0765:
0766: if (fileset instanceof DirectoryListSet) {
0767: DirectoryListSet dset = (DirectoryListSet) fileset;
0768: dset.setDirectory(directory);
0769: dset.setFileFilter(filter);
0770: dset.setRecursive(recurse);
0771: EditBus.send(new SearchSettingsChanged(null));
0772: } else
0773: fileset = new DirectoryListSet(directory, filter,
0774: recurse);
0775: } else {
0776: // can't happen
0777: fileset = null;
0778: }
0779:
0780: jEdit.setBooleanProperty("search.subdirs.toggle", recurse);
0781: jEdit.setBooleanProperty("search.keepDialog.toggle",
0782: keepDialog.isSelected());
0783:
0784: SearchAndReplace.setSearchFileSet(fileset);
0785:
0786: replace.addCurrentToHistory();
0787: SearchAndReplace.setReplaceString(replace.getText());
0788:
0789: if (find.getText().length() == 0) {
0790: if (!cancel)
0791: getToolkit().beep();
0792: return false;
0793: }
0794:
0795: find.addCurrentToHistory();
0796: SearchAndReplace.setSearchString(find.getText());
0797:
0798: return true;
0799: } finally {
0800: saving = false;
0801: }
0802: } //}}}
0803:
0804: //{{{ closeOrKeepDialog() method
0805: private void closeOrKeepDialog() {
0806: if (keepDialog.isSelected()) {
0807: // Windows bug workaround in case a YES/NO confirm
0808: // was shown
0809:
0810: // ... but if HyperSearch results window is floating,
0811: // the workaround causes problems!
0812: if (!hyperSearch.isSelected()) {
0813: toFront();
0814: requestFocus();
0815: find.requestFocus();
0816: }
0817: } else {
0818: GUIUtilities.saveGeometry(this , "search");
0819: setVisible(false);
0820: }
0821: } //}}}
0822:
0823: //{{{ load() method
0824: private void load() {
0825: ignoreCase.setSelected(SearchAndReplace.getIgnoreCase());
0826: regexp.setSelected(SearchAndReplace.getRegexp());
0827: wrap.setSelected(SearchAndReplace.getAutoWrapAround());
0828:
0829: if (SearchAndReplace.getReverseSearch())
0830: searchBack.setSelected(true);
0831: else
0832: searchForward.setSelected(true);
0833:
0834: if (SearchAndReplace.getBeanShellReplace()) {
0835: replace.setModel("replace.script");
0836: beanShellReplace.setSelected(true);
0837: } else {
0838: replace.setModel("replace");
0839: stringReplace.setSelected(true);
0840: }
0841:
0842: SearchFileSet fileset = SearchAndReplace.getSearchFileSet();
0843:
0844: HistoryModel model = filter.getModel();
0845: if (model.getSize() != 0)
0846: filter.setText(model.getItem(0));
0847: else {
0848: filter.setText('*' + MiscUtilities.getFileExtension(view
0849: .getBuffer().getName()));
0850: }
0851: model = directory.getModel();
0852: if (model.getSize() != 0)
0853: directory.setText(model.getItem(0));
0854: else
0855: directory.setText(view.getBuffer().getDirectory());
0856:
0857: searchSubDirectories.setSelected(jEdit
0858: .getBooleanProperty("search.subdirs.toggle"));
0859:
0860: if (fileset instanceof DirectoryListSet) {
0861: filter
0862: .setText(((DirectoryListSet) fileset)
0863: .getFileFilter());
0864: directory.setText(((DirectoryListSet) fileset)
0865: .getDirectory());
0866: searchSubDirectories
0867: .setSelected(((DirectoryListSet) fileset)
0868: .isRecursive());
0869: } else if (fileset instanceof AllBufferSet) {
0870: filter.setText(((AllBufferSet) fileset).getFileFilter());
0871: }
0872:
0873: directory.addCurrentToHistory();
0874:
0875: keepDialog.setSelected(jEdit
0876: .getBooleanProperty("search.keepDialog.toggle"));
0877: } //}}}
0878:
0879: //}}}
0880:
0881: //{{{ Inner classes
0882:
0883: //{{{ MyJRadioButton class
0884:
0885: // used for the stringReplace and beanShell replace radio buttons,
0886: // so that the user can press tab to go from the find field to the
0887: // replace field in one go
0888: static class MyJRadioButton extends JRadioButton {
0889: MyJRadioButton(String label) {
0890: super (label);
0891: }
0892:
0893: public boolean isFocusable() {
0894: return false;
0895: }
0896: } //}}}
0897:
0898: //{{{ ReplaceActionHandler class
0899: class ReplaceActionHandler implements ActionListener {
0900: public void actionPerformed(ActionEvent evt) {
0901: replace
0902: .setModel(beanShellReplace.isSelected() ? "replace.script"
0903: : "replace");
0904: SearchAndReplace.setBeanShellReplace(beanShellReplace
0905: .isSelected());
0906: }
0907: } //}}}
0908:
0909: //{{{ SettingsActionHandler class
0910: class SettingsActionHandler implements ActionListener {
0911: public void actionPerformed(ActionEvent evt) {
0912: Object source = evt.getSource();
0913:
0914: if (source == searchCurrentBuffer)
0915: hyperSearch.setSelected(false);
0916: else if (source == searchSelection
0917: || source == searchAllBuffers
0918: || source == searchDirectory)
0919: hyperSearch.setSelected(true);
0920:
0921: save(true);
0922: updateEnabled();
0923: }
0924: } //}}}
0925:
0926: //{{{ MultiFileActionHandler class
0927: class MultiFileActionHandler implements ActionListener {
0928: public void actionPerformed(ActionEvent evt) {
0929: if (evt.getSource() == choose) {
0930: String[] dirs = GUIUtilities.showVFSFileDialog(
0931: SearchDialog.this , view, directory.getText(),
0932: VFSBrowser.CHOOSE_DIRECTORY_DIALOG, false);
0933: if (dirs != null)
0934: directory.setText(dirs[0]);
0935: } else if (evt.getSource() == synchronize) {
0936: synchronizeMultiFileSettings();
0937: } else // source is directory or filter field
0938: {
0939: // just as if Enter was pressed in another
0940: // text field
0941: ok();
0942: }
0943: }
0944:
0945: //{{{ synchronizeMultiFileSettings() method
0946: private void synchronizeMultiFileSettings() {
0947: directory.setText(view.getBuffer().getDirectory());
0948:
0949: SearchFileSet fileset = SearchAndReplace.getSearchFileSet();
0950:
0951: if (fileset instanceof AllBufferSet) {
0952: filter
0953: .setText(((AllBufferSet) fileset)
0954: .getFileFilter());
0955: } else {
0956: filter.setText('*' + MiscUtilities
0957: .getFileExtension(view.getBuffer().getName()));
0958: }
0959: } //}}}
0960: } //}}}
0961:
0962: //{{{ ButtonActionHandler class
0963: class ButtonActionHandler implements ActionListener {
0964: public void actionPerformed(ActionEvent evt) {
0965: Object source = evt.getSource();
0966:
0967: if (source == closeBtn)
0968: cancel();
0969: else if (source == findBtn || source == find
0970: || source == replace) {
0971: ok();
0972: } else if (source == replaceAndFindBtn) {
0973: save(false);
0974: if (SearchAndReplace.replace(view))
0975: ok();
0976: else
0977: getToolkit().beep();
0978: } else if (source == replaceAllBtn) {
0979: if (searchSelection.isSelected()
0980: && view.getTextArea().getSelectionCount() == 0) {
0981: GUIUtilities.error(view, "search-no-selection",
0982: null);
0983: return;
0984: }
0985:
0986: setCursor(Cursor
0987: .getPredefinedCursor(Cursor.WAIT_CURSOR));
0988:
0989: if (!save(false)) {
0990: setCursor(Cursor
0991: .getPredefinedCursor(Cursor.DEFAULT_CURSOR));
0992: getToolkit().beep();
0993: return;
0994: }
0995:
0996: if (searchSelection.isSelected()) {
0997: if (SearchAndReplace.replace(view))
0998: closeOrKeepDialog();
0999: else
1000: getToolkit().beep();
1001: } else {
1002: if (SearchAndReplace.replaceAll(view))
1003: closeOrKeepDialog();
1004: else
1005: getToolkit().beep();
1006: }
1007:
1008: setCursor(Cursor
1009: .getPredefinedCursor(Cursor.DEFAULT_CURSOR));
1010: }
1011: }
1012: } //}}}
1013:
1014: //}}}
1015: }
|