Lines 1-823
Link Here
|
1 |
/* |
|
|
2 |
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. |
3 |
* |
4 |
* Copyright 1997-2010 Oracle and/or its affiliates. All rights reserved. |
5 |
* |
6 |
* Oracle and Java are registered trademarks of Oracle and/or its affiliates. |
7 |
* Other names may be trademarks of their respective owners. |
8 |
* |
9 |
* The contents of this file are subject to the terms of either the GNU |
10 |
* General Public License Version 2 only ("GPL") or the Common |
11 |
* Development and Distribution License("CDDL") (collectively, the |
12 |
* "License"). You may not use this file except in compliance with the |
13 |
* License. You can obtain a copy of the License at |
14 |
* http://www.netbeans.org/cddl-gplv2.html |
15 |
* or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the |
16 |
* specific language governing permissions and limitations under the |
17 |
* License. When distributing the software, include this License Header |
18 |
* Notice in each file and include the License file at |
19 |
* nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this |
20 |
* particular file as subject to the "Classpath" exception as provided |
21 |
* by Oracle in the GPL Version 2 section of the License file that |
22 |
* accompanied this code. If applicable, add the following below the |
23 |
* License Header, with the fields enclosed by brackets [] replaced by |
24 |
* your own identifying information: |
25 |
* "Portions Copyrighted [year] [name of copyright owner]" |
26 |
* |
27 |
* Contributor(s): |
28 |
* |
29 |
* The Original Software is NetBeans. The Initial Developer of the Original |
30 |
* Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun |
31 |
* Microsystems, Inc. All Rights Reserved. |
32 |
* |
33 |
* If you wish your version of this file to be governed by only the CDDL |
34 |
* or only the GPL Version 2, indicate your decision by adding |
35 |
* "[Contributor] elects to include this software in this distribution |
36 |
* under the [CDDL or GPL Version 2] license." If you do not indicate a |
37 |
* single choice of license, a recipient has the option to distribute |
38 |
* your version of this file under either the CDDL, the GPL Version 2 or |
39 |
* to extend the choice of license to its licensees as provided above. |
40 |
* However, if you add GPL Version 2 code and therefore, elected the GPL |
41 |
* Version 2 license, then the option applies only if the new code is |
42 |
* made subject to such option by the copyright holder. |
43 |
*/ |
44 |
|
45 |
package org.netbeans.editor.ext; |
46 |
|
47 |
import java.awt.Color; |
48 |
import java.awt.Component; |
49 |
import java.awt.Dialog; |
50 |
import java.awt.event.*; |
51 |
import java.beans.PropertyChangeEvent; |
52 |
import java.beans.PropertyChangeListener; |
53 |
import java.util.ArrayList; |
54 |
import java.util.List; |
55 |
import java.util.Map; |
56 |
import java.util.HashMap; |
57 |
import java.util.Collections; |
58 |
import java.util.ResourceBundle; |
59 |
import javax.swing.*; |
60 |
import javax.swing.JComponent; |
61 |
import javax.swing.text.JTextComponent; |
62 |
import javax.swing.text.BadLocationException; |
63 |
import javax.swing.text.Position; |
64 |
import org.netbeans.editor.BaseKit; |
65 |
import org.netbeans.editor.DialogSupport; |
66 |
import org.netbeans.editor.GuardedException; |
67 |
import org.netbeans.editor.Utilities; |
68 |
import java.util.Iterator; |
69 |
import java.util.regex.Pattern; |
70 |
import java.util.regex.PatternSyntaxException; |
71 |
import javax.swing.text.DefaultEditorKit; |
72 |
import javax.swing.text.Document; |
73 |
import org.netbeans.editor.BaseDocument; |
74 |
import org.netbeans.modules.editor.lib2.search.EditorFindSupport; |
75 |
import org.openide.util.NbBundle; |
76 |
|
77 |
/** |
78 |
* Support for displaying find and replace dialogs |
79 |
* |
80 |
* @author Miloslav Metelka |
81 |
* @version 1.00 |
82 |
* @deprecated Without any replacement. |
83 |
*/ |
84 |
|
85 |
public class FindDialogSupport extends WindowAdapter implements ActionListener { |
86 |
|
87 |
/** This lock is used to create a barrier between showing/hiding/changing |
88 |
* the dialog and testing if the dialog is already shown. |
89 |
* it is used to make test-and-change / test-and-display actions atomic. |
90 |
* It covers the following four fields: findDialog, isReplaceDialog, |
91 |
* findPanel, findButtons |
92 |
*/ |
93 |
private static Object dialogLock = new Object(); |
94 |
|
95 |
/** Whether the currently visible dialog is for replace */ |
96 |
private static boolean isReplaceDialog = false; |
97 |
|
98 |
/** The buttons used in the visible dialog */ |
99 |
private static JButton findButtons[]; |
100 |
|
101 |
private static JButton findDialogButtons[]; |
102 |
private static JButton replaceDialogButtons[]; |
103 |
|
104 |
/** The FindPanel used inside the visible dialog */ |
105 |
private static FindPanel findPanel; |
106 |
|
107 |
/** Currently visible dialog */ |
108 |
private static Dialog findDialog = null; |
109 |
|
110 |
private int caretPosition; |
111 |
|
112 |
private static FindDialogSupport singleton = null; |
113 |
|
114 |
private boolean findPerformed = false; |
115 |
|
116 |
private static int xPos = Integer.MIN_VALUE; |
117 |
private static int yPos = Integer.MIN_VALUE; |
118 |
|
119 |
/** Flag for determining a dialog invocation. It the dialog |
120 |
* is invoked by keystroke or by the menu the value is true. |
121 |
* If the dialog was already shown and the focus was bring to it only, |
122 |
* value is false - needed for fixing the issue #68021 |
123 |
*/ |
124 |
private static boolean dialogInvokedViaKeystroke; |
125 |
|
126 |
/** Whether the block search checkbox was selected by code or by a user. */ |
127 |
private static boolean expectedBlockSearchItemChange; |
128 |
|
129 |
public static FindDialogSupport getFindDialogSupport() { |
130 |
if (singleton == null) { |
131 |
singleton = new FindDialogSupport(); |
132 |
} |
133 |
return singleton; |
134 |
} |
135 |
|
136 |
private FindDialogSupport() { |
137 |
} |
138 |
|
139 |
private void createFindButtons() { |
140 |
if (findButtons == null) { |
141 |
ResourceBundle bundle = NbBundle.getBundle(BaseKit.class); |
142 |
findButtons = new JButton[] { |
143 |
new JButton(bundle.getString("find-button-find")), // NOI18N |
144 |
new JButton(bundle.getString("find-button-replace")), // NOI18N |
145 |
new JButton(bundle.getString("find-button-replace-all")), // NOI18N |
146 |
new JButton(bundle.getString("find-button-cancel")) // NOI18N |
147 |
}; |
148 |
|
149 |
findButtons[0].setMnemonic(bundle.getString("find-button-find-mnemonic").charAt(0)); // NOI18N |
150 |
findButtons[1].setMnemonic(bundle.getString("find-button-replace-mnemonic").charAt(0)); // NOI18N |
151 |
findButtons[2].setMnemonic(bundle.getString("find-button-replace-all-mnemonic").charAt(0)); // NOI18N |
152 |
|
153 |
findButtons[0].getAccessibleContext().setAccessibleDescription(bundle.getString("ACSD_find-button-find")); // NOI18N |
154 |
findButtons[1].getAccessibleContext().setAccessibleDescription(bundle.getString("ACSD_find-button-replace")); // NOI18N |
155 |
findButtons[2].getAccessibleContext().setAccessibleDescription(bundle.getString("ACSD_find-button-replace-all")); // NOI18N |
156 |
findButtons[3].getAccessibleContext().setAccessibleDescription(bundle.getString("ACSD_find-button-cancel")); // NOI18N |
157 |
|
158 |
findDialogButtons = new JButton[2]; |
159 |
findDialogButtons[0] = findButtons[0]; |
160 |
findDialogButtons[1] = findButtons[3]; |
161 |
|
162 |
replaceDialogButtons = new JButton[4]; |
163 |
replaceDialogButtons[0] = findButtons[0]; |
164 |
replaceDialogButtons[1] = findButtons[1]; |
165 |
replaceDialogButtons[2] = findButtons[2]; |
166 |
replaceDialogButtons[3] = findButtons[3]; |
167 |
} |
168 |
} |
169 |
|
170 |
private void createFindPanel() { |
171 |
if (findPanel == null) { |
172 |
findPanel = new FindPanel(); |
173 |
} |
174 |
} |
175 |
|
176 |
private Dialog createFindDialog(JPanel findPanel, final JButton[] buttons, |
177 |
final ActionListener l) { |
178 |
Dialog d = DialogSupport.createDialog( |
179 |
isReplaceDialog |
180 |
? NbBundle.getBundle(BaseKit.class).getString ("replace-title") |
181 |
: NbBundle.getBundle(BaseKit.class).getString ("find-title" ), // NOI18N |
182 |
findPanel, false, // non-modal |
183 |
buttons, true, // sidebuttons, |
184 |
0, // defaultIndex = 0 => findButton |
185 |
isReplaceDialog ? 3 : 1, // cancelIndex = 3 => cancelButton |
186 |
l //listener |
187 |
); |
188 |
|
189 |
return d; |
190 |
} |
191 |
|
192 |
private void showFindDialogImpl( boolean isReplace, KeyEventBlocker blocker) { |
193 |
dialogInvokedViaKeystroke = true; |
194 |
synchronized( dialogLock ) { |
195 |
if (findDialog != null && isReplaceDialog != isReplace ) { |
196 |
xPos = findDialog.getLocation().x; |
197 |
yPos = findDialog.getLocation().y; |
198 |
findDialog.dispose(); |
199 |
findDialog = null; |
200 |
} |
201 |
if (findDialog == null) { // create and show new dialog of required type |
202 |
isReplaceDialog = isReplace; |
203 |
createFindButtons(); |
204 |
createFindPanel(); |
205 |
findPanel.changeVisibility(isReplace); |
206 |
|
207 |
findDialog = createFindDialog( findPanel, isReplace ? replaceDialogButtons : findDialogButtons, this ); |
208 |
findDialog.addWindowListener( this ); |
209 |
((JDialog)findDialog).getRootPane().setFocusable(false); |
210 |
if(xPos > Integer.MIN_VALUE){ |
211 |
findDialog.setLocation(xPos, yPos); |
212 |
} |
213 |
} |
214 |
} // end of synchronized section |
215 |
|
216 |
findDialog.pack(); |
217 |
findPanel.init(isReplace, blocker); |
218 |
findDialog.setVisible(true); |
219 |
findPanel.showNotify(); |
220 |
findPanel.initBlockSearch(); |
221 |
updateCaretPosition(); |
222 |
} |
223 |
|
224 |
private void updateCaretPosition() { |
225 |
JTextComponent c = Utilities.getLastActiveComponent(); |
226 |
if (c != null) { |
227 |
caretPosition = c.getCaret().getDot(); |
228 |
} |
229 |
} |
230 |
|
231 |
public @Override void windowActivated(WindowEvent evt) { |
232 |
findPerformed = false; |
233 |
createFindPanel(); |
234 |
findPanel.initBlockSearch(); |
235 |
updateCaretPosition(); |
236 |
} |
237 |
|
238 |
public @Override void windowDeactivated(WindowEvent evt) { |
239 |
JTextComponent c = Utilities.getLastActiveComponent(); |
240 |
EditorFindSupport.getInstance().incSearchReset(); |
241 |
KeyEventBlocker blocker = findPanel.getBlocker(); |
242 |
if (blocker!=null){ |
243 |
blocker.stopBlocking(false); |
244 |
} |
245 |
} |
246 |
|
247 |
public @Override void windowClosing(WindowEvent e) { |
248 |
hideDialog(); |
249 |
} |
250 |
|
251 |
public @Override void windowClosed(WindowEvent e) { |
252 |
synchronized (dialogLock) { |
253 |
if (findDialog != null){ |
254 |
xPos = findDialog.getLocation().x; |
255 |
yPos = findDialog.getLocation().y; |
256 |
} |
257 |
} |
258 |
Map findProps = findPanel.getFindProps(); |
259 |
if (Boolean.TRUE.equals(findProps.get(EditorFindSupport.FIND_BLOCK_SEARCH))) { |
260 |
Position startPos = (Position) findProps.get(EditorFindSupport.FIND_BLOCK_SEARCH_START); |
261 |
Position endPos = (Position) findProps.get(EditorFindSupport.FIND_BLOCK_SEARCH_END); |
262 |
if (startPos != null && endPos != null) { |
263 |
JTextComponent c = Utilities.getLastActiveComponent(); |
264 |
if (c != null) { |
265 |
c.select(startPos.getOffset(), endPos.getOffset()); |
266 |
} |
267 |
|
268 |
} |
269 |
} |
270 |
EditorFindSupport.getInstance().incSearchReset(); |
271 |
findPanel.resetBlockSearch(); |
272 |
EditorFindSupport.getInstance().setBlockSearchHighlight(0, 0); |
273 |
findProps.put(EditorFindSupport.FIND_BLOCK_SEARCH, Boolean.FALSE); |
274 |
findProps.put(EditorFindSupport.FIND_BLOCK_SEARCH_START, null); |
275 |
findProps.put(EditorFindSupport.FIND_BLOCK_SEARCH_END, null); |
276 |
EditorFindSupport.getInstance().putFindProperties(findProps); |
277 |
KeyEventBlocker blocker = findPanel.getBlocker(); |
278 |
if (blocker!=null){ |
279 |
blocker.stopBlocking(false); |
280 |
} |
281 |
findPanel.reset(); |
282 |
|
283 |
Utilities.returnFocus(); |
284 |
} |
285 |
|
286 |
public void showFindDialog(KeyEventBlocker blocker) { |
287 |
showFindDialogImpl(false, blocker); |
288 |
} |
289 |
|
290 |
public void showReplaceDialog(KeyEventBlocker blocker) { |
291 |
showFindDialogImpl(true, blocker); |
292 |
} |
293 |
|
294 |
public void hideDialog() { |
295 |
synchronized (dialogLock) { |
296 |
if (findDialog != null){ |
297 |
xPos = findDialog.getLocation().x; |
298 |
yPos = findDialog.getLocation().y; |
299 |
findDialog.dispose(); |
300 |
} |
301 |
findDialog = null; |
302 |
} |
303 |
} |
304 |
|
305 |
private List getHistoryList(){ |
306 |
List<EditorFindSupport.SPW> histList = (List)EditorFindSupport.getInstance().getHistory(); |
307 |
if (histList == null) histList = new ArrayList(); |
308 |
List<String> list = new ArrayList<String>(); |
309 |
for (EditorFindSupport.SPW spw : histList){ |
310 |
list.add(spw.getSearchExpression()); |
311 |
} |
312 |
return list; |
313 |
} |
314 |
|
315 |
private boolean getBooleanProp(String propName, Map map){ |
316 |
Boolean b = (Boolean) map.get(propName); |
317 |
return (b!=null) ? b.booleanValue() : false; |
318 |
} |
319 |
|
320 |
@Override |
321 |
public void actionPerformed(ActionEvent evt) { |
322 |
if( findButtons == null ) return; |
323 |
|
324 |
Object src = evt.getSource(); |
325 |
EditorFindSupport fSup = EditorFindSupport.getInstance(); |
326 |
Map findPanelMap = findPanel.getFindProps(); |
327 |
|
328 |
EditorFindSupport.SPW spw = new EditorFindSupport.SPW((String)findPanelMap.get(EditorFindSupport.FIND_WHAT), |
329 |
getBooleanProp(EditorFindSupport.FIND_WHOLE_WORDS, findPanelMap), |
330 |
getBooleanProp(EditorFindSupport.FIND_MATCH_CASE, findPanelMap), |
331 |
getBooleanProp(EditorFindSupport.FIND_REG_EXP, findPanelMap)); |
332 |
|
333 |
if (src == findButtons[0]) { // Find button |
334 |
fSup.addToHistory(spw); |
335 |
findPanel.updateFindHistory(); |
336 |
fSup.putFindProperties(findPanelMap); |
337 |
fSup.find(null, false); |
338 |
updateCaretPosition(); |
339 |
findPerformed = true; |
340 |
} else if (src == findButtons[1]) { // Replace button |
341 |
fSup.addToHistory(spw); |
342 |
findPanel.updateFindHistory(); |
343 |
findPanel.updateReplaceHistory(); |
344 |
fSup.putFindProperties(findPanelMap); |
345 |
try { |
346 |
if (fSup.replace(null, false)) { // replaced |
347 |
findPanelMap.put(EditorFindSupport.FIND_BLOCK_SEARCH_START, |
348 |
fSup.getFindProperty(EditorFindSupport.FIND_BLOCK_SEARCH_START)); |
349 |
fSup.find(null, false); |
350 |
} |
351 |
} catch (GuardedException e) { |
352 |
// replace in guarded block |
353 |
} catch (BadLocationException e) { |
354 |
e.printStackTrace(); |
355 |
} |
356 |
updateCaretPosition(); |
357 |
findPerformed = true; |
358 |
} else if (src == findButtons[2]) { // Replace All button |
359 |
fSup.addToHistory(spw); |
360 |
findPanel.updateFindHistory(); |
361 |
findPanel.updateReplaceHistory(); |
362 |
fSup.putFindProperties(findPanelMap); |
363 |
fSup.replaceAll(null); |
364 |
findPanelMap.put(EditorFindSupport.FIND_BLOCK_SEARCH_START, |
365 |
fSup.getFindProperty(EditorFindSupport.FIND_BLOCK_SEARCH_START)); |
366 |
findPerformed = true; |
367 |
} else if (src == findButtons[3]) { // Cancel button |
368 |
hideDialog(); |
369 |
} |
370 |
} |
371 |
|
372 |
/** Panel that holds the find logic */ |
373 |
private class FindPanel extends FindDialogPanel |
374 |
implements ItemListener, KeyListener, ActionListener, FocusListener { |
375 |
|
376 |
private Map findProps = Collections.synchronizedMap(new HashMap(20)); |
377 |
private Map objToProps = Collections.synchronizedMap(new HashMap(20)); |
378 |
|
379 |
private javax.swing.DefaultComboBoxModel findHistory = new javax.swing.DefaultComboBoxModel(); |
380 |
private javax.swing.DefaultComboBoxModel replaceHistory = new javax.swing.DefaultComboBoxModel(); |
381 |
|
382 |
private KeyEventBlocker blocker; |
383 |
|
384 |
private Position blockSearchStartPos; |
385 |
private Position blockSearchEndPos; |
386 |
|
387 |
|
388 |
FindPanel() { |
389 |
objToProps.put(findWhat, EditorFindSupport.FIND_WHAT); |
390 |
objToProps.put(replaceWith, EditorFindSupport.FIND_REPLACE_WITH); |
391 |
objToProps.put(highlightSearch, EditorFindSupport.FIND_HIGHLIGHT_SEARCH); |
392 |
objToProps.put(incSearch, EditorFindSupport.FIND_INC_SEARCH); |
393 |
objToProps.put(matchCase, EditorFindSupport.FIND_MATCH_CASE); |
394 |
objToProps.put(preserveCase, EditorFindSupport.FIND_PRESERVE_CASE); |
395 |
//objToProps.put(smartCase, SettingsNames.FIND_SMART_CASE); |
396 |
objToProps.put(wholeWords, EditorFindSupport.FIND_WHOLE_WORDS); |
397 |
objToProps.put(regExp, EditorFindSupport.FIND_REG_EXP); |
398 |
objToProps.put(bwdSearch, EditorFindSupport.FIND_BACKWARD_SEARCH); |
399 |
objToProps.put(wrapSearch, EditorFindSupport.FIND_WRAP_SEARCH); |
400 |
objToProps.put(blockSearch, EditorFindSupport.FIND_BLOCK_SEARCH); |
401 |
|
402 |
findProps.putAll(EditorFindSupport.getInstance().getFindProperties()); |
403 |
revertMap(); |
404 |
|
405 |
findWhat.setModel(findHistory); |
406 |
findWhat.getEditor().setItem(getProperty(findWhat)); |
407 |
Component editorC = findWhat.getEditor().getEditorComponent(); |
408 |
if (editorC instanceof JComponent) { |
409 |
InputMap inputMap = ((JComponent)editorC).getInputMap(); |
410 |
inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_INSERT, InputEvent.SHIFT_MASK), |
411 |
DefaultEditorKit.pasteAction); |
412 |
inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_INSERT, InputEvent.CTRL_MASK), |
413 |
DefaultEditorKit.copyAction); |
414 |
} |
415 |
replaceWith.setModel(replaceHistory); |
416 |
replaceWith.getEditor().setItem(getProperty(replaceWith)); |
417 |
highlightSearch.setSelected(getBooleanProperty(highlightSearch)); |
418 |
incSearch.setSelected(getBooleanProperty(incSearch)); |
419 |
matchCase.setSelected(getBooleanProperty(matchCase)); |
420 |
preserveCase.setSelected(getBooleanProperty(preserveCase)); |
421 |
preserveCase.setVisible(isReplaceDialog); |
422 |
//smartCase.setSelected(getBooleanProperty(smartCase)); |
423 |
wholeWords.setSelected(getBooleanProperty(wholeWords)); |
424 |
regExp.setSelected(getBooleanProperty(regExp)); |
425 |
bwdSearch.setSelected(getBooleanProperty(bwdSearch)); |
426 |
wrapSearch.setSelected(getBooleanProperty(wrapSearch)); |
427 |
updateFindDialogUI(); |
428 |
|
429 |
findWhat.getEditor().getEditorComponent().addKeyListener(this); |
430 |
findWhat.addActionListener(this); |
431 |
replaceWith.getEditor().getEditorComponent().addKeyListener(this); |
432 |
replaceWith.addActionListener(this); |
433 |
highlightSearch.addItemListener(this); |
434 |
incSearch.addItemListener(this); |
435 |
matchCase.addItemListener(this); |
436 |
preserveCase.addItemListener(this); |
437 |
//smartCase.addItemListener(this); |
438 |
wholeWords.addItemListener(this); |
439 |
regExp.addItemListener(this); |
440 |
bwdSearch.addItemListener(this); |
441 |
wrapSearch.addItemListener(this); |
442 |
blockSearch.addItemListener(this); |
443 |
} |
444 |
|
445 |
protected Map getFindProps() { |
446 |
return findProps; |
447 |
} |
448 |
|
449 |
private KeyEventBlocker getBlocker(){ |
450 |
return blocker; |
451 |
} |
452 |
|
453 |
private void putProperty(Object component, Object value) { |
454 |
String prop = (String)objToProps.get(component); |
455 |
if (prop != null) { |
456 |
findProps.put(prop, value); |
457 |
} |
458 |
} |
459 |
|
460 |
private Object getProperty(Object component) { |
461 |
String prop = (String)objToProps.get(component); |
462 |
return (prop != null) ? findProps.get(prop) : null; |
463 |
} |
464 |
|
465 |
private boolean getBooleanProperty(Object component) { |
466 |
Object prop = getProperty(component); |
467 |
return (prop != null) ? ((Boolean)prop).booleanValue() : false; |
468 |
} |
469 |
|
470 |
protected void changeVisibility(boolean v) { |
471 |
replaceWith.setVisible(v); |
472 |
replaceWithLabel.setVisible(v); |
473 |
} |
474 |
|
475 |
/** |
476 |
* update dialog view based on search and replace texts |
477 |
*/ |
478 |
private void updateFindDialogUI() |
479 |
{ |
480 |
boolean wrongFindPattern=false; |
481 |
boolean wrongReplacePattern=false; |
482 |
String what=findWhat.getEditor().getItem().toString(); |
483 |
String toWhat=replaceWith.getEditor().getItem().toString(); |
484 |
if(what==null || what.length()==0)wrongFindPattern=true; |
485 |
if(toWhat==null)wrongReplacePattern=true; |
486 |
if(regExp.isSelected()) |
487 |
{ |
488 |
Pattern searchPattern; |
489 |
int numGroups=0; |
490 |
if(!wrongFindPattern) |
491 |
{ |
492 |
try |
493 |
{ |
494 |
searchPattern=Pattern.compile(what); |
495 |
numGroups=searchPattern.matcher("").groupCount(); |
496 |
} |
497 |
catch(PatternSyntaxException ex) |
498 |
{ |
499 |
wrongFindPattern=true; |
500 |
} |
501 |
} |
502 |
if(!wrongReplacePattern) |
503 |
{ |
504 |
//the obly problemmatic part of replacement is references to initial pattern |
505 |
//emulate replacement below to find any problems |
506 |
String pseudoText="0123456789";//NOI18N |
507 |
String pseudoWhat="";//NOI18N |
508 |
for(int i=0;i<numGroups;i++) |
509 |
{ |
510 |
pseudoWhat+="("+i+")";//NOI18N |
511 |
} |
512 |
Pattern pseudoP=Pattern.compile(pseudoWhat); |
513 |
try |
514 |
{ |
515 |
pseudoP.matcher(pseudoText).replaceFirst(toWhat); |
516 |
} |
517 |
catch(Exception ex) |
518 |
{ |
519 |
//got probem with group reference, either not a number after $ or not existent group |
520 |
wrongReplacePattern=true; |
521 |
} |
522 |
} |
523 |
} |
524 |
findButtons[0].setEnabled(!wrongFindPattern);//find button |
525 |
findButtons[1].setEnabled(!wrongReplacePattern && !wrongFindPattern);//replace button |
526 |
findButtons[2].setEnabled(!wrongReplacePattern && !wrongFindPattern);//replace all button |
527 |
findWhat.getEditor().getEditorComponent().setForeground(wrongFindPattern ? Color.RED : UIManager.getColor("textText")); //NOI18N |
528 |
replaceWith.getEditor().getEditorComponent().setForeground(wrongReplacePattern ? Color.RED : UIManager.getColor("textText")); //NOI18N |
529 |
} |
530 |
|
531 |
private void resetBlockSearch() { |
532 |
findProps.put(EditorFindSupport.FIND_BLOCK_SEARCH, Boolean.FALSE); |
533 |
EditorFindSupport.getInstance().setBlockSearchHighlight(0,0); |
534 |
EditorFindSupport.getInstance().putFindProperties(findProps); |
535 |
} |
536 |
|
537 |
private void initBlockSearch() { |
538 |
JTextComponent c = Utilities.getLastActiveComponent(); |
539 |
String selText; |
540 |
boolean multiLineSelection; |
541 |
boolean invokedViaKeystroke = dialogInvokedViaKeystroke; |
542 |
dialogInvokedViaKeystroke = false; |
543 |
|
544 |
if (c != null) { |
545 |
Document doc = c.getDocument(); |
546 |
int blockSearchStartOffset = c.getSelectionStart(); |
547 |
int blockSearchEndOffset = c.getSelectionEnd(); |
548 |
try { |
549 |
blockSearchStartPos = doc.createPosition(blockSearchStartOffset); |
550 |
blockSearchEndPos = doc.createPosition(blockSearchEndOffset); |
551 |
} catch (BadLocationException e) { |
552 |
// Should never happen |
553 |
} |
554 |
BaseDocument bdoc = (BaseDocument) doc; |
555 |
try{ |
556 |
multiLineSelection = (blockSearchEndOffset != blockSearchStartOffset) |
557 |
&& (doc instanceof BaseDocument) && |
558 |
(Utilities.getLineOffset((BaseDocument)doc, blockSearchEndOffset) > |
559 |
Utilities.getLineOffset((BaseDocument)doc, blockSearchStartOffset)); |
560 |
} catch (BadLocationException ble){ |
561 |
multiLineSelection = false; |
562 |
} |
563 |
|
564 |
caretPosition = bwdSearch.isSelected() ? blockSearchEndOffset : blockSearchStartOffset; |
565 |
|
566 |
if (!multiLineSelection && invokedViaKeystroke) { |
567 |
selText = c.getSelectedText(); |
568 |
if (selText != null && selText.length() > 0) { |
569 |
int n = selText.indexOf( '\n' ); |
570 |
if (n >= 0 ) selText = selText.substring(0, n); |
571 |
findWhat.getEditor().setItem(selText); |
572 |
} |
573 |
} |
574 |
|
575 |
// For multi-line selection turn on block-search checkbox automatically |
576 |
if (invokedViaKeystroke) { |
577 |
expectedBlockSearchItemChange = true; |
578 |
blockSearch.setSelected(multiLineSelection); |
579 |
} |
580 |
|
581 |
findProps.put(EditorFindSupport.FIND_BLOCK_SEARCH, blockSearch.isSelected()); |
582 |
findProps.put(EditorFindSupport.FIND_BLOCK_SEARCH_START, blockSearchStartPos); |
583 |
findProps.put(EditorFindSupport.FIND_BLOCK_SEARCH_END, blockSearchEndPos); |
584 |
EditorFindSupport.getInstance().setBlockSearchHighlight( |
585 |
blockSearchStartOffset, blockSearchEndOffset); |
586 |
} |
587 |
} |
588 |
|
589 |
protected void init(boolean isReplace, KeyEventBlocker blocker) { |
590 |
this.blocker = blocker; |
591 |
findHistory.setSelectedItem(null); |
592 |
replaceHistory.setSelectedItem(null); |
593 |
findWhat.getEditor().getEditorComponent().addFocusListener(this); |
594 |
if (isReplace) { |
595 |
replaceWith.getEditor().getEditorComponent().addFocusListener(this); |
596 |
} |
597 |
|
598 |
findProps.putAll(EditorFindSupport.getInstance().getFindProperties()); |
599 |
revertMap(); |
600 |
|
601 |
highlightSearch.setSelected(getBooleanProperty(highlightSearch)); |
602 |
incSearch.setSelected(getBooleanProperty(incSearch)); |
603 |
matchCase.setSelected(getBooleanProperty(matchCase)); |
604 |
preserveCase.setSelected(getBooleanProperty(preserveCase)); |
605 |
preserveCase.setVisible(isReplaceDialog); |
606 |
//smartCase.setSelected(getBooleanProperty(smartCase)); |
607 |
wholeWords.setSelected(getBooleanProperty(wholeWords)); |
608 |
boolean regExpValue = getBooleanProperty(regExp); |
609 |
regExp.setSelected(regExpValue); |
610 |
wholeWords.setEnabled(!regExpValue); |
611 |
incSearch.setEnabled(!regExpValue); |
612 |
preserveCase.setEnabled(!(getBooleanProperty(regExp) || getBooleanProperty(matchCase))); |
613 |
bwdSearch.setSelected(getBooleanProperty(bwdSearch)); |
614 |
wrapSearch.setSelected(getBooleanProperty(wrapSearch)); |
615 |
findHistory = new DefaultComboBoxModel(getHistoryList().toArray()); |
616 |
findWhat.setModel(findHistory); |
617 |
} |
618 |
|
619 |
protected void reset() { |
620 |
this.blocker = null; |
621 |
} |
622 |
|
623 |
protected void showNotify() { |
624 |
// fix of issue #66217 |
625 |
boolean focused = findWhat.getEditor().getEditorComponent().requestFocusInWindow(); |
626 |
if (focused == false){ |
627 |
SwingUtilities.invokeLater(new Runnable(){ |
628 |
@Override |
629 |
public void run(){ |
630 |
findWhat.getEditor().getEditorComponent().requestFocusInWindow(); |
631 |
} |
632 |
}); |
633 |
} |
634 |
} |
635 |
|
636 |
private void updateHistory(JComboBox c, javax.swing.DefaultComboBoxModel history) { |
637 |
Object item = c.getEditor().getItem(); |
638 |
if( item != null && !item.equals("")) { //NOI18N |
639 |
history.removeElement(item); |
640 |
history.insertElementAt(item, 0); |
641 |
history.setSelectedItem(null); |
642 |
} |
643 |
c.getEditor().setItem(item); |
644 |
} |
645 |
|
646 |
protected void updateFindHistory() { |
647 |
//updateHistory(findWhat, findHistory); |
648 |
/* |
649 |
List list = new ArrayList(); |
650 |
for (int i = 0; i<findHistory.getSize(); i++){ |
651 |
list.add(findHistory.getElementAt(i)); |
652 |
} |
653 |
EditorFindSupport.getInstance().putFindProperty(SettingsNames.FIND_HISTORY, list); |
654 |
findProps.put(SettingsNames.FIND_HISTORY, list); |
655 |
*/ |
656 |
Object obj = findWhat.getEditor().getItem(); |
657 |
findHistory = new DefaultComboBoxModel(getHistoryList().toArray()); |
658 |
findWhat.setModel(findHistory); |
659 |
if (obj != null){ |
660 |
findWhat.getEditor().setItem(obj); |
661 |
} |
662 |
} |
663 |
|
664 |
protected void updateReplaceHistory() { |
665 |
updateHistory(replaceWith, replaceHistory); |
666 |
} |
667 |
|
668 |
private void revertMap(){ |
669 |
Object prop = findProps.get(EditorFindSupport.REVERT_MAP); |
670 |
if (!(prop instanceof Map)) return; |
671 |
Map revertMap = (Map)prop; |
672 |
|
673 |
for( Iterator i = revertMap.keySet().iterator(); i.hasNext(); ) { |
674 |
String key = (String)i.next(); |
675 |
|
676 |
Object obj = findProps.get(key); |
677 |
boolean value = ( obj != null ) ? ((Boolean)obj).booleanValue() : false; |
678 |
if (value != ((Boolean)revertMap.get(key)).booleanValue()); |
679 |
findProps.put(key, value ? Boolean.FALSE : Boolean.TRUE); |
680 |
} |
681 |
|
682 |
findProps.put(EditorFindSupport.REVERT_MAP, null); |
683 |
} |
684 |
|
685 |
private void changeFindWhat(boolean performIncSearch) { |
686 |
Object old = getProperty(findWhat); |
687 |
Object cur = findWhat.getEditor().getItem(); |
688 |
if ((old == null && cur != null && !cur.equals("")) || (old != null && !old.equals(cur))) { // NOI18N |
689 |
putProperty(findWhat, cur); |
690 |
if (performIncSearch){ |
691 |
findPerformed = EditorFindSupport.getInstance().incSearch(getFindProps(), caretPosition); |
692 |
} |
693 |
} |
694 |
} |
695 |
|
696 |
private void changeReplaceWith() { |
697 |
Object old = getProperty(replaceWith); |
698 |
Object cur = replaceWith.getEditor().getItem(); |
699 |
if ((old == null && cur != null && !cur.equals("")) || (old != null && !old.equals(cur))) { // NOI18N |
700 |
putProperty(replaceWith, cur); |
701 |
} |
702 |
} |
703 |
|
704 |
private void postChangeCombos(final boolean performIncSearch) { |
705 |
SwingUtilities.invokeLater( |
706 |
new Runnable() { |
707 |
@Override |
708 |
public void run() { |
709 |
updateFindDialogUI(); |
710 |
changeFindWhat(performIncSearch); |
711 |
changeReplaceWith(); |
712 |
} |
713 |
} |
714 |
); |
715 |
} |
716 |
|
717 |
@Override |
718 |
public void keyPressed(KeyEvent evt) { |
719 |
if (evt.getKeyChar() == '\n') { |
720 |
evt.consume(); |
721 |
} |
722 |
} |
723 |
|
724 |
@Override |
725 |
public void keyReleased(KeyEvent evt) { |
726 |
if (evt.getKeyChar() == '\n') { |
727 |
evt.consume(); |
728 |
} else if (evt.getKeyCode() == KeyEvent.VK_INSERT){ |
729 |
postChangeCombos(true); |
730 |
} |
731 |
} |
732 |
|
733 |
@Override |
734 |
public void keyTyped(KeyEvent evt) { |
735 |
if (evt.getKeyChar() == '\n') { |
736 |
findButtons[0].doClick(20); |
737 |
evt.consume(); |
738 |
((JComboBox)((JTextField)evt.getSource()).getParent()).hidePopup(); |
739 |
} else { |
740 |
postChangeCombos(true); |
741 |
} |
742 |
} |
743 |
|
744 |
@Override |
745 |
public void itemStateChanged(ItemEvent evt) { |
746 |
Boolean val = (evt.getStateChange() == ItemEvent.SELECTED) ? Boolean.TRUE |
747 |
: Boolean.FALSE; |
748 |
if (evt.getItem() == bwdSearch){ |
749 |
if (blockSearch.isSelected()) { |
750 |
boolean value = val.booleanValue(); |
751 |
JTextComponent c = Utilities.getLastActiveComponent(); |
752 |
if (c!=null) { |
753 |
Position pos = value ? blockSearchEndPos : blockSearchStartPos; |
754 |
c.getCaret().setDot(pos.getOffset()); |
755 |
updateCaretPosition(); |
756 |
} |
757 |
|
758 |
} |
759 |
} |
760 |
if (evt.getItem() == regExp){ |
761 |
boolean value = val.booleanValue(); |
762 |
incSearch.setEnabled(!value); |
763 |
wholeWords.setEnabled(!value); |
764 |
preserveCase.setEnabled(!(value || getBooleanProperty(matchCase))); |
765 |
updateFindDialogUI(); |
766 |
} |
767 |
if (evt.getItem() == matchCase) { |
768 |
boolean value = val.booleanValue(); |
769 |
preserveCase.setEnabled(!(getBooleanProperty(regExp) || value)); |
770 |
updateFindDialogUI(); |
771 |
} |
772 |
if (evt.getItem() == blockSearch){ |
773 |
boolean expectedChange = expectedBlockSearchItemChange; |
774 |
expectedBlockSearchItemChange = false; |
775 |
boolean value = val.booleanValue(); |
776 |
if (value){ |
777 |
if (!expectedChange) { |
778 |
JTextComponent c = Utilities.getLastActiveComponent(); |
779 |
if (c != null) { |
780 |
Position pos = bwdSearch.isSelected() ? blockSearchEndPos : blockSearchStartPos; |
781 |
c.getCaret().setDot(pos.getOffset()); |
782 |
updateCaretPosition(); |
783 |
findPerformed = EditorFindSupport.getInstance().incSearch(getFindProps(), caretPosition); |
784 |
} |
785 |
} |
786 |
EditorFindSupport.getInstance().setBlockSearchHighlight( |
787 |
blockSearchStartPos.getOffset(), blockSearchEndPos.getOffset()); |
788 |
} else { |
789 |
EditorFindSupport.getInstance().putFindProperty(EditorFindSupport.FIND_BLOCK_SEARCH, Boolean.FALSE); |
790 |
EditorFindSupport.getInstance().setBlockSearchHighlight(0, 0); |
791 |
} |
792 |
} |
793 |
|
794 |
putProperty(evt.getSource(), val); |
795 |
|
796 |
if (evt.getItem() == regExp){ |
797 |
updateFindHistory(); |
798 |
} |
799 |
} |
800 |
|
801 |
public void actionPerformed(ActionEvent evt) { |
802 |
postChangeCombos(false); |
803 |
} |
804 |
|
805 |
public void focusGained(FocusEvent e) { |
806 |
if (e.getSource() instanceof JTextField) { |
807 |
((JTextField)e.getSource()).selectAll(); |
808 |
if (blocker != null){ |
809 |
blocker.stopBlocking(); |
810 |
} |
811 |
} |
812 |
((JComponent)e.getSource()).removeFocusListener(this); |
813 |
} |
814 |
|
815 |
public void focusLost(FocusEvent e) { |
816 |
|
817 |
} |
818 |
|
819 |
|
820 |
|
821 |
} |
822 |
|
823 |
} |