IDEA-98202

This commit is contained in:
Alexey Kudravtsev
2013-04-12 13:48:43 +04:00
parent 7caa1fc8bc
commit 11ae753a47
4 changed files with 77 additions and 7 deletions
@@ -155,8 +155,8 @@ public class ReplaceInProjectManager {
UsageViewPresentation presentation,
FindUsagesProcessPresentation processPresentation,
final FindManager findManager) {
final ReplaceContext[] context = new ReplaceContext[1];
presentation.setMergeDupLinesAvailable(false);
final ReplaceContext[] context = new ReplaceContext[1];
manager.searchAndShowUsages(new UsageTarget[]{new FindInProjectUtil.StringUsageTarget(findModelCopy.getStringToFind())},
usageSearcherFactory, processPresentation, presentation, new UsageViewManager.UsageViewStateListener() {
@Override
@@ -335,16 +335,15 @@ public class ReplaceInProjectManager {
replaceContext.getUsageView().addButtonToLowerPane(replaceSelectedRunnable, FindBundle.message("find.replace.selected.action"));
}
private boolean replaceUsages(final ReplaceContext replaceContext, Collection<Usage> usages) {
boolean success = true;
int replacedCount = 0;
private boolean replaceUsages(@NotNull ReplaceContext replaceContext, @NotNull Collection<Usage> usages) {
if (!ensureUsagesWritable(replaceContext, usages)) {
return true;
}
int replacedCount = 0;
boolean success = true;
for (final Usage usage : usages) {
try {
if (replaceUsage(usage, replaceContext.getFindModel(), replaceContext.getExcludedSetCached(), false)) {
replaceContext.getUsageView().removeUsage(usage);
replacedCount++;
}
}
@@ -353,6 +352,7 @@ public class ReplaceInProjectManager {
success = false;
}
}
replaceContext.getUsageView().removeUsagesBulk(usages);
reportNumberReplacedOccurrences(myProject, replacedCount);
return success;
}
@@ -386,7 +386,7 @@ public class ReplaceInProjectManager {
final Document document = ((UsageInfo2UsageAdapter)usage).getDocument();
if (!document.isWritable()) return false;
return ((UsageInfo2UsageAdapter)usage).processRangeMarkers(new Processor<Segment>() {
boolean result = ((UsageInfo2UsageAdapter)usage).processRangeMarkers(new Processor<Segment>() {
@Override
public boolean process(Segment segment) {
final int textOffset = segment.getStartOffset();
@@ -405,6 +405,7 @@ public class ReplaceInProjectManager {
return true;
}
});
return result;
}
});
@@ -493,7 +494,8 @@ public class ReplaceInProjectManager {
if (usageView.getUsages().isEmpty()) {
usageView.close();
return true;
} else if (!success) {
}
if (!success) {
NOTIFICATION_GROUP.createNotification("One or more malformed replacement strings", MessageType.ERROR).notify(myProject);
}
return false;
@@ -22,6 +22,7 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.util.Collection;
import java.util.List;
import java.util.Set;
@@ -83,4 +84,11 @@ public interface UsageView extends Disposable {
@NotNull JComponent getComponent();
int getUsagesCount();
/**
* Removes all specified usages from the usage view in one heroic swoop.
* Reloads the whole tree model once instead of firing individual remove event for each node.
* Useful for processing huge number of usages faster, e.g. during "find in path/replace all".
*/
void removeUsagesBulk(@NotNull Collection<Usage> usages);
}
@@ -29,6 +29,7 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.MutableTreeNode;
import javax.swing.tree.TreeNode;
import java.util.*;
@@ -155,6 +156,35 @@ public class GroupNode extends Node implements Navigatable, Comparable<GroupNode
return false;
}
public boolean removeUsagesBulk(@NotNull Set<UsageNode> usages) {
boolean removed;
synchronized (lock) {
removed = myUsageNodes.removeAll(usages);
}
Collection<GroupNode> groupNodes = mySubgroupNodes.values();
for (Iterator<GroupNode> iterator = groupNodes.iterator(); iterator.hasNext(); ) {
GroupNode groupNode = iterator.next();
if (groupNode.removeUsagesBulk(usages)) {
if (groupNode.getRecursiveUsageCount() == 0) {
MutableTreeNode parent = (MutableTreeNode)groupNode.getParent();
int childIndex = parent.getIndex(groupNode);
if (childIndex != -1) {
parent.remove(childIndex);
}
iterator.remove();
}
removed = true;
}
}
if (removed) {
--myRecursiveUsageCount;
}
return removed;
}
private void doUpdate() {
ApplicationManager.getApplication().assertIsDispatchThread();
--myRecursiveUsageCount;
@@ -859,6 +859,36 @@ public class UsageViewImpl implements UsageView, UsageModelTracker.UsageModelTra
}
}
@Override
public void removeUsagesBulk(@NotNull Collection<Usage> usages) {
final Set<UsageNode> nodes = new THashSet<UsageNode>(usages.size());
for (Usage usage : usages) {
UsageNode node = myUsageNodes.remove(usage);
if (node != null && node != NULL_NODE) {
nodes.add(node);
}
}
if (!nodes.isEmpty() && !myPresentation.isDetachedMode()) {
UIUtil.invokeLaterIfNeeded(new Runnable() {
@Override
public void run() {
if (isDisposed) return;
DefaultTreeModel treeModel = (DefaultTreeModel)myTree.getModel();
for (UsageNode node : nodes) {
MutableTreeNode parent = (MutableTreeNode)node.getParent();
int childIndex = parent.getIndex(node);
if (childIndex != -1) {
parent.remove(childIndex);
}
}
((GroupNode)myTree.getModel().getRoot()).removeUsagesBulk(nodes);
treeModel.reload();
}
});
}
}
@Override
public void includeUsages(@NotNull Usage[] usages) {
List<TreeNode> nodes = new ArrayList<TreeNode>(usages.length);