usage view: cancel search progress and view synchronously; do not cancel all searches when one was canceled

This commit is contained in:
Anna Kozlova
2012-06-05 18:09:48 +04:00
parent ed1348ccb3
commit 4639086c04
5 changed files with 62 additions and 45 deletions
@@ -550,13 +550,10 @@ public class FindUsagesManager implements JDOMExternalizable {
final FileSearchScope direction = dir;
final com.intellij.usages.UsageViewManager usageViewManager = com.intellij.usages.UsageViewManager.getInstance(project);
usageViewManager.setCurrentSearchCancelled(false);
final Usage[] foundUsage = {null};
usageSearcher.generate(new Processor<Usage>() {
@Override
public boolean process(Usage usage) {
if (usageViewManager.searchHasBeenCancelled()) return false;
usagesWereFound[0] = true;
@@ -226,9 +226,7 @@ public class FindInProjectUtil {
int count = 0;
final boolean[] warningShown = {false};
final UsageViewManager usageViewManager = UsageViewManager.getInstance(project);
for (final PsiFile psiFile : psiFiles) {
usageViewManager.checkSearchCanceled();
final VirtualFile virtualFile = psiFile.getVirtualFile();
final int index = i++;
if (virtualFile == null) continue;
@@ -588,10 +586,8 @@ public class FindInProjectUtil {
Project project = psiFile.getProject();
UsageViewManager usageViewManager = UsageViewManager.getInstance(project);
FindManager findManager = FindManager.getInstance(project);
while (offset < textLength) {
usageViewManager.checkSearchCanceled();
FindResult result = findManager.findString(text, offset, findModel, psiFile.getVirtualFile());
if (!result.isStringFound()) break;
@@ -601,7 +597,9 @@ public class FindInProjectUtil {
if (!((LocalSearchScope)customScope).containsRange(psiFile, range)) break;
}
UsageInfo info = new UsageInfo(psiFile, result.getStartOffset(), result.getEndOffset());
if (!consumer.process(info)) break;
if (!consumer.process(info)){
throw new ProcessCanceledException();
}
count++;
final int prevOffset = offset;
@@ -52,12 +52,6 @@ public abstract class UsageViewManager {
@NotNull UsageViewPresentation presentation,
UsageViewStateListener listener);
public abstract void setCurrentSearchCancelled(boolean flag);
public abstract boolean searchHasBeenCancelled();
public abstract void checkSearchCanceled() throws ProcessCanceledException;
public interface UsageViewStateListener {
void usageViewCreated(UsageView usageView);
void findingUsagesFinished(final UsageView usageView);
@@ -24,6 +24,7 @@ import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.command.CommandProcessor;
import com.intellij.openapi.extensions.Extensions;
import com.intellij.openapi.ide.CopyPasteManager;
import com.intellij.openapi.progress.ProcessCanceledException;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.progress.Task;
@@ -247,11 +248,17 @@ public class UsageViewImpl implements UsageView, UsageModelTracker.UsageModelTra
}, new Condition<Object>() {
@Override
public boolean value(Object o) {
return isDisposed || project.isDisposed() || com.intellij.usages.UsageViewManager.getInstance(project).searchHasBeenCancelled();
return isDisposed || project.isDisposed() || searchHasBeenCancelled();
}
},200);
}
protected boolean searchHasBeenCancelled() {
return false;
}
protected void setCurrentSearchCancelled(boolean flag){}
private void setupCentralPanel() {
myCentralPanel.removeAll();
if (myUsagePreviewPanel != null) {
@@ -650,14 +657,14 @@ public class UsageViewImpl implements UsageView, UsageModelTracker.UsageModelTra
public void run(@NotNull final ProgressIndicator indicator) {
setSearchInProgress(true);
final com.intellij.usages.UsageViewManager usageViewManager = com.intellij.usages.UsageViewManager.getInstance(myProject);
usageViewManager.setCurrentSearchCancelled(false);
setCurrentSearchCancelled(false);
myChangesDetected = false;
UsageSearcher usageSearcher = myUsageSearcherFactory.create();
usageSearcher.generate(new Processor<Usage>() {
@Override
public boolean process(final Usage usage) {
if (usageViewManager.searchHasBeenCancelled()) return false;
if (searchHasBeenCancelled()) return false;
if (tooManyUsages.get() == 1) {
try {
waitWhileUserClick.await(1, TimeUnit.SECONDS);
@@ -671,7 +678,8 @@ public class UsageViewImpl implements UsageView, UsageModelTracker.UsageModelTra
if (incrementCounter) {
final int usageCount = usageCountWithoutDefinition.incrementAndGet();
if (usageCount > UsageLimitUtil.USAGES_LIMIT && tooManyUsages.get() == 0 && tooManyUsages.compareAndSet(0, 1)) {
((UsageViewManagerImpl)usageViewManager).showTooManyUsagesWarning(indicator, waitWhileUserClick, usageCountWithoutDefinition.get());
((UsageViewManagerImpl)usageViewManager)
.showTooManyUsagesWarning(indicator, waitWhileUserClick, usageCountWithoutDefinition.get(), UsageViewImpl.this);
}
appendUsage(usage);
}
@@ -835,8 +843,6 @@ public class UsageViewImpl implements UsageView, UsageModelTracker.UsageModelTra
@Override
public void close() {
// todo ? crazyness
com.intellij.usages.UsageViewManager.getInstance(myProject).setCurrentSearchCancelled(true);
UsageViewManager.getInstance(myProject).closeContent(myContent);
}
@@ -66,7 +66,7 @@ import java.util.concurrent.atomic.AtomicReference;
public class UsageViewManagerImpl extends UsageViewManager {
private final Project myProject;
private static final Key<UsageView> USAGE_VIEW_KEY = Key.create("USAGE_VIEW");
private volatile boolean mySearchHasBeenCancelled;
public UsageViewManagerImpl(Project project) {
myProject = project;
@@ -75,7 +75,6 @@ public class UsageViewManagerImpl extends UsageViewManager {
@Override
@NotNull
public UsageView createUsageView(@NotNull UsageTarget[] targets, @NotNull Usage[] usages, @NotNull UsageViewPresentation presentation, Factory<UsageSearcher> usageSearcherFactory) {
mySearchHasBeenCancelled = false;
UsageViewImpl usageView = new UsageViewImpl(myProject, presentation, targets, usageSearcherFactory);
appendUsages(usages, usageView);
usageView.setSearchInProgress(false);
@@ -217,31 +216,18 @@ public class UsageViewManagerImpl extends UsageViewManager {
}
@Override
public void setCurrentSearchCancelled(boolean flag) {
mySearchHasBeenCancelled = flag;
}
@Override
public boolean searchHasBeenCancelled() {
return mySearchHasBeenCancelled;
}
@Override
public void checkSearchCanceled() throws ProcessCanceledException {
if (searchHasBeenCancelled()) throw new ProcessCanceledException();
ProgressManager.checkCanceled();
}
public void showTooManyUsagesWarning(final ProgressIndicator indicator, final CountDownLatch waitWhileUserClick, final int usageCount) {
public void showTooManyUsagesWarning(final ProgressIndicator indicator,
final CountDownLatch waitWhileUserClick,
final int usageCount,
final UsageViewImpl usageView) {
UIUtil.invokeLaterIfNeeded(new Runnable() {
@Override
public void run() {
if (searchHasBeenCancelled() || indicator != null && indicator.isCanceled()) return;
if (usageView != null && usageView.searchHasBeenCancelled() || indicator != null && indicator.isCanceled()) return;
String message = UsageViewBundle.message("find.excessive.usage.count.prompt", usageCount);
int ret = UsageLimitUtil.showTooManyUsagesWarning(myProject, message);
if (ret != 0) {
setCurrentSearchCancelled(true);
if (ret != 0 && usageView != null) {
usageView.setCurrentSearchCancelled(true);
}
waitWhileUserClick.countDown();
}
@@ -257,6 +243,7 @@ public class UsageViewManagerImpl extends UsageViewManager {
private final Factory<UsageSearcher> mySearcherFactory;
private final FindUsagesProcessPresentation myProcessPresentation;
private final UsageViewStateListener myListener;
private volatile boolean mySearchHasBeenCancelled;
private SearchForUsagesRunnable(@NotNull final AtomicReference<UsageViewImpl> usageView,
@NotNull final UsageViewPresentation presentation,
@@ -278,7 +265,7 @@ public class UsageViewManagerImpl extends UsageViewManager {
if (usageView != null) return usageView;
int usageCount = myUsageCountWithoutDefinition.get();
if (usageCount >= 2 || usageCount == 1 && myProcessPresentation.isShowPanelIfOnlyOneUsage()) {
usageView = new UsageViewImpl(myProject, myPresentation, mySearchFor, mySearcherFactory);
usageView = new MyUsageViewImpl();
if (myUsageViewRef.compareAndSet(null, usageView)) {
openView(usageView);
Usage firstUsage = myFirstUsage.get();
@@ -340,10 +327,13 @@ public class UsageViewManagerImpl extends UsageViewManager {
if (usageCount == 1 && !myProcessPresentation.isShowPanelIfOnlyOneUsage()) {
myFirstUsage.compareAndSet(null, usage);
}
final UsageViewImpl usageView = getUsageView();
if (usageCount > UsageLimitUtil.USAGES_LIMIT && tooManyUsages.get() == 0 && tooManyUsages.compareAndSet(0, 1)) {
showTooManyUsagesWarning(indicator, waitWhileUserClick, myUsageCountWithoutDefinition.get());
showTooManyUsagesWarning(indicator, waitWhileUserClick, myUsageCountWithoutDefinition.get(), usageView);
}
UsageViewImpl usageView = getUsageView();
if (usageView != null) {
usageView.appendUsage(usage);
}
@@ -361,6 +351,14 @@ public class UsageViewManagerImpl extends UsageViewManager {
}
}
public void setCurrentSearchCancelled(boolean cancelled) {
mySearchHasBeenCancelled = cancelled;
}
public boolean searchHasBeenCancelled() {
return mySearchHasBeenCancelled;
}
private void endSearchForUsages() {
assert !ApplicationManager.getApplication().isDispatchThread() : Thread.currentThread();
int usageCount = myUsageCountWithoutDefinition.get();
@@ -424,6 +422,30 @@ public class UsageViewManagerImpl extends UsageViewManager {
myListener.findingUsagesFinished(myUsageViewRef.get());
}
}
private class MyUsageViewImpl extends UsageViewImpl {
public MyUsageViewImpl() {
super(myProject, SearchForUsagesRunnable.this.myPresentation,
SearchForUsagesRunnable.this.mySearchFor,
SearchForUsagesRunnable.this.mySearcherFactory);
}
@Override
public void close() {
setCurrentSearchCancelled(true);
super.close();
}
@Override
public boolean searchHasBeenCancelled() {
return SearchForUsagesRunnable.this.searchHasBeenCancelled();
}
@Override
public void setCurrentSearchCancelled(boolean cancelled) {
SearchForUsagesRunnable.this.setCurrentSearchCancelled(cancelled);
}
}
}
private static void flashUsageScriptaculously(final Usage usage) {