diff --git a/platform/lang-impl/src/com/intellij/find/EditorSearchComponent.java b/platform/lang-impl/src/com/intellij/find/EditorSearchComponent.java index ab0f53555ac9..56314ae8291b 100644 --- a/platform/lang-impl/src/com/intellij/find/EditorSearchComponent.java +++ b/platform/lang-impl/src/com/intellij/find/EditorSearchComponent.java @@ -113,16 +113,6 @@ public class EditorSearchComponent extends JPanel implements DataProvider, Selec @Override public void replaceAllPerformed(Editor e) { } - @Override - public void replaceDenied() { - updateReplaceButton(); - } - - @Override - public void replaceAllowed() { - updateReplaceButton(); - } - private void updateReplaceButton() { if (myReplaceButton != null) { myReplaceButton.setEnabled(mySearchResults != null && mySearchResults.getCursor() != null && diff --git a/platform/lang-impl/src/com/intellij/find/impl/livePreview/LivePreview.java b/platform/lang-impl/src/com/intellij/find/impl/livePreview/LivePreview.java index 98dc5b45e4e4..b571387e4c1e 100644 --- a/platform/lang-impl/src/com/intellij/find/impl/livePreview/LivePreview.java +++ b/platform/lang-impl/src/com/intellij/find/impl/livePreview/LivePreview.java @@ -50,10 +50,13 @@ public class LivePreview extends DocumentAdapter implements ReplacementView.Dele private static final Key IN_SELECTION_KEY = Key.create("LivePreview.IN_SELECTION_KEY"); private static final Object IN_SELECTION1 = new Object(); private static final Object IN_SELECTION2 = new Object(); + private boolean myListeningSelection = false; private boolean mySuppressedUpdate = false; private boolean myInSmartUpdate = false; + private static final Key MARKER_USED = Key.create("LivePreview.MARKER_USED"); + private static final Object YES = new Object(); @Override public void selectionChanged(SelectionEvent e) { @@ -361,10 +364,11 @@ public class LivePreview extends DocumentAdapter implements ReplacementView.Dele private RangeHighlighter highlightRange(TextRange textRange, TextAttributes attributes, Collection highlighters) { if (myInSmartUpdate) { for (RangeHighlighter highlighter : myHighlighters) { - if (highlighter.getStartOffset() == textRange.getStartOffset() && highlighter.getEndOffset() == textRange.getEndOffset()) { + if (highlighter.isValid() && highlighter.getStartOffset() == textRange.getStartOffset() && highlighter.getEndOffset() == textRange.getEndOffset()) { if (attributes.equals(highlighter.getTextAttributes())) { - if (myInSmartUpdate) { - highlighter.putUserData(MARKER_USED, new Object()); + highlighter.putUserData(MARKER_USED, YES); + if (highlighters != myHighlighters) { + highlighters.add(highlighter); } return highlighter; } @@ -373,7 +377,7 @@ public class LivePreview extends DocumentAdapter implements ReplacementView.Dele } final RangeHighlighter highlighter = doHightlightRange(textRange, attributes, highlighters); if (myInSmartUpdate) { - highlighter.putUserData(MARKER_USED, new Object()); + highlighter.putUserData(MARKER_USED, YES); } return highlighter; } @@ -384,8 +388,16 @@ public class LivePreview extends DocumentAdapter implements ReplacementView.Dele highlightManager.addRangeHighlight(mySearchResults.getEditor(), textRange.getStartOffset(), textRange.getEndOffset(), attributes, false, dummy); - highlighters.addAll(dummy); - return dummy.get(0); + + final RangeHighlighter h = dummy.get(0); + for (RangeHighlighter highlighter : highlighters) { + if (h.getStartOffset() == highlighter.getStartOffset() && h.getEndOffset() == highlighter.getEndOffset() && + h.getTextAttributes().equals(highlighter.getTextAttributes())) { + return h; + } + } + highlighters.add(h); + return h; } diff --git a/platform/lang-impl/src/com/intellij/find/impl/livePreview/LivePreviewControllerBase.java b/platform/lang-impl/src/com/intellij/find/impl/livePreview/LivePreviewControllerBase.java index d8b38eafddfb..77be7b94990f 100644 --- a/platform/lang-impl/src/com/intellij/find/impl/livePreview/LivePreviewControllerBase.java +++ b/platform/lang-impl/src/com/intellij/find/impl/livePreview/LivePreviewControllerBase.java @@ -64,7 +64,6 @@ public class LivePreviewControllerBase implements LivePreview.Delegate, FindUtil @Override public void searchResultsUpdated(SearchResults sr) { - //setReplaceDenied(false); } @Override @@ -89,24 +88,9 @@ public class LivePreviewControllerBase implements LivePreview.Delegate, FindUtil return myReplaceDenied; } - public void setReplaceDenied(final boolean replaceDenied) { - boolean changed = replaceDenied != myReplaceDenied; - myReplaceDenied = replaceDenied; - if (changed && myReplaceListener != null) { - if (replaceDenied) { - myReplaceListener.replaceDenied(); - } - else { - myReplaceListener.replaceAllowed(); - } - } - } - public interface ReplaceListener { void replacePerformed(LiveOccurrence occurrence, final String replacement, final Editor editor); void replaceAllPerformed(Editor e); - void replaceDenied(); - void replaceAllowed(); } private ReplaceListener myReplaceListener; @@ -146,17 +130,6 @@ public class LivePreviewControllerBase implements LivePreview.Delegate, FindUtil Runnable request = new Runnable() { @Override public void run() { - Runnable denyReplace = new Runnable() { - @Override - public void run() { - //setReplaceDenied(true); - } - }; - if (unitTestMode) { - denyReplace.run(); - } else { - ApplicationManager.getApplication().invokeAndWait(denyReplace, modalityState); - } mySearchResults.updateThreadSafe(copy, allowedToChangedEditorSelection, null, stamp); } }; @@ -213,10 +186,8 @@ public class LivePreviewControllerBase implements LivePreview.Delegate, FindUtil if (myReplaceListener != null) { myReplaceListener.replacePerformed(occurrence, replacement, editor); } - //setReplaceDenied(true); myLivePreview.inSmartUpdate(); mySearchResults.updateThreadSafe(findModel, true, result, mySearchResults.getStamp()); - //myLivePreview.supressUpdate(); return result; } @@ -251,9 +222,8 @@ public class LivePreviewControllerBase implements LivePreview.Delegate, FindUtil @Override public boolean shouldReplace(TextRange range, String replace) { - for (LiveOccurrence o : mySearchResults.getExcluded()) { - TextRange primaryRange = o.getPrimaryRange(); - if (primaryRange.equals(range)) { + for (RangeMarker r : mySearchResults.getExcluded()) { + if (r.getStartOffset() == range.getStartOffset() && r.getEndOffset() == range.getEndOffset()) { return false; } } diff --git a/platform/lang-impl/src/com/intellij/find/impl/livePreview/SearchResults.java b/platform/lang-impl/src/com/intellij/find/impl/livePreview/SearchResults.java index dce37e881c9e..d812c1b25b85 100644 --- a/platform/lang-impl/src/com/intellij/find/impl/livePreview/SearchResults.java +++ b/platform/lang-impl/src/com/intellij/find/impl/livePreview/SearchResults.java @@ -7,10 +7,12 @@ import com.intellij.find.FindResult; import com.intellij.find.FindUtil; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.RangeMarker; import com.intellij.openapi.fileEditor.FileDocumentManager; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.TextRange; import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.util.containers.HashSet; import org.jetbrains.annotations.Nullable; import java.awt.*; @@ -34,7 +36,7 @@ public class SearchResults { private List myOccurrences = new ArrayList(); - private Set myExcluded = new HashSet(); + private Set myExcluded = new HashSet(); private Editor myEditor; private FindModel myFindModel; @@ -72,19 +74,32 @@ public class SearchResults { } public boolean isExcluded(LiveOccurrence occurrence) { - return myExcluded.contains(occurrence); + for (RangeMarker rangeMarker : myExcluded) { + if (rangeMarker.getStartOffset() == occurrence.getPrimaryRange().getStartOffset() && rangeMarker.getEndOffset() == occurrence.getPrimaryRange().getEndOffset()) { + return true; + } + } + return false; } public void exclude(LiveOccurrence occurrence) { - if (myExcluded.contains(occurrence)) { - myExcluded.remove(occurrence); - } else { - myExcluded.add(occurrence); + boolean include = false; + final TextRange r = occurrence.getPrimaryRange(); + for (RangeMarker rangeMarker : myExcluded) { + if (rangeMarker.getStartOffset() == r.getStartOffset() && rangeMarker.getEndOffset() == r.getEndOffset()) { + myExcluded.remove(rangeMarker); + rangeMarker.dispose(); + include = true; + break; + } + } + if (!include) { + myExcluded.add(myEditor.getDocument().createRangeMarker(r.getStartOffset(), r.getEndOffset(), true)); } notifyChanged(); } - public Set getExcluded() { + public Set getExcluded() { return myExcluded; } @@ -230,6 +245,7 @@ public class SearchResults { myFindModel = findModel; updateCursor(oldCursorRange, next); + updateExcluded(); myActualFound = size; notifyChanged(); if (oldCursorRange == null || myCursor == null || !myCursor.getPrimaryRange().equals(oldCursorRange)) { @@ -238,6 +254,17 @@ public class SearchResults { } } + private void updateExcluded() { + Set invalid = new HashSet(); + for (RangeMarker marker : myExcluded) { + if (!marker.isValid()) { + invalid.add(marker); + marker.dispose(); + } + } + myExcluded.removeAll(invalid); + } + private void updateCursor(@Nullable TextRange oldCursorRange, @Nullable TextRange next) { boolean justReplaced = next != null; if (justReplaced || !tryToRepairOldCursor(oldCursorRange)) {