PageRenderTime 56ms CodeModel.GetById 24ms RepoModel.GetById 0ms app.codeStats 1ms

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

#
Java | 1058 lines | 774 code | 159 blank | 125 comment | 109 complexity | 7ba891ec10c97c5a67495a149f90b228 MD5 | raw file
Possible License(s): BSD-3-Clause, AGPL-1.0, Apache-2.0, LGPL-2.0, LGPL-3.0, GPL-2.0, CC-BY-SA-3.0, LGPL-2.1, GPL-3.0, MPL-2.0-no-copyleft-exception, IPL-1.0
  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, 2004 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.*;
  26. import java.awt.*;
  27. import java.awt.event.*;
  28. import java.io.File;
  29. import java.util.HashMap;
  30. import org.gjt.sp.jedit.browser.VFSBrowser;
  31. import org.gjt.sp.jedit.gui.*;
  32. import org.gjt.sp.jedit.io.*;
  33. import org.gjt.sp.jedit.msg.SearchSettingsChanged;
  34. import org.gjt.sp.jedit.msg.ViewUpdate;
  35. import org.gjt.sp.jedit.*;
  36. //}}}
  37. /**
  38. * Search and replace dialog.
  39. * @author Slava Pestov
  40. * @version $Id: SearchDialog.java 5425 2006-05-24 18:39:23Z ezust $
  41. */
  42. public class SearchDialog extends EnhancedDialog implements EBComponent
  43. {
  44. //{{{ Constants
  45. /**
  46. * Default file set.
  47. * @since jEdit 3.2pre2
  48. */
  49. public static final int CURRENT_BUFFER = 0;
  50. public static final int ALL_BUFFERS = 1;
  51. public static final int DIRECTORY = 2;
  52. //}}}
  53. //{{{ getSearchDialog() method
  54. public static SearchDialog getSearchDialog(View view)
  55. {
  56. if(Debug.DISABLE_SEARCH_DIALOG_POOL)
  57. return new SearchDialog(view);
  58. else
  59. return (SearchDialog)viewHash.get(view);
  60. } //}}}
  61. //{{{ preloadSearchDialog() method
  62. /**
  63. * Preloads the search dialog for the given for so that it can be
  64. * quickly displayed later.
  65. * @since jEdit 4.2pre3
  66. */
  67. public static void preloadSearchDialog(View view)
  68. {
  69. if(Debug.DISABLE_SEARCH_DIALOG_POOL)
  70. return;
  71. SearchDialog dialog = new SearchDialog(view);
  72. viewHash.put(view,dialog);
  73. } //}}}
  74. //{{{ showSearchDialog() method
  75. /**
  76. * Displays a search and replace dialog box, reusing an existing one
  77. * if necessary.
  78. * @param view The view
  79. * @param searchString The search string
  80. * @param searchIn One of CURRENT_BUFFER, ALL_BUFFERS, or DIRECTORY
  81. * @since jEdit 4.0pre6
  82. */
  83. public static void showSearchDialog(View view, String searchString,
  84. int searchIn)
  85. {
  86. final SearchDialog dialog = getSearchDialog(view);
  87. dialog.setSearchString(searchString,searchIn);
  88. // ugly workaround
  89. if(OperatingSystem.isUnix() && !OperatingSystem.isMacOS())
  90. dialog.setVisible(false);
  91. // I'm not sure if calling requestFocus() is strictly necessary
  92. // (focus looks fine without this, on Linux at least), but
  93. // it doesn't hurt to leave it here.
  94. SwingUtilities.invokeLater(new Runnable() {
  95. public void run() {
  96. dialog.toFront();
  97. dialog.find.requestFocus();
  98. }
  99. });
  100. dialog.setVisible(true);
  101. } //}}}
  102. //{{{ setSearchString() method
  103. /**
  104. * Sets the search string.
  105. * @since jEdit 4.0pre5
  106. */
  107. public void setSearchString(String searchString, int searchIn)
  108. {
  109. find.setText(null);
  110. replace.setText(null);
  111. if(searchString == null)
  112. searchCurrentBuffer.setSelected(true);
  113. else
  114. {
  115. if(searchString.indexOf('\n') == -1)
  116. {
  117. if(SearchAndReplace.getRegexp())
  118. {
  119. find.setText(SearchAndReplace.escapeRegexp(
  120. searchString,true));
  121. }
  122. else
  123. find.setText(searchString);
  124. find.selectAll();
  125. searchCurrentBuffer.setSelected(true);
  126. }
  127. else if(searchIn == CURRENT_BUFFER)
  128. {
  129. searchSelection.setSelected(true);
  130. hyperSearch.setSelected(true);
  131. }
  132. }
  133. if(searchIn == CURRENT_BUFFER)
  134. {
  135. if(!searchSelection.isSelected())
  136. {
  137. // might be already selected, see above.
  138. searchCurrentBuffer.setSelected(true);
  139. /* this property is only loaded and saved if
  140. * the 'current buffer' file set is selected.
  141. * otherwise, it defaults to on. */
  142. hyperSearch.setSelected(jEdit.getBooleanProperty(
  143. "search.hypersearch.toggle"));
  144. }
  145. }
  146. else if(searchIn == ALL_BUFFERS)
  147. {
  148. searchAllBuffers.setSelected(true);
  149. hyperSearch.setSelected(true);
  150. }
  151. else if(searchIn == DIRECTORY)
  152. {
  153. SearchFileSet fileset = SearchAndReplace.getSearchFileSet();
  154. if(fileset instanceof DirectoryListSet)
  155. {
  156. filter.setText(((DirectoryListSet)fileset)
  157. .getFileFilter());
  158. directory.setText(((DirectoryListSet)fileset)
  159. .getDirectory());
  160. searchSubDirectories.setSelected(((DirectoryListSet)fileset)
  161. .isRecursive());
  162. }
  163. hyperSearch.setSelected(true);
  164. searchDirectory.setSelected(true);
  165. }
  166. updateEnabled();
  167. } //}}}
  168. //{{{ ok() method
  169. public void ok()
  170. {
  171. try
  172. {
  173. setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
  174. if(!save(false))
  175. return;
  176. if(searchSelection.isSelected()
  177. && view.getTextArea().getSelectionCount() == 0)
  178. {
  179. GUIUtilities.error(view,"search-no-selection",null);
  180. return;
  181. }
  182. if(hyperSearch.isSelected() || searchSelection.isSelected())
  183. {
  184. if(SearchAndReplace.hyperSearch(view,
  185. searchSelection.isSelected()))
  186. closeOrKeepDialog();
  187. }
  188. else
  189. {
  190. if(SearchAndReplace.find(view))
  191. closeOrKeepDialog();
  192. else
  193. {
  194. toFront();
  195. requestFocus();
  196. find.requestFocus();
  197. }
  198. }
  199. }
  200. finally
  201. {
  202. setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
  203. }
  204. } //}}}
  205. //{{{ cancel() method
  206. public void cancel()
  207. {
  208. save(true);
  209. GUIUtilities.saveGeometry(this,"search");
  210. setVisible(false);
  211. } //}}}
  212. //{{{ handleMessage() method
  213. public void handleMessage(EBMessage msg)
  214. {
  215. if(msg instanceof SearchSettingsChanged)
  216. {
  217. if(!saving)
  218. load();
  219. }
  220. } //}}}
  221. //{{{ dispose() method
  222. public void dispose()
  223. {
  224. EditBus.removeFromBus(this);
  225. viewHash.remove(view);
  226. super.dispose();
  227. } //}}}
  228. //{{{ Private members
  229. private static HashMap viewHash = new HashMap();
  230. //{{{ Instance variables
  231. private View view;
  232. // fields
  233. private HistoryTextArea find, replace;
  234. private JRadioButton stringReplace, beanShellReplace;
  235. // search settings
  236. private JCheckBox keepDialog, ignoreCase, regexp, hyperSearch,
  237. wrap;
  238. private JRadioButton searchBack, searchForward;
  239. private JRadioButton searchSelection, searchCurrentBuffer,
  240. searchAllBuffers, searchDirectory;
  241. // multifile settings
  242. private HistoryTextField filter, directory;
  243. private JCheckBox searchSubDirectories;
  244. private JCheckBox skipBinaryFiles;
  245. private JCheckBox skipHidden;
  246. private JButton choose;
  247. private JButton synchronize;
  248. // buttons
  249. private JButton findBtn, /* replaceBtn, */ replaceAndFindBtn, replaceAllBtn,
  250. closeBtn;
  251. private boolean saving;
  252. //}}}
  253. //{{{ SearchDialog constructor
  254. /**
  255. * Creates a new search and replace dialog box.
  256. * @param view The view
  257. * @param searchString The search string
  258. */
  259. private SearchDialog(View view)
  260. {
  261. super(view,jEdit.getProperty("search.title"),false);
  262. this.view = view;
  263. JPanel content = new JPanel(new BorderLayout());
  264. content.setBorder(new EmptyBorder(0,12,12,12));
  265. setContentPane(content);
  266. JPanel centerPanel = new JPanel(new BorderLayout());
  267. centerPanel.add(BorderLayout.CENTER,createFieldPanel());
  268. centerPanel.add(BorderLayout.SOUTH,createSearchSettingsPanel());
  269. content.add(BorderLayout.CENTER,centerPanel);
  270. content.add(BorderLayout.SOUTH,createMultiFilePanel());
  271. content.add(BorderLayout.EAST,createButtonsPanel());
  272. pack();
  273. jEdit.unsetProperty("search.width");
  274. jEdit.unsetProperty("search.d-width");
  275. jEdit.unsetProperty("search.height");
  276. jEdit.unsetProperty("search.d-height");
  277. GUIUtilities.loadGeometry(this,"search");
  278. load();
  279. EditBus.addToBus(this);
  280. } //}}}
  281. //{{{ createFindLabelAndField() method
  282. private void createFindLabelAndField(JPanel fieldPanel,
  283. GridBagConstraints cons)
  284. {
  285. JLabel label = new JLabel(jEdit.getProperty("search.find"));
  286. label.setDisplayedMnemonic(jEdit.getProperty("search.find.mnemonic")
  287. .charAt(0));
  288. find = new HistoryTextArea("find");
  289. find.setColumns(25);
  290. label.setLabelFor(find);
  291. label.setBorder(new EmptyBorder(12,0,2,0));
  292. cons.gridx = 0;
  293. cons.weightx = 0.0f;
  294. cons.weighty = 0.0f;
  295. fieldPanel.add(label,cons);
  296. cons.gridy++;
  297. cons.weightx = 1.0f;
  298. cons.weighty = 1.0f;
  299. fieldPanel.add(new JScrollPane(find),cons);
  300. cons.gridy++;
  301. } //}}}
  302. //{{{ createReplaceLabelAndField() method
  303. private void createReplaceLabelAndField(JPanel fieldPanel,
  304. GridBagConstraints cons)
  305. {
  306. JLabel label = new JLabel(jEdit.getProperty("search.replace"));
  307. label.setDisplayedMnemonic(jEdit.getProperty("search.replace.mnemonic")
  308. .charAt(0));
  309. label.setBorder(new EmptyBorder(12,0,0,0));
  310. cons.gridx = 0;
  311. cons.weightx = 0.0f;
  312. cons.weighty = 0.0f;
  313. fieldPanel.add(label,cons);
  314. cons.gridy++;
  315. ButtonGroup grp = new ButtonGroup();
  316. ReplaceActionHandler replaceActionHandler = new ReplaceActionHandler();
  317. // we use a custom JRadioButton subclass that returns
  318. // false for isFocusTraversable() so that the user can
  319. // tab from the search field to the replace field with
  320. // one keystroke
  321. stringReplace = new MyJRadioButton(jEdit.getProperty(
  322. "search.string-replace-btn"));
  323. stringReplace.addActionListener(replaceActionHandler);
  324. grp.add(stringReplace);
  325. cons.gridwidth = 1;
  326. fieldPanel.add(stringReplace,cons);
  327. cons.gridx++;
  328. cons.insets = new Insets(0,12,0,0);
  329. beanShellReplace = new MyJRadioButton(jEdit.getProperty(
  330. "search.beanshell-replace-btn"));
  331. beanShellReplace.addActionListener(replaceActionHandler);
  332. grp.add(beanShellReplace);
  333. fieldPanel.add(beanShellReplace,cons);
  334. cons.gridx = 0;
  335. cons.gridwidth = 2;
  336. cons.insets = new Insets(0,0,0,0);
  337. replace = new HistoryTextArea("replace");
  338. label.setLabelFor(replace);
  339. cons.gridx = 0;
  340. cons.gridy++;
  341. cons.weightx = 1.0f;
  342. cons.weighty = 1.0f;
  343. fieldPanel.add(new JScrollPane(replace),cons);
  344. cons.gridy++;
  345. } //}}}
  346. //{{{ createFieldPanel() method
  347. private JPanel createFieldPanel()
  348. {
  349. JPanel fieldPanel = new JPanel(new GridBagLayout());
  350. fieldPanel.setBorder(new EmptyBorder(0,0,12,12));
  351. GridBagConstraints cons = new GridBagConstraints();
  352. cons.fill = GridBagConstraints.BOTH;
  353. cons.gridy = 0;
  354. cons.gridwidth = 2;
  355. createFindLabelAndField(fieldPanel,cons);
  356. createReplaceLabelAndField(fieldPanel,cons);
  357. return fieldPanel;
  358. } //}}}
  359. //{{{ createSearchSettingsPanel() method
  360. private JPanel createSearchSettingsPanel()
  361. {
  362. JPanel searchSettings = new JPanel(new VariableGridLayout(
  363. VariableGridLayout.FIXED_NUM_COLUMNS,3));
  364. searchSettings.setBorder(new EmptyBorder(0,0,12,12));
  365. SettingsActionHandler actionHandler = new SettingsActionHandler();
  366. ButtonGroup fileset = new ButtonGroup();
  367. ButtonGroup direction = new ButtonGroup();
  368. searchSettings.add(new JLabel(jEdit.getProperty("search.fileset")));
  369. searchSettings.add(new JLabel(jEdit.getProperty("search.settings")));
  370. searchSettings.add(new JLabel(jEdit.getProperty("search.direction")));
  371. searchSelection = new JRadioButton(jEdit.getProperty("search.selection"));
  372. searchSelection.setMnemonic(jEdit.getProperty("search.selection.mnemonic")
  373. .charAt(0));
  374. fileset.add(searchSelection);
  375. searchSettings.add(searchSelection);
  376. searchSelection.addActionListener(actionHandler);
  377. keepDialog = new JCheckBox(jEdit.getProperty("search.keep"));
  378. keepDialog.setMnemonic(jEdit.getProperty("search.keep.mnemonic")
  379. .charAt(0));
  380. searchSettings.add(keepDialog);
  381. searchBack = new JRadioButton(jEdit.getProperty("search.back"));
  382. searchBack.setMnemonic(jEdit.getProperty("search.back.mnemonic")
  383. .charAt(0));
  384. direction.add(searchBack);
  385. searchSettings.add(searchBack);
  386. searchBack.addActionListener(actionHandler);
  387. searchCurrentBuffer = new JRadioButton(jEdit.getProperty("search.current"));
  388. searchCurrentBuffer.setMnemonic(jEdit.getProperty("search.current.mnemonic")
  389. .charAt(0));
  390. fileset.add(searchCurrentBuffer);
  391. searchSettings.add(searchCurrentBuffer);
  392. searchCurrentBuffer.addActionListener(actionHandler);
  393. ignoreCase = new JCheckBox(jEdit.getProperty("search.case"));
  394. ignoreCase.setMnemonic(jEdit.getProperty("search.case.mnemonic")
  395. .charAt(0));
  396. searchSettings.add(ignoreCase);
  397. ignoreCase.addActionListener(actionHandler);
  398. searchForward = new JRadioButton(jEdit.getProperty("search.forward"));
  399. searchForward.setMnemonic(jEdit.getProperty("search.forward.mnemonic")
  400. .charAt(0));
  401. direction.add(searchForward);
  402. searchSettings.add(searchForward);
  403. searchForward.addActionListener(actionHandler);
  404. searchAllBuffers = new JRadioButton(jEdit.getProperty("search.all"));
  405. searchAllBuffers.setMnemonic(jEdit.getProperty("search.all.mnemonic")
  406. .charAt(0));
  407. fileset.add(searchAllBuffers);
  408. searchSettings.add(searchAllBuffers);
  409. searchAllBuffers.addActionListener(actionHandler);
  410. regexp = new JCheckBox(jEdit.getProperty("search.regexp"));
  411. regexp.setMnemonic(jEdit.getProperty("search.regexp.mnemonic")
  412. .charAt(0));
  413. searchSettings.add(regexp);
  414. regexp.addActionListener(actionHandler);
  415. wrap = new JCheckBox(jEdit.getProperty("search.wrap"));
  416. wrap.setMnemonic(jEdit.getProperty("search.wrap.mnemonic")
  417. .charAt(0));
  418. searchSettings.add(wrap);
  419. wrap.addActionListener(actionHandler);
  420. searchDirectory = new JRadioButton(jEdit.getProperty("search.directory"));
  421. searchDirectory.setMnemonic(jEdit.getProperty("search.directory.mnemonic")
  422. .charAt(0));
  423. fileset.add(searchDirectory);
  424. searchSettings.add(searchDirectory);
  425. searchDirectory.addActionListener(actionHandler);
  426. hyperSearch = new JCheckBox(jEdit.getProperty("search.hypersearch"));
  427. hyperSearch.setMnemonic(jEdit.getProperty("search.hypersearch.mnemonic")
  428. .charAt(0));
  429. searchSettings.add(hyperSearch);
  430. hyperSearch.addActionListener(actionHandler);
  431. return searchSettings;
  432. } //}}}
  433. //{{{ createMultiFilePanel() method
  434. private JPanel createMultiFilePanel()
  435. {
  436. JPanel multifile = new JPanel();
  437. GridBagLayout layout = new GridBagLayout();
  438. multifile.setLayout(layout);
  439. GridBagConstraints cons = new GridBagConstraints();
  440. cons.gridy = cons.gridwidth = cons.gridheight = 1;
  441. cons.anchor = GridBagConstraints.WEST;
  442. cons.fill = GridBagConstraints.HORIZONTAL;
  443. MultiFileActionHandler actionListener = new MultiFileActionHandler();
  444. filter = new HistoryTextField("search.filter");
  445. filter.addActionListener(actionListener);
  446. cons.insets = new Insets(0,0,3,0);
  447. JLabel label = new JLabel(jEdit.getProperty("search.filterField"),
  448. SwingConstants.RIGHT);
  449. label.setBorder(new EmptyBorder(0,0,0,12));
  450. label.setDisplayedMnemonic(jEdit.getProperty("search.filterField.mnemonic")
  451. .charAt(0));
  452. label.setLabelFor(filter);
  453. cons.weightx = 0.0f;
  454. layout.setConstraints(label,cons);
  455. multifile.add(label);
  456. cons.gridwidth = 2;
  457. cons.insets = new Insets(0,0,3,6);
  458. cons.weightx = 1.0f;
  459. layout.setConstraints(filter,cons);
  460. multifile.add(filter);
  461. cons.gridwidth = 1;
  462. cons.weightx = 0.0f;
  463. cons.insets = new Insets(0,0,3,0);
  464. synchronize = new JButton(jEdit.getProperty(
  465. "search.synchronize"));
  466. synchronize.setMnemonic(jEdit.getProperty(
  467. "search.synchronize.mnemonic")
  468. .charAt(0));
  469. synchronize.addActionListener(actionListener);
  470. layout.setConstraints(synchronize,cons);
  471. multifile.add(synchronize);
  472. cons.gridy++;
  473. directory = new HistoryTextField("search.directory");
  474. directory.setColumns(25);
  475. directory.addActionListener(actionListener);
  476. label = new JLabel(jEdit.getProperty("search.directoryField"),
  477. SwingConstants.RIGHT);
  478. label.setBorder(new EmptyBorder(0,0,0,12));
  479. label.setDisplayedMnemonic(jEdit.getProperty("search.directoryField.mnemonic")
  480. .charAt(0));
  481. label.setLabelFor(directory);
  482. cons.insets = new Insets(0,0,3,0);
  483. cons.weightx = 0.0f;
  484. layout.setConstraints(label,cons);
  485. multifile.add(label);
  486. cons.insets = new Insets(0,0,3,6);
  487. cons.weightx = 1.0f;
  488. cons.gridwidth = 2;
  489. layout.setConstraints(directory,cons);
  490. multifile.add(directory);
  491. choose = new JButton(jEdit.getProperty("search.choose"));
  492. choose.setMnemonic(jEdit.getProperty("search.choose.mnemonic")
  493. .charAt(0));
  494. cons.insets = new Insets(0,0,3,0);
  495. cons.weightx = 0.0f;
  496. cons.gridwidth = 1;
  497. layout.setConstraints(choose,cons);
  498. multifile.add(choose);
  499. choose.addActionListener(actionListener);
  500. cons.insets = new Insets(0,0,0,0);
  501. cons.gridy++;
  502. cons.gridwidth = 3;
  503. JPanel dirCheckBoxPanel = new JPanel();
  504. searchSubDirectories = new JCheckBox(jEdit.getProperty(
  505. "search.subdirs"));
  506. String mnemonic = jEdit.getProperty(
  507. "search.subdirs.mnemonic");
  508. searchSubDirectories.setMnemonic(mnemonic.charAt(0));
  509. searchSubDirectories.setSelected(jEdit.getBooleanProperty("search.subdirs.toggle"));
  510. skipHidden = new JCheckBox(jEdit.getProperty("search.skipHidden"));
  511. skipHidden.setSelected(jEdit.getBooleanProperty("search.skipHidden.toggle", true));
  512. skipBinaryFiles = new JCheckBox(jEdit.getProperty("search.skipBinary"));
  513. skipBinaryFiles.setSelected(jEdit.getBooleanProperty("search.skipBinary.toggle", true));
  514. dirCheckBoxPanel.add(searchSubDirectories);
  515. dirCheckBoxPanel.add(skipHidden);
  516. dirCheckBoxPanel.add(skipBinaryFiles);
  517. cons.insets = new Insets(0, 0, 0, 0);
  518. cons.gridy++;
  519. cons.gridwidth = 4;
  520. layout.setConstraints(dirCheckBoxPanel, cons);
  521. multifile.add(dirCheckBoxPanel);
  522. return multifile;
  523. } //}}}
  524. //{{{ createButtonsPanel() method
  525. private Box createButtonsPanel()
  526. {
  527. Box box = new Box(BoxLayout.Y_AXIS);
  528. ButtonActionHandler actionHandler = new ButtonActionHandler();
  529. box.add(Box.createVerticalStrut(12));
  530. JPanel grid = new JPanel(new GridLayout(5,1,0,12));
  531. findBtn = new JButton(jEdit.getProperty("search.findBtn"));
  532. /* findBtn.setMnemonic(jEdit.getProperty("search.findBtn.mnemonic")
  533. .charAt(0)); */
  534. getRootPane().setDefaultButton(findBtn);
  535. grid.add(findBtn);
  536. findBtn.addActionListener(actionHandler);
  537. /* replaceBtn = new JButton(jEdit.getProperty("search.replaceBtn"));
  538. replaceBtn.setMnemonic(jEdit.getProperty("search.replaceBtn.mnemonic")
  539. .charAt(0));
  540. grid.add(replaceBtn);
  541. replaceBtn.addActionListener(actionHandler); */
  542. replaceAndFindBtn = new JButton(jEdit.getProperty("search.replaceAndFindBtn"));
  543. replaceAndFindBtn.setMnemonic(jEdit.getProperty("search.replaceAndFindBtn.mnemonic")
  544. .charAt(0));
  545. grid.add(replaceAndFindBtn);
  546. replaceAndFindBtn.addActionListener(actionHandler);
  547. replaceAllBtn = new JButton(jEdit.getProperty("search.replaceAllBtn"));
  548. replaceAllBtn.setMnemonic(jEdit.getProperty("search.replaceAllBtn.mnemonic")
  549. .charAt(0));
  550. grid.add(replaceAllBtn);
  551. replaceAllBtn.addActionListener(actionHandler);
  552. closeBtn = new JButton(jEdit.getProperty("common.close"));
  553. grid.add(closeBtn);
  554. closeBtn.addActionListener(actionHandler);
  555. grid.setMaximumSize(grid.getPreferredSize());
  556. box.add(grid);
  557. box.add(Box.createGlue());
  558. return box;
  559. } //}}}
  560. //{{{ updateEnabled() method
  561. private void updateEnabled()
  562. {
  563. wrap.setEnabled(!hyperSearch.isSelected()
  564. && !searchSelection.isSelected());
  565. boolean reverseEnabled = !hyperSearch.isSelected()
  566. && searchCurrentBuffer.isSelected()
  567. && !regexp.isSelected();
  568. searchBack.setEnabled(reverseEnabled);
  569. searchForward.setEnabled(reverseEnabled);
  570. if(!reverseEnabled)
  571. searchForward.setSelected(true);
  572. filter.setEnabled(searchAllBuffers.isSelected()
  573. || searchDirectory.isSelected());
  574. boolean searchDirs = searchDirectory.isSelected();
  575. directory.setEnabled(searchDirs);
  576. choose.setEnabled(searchDirs);
  577. searchSubDirectories.setEnabled(searchDirs);
  578. skipHidden.setEnabled(searchDirs);
  579. skipBinaryFiles.setEnabled(searchDirs);
  580. synchronize.setEnabled(searchAllBuffers.isSelected()
  581. || searchDirectory.isSelected());
  582. findBtn.setEnabled(!searchSelection.isSelected()
  583. || hyperSearch.isSelected());
  584. replaceAndFindBtn.setEnabled(!hyperSearch.isSelected()
  585. && !searchSelection.isSelected());
  586. } //}}}
  587. //{{{ save() method
  588. /**
  589. * @param cancel If true, we don't bother the user with warning messages
  590. */
  591. private boolean save(boolean cancel)
  592. {
  593. try
  594. {
  595. // prevents us from handling SearchSettingsChanged
  596. // as a result of below
  597. saving = true;
  598. SearchAndReplace.setIgnoreCase(ignoreCase.isSelected());
  599. SearchAndReplace.setRegexp(regexp.isSelected());
  600. SearchAndReplace.setReverseSearch(searchBack.isSelected());
  601. SearchAndReplace.setAutoWrapAround(wrap.isSelected());
  602. jEdit.setBooleanProperty("search.subdirs.toggle", searchSubDirectories.isSelected());
  603. jEdit.setBooleanProperty("search.skipHidden.toggle", skipHidden.isSelected());
  604. jEdit.setBooleanProperty("search.skipBinary.toggle", skipBinaryFiles.isSelected());
  605. String filter = this.filter.getText();
  606. this.filter.addCurrentToHistory();
  607. if(filter.length() == 0)
  608. filter = "*";
  609. SearchFileSet fileset = SearchAndReplace.getSearchFileSet();
  610. boolean recurse = searchSubDirectories.isSelected();
  611. if(searchSelection.isSelected())
  612. fileset = new CurrentBufferSet();
  613. else if(searchCurrentBuffer.isSelected())
  614. {
  615. fileset = new CurrentBufferSet();
  616. jEdit.setBooleanProperty("search.hypersearch.toggle",
  617. hyperSearch.isSelected());
  618. }
  619. else if(searchAllBuffers.isSelected())
  620. fileset = new AllBufferSet(filter);
  621. else if(searchDirectory.isSelected())
  622. {
  623. String directory = this.directory.getText();
  624. this.directory.addCurrentToHistory();
  625. directory = MiscUtilities.constructPath(
  626. view.getBuffer().getDirectory(),directory);
  627. if((VFSManager.getVFSForPath(directory).getCapabilities()
  628. & VFS.LOW_LATENCY_CAP) == 0)
  629. {
  630. if(cancel)
  631. return false;
  632. int retVal = GUIUtilities.confirm(
  633. SearchDialog.this,"remote-dir-search",
  634. null,JOptionPane.YES_NO_OPTION,
  635. JOptionPane.WARNING_MESSAGE);
  636. if(retVal != JOptionPane.YES_OPTION)
  637. return false;
  638. }
  639. if(fileset instanceof DirectoryListSet)
  640. {
  641. DirectoryListSet dset = (DirectoryListSet)fileset;
  642. dset.setDirectory(directory);
  643. dset.setFileFilter(filter);
  644. dset.setRecursive(recurse);
  645. EditBus.send(new SearchSettingsChanged(null));
  646. }
  647. else
  648. fileset = new DirectoryListSet(directory,filter,recurse);
  649. }
  650. else
  651. {
  652. // can't happen
  653. fileset = null;
  654. }
  655. jEdit.setBooleanProperty("search.subdirs.toggle",
  656. recurse);
  657. jEdit.setBooleanProperty("search.keepDialog.toggle",
  658. keepDialog.isSelected());
  659. SearchAndReplace.setSearchFileSet(fileset);
  660. replace.addCurrentToHistory();
  661. SearchAndReplace.setReplaceString(replace.getText());
  662. if(find.getText().length() == 0)
  663. {
  664. if(!cancel)
  665. getToolkit().beep();
  666. return false;
  667. }
  668. find.addCurrentToHistory();
  669. SearchAndReplace.setSearchString(find.getText());
  670. return true;
  671. }
  672. finally
  673. {
  674. saving = false;
  675. }
  676. } //}}}
  677. //{{{ synchronizeMultiFileSettings() method
  678. private void synchronizeMultiFileSettings()
  679. {
  680. directory.setText(view.getBuffer().getDirectory());
  681. SearchFileSet fileset = SearchAndReplace.getSearchFileSet();
  682. if(fileset instanceof AllBufferSet)
  683. {
  684. filter.setText(((AllBufferSet)fileset)
  685. .getFileFilter());
  686. }
  687. else
  688. {
  689. filter.setText("*" + MiscUtilities
  690. .getFileExtension(view.getBuffer()
  691. .getName()));
  692. }
  693. } //}}}
  694. //{{{ closeOrKeepDialog() method
  695. private void closeOrKeepDialog()
  696. {
  697. if(keepDialog.isSelected())
  698. {
  699. // Windows bug workaround in case a YES/NO confirm
  700. // was shown
  701. // ... but if HyperSearch results window is floating,
  702. // the workaround causes problems!
  703. if(!hyperSearch.isSelected())
  704. {
  705. toFront();
  706. requestFocus();
  707. find.requestFocus();
  708. }
  709. return;
  710. }
  711. else
  712. {
  713. GUIUtilities.saveGeometry(this,"search");
  714. setVisible(false);
  715. }
  716. } //}}}
  717. //{{{ load() method
  718. private void load()
  719. {
  720. ignoreCase.setSelected(SearchAndReplace.getIgnoreCase());
  721. regexp.setSelected(SearchAndReplace.getRegexp());
  722. wrap.setSelected(SearchAndReplace.getAutoWrapAround());
  723. if(SearchAndReplace.getReverseSearch())
  724. searchBack.setSelected(true);
  725. else
  726. searchForward.setSelected(true);
  727. if(SearchAndReplace.getBeanShellReplace())
  728. {
  729. replace.setModel("replace.script");
  730. beanShellReplace.setSelected(true);
  731. }
  732. else
  733. {
  734. replace.setModel("replace");
  735. stringReplace.setSelected(true);
  736. }
  737. SearchFileSet fileset = SearchAndReplace.getSearchFileSet();
  738. HistoryModel model = filter.getModel();
  739. if(model.getSize() != 0)
  740. filter.setText(model.getItem(0));
  741. else
  742. {
  743. filter.setText("*" + MiscUtilities
  744. .getFileExtension(view.getBuffer()
  745. .getName()));
  746. }
  747. model = directory.getModel();
  748. if(model.getSize() != 0)
  749. directory.setText(model.getItem(0));
  750. else
  751. directory.setText(view.getBuffer().getDirectory());
  752. searchSubDirectories.setSelected(jEdit.getBooleanProperty(
  753. "search.subdirs.toggle"));
  754. if(fileset instanceof DirectoryListSet)
  755. {
  756. filter.setText(((DirectoryListSet)fileset)
  757. .getFileFilter());
  758. directory.setText(((DirectoryListSet)fileset)
  759. .getDirectory());
  760. searchSubDirectories.setSelected(((DirectoryListSet)fileset)
  761. .isRecursive());
  762. }
  763. else if(fileset instanceof AllBufferSet)
  764. {
  765. filter.setText(((AllBufferSet)fileset)
  766. .getFileFilter());
  767. }
  768. directory.addCurrentToHistory();
  769. keepDialog.setSelected(jEdit.getBooleanProperty(
  770. "search.keepDialog.toggle"));
  771. } //}}}
  772. //}}}
  773. //{{{ Inner classes
  774. //{{{ MyJRadioButton class
  775. // used for the stringReplace and beanShell replace radio buttons,
  776. // so that the user can press tab to go from the find field to the
  777. // replace field in one go
  778. class MyJRadioButton extends JRadioButton
  779. {
  780. MyJRadioButton(String label)
  781. {
  782. super(label);
  783. }
  784. public boolean isFocusTraversable()
  785. {
  786. return false;
  787. }
  788. } //}}}
  789. //{{{ ReplaceActionHandler class
  790. class ReplaceActionHandler implements ActionListener
  791. {
  792. public void actionPerformed(ActionEvent evt)
  793. {
  794. replace.setModel(beanShellReplace.isSelected()
  795. ? "replace.script"
  796. : "replace");
  797. SearchAndReplace.setBeanShellReplace(
  798. beanShellReplace.isSelected());
  799. }
  800. } //}}}
  801. //{{{ SettingsActionHandler class
  802. class SettingsActionHandler implements ActionListener
  803. {
  804. public void actionPerformed(ActionEvent evt)
  805. {
  806. Object source = evt.getSource();
  807. if(source == searchCurrentBuffer)
  808. hyperSearch.setSelected(false);
  809. else if(source == searchSelection
  810. || source == searchAllBuffers
  811. || source == searchDirectory)
  812. hyperSearch.setSelected(true);
  813. save(true);
  814. updateEnabled();
  815. }
  816. } //}}}
  817. //{{{ MultiFileActionHandler class
  818. class MultiFileActionHandler implements ActionListener
  819. {
  820. public void actionPerformed(ActionEvent evt)
  821. {
  822. if(evt.getSource() == choose)
  823. {
  824. String[] dirs = GUIUtilities.showVFSFileDialog(
  825. view,directory.getText(),
  826. VFSBrowser.CHOOSE_DIRECTORY_DIALOG,
  827. false);
  828. if(dirs != null)
  829. directory.setText(dirs[0]);
  830. }
  831. else if(evt.getSource() == synchronize)
  832. {
  833. synchronizeMultiFileSettings();
  834. }
  835. else // source is directory or filter field
  836. {
  837. // just as if Enter was pressed in another
  838. // text field
  839. ok();
  840. }
  841. }
  842. } //}}}
  843. //{{{ ButtonActionHandler class
  844. class ButtonActionHandler implements ActionListener
  845. {
  846. public void actionPerformed(ActionEvent evt)
  847. {
  848. Object source = evt.getSource();
  849. if(source == closeBtn)
  850. cancel();
  851. else if(source == findBtn || source == find
  852. || source == replace)
  853. {
  854. ok();
  855. }
  856. else if(source == replaceAndFindBtn)
  857. {
  858. save(false);
  859. if(SearchAndReplace.replace(view))
  860. ok();
  861. else
  862. getToolkit().beep();
  863. }
  864. else if(source == replaceAllBtn)
  865. {
  866. if(searchSelection.isSelected() &&
  867. view.getTextArea().getSelectionCount()
  868. == 0)
  869. {
  870. GUIUtilities.error(view,"search-no-selection",null);
  871. return;
  872. }
  873. setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
  874. if(!save(false))
  875. {
  876. setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
  877. getToolkit().beep();
  878. return;
  879. }
  880. if(searchSelection.isSelected())
  881. {
  882. if(SearchAndReplace.replace(view))
  883. closeOrKeepDialog();
  884. else
  885. getToolkit().beep();
  886. }
  887. else
  888. {
  889. if(SearchAndReplace.replaceAll(view))
  890. closeOrKeepDialog();
  891. else
  892. getToolkit().beep();
  893. }
  894. setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
  895. }
  896. }
  897. } //}}}
  898. //}}}
  899. }