4444 * <A HREF="http://dev.processing.org/bugs/show_bug.cgi?id=244"> Bug 244</A>
4545 * should anyone have clues about how to fix.
4646 */
47+ @ SuppressWarnings ("serial" )
4748public class FindReplace extends JFrame implements ActionListener {
4849
4950 static final int EDGE = Base .isMacOS () ? 20 : 13 ;
@@ -69,25 +70,41 @@ public class FindReplace extends JFrame implements ActionListener {
6970 JCheckBox wrapAroundBox ;
7071 static boolean wrapAround = true ;
7172
73+ JCheckBox searchAllFilesBox ;
74+ static boolean searchAllFiles = false ;
75+
7276 public FindReplace (Editor editor ) {
7377 super ("Find" );
7478 setResizable (false );
7579 this .editor = editor ;
76-
77- Container pain = getContentPane ();
78- pain .setLayout (null );
80+
81+ FlowLayout searchLayout = new FlowLayout (FlowLayout .RIGHT ,5 ,0 );
82+ Container pane = getContentPane ();
83+ pane .setLayout (searchLayout );
7984
8085 JLabel findLabel = new JLabel (_ ("Find:" ));
8186 JLabel replaceLabel = new JLabel (_ ("Replace with:" ));
8287 Dimension labelDimension = replaceLabel .getPreferredSize ();
83-
84- pain .add (findLabel );
85- pain .add (replaceLabel );
86-
87- pain .add (findField = new JTextField (20 ));
88- pain .add (replaceField = new JTextField (20 ));
88+
89+ JPanel find = new JPanel ();
90+ find .add (findLabel );
91+ find .add (findField = new JTextField (20 ));
92+ pane .add (find );
93+
94+ JPanel replace = new JPanel ();
95+ replace .add (replaceLabel );
96+ replace .add (replaceField = new JTextField (20 ));
97+ pane .add (replace );
98+
8999 int fieldHeight = findField .getPreferredSize ().height ;
90100
101+ JPanel checkbox = new JPanel ();
102+
103+ // Fill the findString with selected text if no previous value
104+ if (editor .getSelectedText () != null &&
105+ editor .getSelectedText ().length () > 0 )
106+ findString = editor .getSelectedText ();
107+
91108 if (findString != null ) findField .setText (findString );
92109 if (replaceString != null ) replaceField .setText (replaceString );
93110 //System.out.println("setting find str to " + findString);
@@ -100,7 +117,7 @@ public void actionPerformed(ActionEvent e) {
100117 }
101118 });
102119 ignoreCaseBox .setSelected (ignoreCase );
103- pain .add (ignoreCaseBox );
120+ checkbox .add (ignoreCaseBox );
104121
105122 wrapAroundBox = new JCheckBox (_ ("Wrap Around" ));
106123 wrapAroundBox .addActionListener (new ActionListener () {
@@ -109,11 +126,21 @@ public void actionPerformed(ActionEvent e) {
109126 }
110127 });
111128 wrapAroundBox .setSelected (wrapAround );
112- pain .add (wrapAroundBox );
129+ checkbox .add (wrapAroundBox );
130+
131+ searchAllFilesBox = new JCheckBox (_ ("Search all Sketch Tabs" ));
132+ searchAllFilesBox .addActionListener (new ActionListener () {
133+ public void actionPerformed (ActionEvent e ) {
134+ searchAllFiles = searchAllFilesBox .isSelected ();
135+ }
136+ });
137+ searchAllFilesBox .setSelected (searchAllFiles );
138+ checkbox .add (searchAllFilesBox );
113139
114- JPanel buttons = new JPanel ( );
140+ pane . add ( checkbox );
115141
116- buttons .setLayout (new FlowLayout (FlowLayout .CENTER ,BUTTONGAP ,0 ));
142+ JPanel buttons = new JPanel ();
143+ buttons .setLayout (new FlowLayout (FlowLayout .CENTER , BUTTONGAP , 0 ));
117144
118145 // ordering is different on mac versus pc
119146 if (Base .isMacOS ()) {
@@ -130,7 +157,7 @@ public void actionPerformed(ActionEvent e) {
130157 buttons .add (replaceButton = new JButton (_ ("Replace" )));
131158 buttons .add (replaceAllButton = new JButton (_ ("Replace All" )));
132159 }
133- pain .add (buttons );
160+ pane .add (buttons );
134161
135162 // to fix ugliness.. normally macosx java 1.3 puts an
136163 // ugly white border around this object, so turn it off.
@@ -180,9 +207,13 @@ public void focusLost(FocusEvent e) {
180207
181208 ignoreCaseBox .setBounds (EDGE + labelDimension .width + SMALL ,
182209 ypos ,
183- (fieldWidth -SMALL )/2 , fieldHeight );
210+ (fieldWidth -SMALL )/4 , fieldHeight );
211+
212+ wrapAroundBox .setBounds (EDGE + labelDimension .width + SMALL + (fieldWidth -SMALL )/4 + SMALL ,
213+ ypos ,
214+ (fieldWidth -SMALL )/4 , fieldHeight );
184215
185- wrapAroundBox .setBounds (EDGE + labelDimension .width + SMALL + (fieldWidth -SMALL )/2 + SMALL ,
216+ searchAllFilesBox .setBounds (EDGE + labelDimension .width + SMALL + (int )(( fieldWidth -SMALL )/1.9 ) + SMALL ,
186217 ypos ,
187218 (fieldWidth -SMALL )/2 , fieldHeight );
188219
@@ -191,7 +222,7 @@ public void focusLost(FocusEvent e) {
191222 buttons .setBounds (EDGE -BUTTONGAP , ypos ,
192223 buttonsDimension .width , buttonsDimension .height );
193224
194- ypos += buttonsDimension .height + EDGE ;
225+ ypos += buttonsDimension .height ;
195226
196227// Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
197228
@@ -291,8 +322,9 @@ public void actionPerformed(ActionEvent e) {
291322 // look for the next instance of the find string to be found
292323 // once found, select it (and go to that line)
293324
294- private boolean find (boolean wrap ,boolean backwards ) {
295-
325+ private boolean find (boolean wrap ,boolean backwards ,boolean searchTabs ,int originTab ) {
326+ //System.out.println("Find: " + originTab);
327+ boolean wrapNeeded = false ;
296328 String search = findField .getText ();
297329 //System.out.println("finding for " + search + " " + findString);
298330 // this will catch "find next" being called when no search yet
@@ -313,7 +345,7 @@ private boolean find(boolean wrap,boolean backwards ) {
313345 nextIndex = text .indexOf (search , selectionEnd );
314346 if (wrap && nextIndex == -1 ) {
315347 // if wrapping, a second chance is ok, start from beginning
316- nextIndex = text . indexOf ( search , 0 ) ;
348+ wrapNeeded = true ;
317349 }
318350 } else {
319351 //int selectionStart = editor.textarea.getSelectionStart();
@@ -326,16 +358,53 @@ private boolean find(boolean wrap,boolean backwards ) {
326358 }
327359 if (wrap && nextIndex == -1 ) {
328360 // if wrapping, a second chance is ok, start from the end
329- nextIndex = text . lastIndexOf ( search ) ;
361+ wrapNeeded = true ;
330362 }
331363 }
332364
333- if (nextIndex != -1 ) {
334- editor .setSelection (nextIndex , nextIndex + search .length ());
335- } else {
336- //Toolkit.getDefaultToolkit().beep();
365+ if (nextIndex == -1 ) {
366+ // Nothing found on this tab: Search other tabs if required
367+ if (searchTabs ) {
368+ // editor.
369+ Sketch sketch = editor .getSketch ();
370+ if (sketch .getCodeCount () > 1 ) {
371+ int realCurrentTab = sketch .getCodeIndex (sketch .getCurrentCode ());
372+
373+ if (originTab != realCurrentTab ) {
374+ if (originTab < 0 )
375+ originTab = realCurrentTab ;
376+
377+ if (!wrap )
378+ if ((!backwards && realCurrentTab + 1 >= sketch .getCodeCount ()) ||
379+ (backwards && realCurrentTab - 1 < 0 ))
380+ return false ; // Can't continue without wrap
381+
382+ if (backwards ) {
383+ sketch .handlePrevCode ();
384+ this .setVisible (true );
385+ int l = editor .getText ().length () - 1 ;
386+ editor .setSelection (l , l );
387+ } else {
388+ sketch .handleNextCode ();
389+ this .setVisible (true );
390+ editor .setSelection (0 , 0 );
391+ }
392+
393+ return find (wrap , backwards , searchTabs , originTab );
394+ }
395+ }
396+ }
397+
398+ if (wrapNeeded )
399+ nextIndex = backwards ? text .lastIndexOf (search ) : text .indexOf (search , 0 );
337400 }
338- return nextIndex != -1 ;
401+
402+ if (nextIndex != -1 ) {
403+ editor .setSelection (nextIndex , nextIndex + search .length ());
404+ return true ;
405+ }
406+
407+ return false ;
339408 }
340409
341410
@@ -344,8 +413,26 @@ private boolean find(boolean wrap,boolean backwards ) {
344413 * replacement text field.
345414 */
346415 public void replace () {
347- editor .setSelectedText (replaceField .getText ());
348- editor .getSketch ().setModified (true ); // TODO is this necessary?
416+ if (findField .getText ().length () == 0 )
417+ return ;
418+
419+ int newpos = editor .getSelectionStart () - findField .getText ().length ();
420+ if (newpos < 0 )
421+ newpos = 0 ;
422+ editor .setSelection (newpos , newpos );
423+
424+ boolean foundAtLeastOne = false ;
425+
426+ if (find (false , false , searchAllFiles , -1 )) {
427+ foundAtLeastOne = true ;
428+ editor .setSelectedText (replaceField .getText ());
429+ editor .getSketch ().setModified (true ); // TODO is this necessary?
430+ }
431+
432+ if (!foundAtLeastOne ) {
433+ Toolkit .getDefaultToolkit ().beep ();
434+ }
435+
349436 }
350437
351438 /**
@@ -362,19 +449,22 @@ public void replaceAndFindNext() {
362449 * alternately until nothing more found.
363450 */
364451 public void replaceAll () {
452+ if (findField .getText ().length () == 0 )
453+ return ;
365454 // move to the beginning
366455 editor .setSelection (0 , 0 );
367456
368457 boolean foundAtLeastOne = false ;
369- while ( true ) {
370- if ( find (false ,false ) ) {
458+ while (true ) {
459+ if (find (false , false , searchAllFiles , - 1 ) ) {
371460 foundAtLeastOne = true ;
372- replace ();
373- } else {
461+ editor .setSelectedText (replaceField .getText ());
462+ editor .getSketch ().setModified (true ); // TODO is this necessary?
463+ } else {
374464 break ;
375465 }
376466 }
377- if ( !foundAtLeastOne ) {
467+ if (!foundAtLeastOne ) {
378468 Toolkit .getDefaultToolkit ().beep ();
379469 }
380470 }
@@ -385,13 +475,13 @@ public void setFindText( String t ) {
385475 }
386476
387477 public void findNext () {
388- if ( !find ( wrapAround , false ) ) {
478+ if ( !find ( wrapAround , false , searchAllFiles ,- 1 ) ) {
389479 Toolkit .getDefaultToolkit ().beep ();
390480 }
391481 }
392482
393483 public void findPrevious () {
394- if ( !find ( wrapAround , true ) ) {
484+ if ( !find ( wrapAround , true , searchAllFiles ,- 1 ) ) {
395485 Toolkit .getDefaultToolkit ().beep ();
396486 }
397487 }
0 commit comments