KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > gjt > sp > jedit > search > SearchBar


1 /*
2  * SearchBar.java - Search & replace toolbar
3  * :tabSize=8:indentSize=8:noTabs=false:
4  * :folding=explicit:collapseFolds=1:
5  *
6  * Copyright (C) 2000, 2001, 2002 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
23 package org.gjt.sp.jedit.search;
24
25 //{{{ Imports
26
import java.awt.event.*;
27 import java.awt.*;
28 import javax.swing.event.*;
29 import javax.swing.*;
30 import org.gjt.sp.jedit.*;
31 import org.gjt.sp.jedit.syntax.SyntaxStyle;
32 import org.gjt.sp.jedit.gui.*;
33 import org.gjt.sp.jedit.textarea.*;
34 import org.gjt.sp.util.Log;
35 //}}}
36

37 /**
38  * Incremental search tool bar.
39  * @version $Id: SearchBar.java 8022 2006-11-12 21:56:12Z kpouer $
40  */

41 public class SearchBar extends JPanel
42 {
43     //{{{ SearchBar constructor
44
public SearchBar(final View view, boolean temp)
45     {
46         setLayout(new BoxLayout(this,BoxLayout.X_AXIS));
47
48         this.view = view;
49
50         add(Box.createHorizontalStrut(2));
51
52         JLabel label = new JLabel(jEdit.getProperty("view.search.find"));
53         add(label);
54         add(Box.createHorizontalStrut(12));
55         add(find = new HistoryTextField("find"));
56         find.setSelectAllOnFocus(true);
57
58         SyntaxStyle style = GUIUtilities.parseStyle(jEdit.getProperty("view.style.invalid"), "Dialog", 12);
59         errorBackground = style.getBackgroundColor();
60         errorForeground = style.getForegroundColor();
61         defaultBackground = find.getBackground();
62         defaultForeground = find.getForeground();
63         Dimension max = find.getPreferredSize();
64         max.width = Integer.MAX_VALUE;
65         find.setMaximumSize(max);
66         ActionHandler actionHandler = new ActionHandler();
67         find.addKeyListener(new KeyHandler());
68         find.addActionListener(actionHandler);
69         find.getDocument().addDocumentListener(new DocumentHandler());
70
71         Insets margin = new Insets(1,1,1,1);
72
73         add(Box.createHorizontalStrut(12));
74         add(ignoreCase = new JCheckBox(jEdit.getProperty(
75             "search.case")));
76         ignoreCase.addActionListener(actionHandler);
77         ignoreCase.setMargin(margin);
78         ignoreCase.setRequestFocusEnabled(false);
79         add(Box.createHorizontalStrut(2));
80         add(regexp = new JCheckBox(jEdit.getProperty(
81             "search.regexp")));
82         regexp.addActionListener(actionHandler);
83         regexp.setMargin(margin);
84         regexp.setRequestFocusEnabled(false);
85         add(Box.createHorizontalStrut(2));
86         add(hyperSearch = new JCheckBox(jEdit.getProperty(
87             "search.hypersearch")));
88         hyperSearch.addActionListener(actionHandler);
89         hyperSearch.setMargin(margin);
90         hyperSearch.setRequestFocusEnabled(false);
91
92         update();
93
94         //{{{ Create the timer used by incremental search
95
timer = new Timer(0,new ActionListener()
96         {
97             public void actionPerformed(ActionEvent evt)
98             {
99                 if(!incrementalSearch(searchStart,searchReverse))
100                 {
101                     if(!incrementalSearch(
102                         (searchReverse
103                         ? view.getBuffer().getLength()
104                         : 0),searchReverse))
105                     {
106                         // not found at all.
107
view.getStatus().setMessageAndClear(
108                             jEdit.getProperty(
109                             "view.status.search-not-found"));
110                     }
111                 }
112             }
113         }); //}}}
114

115         // if 'temp' is true, hide search bar after user is done with it
116
this.temp = temp;
117
118         propertiesChanged();
119     } //}}}
120

121     //{{{ getField() method
122
public HistoryTextField getField()
123     {
124         return find;
125     } //}}}
126

127     //{{{ setHyperSearch() method
128
public void setHyperSearch(boolean hyperSearch)
129     {
130         jEdit.setBooleanProperty("view.search.hypersearch.toggle",hyperSearch);
131         this.hyperSearch.setSelected(hyperSearch);
132     } //}}}
133

134     //{{{ update() method
135
public void update()
136     {
137         ignoreCase.setSelected(SearchAndReplace.getIgnoreCase());
138         regexp.setSelected(SearchAndReplace.getRegexp());
139         hyperSearch.setSelected(jEdit.getBooleanProperty(
140             "view.search.hypersearch.toggle"));
141     } //}}}
142

143     //{{{ propertiesChanged() method
144
public void propertiesChanged()
145     {
146         if(temp)
147         {
148             if(close == null)
149             {
150                 close = new RolloverButton(GUIUtilities.loadIcon("closebox.gif"));
151                 close.addActionListener(new ActionHandler());
152                 close.setToolTipText(jEdit.getProperty(
153                     "view.search.close-tooltip"));
154             }
155             add(close);
156         }
157         else if(close != null)
158             remove(close);
159     } //}}}
160

161     //{{{ Private members
162

163     //{{{ Instance variables
164
private View view;
165     private HistoryTextField find;
166     private JCheckBox ignoreCase, regexp, hyperSearch;
167     private Timer timer;
168     private boolean wasError;
169     private Color defaultBackground;
170     private Color defaultForeground;
171     private Color errorForeground;
172     private Color errorBackground;
173     // close button only there if 'temp' is true
174
private RolloverButton close;
175
176     private int searchStart;
177     private boolean searchReverse;
178     private boolean temp;
179     //}}}
180

181     //{{{ find() method
182
private void find(boolean reverse)
183     {
184         timer.stop();
185
186         String JavaDoc text = find.getText();
187         //{{{ If nothing entered, show search and replace dialog box
188
if(text.length() == 0)
189         {
190             jEdit.setBooleanProperty("search.hypersearch.toggle",
191                 hyperSearch.isSelected());
192             SearchDialog.showSearchDialog(view,null,SearchDialog.CURRENT_BUFFER);
193         } //}}}
194
//{{{ HyperSearch
195
else if(hyperSearch.isSelected())
196         {
197             if(temp)
198             {
199                 view.removeToolBar(SearchBar.this);
200             }
201             else
202                 find.setText(null);
203
204             SearchAndReplace.setSearchString(text);
205             SearchAndReplace.setSearchFileSet(new CurrentBufferSet());
206             SearchAndReplace.hyperSearch(view);
207         } //}}}
208
//{{{ Incremental search
209
else
210         {
211             if(reverse && SearchAndReplace.getRegexp())
212             {
213                 GUIUtilities.error(view,"regexp-reverse",null);
214                 return;
215             }
216
217             // on enter, start search from end
218
// of current match to find next one
219
int start;
220             JEditTextArea textArea = view.getTextArea();
221             Selection s = textArea.getSelectionAtOffset(
222                 textArea.getCaretPosition());
223             if(s == null)
224                 start = textArea.getCaretPosition();
225             else if(reverse)
226                 start = s.getStart();
227             else
228                 start = s.getEnd();
229
230             if(!incrementalSearch(start,reverse))
231             {
232                 // not found. start from
233
// beginning
234
if(!incrementalSearch(reverse
235                     ? view.getBuffer().getLength()
236                     : 0,reverse))
237                 {
238                     // not found at all.
239
view.getStatus().setMessageAndClear(
240                         jEdit.getProperty(
241                         "view.status.search-not-found"));
242                 }
243                 else
244                 {
245                     // inform user search restarted
246
view.getStatus().setMessageAndClear(
247                         jEdit.getProperty("view.status.auto-wrap"));
248                     // beep if beep property set
249
if(jEdit.getBooleanProperty("search.beepOnSearchAutoWrap"))
250                     {
251                         getToolkit().beep();
252                     }
253                 }
254             }
255         } //}}}
256
} //}}}
257

258     //{{{ incrementalSearch() method
259
private boolean incrementalSearch(int start, boolean reverse)
260     {
261         /* For example, if the current fileset is a directory,
262          * C+g will find the next match within that fileset.
263          * This can be annoying if you have just done an
264          * incremental search and want the next occurrence
265          * in the current buffer. */

266         SearchAndReplace.setSearchFileSet(new CurrentBufferSet());
267         SearchAndReplace.setSearchString(find.getText());
268         SearchAndReplace.setReverseSearch(reverse);
269
270         boolean ret = false;
271         try
272         {
273             if(SearchAndReplace.find(view,view.getBuffer(),start,false,reverse))
274                 ret = true;
275         }
276         catch(Exception JavaDoc e)
277         {
278             Log.log(Log.DEBUG,this,e);
279
280             // invalid regexp, ignore
281
// return true to avoid annoying beeping while
282
// typing a re
283
ret = true;
284         }
285         if (ret)
286         {
287             if (wasError)
288             {
289                 find.setForeground(defaultForeground);
290                 find.setBackground(defaultBackground);
291                 wasError = false;
292             }
293         }
294         else
295         {
296             if (!wasError)
297             {
298                 find.setForeground(errorForeground);
299                 find.setBackground(errorBackground);
300                 wasError = true;
301             }
302         }
303
304
305         return ret;
306     } //}}}
307

308     //{{{ timerIncrementalSearch() method
309
private void timerIncrementalSearch(int start, boolean reverse)
310     {
311         searchStart = start;
312         searchReverse = reverse;
313
314         timer.stop();
315         timer.setRepeats(false);
316         timer.setInitialDelay(150);
317         timer.start();
318     } //}}}
319

320     //}}}
321

322     //{{{ Inner classes
323

324     //{{{ ActionHandler class
325
class ActionHandler implements ActionListener
326     {
327         //{{{ actionPerformed() method
328
public void actionPerformed(ActionEvent evt)
329         {
330             Object JavaDoc source = evt.getSource();
331             if(source == find)
332                 find(false);
333             else if(source == hyperSearch)
334             {
335                 jEdit.setBooleanProperty("view.search.hypersearch.toggle",
336                     hyperSearch.isSelected());
337                 update();
338             }
339             else if(source == ignoreCase)
340             {
341                 SearchAndReplace.setIgnoreCase(ignoreCase
342                     .isSelected());
343             }
344             else if(source == regexp)
345             {
346                 SearchAndReplace.setRegexp(regexp
347                     .isSelected());
348             }
349             else if(source == close)
350             {
351                 view.removeToolBar(SearchBar.this);
352                 view.getEditPane().focusOnTextArea();
353             }
354         } //}}}
355
} //}}}
356

357     //{{{ DocumentHandler class
358
class DocumentHandler implements DocumentListener
359     {
360         //{{{ insertUpdate() method
361
public void insertUpdate(DocumentEvent evt)
362         {
363             // on insert, start search from beginning of
364
// current match. This will continue to highlight
365
// the current match until another match is found
366
if(!hyperSearch.isSelected())
367             {
368                 int start;
369                 JEditTextArea textArea = view.getTextArea();
370                 Selection s = textArea.getSelectionAtOffset(
371                     textArea.getCaretPosition());
372                 if(s == null)
373                     start = textArea.getCaretPosition();
374                 else
375                     start = s.getStart();
376
377                 timerIncrementalSearch(start,false);
378             }
379         } //}}}
380

381         //{{{ removeUpdate() method
382
public void removeUpdate(DocumentEvent evt)
383         {
384             // on backspace, restart from beginning
385
if(!hyperSearch.isSelected())
386             {
387                 String JavaDoc text = find.getText();
388                 if(text.length() != 0)
389                 {
390                     // don't beep if not found.
391
// subsequent beeps are very
392
// annoying when backspacing an
393
// invalid search string.
394
if(regexp.isSelected())
395                     {
396                         // reverse regexp search
397
// not supported yet, so
398
// 'simulate' with restart
399
timerIncrementalSearch(0,false);
400                     }
401                     else
402                     {
403                         int start;
404                         JEditTextArea textArea = view.getTextArea();
405                         Selection s = textArea.getSelectionAtOffset(
406                             textArea.getCaretPosition());
407                         if(s == null)
408                             start = textArea.getCaretPosition();
409                         else
410                             start = s.getStart();
411                         timerIncrementalSearch(start,true);
412                     }
413                 }
414             }
415         } //}}}
416

417         //{{{ changedUpdate() method
418
public void changedUpdate(DocumentEvent evt) {}
419         //}}}
420
} //}}}
421

422     //{{{ KeyHandler class
423
class KeyHandler extends KeyAdapter
424     {
425         public void keyPressed(KeyEvent evt)
426         {
427             switch(evt.getKeyCode())
428             {
429             case KeyEvent.VK_ESCAPE:
430                 if(temp)
431                 {
432                     view.removeToolBar(SearchBar.this);
433                 }
434                 evt.consume();
435                 view.getEditPane().focusOnTextArea();
436                 break;
437             case KeyEvent.VK_ENTER:
438                 if(evt.isShiftDown())
439                 {
440                     evt.consume();
441                     find(true);
442                 }
443                 break;
444             }
445         }
446     } //}}}
447

448     //{{{ FocusHandler class
449
class FocusHandler extends FocusAdapter
450     {
451         public void focusLost(FocusEvent e)
452         {
453             getField().addCurrentToHistory();
454         }
455     } //}}}
456

457     //}}}
458
}
459
Popular Tags