/jEdit/tags/jedit-3-2-2/org/gjt/sp/jedit/search/SearchBar.java

# · Java · 319 lines · 244 code · 24 blank · 51 comment · 38 complexity · c65a4b2e4ccc6866f3eb5ab79ce17ce4 MD5 · raw file

  1. /*
  2. * SearchBar.java - Search & replace toolbar
  3. * Portions copyright (C) 2000, 2001 Slava Pestov
  4. *
  5. * This program is free software; you can redistribute it and/or
  6. * modify it under the terms of the GNU General Public License
  7. * as published by the Free Software Foundation; either version 2
  8. * of the License, or any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License
  16. * along with this program; if not, write to the Free Software
  17. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  18. */
  19. package org.gjt.sp.jedit.search;
  20. import java.awt.event.*;
  21. import java.awt.*;
  22. import javax.swing.border.*;
  23. import javax.swing.event.*;
  24. import javax.swing.text.BadLocationException;
  25. import javax.swing.*;
  26. import org.gjt.sp.jedit.*;
  27. import org.gjt.sp.jedit.gui.HistoryTextField;
  28. import org.gjt.sp.jedit.textarea.*;
  29. import org.gjt.sp.util.Log;
  30. public class SearchBar extends JPanel
  31. {
  32. public SearchBar(View view)
  33. {
  34. super(new BorderLayout());
  35. this.view = view;
  36. //Font boldFont = new Font("Dialog",Font.BOLD,12);
  37. //Font plainFont = new Font("Dialog",Font.PLAIN,12);
  38. JLabel label = new JLabel(jEdit.getProperty("view.search.find"));
  39. //label.setFont(boldFont);
  40. label.setBorder(new EmptyBorder(0,2,0,12));
  41. add(label,BorderLayout.WEST);
  42. Box box = new Box(BoxLayout.Y_AXIS);
  43. box.add(Box.createGlue());
  44. box.add(find = new HistoryTextField("find"));
  45. //find.setFont(plainFont);
  46. Dimension min = find.getPreferredSize();
  47. min.width = Integer.MAX_VALUE;
  48. find.setMaximumSize(min);
  49. ActionHandler actionHandler = new ActionHandler();
  50. find.addKeyListener(new KeyHandler());
  51. find.addActionListener(actionHandler);
  52. find.getDocument().addDocumentListener(new DocumentHandler());
  53. box.add(Box.createGlue());
  54. add(box,BorderLayout.CENTER);
  55. Insets margin = new Insets(1,1,1,1);
  56. Box buttons = new Box(BoxLayout.X_AXIS);
  57. buttons.add(Box.createHorizontalStrut(12));
  58. buttons.add(ignoreCase = new JCheckBox(jEdit.getProperty(
  59. "search.case")));
  60. //ignoreCase.setFont(boldFont);
  61. ignoreCase.addActionListener(actionHandler);
  62. ignoreCase.setMargin(margin);
  63. buttons.add(Box.createHorizontalStrut(2));
  64. buttons.add(regexp = new JCheckBox(jEdit.getProperty(
  65. "search.regexp")));
  66. //regexp.setFont(boldFont);
  67. regexp.addActionListener(actionHandler);
  68. regexp.setMargin(margin);
  69. buttons.add(Box.createHorizontalStrut(2));
  70. buttons.add(hyperSearch = new JCheckBox(jEdit.getProperty(
  71. "search.hypersearch")));
  72. //hyperSearch.setFont(boldFont);
  73. hyperSearch.addActionListener(actionHandler);
  74. hyperSearch.setMargin(margin);
  75. update();
  76. add(buttons,BorderLayout.EAST);
  77. }
  78. public HistoryTextField getField()
  79. {
  80. return find;
  81. }
  82. public void setHyperSearch(boolean hyperSearch)
  83. {
  84. jEdit.setBooleanProperty("view.search.hypersearch.toggle",hyperSearch);
  85. this.hyperSearch.setSelected(hyperSearch);
  86. find.setModel(this.hyperSearch.isSelected() ? "find" : null);
  87. }
  88. public void update()
  89. {
  90. ignoreCase.setSelected(SearchAndReplace.getIgnoreCase());
  91. regexp.setSelected(SearchAndReplace.getRegexp());
  92. hyperSearch.setSelected(jEdit.getBooleanProperty(
  93. "view.search.hypersearch.toggle"));
  94. find.setModel(hyperSearch.isSelected() ? "find" : null);
  95. }
  96. // private members
  97. private View view;
  98. private HistoryTextField find;
  99. private JCheckBox ignoreCase, regexp, hyperSearch;
  100. private void find(boolean reverse)
  101. {
  102. String text = find.getText();
  103. if(text.length() == 0)
  104. {
  105. jEdit.setBooleanProperty("search.hypersearch.toggle",
  106. hyperSearch.isSelected());
  107. new SearchDialog(view,null);
  108. }
  109. else if(hyperSearch.isSelected())
  110. {
  111. find.setText(null);
  112. SearchAndReplace.setSearchString(text);
  113. SearchAndReplace.setSearchFileSet(new CurrentBufferSet());
  114. SearchAndReplace.hyperSearch(view);
  115. }
  116. else
  117. {
  118. // on enter, start search from end
  119. // of current match to find next one
  120. int start;
  121. JEditTextArea textArea = view.getTextArea();
  122. Selection s = textArea.getSelectionAtOffset(
  123. textArea.getCaretPosition());
  124. if(s == null)
  125. start = textArea.getCaretPosition();
  126. else if(reverse)
  127. start = s.getStart();
  128. else
  129. start = s.getEnd();
  130. if(!incrementalSearch(start,reverse))
  131. {
  132. // not found. start from
  133. // beginning
  134. if(!incrementalSearch(reverse
  135. ? view.getBuffer().getLength()
  136. : 0,reverse))
  137. {
  138. // not found at all. beep.
  139. getToolkit().beep();
  140. }
  141. }
  142. }
  143. }
  144. private boolean incrementalSearch(int start, boolean reverse)
  145. {
  146. /* For example, if the current fileset is a directory,
  147. * C+g will find the next match within that fileset.
  148. * This can be annoying if you have just done an
  149. * incremental search and want the next occurrence
  150. * in the current buffer. */
  151. SearchAndReplace.setSearchFileSet(new CurrentBufferSet());
  152. SearchAndReplace.setSearchString(find.getText());
  153. SearchAndReplace.setReverseSearch(reverse);
  154. try
  155. {
  156. if(SearchAndReplace.find(view,view.getBuffer(),start))
  157. return true;
  158. }
  159. catch(BadLocationException bl)
  160. {
  161. Log.log(Log.ERROR,this,bl);
  162. }
  163. catch(Exception e)
  164. {
  165. Log.log(Log.DEBUG,this,e);
  166. // invalid regexp, ignore
  167. // return true to avoid annoying beeping while
  168. // typing a re
  169. return true;
  170. }
  171. return false;
  172. }
  173. class ActionHandler implements ActionListener
  174. {
  175. public void actionPerformed(ActionEvent evt)
  176. {
  177. Object source = evt.getSource();
  178. if(evt.getSource() == find)
  179. find(false);
  180. else if(evt.getSource() == hyperSearch)
  181. {
  182. jEdit.setBooleanProperty("view.search.hypersearch.toggle",
  183. hyperSearch.isSelected());
  184. update();
  185. }
  186. else if(evt.getSource() == ignoreCase)
  187. {
  188. SearchAndReplace.setIgnoreCase(ignoreCase
  189. .isSelected());
  190. }
  191. else if(evt.getSource() == regexp)
  192. {
  193. SearchAndReplace.setRegexp(regexp
  194. .isSelected());
  195. }
  196. }
  197. }
  198. class DocumentHandler implements DocumentListener
  199. {
  200. public void insertUpdate(DocumentEvent evt)
  201. {
  202. // on insert, start search from beginning of
  203. // current match. This will continue to highlight
  204. // the current match until another match is found
  205. if(!hyperSearch.isSelected())
  206. {
  207. int start;
  208. JEditTextArea textArea = view.getTextArea();
  209. Selection s = textArea.getSelectionAtOffset(
  210. textArea.getCaretPosition());
  211. if(s == null)
  212. start = textArea.getCaretPosition();
  213. else
  214. start = s.getStart();
  215. if(!incrementalSearch(start,false))
  216. {
  217. if(!incrementalSearch(0,false))
  218. {
  219. // not found at all. beep.
  220. getToolkit().beep();
  221. }
  222. }
  223. }
  224. }
  225. public void removeUpdate(DocumentEvent evt)
  226. {
  227. // on backspace, restart from beginning
  228. if(!hyperSearch.isSelected())
  229. {
  230. String text = find.getText();
  231. if(text.length() != 0)
  232. {
  233. // don't beep if not found.
  234. // subsequent beeps are very
  235. // annoying when backspacing an
  236. // invalid search string.
  237. if(regexp.isSelected())
  238. {
  239. // reverse regexp search
  240. // not supported yet, so
  241. // 'sumulate' with restart
  242. incrementalSearch(0,false);
  243. }
  244. else
  245. {
  246. int start;
  247. JEditTextArea textArea = view.getTextArea();
  248. Selection s = textArea.getSelectionAtOffset(
  249. textArea.getCaretPosition());
  250. if(s == null)
  251. start = textArea.getCaretPosition();
  252. else
  253. start = s.getStart();
  254. incrementalSearch(start,true);
  255. }
  256. }
  257. }
  258. }
  259. public void changedUpdate(DocumentEvent evt)
  260. {
  261. }
  262. }
  263. class KeyHandler extends KeyAdapter
  264. {
  265. public void keyPressed(KeyEvent evt)
  266. {
  267. switch(evt.getKeyCode())
  268. {
  269. case KeyEvent.VK_LEFT:
  270. case KeyEvent.VK_RIGHT:
  271. case KeyEvent.VK_UP:
  272. case KeyEvent.VK_DOWN:
  273. if(!hyperSearch.isSelected())
  274. {
  275. evt.consume();
  276. view.getEditPane().focusOnTextArea();
  277. view.getEditPane().getTextArea()
  278. .processKeyEvent(evt);
  279. }
  280. break;
  281. case KeyEvent.VK_ESCAPE:
  282. evt.consume();
  283. view.getEditPane().focusOnTextArea();
  284. break;
  285. case KeyEvent.VK_ENTER:
  286. if(evt.isShiftDown())
  287. {
  288. evt.consume();
  289. find(true);
  290. }
  291. break;
  292. }
  293. }
  294. }
  295. }