PageRenderTime 47ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 0ms

/jEdit/tags/jedit-4-0-pre3/org/gjt/sp/jedit/search/SearchBar.java

#
Java | 381 lines | 272 code | 33 blank | 76 comment | 36 complexity | 764c5e4831ff78ec106da590bbdd8ac3 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. * SearchBar.java - Search & replace toolbar
  3. * :tabSize=8:indentSize=8:noTabs=false:
  4. * :folding=explicit:collapseFolds=1:
  5. *
  6. * Portions copyright (C) 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 java.awt.event.*;
  25. import java.awt.*;
  26. import javax.swing.border.*;
  27. import javax.swing.event.*;
  28. import javax.swing.*;
  29. import org.gjt.sp.jedit.*;
  30. import org.gjt.sp.jedit.gui.HistoryTextField;
  31. import org.gjt.sp.jedit.textarea.*;
  32. import org.gjt.sp.util.Log;
  33. //}}}
  34. public class SearchBar extends JPanel
  35. {
  36. //{{{ SearchBar constructor
  37. public SearchBar(final View view)
  38. {
  39. super(new BorderLayout());
  40. this.view = view;
  41. JLabel label = new JLabel(jEdit.getProperty("view.search.find"));
  42. label.setBorder(new EmptyBorder(0,2,0,12));
  43. add(label,BorderLayout.WEST);
  44. Box box = new Box(BoxLayout.Y_AXIS);
  45. box.add(Box.createGlue());
  46. box.add(find = new HistoryTextField("find"));
  47. find.setSelectAllOnFocus(true);
  48. Dimension min = find.getPreferredSize();
  49. min.width = Integer.MAX_VALUE;
  50. find.setMaximumSize(min);
  51. ActionHandler actionHandler = new ActionHandler();
  52. find.addKeyListener(new KeyHandler());
  53. find.addActionListener(actionHandler);
  54. find.getDocument().addDocumentListener(new DocumentHandler());
  55. box.add(Box.createGlue());
  56. add(box,BorderLayout.CENTER);
  57. Insets margin = new Insets(1,1,1,1);
  58. Box buttons = new Box(BoxLayout.X_AXIS);
  59. buttons.add(Box.createHorizontalStrut(12));
  60. buttons.add(ignoreCase = new JCheckBox(jEdit.getProperty(
  61. "search.case")));
  62. ignoreCase.addActionListener(actionHandler);
  63. ignoreCase.setMargin(margin);
  64. buttons.add(Box.createHorizontalStrut(2));
  65. buttons.add(regexp = new JCheckBox(jEdit.getProperty(
  66. "search.regexp")));
  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.addActionListener(actionHandler);
  73. hyperSearch.setMargin(margin);
  74. update();
  75. add(buttons,BorderLayout.EAST);
  76. //{{{ Create the timer used by incremental search
  77. timer = new Timer(0,new ActionListener()
  78. {
  79. public void actionPerformed(ActionEvent evt)
  80. {
  81. if(!incrementalSearch(searchStart,searchReverse))
  82. {
  83. if(!incrementalSearch(
  84. (searchReverse
  85. ? view.getBuffer().getLength()
  86. : 0),searchReverse))
  87. {
  88. // not found at all.
  89. view.getStatus().setMessageAndClear(
  90. jEdit.getProperty(
  91. "view.status.search-not-found"));
  92. }
  93. }
  94. }
  95. }); //}}}
  96. } //}}}
  97. //{{{ getField() method
  98. public HistoryTextField getField()
  99. {
  100. return find;
  101. } //}}}
  102. //{{{ setHyperSearch() method
  103. public void setHyperSearch(boolean hyperSearch)
  104. {
  105. jEdit.setBooleanProperty("view.search.hypersearch.toggle",hyperSearch);
  106. this.hyperSearch.setSelected(hyperSearch);
  107. } //}}}
  108. //{{{ update() method
  109. public void update()
  110. {
  111. ignoreCase.setSelected(SearchAndReplace.getIgnoreCase());
  112. regexp.setSelected(SearchAndReplace.getRegexp());
  113. hyperSearch.setSelected(jEdit.getBooleanProperty(
  114. "view.search.hypersearch.toggle"));
  115. } //}}}
  116. //{{{ Private members
  117. //{{{ Instance variables
  118. private View view;
  119. private HistoryTextField find;
  120. private JCheckBox ignoreCase, regexp, hyperSearch;
  121. private Timer timer;
  122. private int searchStart;
  123. private boolean searchReverse;
  124. //}}}
  125. //{{{ find() method
  126. private void find(boolean reverse)
  127. {
  128. timer.stop();
  129. String text = find.getText();
  130. //{{{ If nothing entered, show search and replace dialog box
  131. if(text.length() == 0)
  132. {
  133. jEdit.setBooleanProperty("search.hypersearch.toggle",
  134. hyperSearch.isSelected());
  135. new SearchDialog(view,null);
  136. } //}}}
  137. //{{{ HyperSearch
  138. else if(hyperSearch.isSelected())
  139. {
  140. find.setText(null);
  141. SearchAndReplace.setSearchString(text);
  142. SearchAndReplace.setSearchFileSet(new CurrentBufferSet());
  143. SearchAndReplace.hyperSearch(view);
  144. } //}}}
  145. //{{{ Incremental search
  146. else
  147. {
  148. // on enter, start search from end
  149. // of current match to find next one
  150. int start;
  151. JEditTextArea textArea = view.getTextArea();
  152. Selection s = textArea.getSelectionAtOffset(
  153. textArea.getCaretPosition());
  154. if(s == null)
  155. start = textArea.getCaretPosition();
  156. else if(reverse)
  157. start = s.getStart();
  158. else
  159. start = s.getEnd();
  160. if(!incrementalSearch(start,reverse))
  161. {
  162. // not found. start from
  163. // beginning
  164. if(!incrementalSearch(reverse
  165. ? view.getBuffer().getLength()
  166. : 0,reverse))
  167. {
  168. // not found at all.
  169. view.getStatus().setMessageAndClear(
  170. jEdit.getProperty(
  171. "view.status.search-not-found"));
  172. }
  173. else
  174. {
  175. // inform user search restarted
  176. view.getStatus().setMessageAndClear(
  177. jEdit.getProperty("view.status.auto-wrap"));
  178. // beep if beep property set
  179. if(jEdit.getBooleanProperty("search.beepOnSearchAutoWrap"))
  180. {
  181. getToolkit().beep();
  182. }
  183. }
  184. }
  185. } //}}}
  186. } //}}}
  187. //{{{ incrementalSearch() method
  188. private boolean incrementalSearch(int start, boolean reverse)
  189. {
  190. /* For example, if the current fileset is a directory,
  191. * C+g will find the next match within that fileset.
  192. * This can be annoying if you have just done an
  193. * incremental search and want the next occurrence
  194. * in the current buffer. */
  195. SearchAndReplace.setSearchFileSet(new CurrentBufferSet());
  196. SearchAndReplace.setSearchString(find.getText());
  197. SearchAndReplace.setReverseSearch(reverse);
  198. try
  199. {
  200. if(SearchAndReplace.find(view,view.getBuffer(),start))
  201. return true;
  202. }
  203. catch(Exception e)
  204. {
  205. Log.log(Log.DEBUG,this,e);
  206. // invalid regexp, ignore
  207. // return true to avoid annoying beeping while
  208. // typing a re
  209. return true;
  210. }
  211. return false;
  212. } //}}}
  213. //{{{ timerIncrementalSearch() method
  214. private void timerIncrementalSearch(int start, boolean reverse)
  215. {
  216. this.searchStart = start;
  217. this.searchReverse = reverse;
  218. timer.stop();
  219. timer.setRepeats(false);
  220. timer.setInitialDelay(150);
  221. timer.start();
  222. } //}}}
  223. //}}}
  224. //{{{ Inner classes
  225. //{{{ ActionHandler class
  226. class ActionHandler implements ActionListener
  227. {
  228. //{{{ actionPerformed() method
  229. public void actionPerformed(ActionEvent evt)
  230. {
  231. Object source = evt.getSource();
  232. if(evt.getSource() == find)
  233. find(false);
  234. else if(evt.getSource() == hyperSearch)
  235. {
  236. jEdit.setBooleanProperty("view.search.hypersearch.toggle",
  237. hyperSearch.isSelected());
  238. update();
  239. }
  240. else if(evt.getSource() == ignoreCase)
  241. {
  242. SearchAndReplace.setIgnoreCase(ignoreCase
  243. .isSelected());
  244. }
  245. else if(evt.getSource() == regexp)
  246. {
  247. SearchAndReplace.setRegexp(regexp
  248. .isSelected());
  249. }
  250. } //}}}
  251. } //}}}
  252. //{{{ DocumentHandler class
  253. class DocumentHandler implements DocumentListener
  254. {
  255. //{{{ insertUpdate() method
  256. public void insertUpdate(DocumentEvent evt)
  257. {
  258. // on insert, start search from beginning of
  259. // current match. This will continue to highlight
  260. // the current match until another match is found
  261. if(!hyperSearch.isSelected())
  262. {
  263. int start;
  264. JEditTextArea textArea = view.getTextArea();
  265. Selection s = textArea.getSelectionAtOffset(
  266. textArea.getCaretPosition());
  267. if(s == null)
  268. start = textArea.getCaretPosition();
  269. else
  270. start = s.getStart();
  271. timerIncrementalSearch(start,false);
  272. }
  273. } //}}}
  274. //{{{ removeUpdate() method
  275. public void removeUpdate(DocumentEvent evt)
  276. {
  277. // on backspace, restart from beginning
  278. if(!hyperSearch.isSelected())
  279. {
  280. String text = find.getText();
  281. if(text.length() != 0)
  282. {
  283. // don't beep if not found.
  284. // subsequent beeps are very
  285. // annoying when backspacing an
  286. // invalid search string.
  287. if(regexp.isSelected())
  288. {
  289. // reverse regexp search
  290. // not supported yet, so
  291. // 'sumulate' with restart
  292. timerIncrementalSearch(0,false);
  293. }
  294. else
  295. {
  296. int start;
  297. JEditTextArea textArea = view.getTextArea();
  298. Selection s = textArea.getSelectionAtOffset(
  299. textArea.getCaretPosition());
  300. if(s == null)
  301. start = textArea.getCaretPosition();
  302. else
  303. start = s.getStart();
  304. timerIncrementalSearch(start,true);
  305. }
  306. }
  307. }
  308. } //}}}
  309. //{{{ changedUpdate() method
  310. public void changedUpdate(DocumentEvent evt) {}
  311. //}}}
  312. } //}}}
  313. //{{{ KeyHandler class
  314. class KeyHandler extends KeyAdapter
  315. {
  316. //{{{ keyPressed() method
  317. public void keyPressed(KeyEvent evt)
  318. {
  319. switch(evt.getKeyCode())
  320. {
  321. case KeyEvent.VK_LEFT:
  322. case KeyEvent.VK_RIGHT:
  323. case KeyEvent.VK_UP:
  324. case KeyEvent.VK_DOWN:
  325. if(!hyperSearch.isSelected())
  326. {
  327. evt.consume();
  328. view.getEditPane().focusOnTextArea();
  329. view.getEditPane().getTextArea()
  330. .processKeyEvent(evt);
  331. }
  332. break;
  333. case KeyEvent.VK_ESCAPE:
  334. evt.consume();
  335. view.getEditPane().focusOnTextArea();
  336. break;
  337. case KeyEvent.VK_ENTER:
  338. if(evt.isShiftDown())
  339. {
  340. evt.consume();
  341. find(true);
  342. }
  343. break;
  344. }
  345. } //}}}
  346. } //}}}
  347. //}}}
  348. }