/jEdit/tags/jedit-4-1-pre5/org/gjt/sp/jedit/search/SearchDialog.java

# · Java · 909 lines · 651 code · 142 blank · 116 comment · 115 complexity · 6af863c2ae3ef77c2f1f53b8d3a92742 MD5 · raw file

  1. /*
  2. * SearchDialog.java - Search and replace dialog
  3. * :tabSize=8:indentSize=8:noTabs=false:
  4. * :folding=explicit:collapseFolds=1:
  5. *
  6. * Copyright (C) 1998, 1999, 2000, 2001 Slava Pestov
  7. *
  8. * This program is free software; you can redistribute it and/or
  9. * modify it under the terms of the GNU General Public License
  10. * as published by the Free Software Foundation; either version 2
  11. * of the License, or any later version.
  12. *
  13. * This program is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License
  19. * along with this program; if not, write to the Free Software
  20. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  21. */
  22. package org.gjt.sp.jedit.search;
  23. //{{{ Imports
  24. import javax.swing.border.*;
  25. import javax.swing.event.*;
  26. import javax.swing.*;
  27. import java.awt.*;
  28. import java.awt.event.*;
  29. import java.io.File;
  30. import java.util.HashMap;
  31. import org.gjt.sp.jedit.browser.VFSBrowser;
  32. import org.gjt.sp.jedit.gui.*;
  33. import org.gjt.sp.jedit.io.*;
  34. import org.gjt.sp.jedit.msg.SearchSettingsChanged;
  35. import org.gjt.sp.jedit.msg.ViewUpdate;
  36. import org.gjt.sp.jedit.*;
  37. import org.gjt.sp.util.Log;
  38. //}}}
  39. /**
  40. * Search and replace dialog.
  41. * @author Slava Pestov
  42. * @version $Id: SearchDialog.java 4261 2002-06-18 02:44:52Z spestov $
  43. */
  44. public class SearchDialog extends EnhancedDialog implements EBComponent
  45. {
  46. //{{{ Constants
  47. /**
  48. * Default file set.
  49. * @since jEdit 3.2pre2
  50. */
  51. public static final int CURRENT_BUFFER = 0;
  52. public static final int ALL_BUFFERS = 1;
  53. public static final int DIRECTORY = 2;
  54. //}}}
  55. //{{{ showSearchDialog() method
  56. /**
  57. * Displays a search and replace dialog box, reusing an existing one
  58. * if necessary.
  59. * @param view The view
  60. * @param searchString The search string
  61. * @param searchIn One of CURRENT_BUFFER, ALL_BUFFERS, or DIRECTORY
  62. * @since jEdit 4.0pre6
  63. */
  64. public static void showSearchDialog(View view, String searchString,
  65. int searchIn)
  66. {
  67. SearchDialog dialog = (SearchDialog)viewHash.get(view);
  68. if(dialog != null)
  69. {
  70. // ugly workaround
  71. if(OperatingSystem.isUnix() && !OperatingSystem.isMacOS())
  72. {
  73. dialog.setVisible(false);
  74. dialog.setVisible(true);
  75. }
  76. dialog.setSearchString(searchString,searchIn);
  77. GUIUtilities.requestFocus(dialog,dialog.find);
  78. dialog.toFront();
  79. dialog.requestFocus();
  80. }
  81. else
  82. {
  83. dialog = new SearchDialog(view,searchString,searchIn);
  84. viewHash.put(view,dialog);
  85. }
  86. } //}}}
  87. //{{{ SearchDialog constructor
  88. /**
  89. * Creates a new search and replace dialog box.
  90. * @param view The view
  91. * @param searchString The search string
  92. */
  93. public SearchDialog(View view, String searchString)
  94. {
  95. this(view,searchString,CURRENT_BUFFER);
  96. } //}}}
  97. //{{{ SearchDialog constructor
  98. /**
  99. * Creates a new search and replace dialog box.
  100. * @param view The view
  101. * @param searchString The search string
  102. * @param searchIn One of CURRENT_BUFFER, ALL_BUFFERS, or DIRECTORY
  103. * @since jEdit 3.2pre2
  104. */
  105. public SearchDialog(View view, String searchString, int searchIn)
  106. {
  107. super(view,jEdit.getProperty("search.title"),false);
  108. this.view = view;
  109. JPanel content = new JPanel(new BorderLayout());
  110. content.setBorder(new EmptyBorder(0,12,12,12));
  111. setContentPane(content);
  112. JPanel centerPanel = new JPanel(new BorderLayout());
  113. centerPanel.add(BorderLayout.NORTH,createFieldPanel());
  114. centerPanel.add(BorderLayout.CENTER,createSearchSettingsPanel());
  115. content.add(BorderLayout.CENTER,centerPanel);
  116. content.add(BorderLayout.SOUTH,createMultiFilePanel());
  117. content.add(BorderLayout.EAST,createButtonsPanel());
  118. ignoreCase.setSelected(SearchAndReplace.getIgnoreCase());
  119. regexp.setSelected(SearchAndReplace.getRegexp());
  120. wrap.setSelected(SearchAndReplace.getAutoWrapAround());
  121. if(SearchAndReplace.getReverseSearch())
  122. searchBack.setSelected(true);
  123. else
  124. searchForward.setSelected(true);
  125. if(SearchAndReplace.getBeanShellReplace())
  126. {
  127. replace.setModel("replace.script");
  128. beanShellReplace.setSelected(true);
  129. }
  130. else
  131. {
  132. replace.setModel("replace");
  133. stringReplace.setSelected(true);
  134. }
  135. SearchFileSet fileset = SearchAndReplace.getSearchFileSet();
  136. if(fileset instanceof DirectoryListSet)
  137. {
  138. filter.setText(((DirectoryListSet)fileset)
  139. .getFileFilter());
  140. directory.setText(((DirectoryListSet)fileset)
  141. .getDirectory());
  142. searchSubDirectories.setSelected(((DirectoryListSet)fileset)
  143. .isRecursive());
  144. }
  145. else
  146. {
  147. String path = MiscUtilities.getParentOfPath(
  148. view.getBuffer().getPath());
  149. if(path.endsWith("/") || path.endsWith(File.separator))
  150. path = path.substring(0,path.length() - 1);
  151. directory.setText(path);
  152. if(fileset instanceof AllBufferSet)
  153. {
  154. filter.setText(((AllBufferSet)fileset)
  155. .getFileFilter());
  156. }
  157. else
  158. {
  159. filter.setText("*" + MiscUtilities
  160. .getFileExtension(view.getBuffer()
  161. .getName()));
  162. }
  163. searchSubDirectories.setSelected(true);
  164. }
  165. directory.addCurrentToHistory();
  166. keepDialog.setSelected(jEdit.getBooleanProperty(
  167. "search.keepDialog.toggle"));
  168. setSearchString(searchString,searchIn);
  169. pack();
  170. jEdit.unsetProperty("search.width");
  171. jEdit.unsetProperty("search.d-width");
  172. jEdit.unsetProperty("search.height");
  173. jEdit.unsetProperty("search.d-height");
  174. GUIUtilities.loadGeometry(this,"search");
  175. show();
  176. EditBus.addToBus(this);
  177. GUIUtilities.requestFocus(this,find);
  178. } //}}}
  179. //{{{ setSearchString() method
  180. /**
  181. * Sets the search string.
  182. * @since jEdit 4.0pre5
  183. */
  184. public void setSearchString(String searchString, int searchIn)
  185. {
  186. if(searchString == null)
  187. find.setText(null);
  188. else
  189. {
  190. if(searchString.indexOf('\n') == -1)
  191. {
  192. find.setText(searchString);
  193. find.selectAll();
  194. }
  195. else if(searchIn == CURRENT_BUFFER)
  196. {
  197. searchSelection.setSelected(true);
  198. hyperSearch.setSelected(true);
  199. }
  200. }
  201. if(searchIn == CURRENT_BUFFER)
  202. {
  203. if(!searchSelection.isSelected())
  204. {
  205. // might be already selected, see above.
  206. searchCurrentBuffer.setSelected(true);
  207. /* this property is only loaded and saved if
  208. * the 'current buffer' file set is selected.
  209. * otherwise, it defaults to on. */
  210. hyperSearch.setSelected(jEdit.getBooleanProperty(
  211. "search.hypersearch.toggle"));
  212. }
  213. }
  214. else if(searchIn == ALL_BUFFERS)
  215. {
  216. searchAllBuffers.setSelected(true);
  217. hyperSearch.setSelected(true);
  218. }
  219. else if(searchIn == DIRECTORY)
  220. {
  221. hyperSearch.setSelected(true);
  222. searchDirectory.setSelected(true);
  223. }
  224. updateEnabled();
  225. } //}}}
  226. //{{{ ok() method
  227. public void ok()
  228. {
  229. try
  230. {
  231. setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
  232. if(!save(false))
  233. return;
  234. if(hyperSearch.isSelected() || searchSelection.isSelected())
  235. {
  236. if(SearchAndReplace.hyperSearch(view,
  237. searchSelection.isSelected()))
  238. closeOrKeepDialog();
  239. }
  240. else
  241. {
  242. if(SearchAndReplace.find(view))
  243. closeOrKeepDialog();
  244. else
  245. {
  246. toFront();
  247. requestFocus();
  248. find.requestFocus();
  249. }
  250. }
  251. }
  252. finally
  253. {
  254. setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
  255. }
  256. } //}}}
  257. //{{{ cancel() method
  258. public void cancel()
  259. {
  260. save(true);
  261. GUIUtilities.saveGeometry(this,"search");
  262. dispose();
  263. } //}}}
  264. //{{{ handleMessage() method
  265. public void handleMessage(EBMessage msg)
  266. {
  267. if(msg instanceof SearchSettingsChanged)
  268. {
  269. ignoreCase.setSelected(SearchAndReplace.getIgnoreCase());
  270. regexp.setSelected(SearchAndReplace.getRegexp());
  271. }
  272. else if(msg instanceof ViewUpdate)
  273. {
  274. ViewUpdate vmsg = (ViewUpdate)msg;
  275. if(vmsg.getView() == view
  276. && vmsg.getWhat() == ViewUpdate.CLOSED)
  277. {
  278. viewHash.remove(view);
  279. }
  280. }
  281. } //}}}
  282. //{{{ dispose() method
  283. public void dispose()
  284. {
  285. EditBus.removeFromBus(this);
  286. viewHash.remove(view);
  287. super.dispose();
  288. } //}}}
  289. //{{{ Private members
  290. private static HashMap viewHash = new HashMap();
  291. //{{{ Instance variables
  292. private View view;
  293. // fields
  294. private HistoryTextField find, replace;
  295. private JRadioButton stringReplace, beanShellReplace;
  296. // search settings
  297. private JCheckBox keepDialog, ignoreCase, regexp, hyperSearch,
  298. wrap;
  299. private JRadioButton searchBack, searchForward;
  300. private JRadioButton searchSelection, searchCurrentBuffer, searchAllBuffers,
  301. searchDirectory;
  302. // multifile settings
  303. private HistoryTextField filter, directory;
  304. private JCheckBox searchSubDirectories;
  305. private JButton choose;
  306. // buttons
  307. private JButton findBtn, /* replaceBtn, */ replaceAndFindBtn, replaceAllBtn,
  308. closeBtn;
  309. //}}}
  310. //{{{ createFieldPanel() method
  311. private JPanel createFieldPanel()
  312. {
  313. ButtonActionHandler actionHandler = new ButtonActionHandler();
  314. JPanel fieldPanel = new JPanel(new VariableGridLayout(
  315. VariableGridLayout.FIXED_NUM_COLUMNS,1));
  316. fieldPanel.setBorder(new EmptyBorder(0,0,12,12));
  317. JLabel label = new JLabel(jEdit.getProperty("search.find"));
  318. label.setDisplayedMnemonic(jEdit.getProperty("search.find.mnemonic")
  319. .charAt(0));
  320. find = new HistoryTextField("find");
  321. // don't want it to be too wide due to long strings
  322. Dimension size = find.getPreferredSize();
  323. size.width = find.getFontMetrics(find.getFont())
  324. .charWidth('a') * 25;
  325. find.setPreferredSize(size);
  326. find.addActionListener(actionHandler);
  327. label.setLabelFor(find);
  328. label.setBorder(new EmptyBorder(12,0,2,0));
  329. fieldPanel.add(label);
  330. fieldPanel.add(find);
  331. label = new JLabel(jEdit.getProperty("search.replace"));
  332. label.setDisplayedMnemonic(jEdit.getProperty("search.replace.mnemonic")
  333. .charAt(0));
  334. label.setBorder(new EmptyBorder(12,0,0,0));
  335. fieldPanel.add(label);
  336. ButtonGroup grp = new ButtonGroup();
  337. ReplaceActionHandler replaceActionHandler = new ReplaceActionHandler();
  338. // we use a custom JRadioButton subclass that returns
  339. // false for isFocusTraversable() so that the user can
  340. // tab from the search field to the replace field with
  341. // one keystroke
  342. Box replaceModeBox = new Box(BoxLayout.X_AXIS);
  343. stringReplace = new MyJRadioButton(jEdit.getProperty(
  344. "search.string-replace-btn"));
  345. stringReplace.addActionListener(replaceActionHandler);
  346. grp.add(stringReplace);
  347. replaceModeBox.add(stringReplace);
  348. replaceModeBox.add(Box.createHorizontalStrut(12));
  349. beanShellReplace = new MyJRadioButton(jEdit.getProperty(
  350. "search.beanshell-replace-btn"));
  351. beanShellReplace.addActionListener(replaceActionHandler);
  352. grp.add(beanShellReplace);
  353. replaceModeBox.add(beanShellReplace);
  354. fieldPanel.add(replaceModeBox);
  355. fieldPanel.add(Box.createVerticalStrut(3));
  356. replace = new HistoryTextField("replace");
  357. replace.addActionListener(actionHandler);
  358. label.setLabelFor(replace);
  359. fieldPanel.add(replace);
  360. return fieldPanel;
  361. } //}}}
  362. //{{{ createSearchSettingsPanel() method
  363. private JPanel createSearchSettingsPanel()
  364. {
  365. JPanel searchSettings = new JPanel(new VariableGridLayout(
  366. VariableGridLayout.FIXED_NUM_COLUMNS,3));
  367. searchSettings.setBorder(new EmptyBorder(0,0,12,12));
  368. SettingsActionHandler actionHandler = new SettingsActionHandler();
  369. ButtonGroup fileset = new ButtonGroup();
  370. ButtonGroup direction = new ButtonGroup();
  371. searchSettings.add(new JLabel(jEdit.getProperty("search.fileset")));
  372. searchSettings.add(new JLabel(jEdit.getProperty("search.settings")));
  373. searchSettings.add(new JLabel(jEdit.getProperty("search.direction")));
  374. searchSelection = new JRadioButton(jEdit.getProperty("search.selection"));
  375. searchSelection.setMnemonic(jEdit.getProperty("search.selection.mnemonic")
  376. .charAt(0));
  377. fileset.add(searchSelection);
  378. searchSettings.add(searchSelection);
  379. searchSelection.addActionListener(actionHandler);
  380. keepDialog = new JCheckBox(jEdit.getProperty("search.keep"));
  381. keepDialog.setMnemonic(jEdit.getProperty("search.keep.mnemonic")
  382. .charAt(0));
  383. searchSettings.add(keepDialog);
  384. searchBack = new JRadioButton(jEdit.getProperty("search.back"));
  385. searchBack.setMnemonic(jEdit.getProperty("search.back.mnemonic")
  386. .charAt(0));
  387. direction.add(searchBack);
  388. searchSettings.add(searchBack);
  389. searchBack.addActionListener(actionHandler);
  390. searchCurrentBuffer = new JRadioButton(jEdit.getProperty("search.current"));
  391. searchCurrentBuffer.setMnemonic(jEdit.getProperty("search.current.mnemonic")
  392. .charAt(0));
  393. fileset.add(searchCurrentBuffer);
  394. searchSettings.add(searchCurrentBuffer);
  395. searchCurrentBuffer.addActionListener(actionHandler);
  396. ignoreCase = new JCheckBox(jEdit.getProperty("search.case"));
  397. ignoreCase.setMnemonic(jEdit.getProperty("search.case.mnemonic")
  398. .charAt(0));
  399. searchSettings.add(ignoreCase);
  400. ignoreCase.addActionListener(actionHandler);
  401. searchForward = new JRadioButton(jEdit.getProperty("search.forward"));
  402. searchForward.setMnemonic(jEdit.getProperty("search.forward.mnemonic")
  403. .charAt(0));
  404. direction.add(searchForward);
  405. searchSettings.add(searchForward);
  406. searchForward.addActionListener(actionHandler);
  407. searchAllBuffers = new JRadioButton(jEdit.getProperty("search.all"));
  408. searchAllBuffers.setMnemonic(jEdit.getProperty("search.all.mnemonic")
  409. .charAt(0));
  410. fileset.add(searchAllBuffers);
  411. searchSettings.add(searchAllBuffers);
  412. searchAllBuffers.addActionListener(actionHandler);
  413. regexp = new JCheckBox(jEdit.getProperty("search.regexp"));
  414. regexp.setMnemonic(jEdit.getProperty("search.regexp.mnemonic")
  415. .charAt(0));
  416. searchSettings.add(regexp);
  417. regexp.addActionListener(actionHandler);
  418. wrap = new JCheckBox(jEdit.getProperty("search.wrap"));
  419. wrap.setMnemonic(jEdit.getProperty("search.wrap.mnemonic")
  420. .charAt(0));
  421. searchSettings.add(wrap);
  422. wrap.addActionListener(actionHandler);
  423. searchDirectory = new JRadioButton(jEdit.getProperty("search.directory"));
  424. searchDirectory.setMnemonic(jEdit.getProperty("search.directory.mnemonic")
  425. .charAt(0));
  426. fileset.add(searchDirectory);
  427. searchSettings.add(searchDirectory);
  428. searchDirectory.addActionListener(actionHandler);
  429. hyperSearch = new JCheckBox(jEdit.getProperty("search.hypersearch"));
  430. hyperSearch.setMnemonic(jEdit.getProperty("search.hypersearch.mnemonic")
  431. .charAt(0));
  432. searchSettings.add(hyperSearch);
  433. hyperSearch.addActionListener(actionHandler);
  434. return searchSettings;
  435. } //}}}
  436. //{{{ createMultiFilePanel() method
  437. private JPanel createMultiFilePanel()
  438. {
  439. JPanel multifile = new JPanel();
  440. GridBagLayout layout = new GridBagLayout();
  441. multifile.setLayout(layout);
  442. GridBagConstraints cons = new GridBagConstraints();
  443. cons.gridy = cons.gridwidth = cons.gridheight = 1;
  444. cons.anchor = GridBagConstraints.WEST;
  445. cons.fill = GridBagConstraints.HORIZONTAL;
  446. MultiFileActionHandler actionListener = new MultiFileActionHandler();
  447. filter = new HistoryTextField("search.filter");
  448. filter.addActionListener(actionListener);
  449. cons.insets = new Insets(0,0,3,0);
  450. JLabel label = new JLabel(jEdit.getProperty("search.filterField"),
  451. SwingConstants.RIGHT);
  452. label.setBorder(new EmptyBorder(0,0,0,12));
  453. label.setDisplayedMnemonic(jEdit.getProperty("search.filterField.mnemonic")
  454. .charAt(0));
  455. label.setLabelFor(filter);
  456. cons.weightx = 0.0f;
  457. layout.setConstraints(label,cons);
  458. multifile.add(label);
  459. cons.insets = new Insets(0,0,3,6);
  460. cons.weightx = 1.0f;
  461. layout.setConstraints(filter,cons);
  462. multifile.add(filter);
  463. cons.gridy++;
  464. directory = new HistoryTextField("search.directory");
  465. directory.addActionListener(actionListener);
  466. label = new JLabel(jEdit.getProperty("search.directoryField"),
  467. SwingConstants.RIGHT);
  468. label.setBorder(new EmptyBorder(0,0,0,12));
  469. label.setDisplayedMnemonic(jEdit.getProperty("search.directoryField.mnemonic")
  470. .charAt(0));
  471. label.setLabelFor(directory);
  472. cons.insets = new Insets(0,0,3,0);
  473. cons.weightx = 0.0f;
  474. layout.setConstraints(label,cons);
  475. multifile.add(label);
  476. cons.insets = new Insets(0,0,3,6);
  477. cons.weightx = 1.0f;
  478. cons.gridwidth = 2;
  479. layout.setConstraints(directory,cons);
  480. multifile.add(directory);
  481. choose = new JButton(jEdit.getProperty("search.choose"));
  482. choose.setMnemonic(jEdit.getProperty("search.choose.mnemonic")
  483. .charAt(0));
  484. cons.insets = new Insets(0,0,3,0);
  485. cons.weightx = 0.0f;
  486. cons.gridwidth = 1;
  487. layout.setConstraints(choose,cons);
  488. multifile.add(choose);
  489. choose.addActionListener(actionListener);
  490. cons.insets = new Insets(0,0,0,0);
  491. cons.gridy++;
  492. cons.gridwidth = 4;
  493. searchSubDirectories = new JCheckBox(jEdit.getProperty(
  494. "search.subdirs"));
  495. searchSubDirectories.setMnemonic(jEdit.getProperty("search.subdirs.mnemonic")
  496. .charAt(0));
  497. layout.setConstraints(searchSubDirectories,cons);
  498. multifile.add(searchSubDirectories);
  499. return multifile;
  500. } //}}}
  501. //{{{ createButtonsPanel() method
  502. private Box createButtonsPanel()
  503. {
  504. Box box = new Box(BoxLayout.Y_AXIS);
  505. ButtonActionHandler actionHandler = new ButtonActionHandler();
  506. box.add(Box.createVerticalStrut(12));
  507. JPanel grid = new JPanel(new GridLayout(5,1,0,12));
  508. findBtn = new JButton(jEdit.getProperty("search.findBtn"));
  509. getRootPane().setDefaultButton(findBtn);
  510. grid.add(findBtn);
  511. findBtn.addActionListener(actionHandler);
  512. /* replaceBtn = new JButton(jEdit.getProperty("search.replaceBtn"));
  513. replaceBtn.setMnemonic(jEdit.getProperty("search.replaceBtn.mnemonic")
  514. .charAt(0));
  515. grid.add(replaceBtn);
  516. replaceBtn.addActionListener(actionHandler); */
  517. replaceAndFindBtn = new JButton(jEdit.getProperty("search.replaceAndFindBtn"));
  518. replaceAndFindBtn.setMnemonic(jEdit.getProperty("search.replaceAndFindBtn.mnemonic")
  519. .charAt(0));
  520. grid.add(replaceAndFindBtn);
  521. replaceAndFindBtn.addActionListener(actionHandler);
  522. replaceAllBtn = new JButton(jEdit.getProperty("search.replaceAllBtn"));
  523. replaceAllBtn.setMnemonic(jEdit.getProperty("search.replaceAllBtn.mnemonic")
  524. .charAt(0));
  525. grid.add(replaceAllBtn);
  526. replaceAllBtn.addActionListener(actionHandler);
  527. closeBtn = new JButton(jEdit.getProperty("common.close"));
  528. grid.add(closeBtn);
  529. closeBtn.addActionListener(actionHandler);
  530. grid.setMaximumSize(grid.getPreferredSize());
  531. box.add(grid);
  532. box.add(Box.createGlue());
  533. return box;
  534. } //}}}
  535. //{{{ updateEnabled() method
  536. private void updateEnabled()
  537. {
  538. wrap.setEnabled(!hyperSearch.isSelected()
  539. && !searchSelection.isSelected());
  540. boolean reverseEnabled = !hyperSearch.isSelected()
  541. && searchCurrentBuffer.isSelected();
  542. searchBack.setEnabled(reverseEnabled && !regexp.isSelected());
  543. searchForward.setEnabled(reverseEnabled);
  544. if(!reverseEnabled)
  545. searchForward.setSelected(true);
  546. filter.setEnabled(searchAllBuffers.isSelected()
  547. || searchDirectory.isSelected());
  548. boolean directoryEnabled = searchDirectory.isSelected();
  549. directory.setEnabled(directoryEnabled);
  550. choose.setEnabled(directoryEnabled);
  551. searchSubDirectories.setEnabled(directoryEnabled);
  552. findBtn.setEnabled(!searchSelection.isSelected()
  553. || hyperSearch.isSelected());
  554. replaceAndFindBtn.setEnabled(!hyperSearch.isSelected()
  555. && !searchSelection.isSelected());
  556. } //}}}
  557. //{{{ save() method
  558. /**
  559. * @param cancel If true, we don't bother the user with warning messages
  560. */
  561. private boolean save(boolean cancel)
  562. {
  563. String filter = this.filter.getText();
  564. this.filter.addCurrentToHistory();
  565. if(filter.length() == 0)
  566. filter = "*";
  567. SearchFileSet fileset = SearchAndReplace.getSearchFileSet();
  568. if(searchSelection.isSelected())
  569. fileset = new CurrentBufferSet();
  570. else if(searchCurrentBuffer.isSelected())
  571. {
  572. fileset = new CurrentBufferSet();
  573. jEdit.setBooleanProperty("search.hypersearch.toggle",
  574. hyperSearch.isSelected());
  575. }
  576. else if(searchAllBuffers.isSelected())
  577. fileset = new AllBufferSet(filter);
  578. else if(searchDirectory.isSelected())
  579. {
  580. String directory = this.directory.getText();
  581. this.directory.addCurrentToHistory();
  582. if((VFSManager.getVFSForPath(directory).getCapabilities()
  583. & VFS.LOW_LATENCY_CAP) == 0)
  584. {
  585. if(cancel)
  586. return false;
  587. int retVal = GUIUtilities.confirm(
  588. SearchDialog.this,"remote-dir-search",
  589. null,JOptionPane.YES_NO_OPTION,
  590. JOptionPane.WARNING_MESSAGE);
  591. if(retVal != JOptionPane.YES_OPTION)
  592. return false;
  593. }
  594. boolean recurse = searchSubDirectories.isSelected();
  595. if(fileset instanceof DirectoryListSet)
  596. {
  597. DirectoryListSet dset = (DirectoryListSet)fileset;
  598. if(!dset.getDirectory().equals(directory)
  599. || !dset.getFileFilter().equals(filter)
  600. || !dset.isRecursive() == recurse)
  601. fileset = new DirectoryListSet(directory,filter,recurse);
  602. }
  603. else
  604. fileset = new DirectoryListSet(directory,filter,recurse);
  605. }
  606. else
  607. {
  608. // can't happen
  609. fileset = null;
  610. }
  611. jEdit.setBooleanProperty("search.keepDialog.toggle",
  612. keepDialog.isSelected());
  613. boolean ok = true;
  614. SearchAndReplace.setSearchFileSet(fileset);
  615. if(find.getText().length() != 0)
  616. {
  617. find.addCurrentToHistory();
  618. SearchAndReplace.setSearchString(find.getText());
  619. replace.addCurrentToHistory();
  620. SearchAndReplace.setReplaceString(replace.getText());
  621. }
  622. else
  623. ok = false;
  624. return ok;
  625. } //}}}
  626. //{{{ closeOrKeepDialog() method
  627. private void closeOrKeepDialog()
  628. {
  629. if(keepDialog.isSelected())
  630. {
  631. // Windows bug workaround in case a YES/NO confirm
  632. // was shown
  633. // ... but if HyperSearch results window is floating,
  634. // the workaround causes problems!
  635. if(!hyperSearch.isSelected())
  636. {
  637. toFront();
  638. requestFocus();
  639. find.requestFocus();
  640. }
  641. return;
  642. }
  643. else
  644. {
  645. GUIUtilities.saveGeometry(this,"search");
  646. dispose();
  647. }
  648. } //}}}
  649. //}}}
  650. //{{{ Inner classes
  651. //{{{ MyJRadioButton class
  652. // used for the stringReplace and beanShell replace radio buttons,
  653. // so that the user can press tab to go from the find field to the
  654. // replace field in one go
  655. class MyJRadioButton extends JRadioButton
  656. {
  657. MyJRadioButton(String label)
  658. {
  659. super(label);
  660. }
  661. public boolean isFocusTraversable()
  662. {
  663. return false;
  664. }
  665. } //}}}
  666. //{{{ ReplaceActionHandler class
  667. class ReplaceActionHandler implements ActionListener
  668. {
  669. public void actionPerformed(ActionEvent evt)
  670. {
  671. replace.setModel(beanShellReplace.isSelected()
  672. ? "replace.script"
  673. : "replace");
  674. SearchAndReplace.setBeanShellReplace(
  675. beanShellReplace.isSelected());
  676. }
  677. } //}}}
  678. //{{{ SettingsActionHandler class
  679. class SettingsActionHandler implements ActionListener
  680. {
  681. public void actionPerformed(ActionEvent evt)
  682. {
  683. Object source = evt.getSource();
  684. if(source == ignoreCase)
  685. SearchAndReplace.setIgnoreCase(ignoreCase.isSelected());
  686. else if(source == regexp)
  687. SearchAndReplace.setRegexp(regexp.isSelected());
  688. else if(source == searchBack || source == searchForward)
  689. SearchAndReplace.setReverseSearch(searchBack.isSelected());
  690. else if(source == wrap)
  691. SearchAndReplace.setAutoWrapAround(wrap.isSelected());
  692. else if(source == searchCurrentBuffer)
  693. hyperSearch.setSelected(false);
  694. else if(source == searchSelection
  695. || source == searchAllBuffers
  696. || source == searchDirectory)
  697. hyperSearch.setSelected(true);
  698. updateEnabled();
  699. }
  700. } //}}}
  701. //{{{ MultiFileActionHandler class
  702. class MultiFileActionHandler implements ActionListener
  703. {
  704. public void actionPerformed(ActionEvent evt)
  705. {
  706. if(evt.getSource() == choose)
  707. {
  708. String[] dirs = GUIUtilities.showVFSFileDialog(
  709. view,directory.getText(),
  710. VFSBrowser.CHOOSE_DIRECTORY_DIALOG,
  711. false);
  712. if(dirs != null)
  713. directory.setText(dirs[0]);
  714. }
  715. else // source is directory or filter field
  716. {
  717. // just as if Enter was pressed in another
  718. // text field
  719. ok();
  720. }
  721. }
  722. } //}}}
  723. //{{{ ButtonActionHandler class
  724. class ButtonActionHandler implements ActionListener
  725. {
  726. public void actionPerformed(ActionEvent evt)
  727. {
  728. Object source = evt.getSource();
  729. if(source == closeBtn)
  730. cancel();
  731. else if(source == findBtn || source == find
  732. || source == replace)
  733. {
  734. ok();
  735. }
  736. else if(source == replaceAndFindBtn)
  737. {
  738. save(false);
  739. if(SearchAndReplace.replace(view))
  740. ok();
  741. else
  742. getToolkit().beep();
  743. }
  744. else if(source == replaceAllBtn)
  745. {
  746. setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
  747. save(false);
  748. if(searchSelection.isSelected())
  749. {
  750. if(SearchAndReplace.replace(view))
  751. closeOrKeepDialog();
  752. else
  753. getToolkit().beep();
  754. }
  755. else
  756. {
  757. if(SearchAndReplace.replaceAll(view))
  758. closeOrKeepDialog();
  759. else
  760. getToolkit().beep();
  761. }
  762. setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
  763. }
  764. }
  765. } //}}}
  766. //}}}
  767. }