1 19 20 package org.netbeans.modules.editor.lib2.search; 21 22 import java.awt.Insets ; 23 import java.awt.Rectangle ; 24 import java.beans.PropertyChangeListener ; 25 import java.beans.PropertyChangeSupport ; 26 import java.lang.ref.WeakReference ; 27 import java.text.MessageFormat ; 28 import java.util.ArrayList ; 29 import java.util.HashMap ; 30 import java.util.List ; 31 import java.util.Map ; 32 import java.util.WeakHashMap ; 33 import java.util.logging.Level ; 34 import java.util.logging.Logger ; 35 import javax.swing.text.JTextComponent ; 36 import javax.swing.text.BadLocationException ; 37 import javax.swing.text.Caret ; 38 import javax.swing.text.Document ; 39 import javax.swing.text.Position ; 40 import org.netbeans.api.editor.settings.FontColorNames; 41 import org.netbeans.modules.editor.lib2.ComponentUtils; 42 import org.netbeans.modules.editor.lib2.DocUtils; 43 import org.netbeans.modules.editor.lib2.DocumentsJumpList; 44 import org.netbeans.modules.editor.lib2.DocumentsRegistry; 45 import org.netbeans.modules.editor.lib2.highlighting.BlockHighlighting; 46 import org.netbeans.modules.editor.lib2.highlighting.Factory; 47 import org.netbeans.modules.editor.lib2.search.DocumentFinder.FindReplaceResult; 48 import org.openide.util.NbBundle; 49 50 56 57 public final class EditorFindSupport { 58 59 private static final Logger LOG = Logger.getLogger(EditorFindSupport.class.getName()); 60 61 81 public static final String FIND_WHAT = "find-what"; public static final String FIND_REPLACE_WITH = "find-replace-with"; public static final String FIND_HIGHLIGHT_SEARCH = "find-highlight-search"; public static final String FIND_INC_SEARCH = "find-inc-search"; public static final String FIND_INC_SEARCH_DELAY = "find-inc-search-delay"; public static final String FIND_BACKWARD_SEARCH = "find-backward-search"; public static final String FIND_WRAP_SEARCH = "find-wrap-search"; public static final String FIND_MATCH_CASE = "find-match-case"; public static final String FIND_SMART_CASE = "find-smart-case"; public static final String FIND_WHOLE_WORDS = "find-whole-words"; public static final String FIND_REG_EXP = "find-reg-exp"; public static final String FIND_HISTORY = "find-history"; public static final String FIND_HISTORY_SIZE = "find-history-size"; public static final String FIND_BLOCK_SEARCH = "find-block-search"; public static final String FIND_BLOCK_SEARCH_START = "find-block-search-start"; public static final String FIND_BLOCK_SEARCH_END = "find-block-search-end"; 98 private static final String FOUND_LOCALE = "find-found"; private static final String NOT_FOUND_LOCALE = "find-not-found"; private static final String WRAP_START_LOCALE = "find-wrap-start"; private static final String WRAP_END_LOCALE = "find-wrap-end"; private static final String WRAP_BLOCK_START_LOCALE = "find-block-wrap-start"; private static final String WRAP_BLOCK_END_LOCALE = "find-block-wrap-end"; private static final String ITEMS_REPLACED_LOCALE = "find-items-replaced"; 106 public static final String REVERT_MAP = "revert-map"; 108 private static final String SEARCH_BLOCK_START="search-block-start"; private static final String SEARCH_BLOCK_END="search-block-end"; 111 112 public static final String FIND_HISTORY_PROP = "find-history-prop"; 114 public static final String FIND_HISTORY_CHANGED_PROP = "find-history-changed-prop"; 116 117 private static EditorFindSupport findSupport; 118 119 120 private Map <String , Object > findProps; 121 122 private WeakHashMap <JTextComponent , Map <String , WeakReference <BlockHighlighting>>> comp2layer = 123 new WeakHashMap <JTextComponent , Map <String , WeakReference <BlockHighlighting>>>(); 124 125 126 private PropertyChangeSupport changeSupport = new PropertyChangeSupport (this); 127 128 private SPW lastSelected; 129 private List <SPW> historyList; 130 131 private EditorFindSupport() { 132 } 134 135 136 public static EditorFindSupport getInstance() { 137 if (findSupport == null) { 138 findSupport = new EditorFindSupport(); 139 } 140 return findSupport; 141 } 142 143 public Map <String , Object > getDefaultFindProperties() { 144 HashMap <String , Object > props = new HashMap <String , Object >(); 145 146 props.put(FIND_WHAT, null); 147 props.put(FIND_REPLACE_WITH, null); 148 props.put(FIND_HIGHLIGHT_SEARCH, Boolean.TRUE); 149 props.put(FIND_INC_SEARCH, Boolean.TRUE); 150 props.put(FIND_BACKWARD_SEARCH, Boolean.FALSE); 151 props.put(FIND_WRAP_SEARCH, Boolean.TRUE); 152 props.put(FIND_MATCH_CASE, Boolean.FALSE); 153 props.put(FIND_SMART_CASE, Boolean.FALSE); 154 props.put(FIND_WHOLE_WORDS, Boolean.FALSE); 155 props.put(FIND_REG_EXP, Boolean.FALSE); 156 props.put(FIND_HISTORY, new Integer (30)); 157 158 return props; 159 } 160 161 private int getBlockEndOffset(){ 162 Position pos = (Position ) getFindProperties().get(FIND_BLOCK_SEARCH_END); 163 return (pos != null) ? pos.getOffset() : -1; 164 } 165 166 public Map <String , Object > getFindProperties() { 167 if (findProps == null) { 168 findProps = getDefaultFindProperties(); 169 } 170 return findProps; 171 } 172 173 174 public Object getFindProperty(String name) { 175 return getFindProperties().get(name); 176 } 177 178 private Map <String , Object > getValidFindProperties(Map <String , Object > props) { 179 return (props != null) ? props : getFindProperties(); 180 } 181 182 186 public int[] getBlocks(int[] blocks, Document doc, 187 int startPos, int endPos) throws BadLocationException { 188 Map props = getValidFindProperties(null); 189 190 Boolean b = (Boolean )props.get(FIND_BLOCK_SEARCH); 191 boolean blockSearch = (b != null && b.booleanValue()); 192 Integer i = (Integer ) props.get(FIND_BLOCK_SEARCH_START); 193 int blockSearchStart = (i != null) ? i.intValue() : -1; 194 int blockSearchEnd = getBlockEndOffset(); 195 196 if (blockSearch && blockSearchStart>-1 && blockSearchEnd >0){ 197 if (endPos>=blockSearchStart && startPos <=blockSearchEnd){ 198 startPos = Math.max(blockSearchStart, startPos); 199 endPos = Math.min(blockSearchEnd, endPos); 200 }else{ 201 return blocks; 202 } 203 } 204 return DocumentFinder.findBlocks(doc, startPos, endPos, props, blocks); 205 } 206 207 215 public Object getPropertyNoInit(String name) { 216 if (findProps == null) { 217 return null; 218 } else { 219 return getFindProperty(name); 220 } 221 } 222 223 225 public void putFindProperty(String name, Object newValue) { 226 Object oldValue = getFindProperty(name); 227 if ((oldValue == null && newValue == null) 228 || (oldValue != null && oldValue.equals(newValue)) 229 ) { 230 return; 231 } 232 if (newValue != null) { 233 getFindProperties().put(name, newValue); 234 } else { 235 getFindProperties().remove(name); 236 } 237 firePropertyChange(name, oldValue, newValue); 238 } 239 240 245 public void putFindProperties(Map <String , Object > propsToAdd) { 246 if (!getFindProperties().equals(propsToAdd)) { 247 getFindProperties().putAll(propsToAdd); 248 firePropertyChange(null, null, null); 249 } 250 } 251 252 public void setBlockSearchHighlight(int startSelection, int endSelection){ 253 JTextComponent comp = DocumentsRegistry.getMostActiveComponent(); 254 BlockHighlighting layer = comp == null ? null : findLayer(comp, Factory.BLOCK_SEARCH_LAYER); 255 256 if (layer != null) { 257 258 if (startSelection >= 0 && endSelection >= 0 && startSelection < endSelection ) { 259 layer.highlightBlock( 260 startSelection, endSelection, FontColorNames.BLOCK_SEARCH_COLORING); 261 } else { 262 layer.highlightBlock(-1, -1, FontColorNames.BLOCK_SEARCH_COLORING); 263 } 264 265 } 266 267 } 319 320 public boolean incSearch(Map <String , Object > props, int caretPos) { 321 props = getValidFindProperties(props); 322 323 Boolean b = (Boolean )props.get(FIND_REG_EXP); 325 if (b !=null && b.booleanValue()){ 326 return false; 327 } 328 329 b = (Boolean )props.get(FIND_INC_SEARCH); 330 if (b != null && b.booleanValue()) { JTextComponent comp = DocumentsRegistry.getMostActiveComponent(); 332 333 if (comp != null) { 334 b = (Boolean )props.get(FIND_BACKWARD_SEARCH); 335 boolean back = (b != null && b.booleanValue()); 336 b = (Boolean )props.get(FIND_BLOCK_SEARCH); 337 boolean blockSearch = (b != null && b.booleanValue()); 338 Integer i = (Integer ) props.get(FIND_BLOCK_SEARCH_START); 339 int blockSearchStart = (i != null) ? i.intValue() : -1; 340 341 Position endPos = (Position ) props.get(FIND_BLOCK_SEARCH_END); 342 int blockSearchEnd = (endPos != null) ? endPos.getOffset() : -1; 343 int endOffset = (back) ? 0 : -1; 344 int pos; 345 try { 346 int start = (blockSearch && blockSearchStart > -1) ? blockSearchStart : 0; 347 int end = (blockSearch && blockSearchEnd > 0) ? blockSearchEnd : -1; 348 if (start>0 && end == -1) return false; 349 int findRet[] = findInBlock(comp, caretPos, 350 start, 351 end, 352 props, false); 353 354 if (findRet == null) { 355 incSearchReset(); 356 return false; 357 } 358 pos = findRet[0]; 359 } catch (BadLocationException e) { 360 LOG.log(Level.WARNING, e.getMessage(), e); 361 return false; 362 } 363 364 BlockHighlighting layer = (BlockHighlighting)findLayer(comp, Factory.INC_SEARCH_LAYER); 366 367 if (pos >= 0) { 368 String s = (String )props.get(FIND_WHAT); 369 int len = (s != null) ? s.length() : 0; 370 if (len > 0) { 371 if (comp.getSelectionEnd() > comp.getSelectionStart()){ 372 comp.select(caretPos, caretPos); 373 } 374 375 380 if (layer != null) { 381 layer.highlightBlock( 382 pos, 383 pos + len, 384 blockSearch ? FontColorNames.INC_SEARCH_COLORING : FontColorNames.SELECTION_COLORING 385 ); 386 } 387 388 Map <String , Object > defaultProps = getValidFindProperties(null); 390 String findWhatDef = (String )defaultProps.get(FIND_WHAT); 391 if (findWhatDef!=null && findWhatDef.length()>0){ 392 defaultProps.put(FIND_WHAT, ""); comp.repaint(); 394 } 395 396 ensureVisible(comp, pos, pos); 397 return true; 398 } 399 } else { } 402 403 } 404 } else { incSearchReset(); 406 } 407 return false; 408 } 409 410 public void incSearchReset() { 411 JTextComponent comp = DocumentsRegistry.getMostActiveComponent(); 413 BlockHighlighting layer = comp == null ? null : (BlockHighlighting)findLayer(comp, Factory.INC_SEARCH_LAYER); 414 415 if (layer != null) { 416 layer.highlightBlock(-1, -1, null); 417 } 418 } 419 420 private boolean isBackSearch(Map props, boolean oppositeDir) { 421 Boolean b = (Boolean )props.get(FIND_BACKWARD_SEARCH); 422 boolean back = (b != null && b.booleanValue()); 423 if (oppositeDir) { 424 back = !back; 425 } 426 return back; 427 } 428 429 private void selectText(JTextComponent c, int start, int end, boolean back){ 430 Caret caret = c.getCaret(); 431 ensureVisible(c, start, end); 432 if (back) { 433 caret.setDot(end); 434 caret.moveDot(start); 435 } else { caret.setDot(start); 437 caret.moveDot(end); 438 } 439 } 440 441 private void ensureVisible(JTextComponent c, int startOffset, int endOffset) { 442 ensureVisible(c, startOffset, endOffset, new Insets (10, 10, 10, 10)); 444 } 445 446 450 private void ensureVisible(JTextComponent c, int startOffset, int endOffset, Insets extraInsets) { 451 try { 452 Rectangle startBounds = c.modelToView(startOffset); 453 Rectangle endBounds = c.modelToView(endOffset); 454 if (startBounds != null && endBounds != null) { 455 startBounds.add(endBounds); 456 if (extraInsets != null) { 457 Rectangle visibleBounds = c.getVisibleRect(); 458 int extraTop = (extraInsets.top < 0) 459 ? -extraInsets.top * visibleBounds.height / 100 : extraInsets.top * endBounds.height; startBounds.y -= extraTop; 462 startBounds.height += extraTop; 463 startBounds.height += (extraInsets.bottom < 0) 464 ? -extraInsets.bottom * visibleBounds.height / 100 : extraInsets.bottom * endBounds.height; int extraLeft = (extraInsets.left < 0) 467 ? -extraInsets.left * visibleBounds.width / 100 : extraInsets.left * endBounds.width; startBounds.x -= extraLeft; 470 startBounds.width += extraLeft; 471 startBounds.width += (extraInsets.right < 0) 472 ? -extraInsets.right * visibleBounds.width / 100 : extraInsets.right * endBounds.width; } 475 c.scrollRectToVisible(startBounds); 476 } 477 } catch (BadLocationException e) { 478 } 480 } 481 482 private FindReplaceResult findReplaceImpl(String replaceExp, Map <String , Object > props, boolean oppositeDir){ 483 incSearchReset(); 484 props = getValidFindProperties(props); 485 boolean back = isBackSearch(props, oppositeDir); 486 JTextComponent c = DocumentsRegistry.getMostActiveComponent(); 487 Object findWhat = props.get(FIND_WHAT); 488 if (findWhat == null) { return null; 490 } 491 492 String exp = "'" + findWhat + "' "; if (c != null) { 494 ComponentUtils.clearStatusText(c); 495 Caret caret = c.getCaret(); 496 int dotPos = caret.getDot(); 497 if (findWhat.equals(c.getSelectedText())) { 498 Object dp = props.get(FIND_BACKWARD_SEARCH); 499 boolean direction = (dp != null) ? ((Boolean )dp).booleanValue() : false; 500 501 if (dotPos == (oppositeDir ^ direction ? c.getSelectionEnd() : c.getSelectionStart())) 502 dotPos += (oppositeDir ^ direction ? -1 : 1); 503 } 504 505 Boolean b = (Boolean )props.get(FIND_BLOCK_SEARCH); 506 boolean blockSearch = (b != null && b.booleanValue()); 507 Integer i = (Integer ) props.get(FIND_BLOCK_SEARCH_START); 508 int blockSearchStart = (i != null) ? i.intValue() : -1; 509 int blockSearchEnd = getBlockEndOffset(); 510 511 try { 512 FindReplaceResult result = findReplaceInBlock(replaceExp, c, dotPos, 513 (blockSearch && blockSearchStart > -1) ? blockSearchStart : 0, 514 (blockSearch && blockSearchEnd > 0) ? blockSearchEnd : -1, 515 props, oppositeDir); 516 int[] blk = null; 517 if (result != null){ 518 blk = result.getFoundPositions(); 519 } 520 if (blk != null) { 521 selectText(c, blk[0], blk[1], back); 522 DocumentsJumpList.checkAddEntry(); 523 String msg = exp + NbBundle.getBundle(EditorFindSupport.class).getString(FOUND_LOCALE) 524 + ' ' + DocUtils.debugPosition(c.getDocument(), blk[0]); 525 if (blk[2] == 1) { msg += "; "; if (blockSearch && blockSearchEnd>0 && blockSearchStart >-1){ 528 msg += back ? NbBundle.getBundle(EditorFindSupport.class).getString(WRAP_BLOCK_END_LOCALE) 529 : NbBundle.getBundle(EditorFindSupport.class).getString(WRAP_BLOCK_START_LOCALE); 530 }else{ 531 msg += back ? NbBundle.getBundle(EditorFindSupport.class).getString(WRAP_END_LOCALE) 532 : NbBundle.getBundle(EditorFindSupport.class).getString(WRAP_START_LOCALE); 533 } 534 ComponentUtils.setStatusBoldText(c, msg); 535 c.getToolkit().beep(); 536 } else { 537 ComponentUtils.setStatusText(c, msg); 538 } 539 return result; 540 } else { ComponentUtils.setStatusBoldText(c, exp + NbBundle.getBundle(EditorFindSupport.class).getString( 542 NOT_FOUND_LOCALE)); 543 c.getCaret().setDot(c.getCaret().getDot()); 545 } 546 } catch (BadLocationException e) { 547 LOG.log(Level.WARNING, e.getMessage(), e); 548 } 549 } 550 return null; 551 } 552 553 557 public boolean find(Map <String , Object > props, boolean oppositeDir) { 558 FindReplaceResult result = findReplaceImpl(null, props, oppositeDir); 559 return (result != null); 560 } 561 562 private FindReplaceResult findReplaceInBlock(String replaceExp, JTextComponent c, int startPos, int blockStartPos, 563 int blockEndPos, Map <String , Object > props, boolean oppositeDir) throws BadLocationException { 564 if (c != null) { 565 props = getValidFindProperties(props); 566 Document doc = (Document )c.getDocument(); 567 int pos = -1; 568 boolean wrapDone = false; 569 String replaced = null; 570 571 boolean back = isBackSearch(props, oppositeDir); 572 Boolean b = (Boolean )props.get(FIND_WRAP_SEARCH); 573 boolean wrap = (b != null && b.booleanValue()); 574 int docLen = doc.getLength(); 575 if (blockEndPos == -1) { 576 blockEndPos = docLen; 577 } 578 579 int retFind[]; 580 while (true) { 581 int off1 = startPos; 583 int off2 = back ? blockStartPos : blockEndPos; 584 FindReplaceResult result = DocumentFinder.findReplaceResult(replaceExp, doc, Math.min(off1, off2), Math.max(off1, off2), 585 props, oppositeDir ); 586 if (result == null){ 587 return null; 588 } 589 retFind = result.getFoundPositions(); 590 replaced = result.getReplacedString(); 591 if (retFind == null){ 592 break; 593 } 594 pos = retFind[0]; 595 596 if (pos != -1) { 597 break; 598 } 599 600 if (wrap) { 601 if (back) { 602 606 startPos = blockEndPos; 608 } else { 609 startPos = blockStartPos; 611 } 612 wrapDone = true; 613 wrap = false; } else { break; 616 } 617 618 } 619 620 if (pos != -1) { 621 int[] ret = new int[3]; 622 ret[0] = pos; 623 ret[1] = retFind[1]; 624 ret[2] = wrapDone ? 1 : 0; 625 return new FindReplaceResult(ret, replaced); 626 } 627 } 628 return null; 629 } 630 631 646 public int[] findInBlock(JTextComponent c, int startPos, int blockStartPos, 647 int blockEndPos, Map <String , Object > props, boolean oppositeDir) throws BadLocationException { 648 FindReplaceResult result = findReplaceInBlock(null, c, startPos, blockStartPos, 649 blockEndPos, props, oppositeDir); 650 return result == null ? null : result.getFoundPositions(); 651 } 652 653 public boolean replace(Map <String , Object > props, boolean oppositeDir) 654 throws BadLocationException { 655 incSearchReset(); 656 props = getValidFindProperties(props); 657 Boolean b = (Boolean )props.get(FIND_BACKWARD_SEARCH); 658 boolean back = (b != null && b.booleanValue()); 659 if (oppositeDir) { 660 back = !back; 661 } 662 663 b = (Boolean )props.get(FIND_BLOCK_SEARCH); 664 boolean blockSearch = (b != null && b.booleanValue()); 665 Integer i = (Integer ) props.get(FIND_BLOCK_SEARCH_START); 666 int blockSearchStart = (i != null) ? i.intValue() : -1; 667 int blockSearchEnd = getBlockEndOffset(); 668 669 JTextComponent c = DocumentsRegistry.getMostActiveComponent(); 670 if (c != null) { 671 String s = (String )props.get(FIND_REPLACE_WITH); 672 Caret caret = c.getCaret(); 673 if (caret.isSelectionVisible()){ 674 int dotPos = caret.getDot(); 675 Object dp = props.get(FIND_BACKWARD_SEARCH); 676 boolean direction = (dp != null) ? ((Boolean )dp).booleanValue() : false; 677 dotPos = (oppositeDir ^ direction ? c.getSelectionEnd() : c.getSelectionStart()); 678 c.setCaretPosition(dotPos); 679 } 680 681 FindReplaceResult result = findReplaceImpl(s, props, oppositeDir); 682 if (result!=null){ 683 s = result.getReplacedString(); 684 } else { 685 return false; 686 } 687 688 Document doc = (Document )c.getDocument(); 689 int startPos = c.getSelectionStart(); 690 int len = c.getSelectionEnd() - startPos; 691 DocUtils.atomicLock(doc); 692 try { 693 if (len > 0) { 694 doc.remove(startPos, len); 695 } 696 if (s != null && s.length() > 0) { 697 doc.insertString(startPos, s, null); 698 } 699 } finally { 700 DocUtils.atomicUnlock(doc); 701 if (blockSearch){ 702 setBlockSearchHighlight(blockSearchStart, getBlockEndOffset()); 703 } 704 } 705 706 int adjustedCaretPos = (back || s == null) ? startPos : startPos + s.length(); 708 caret.setDot(adjustedCaretPos); 709 710 } 711 712 return true; 713 } 714 715 public void replaceAll(Map <String , Object > props) { 716 incSearchReset(); 717 JTextComponent c = DocumentsRegistry.getMostActiveComponent(); 718 Document doc = (Document )c.getDocument(); 719 int maxCnt = doc.getLength(); 720 int replacedCnt = 0; 721 int totalCnt = 0; 722 723 props = getValidFindProperties(props); 724 props = new HashMap <String , Object >(props); 725 String replaceWithOriginal = (String )props.get(FIND_REPLACE_WITH); 726 727 Boolean b = (Boolean )props.get(FIND_BLOCK_SEARCH); 728 boolean blockSearch = (b != null && b.booleanValue()); 729 b = (Boolean )props.get(FIND_WRAP_SEARCH); 730 boolean wrapSearch = (b != null && b.booleanValue()); 731 b = (Boolean )props.get(FIND_BACKWARD_SEARCH); 732 boolean backSearch = (b != null && b.booleanValue()); 733 734 if (wrapSearch){ 735 props.put(FIND_WRAP_SEARCH, Boolean.FALSE); 736 props.put(FIND_BACKWARD_SEARCH, Boolean.FALSE); 737 firePropertyChange(null, null, null); 738 } 739 740 Integer i = (Integer ) props.get(FIND_BLOCK_SEARCH_START); 741 int blockSearchStart = (i != null) ? i.intValue() : -1; 742 int blockSearchEnd = getBlockEndOffset(); 743 744 if (c != null) { 745 DocUtils.atomicLock(doc); 746 try { 747 int startPosWholeSearch = 0; 748 int endPosWholeSearch = -1; 749 int caretPos = c.getCaret().getDot(); 750 751 if (!wrapSearch){ 752 if (backSearch){ 753 startPosWholeSearch = 0; 754 endPosWholeSearch = caretPos; 755 }else{ 756 startPosWholeSearch = caretPos; 757 endPosWholeSearch = -1; 758 } 759 } 760 761 int actualPos = wrapSearch ? 0 : c.getCaret().getDot(); 762 763 int pos = (blockSearch && blockSearchStart > -1) ? ( backSearch ? blockSearchEnd : blockSearchStart) : actualPos; 765 while (true) { 766 blockSearchEnd = getBlockEndOffset(); 767 FindReplaceResult result = findReplaceInBlock(replaceWithOriginal, c, pos, 768 (blockSearch && blockSearchStart > -1) ? blockSearchStart : startPosWholeSearch, 769 (blockSearch && blockSearchEnd > 0) ? blockSearchEnd : endPosWholeSearch, 770 props, false); 771 if (result == null){ 772 break; 773 } 774 int[] blk = result.getFoundPositions(); 775 String replaceWith = result.getReplacedString(); 776 if (blk == null) { 777 break; 778 } 779 totalCnt++; 780 int len = blk[1] - blk[0]; 781 boolean skip = false; try { 783 doc.remove(blk[0], len); 784 } catch (BadLocationException e) { 785 if (ComponentUtils.isGuardedException(e)) { 787 skip = true; 788 } else { 789 throw e; 790 } 791 } 792 if (skip) { 793 pos = blk[0] + len; 794 795 } else { if (replaceWith != null && replaceWith.length() > 0) { 797 doc.insertString(blk[0], replaceWith, null); 798 } 799 pos = blk[0] + ((replaceWith != null) ? replaceWith.length() : 0); 800 replacedCnt++; 801 } 802 } 803 804 if (totalCnt == 0){ 806 Object findWhat = props.get(FIND_WHAT); 807 String exp = "'' "; if (findWhat != null) { exp = "'" + findWhat + "' "; } 811 ComponentUtils.setStatusBoldText(c, exp + NbBundle.getBundle(EditorFindSupport.class).getString( 812 NOT_FOUND_LOCALE)); 813 }else{ 814 MessageFormat fmt = new MessageFormat ( 815 NbBundle.getBundle(EditorFindSupport.class).getString(ITEMS_REPLACED_LOCALE)); 816 String msg = fmt.format(new Object [] { new Integer (replacedCnt), new Integer (totalCnt) }); 817 ComponentUtils.setStatusText(c, msg); 818 } 819 820 } catch (BadLocationException e) { 821 LOG.log(Level.WARNING, e.getMessage(), e); 822 } finally { 823 DocUtils.atomicUnlock(doc); 824 if (blockSearch){ 825 setBlockSearchHighlight(blockSearchStart, getBlockEndOffset()); 826 } 827 } 828 } 829 } 830 831 public void hookLayer(BlockHighlighting layer, JTextComponent component) { 832 synchronized (comp2layer) { 833 Map <String , WeakReference <BlockHighlighting>> type2layer = comp2layer.get(component); 834 835 if (type2layer == null) { 836 type2layer = new HashMap <String , WeakReference <BlockHighlighting>>(); 837 comp2layer.put(component, type2layer); 838 } 839 840 type2layer.put(layer.getLayerTypeId(), new WeakReference <BlockHighlighting>(layer)); 841 } 842 } 843 844 public void unhookLayer(BlockHighlighting layer, JTextComponent component) { 845 synchronized (comp2layer) { 846 Map <String , WeakReference <BlockHighlighting>> type2layer = comp2layer.get(component); 847 848 if (type2layer != null) { 849 type2layer.remove(layer.getLayerTypeId()); 850 if (type2layer.isEmpty()) { 851 comp2layer.remove(component); 852 } 853 } 854 } 855 } 856 857 public BlockHighlighting findLayer(JTextComponent component, String layerId) { 858 synchronized (comp2layer) { 859 Map <String , WeakReference <BlockHighlighting>> type2layer = comp2layer.get(component); 860 BlockHighlighting layer = null; 861 862 if (type2layer != null) { 863 WeakReference <BlockHighlighting> ref = type2layer.get(layerId); 864 if (ref != null) { 865 layer = ref.get(); 866 } 867 } 868 869 return layer; 870 } 871 } 872 873 889 893 public void addPropertyChangeListener(PropertyChangeListener l) { 894 changeSupport.addPropertyChangeListener(l); 895 } 896 897 public synchronized void addPropertyChangeListener(String findPropertyName, 898 PropertyChangeListener l) { 899 changeSupport.addPropertyChangeListener(findPropertyName, l); 900 } 901 902 903 public void removePropertyChangeListener(PropertyChangeListener l) { 904 changeSupport.removePropertyChangeListener(l); 905 } 906 907 911 public void firePropertyChange(String settingName, Object oldValue, Object newValue) { 912 changeSupport.firePropertyChange(settingName, oldValue, newValue); 913 } 914 915 public void setHistory(List <SPW> spwList){ 916 this.historyList = new ArrayList <SPW>(spwList); 917 firePropertyChange(FIND_HISTORY_CHANGED_PROP,null,null); 918 } 919 920 public List <SPW> getHistory(){ 921 return historyList; 922 } 923 924 public void setLastSelected(SPW spw){ 925 this.lastSelected = spw; 926 Map <String , Object > props = getFindProperties(); 927 if (spw == null) return; 928 props.put(FIND_WHAT, spw.getSearchExpression()); 929 props.put(FIND_MATCH_CASE, Boolean.valueOf(spw.isMatchCase())); 930 props.put(FIND_REG_EXP, Boolean.valueOf(spw.isRegExp())); 931 props.put(FIND_WHOLE_WORDS, Boolean.valueOf(spw.isWholeWords())); 932 } 933 934 public SPW getLastSelected(){ 935 return lastSelected; 936 } 937 938 public void addToHistory(SPW spw){ 939 if (spw == null) return; 940 firePropertyChange(FIND_HISTORY_PROP, null, spw); 941 } 942 943 public final static class SPW{ 944 private String searchExpression; 945 private boolean wholeWords; 946 private boolean matchCase; 947 private boolean regExp; 948 949 public SPW(String searchExpression, boolean wholeWords, 950 boolean matchCase, boolean regExp){ 951 this.searchExpression = searchExpression; 952 this.wholeWords = wholeWords; 953 this.matchCase = matchCase; 954 this.regExp = regExp; 955 } 956 957 958 public String getSearchExpression(){ 959 return searchExpression; 960 } 961 962 963 public boolean isWholeWords(){ 964 return wholeWords; 965 } 966 967 968 public boolean isMatchCase(){ 969 return matchCase; 970 } 971 972 973 public boolean isRegExp(){ 974 return regExp; 975 } 976 977 public boolean equals(Object obj){ 978 if (!(obj instanceof SPW)){ 979 return false; 980 } 981 SPW sp = (SPW)obj; 982 return (this.searchExpression.equals(sp.getSearchExpression()) && 983 this.wholeWords == sp.isWholeWords() && 984 this.matchCase == sp.isMatchCase() && 985 this.regExp == sp.isRegExp()); 986 } 987 988 public int hashCode() { 989 int result = 17; 990 result = 37*result + (this.wholeWords ? 1:0); 991 result = 37*result + (this.matchCase ? 1:0); 992 result = 37*result + (this.regExp ? 1:0); 993 result = 37*result + this.searchExpression.hashCode(); 994 return result; 995 } 996 997 public String toString(){ 998 StringBuffer sb = new StringBuffer ("[SearchPatternWrapper:]\nsearchExpression:"+searchExpression); sb.append('\n'); 1000 sb.append("wholeWords:"); sb.append(wholeWords); 1002 sb.append('\n'); 1003 sb.append("matchCase:"); sb.append(matchCase); 1005 sb.append('\n'); 1006 sb.append("regExp:"); sb.append(regExp); 1008 return sb.toString(); 1009 } 1010 } } 1012 | Popular Tags |