From 079d29ffafb5d9dc9b2932e7f74cdd784f16e4d9 Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Fri, 31 May 2013 16:27:03 +0400 Subject: [PATCH] do not wait for user dismiss "Too many usages" dialog under the read action --- .../psi/impl/search/PsiSearchHelperImpl.java | 121 +++++++++++------- .../find/actions/ShowUsagesAction.java | 9 +- .../find/findUsages/FindUsagesManager.java | 22 +++- .../refactoring/util/TextOccurrencesUtil.java | 8 +- .../intellij/usages/impl/UsageViewImpl.java | 41 +++--- .../usages/impl/UsageViewManagerImpl.java | 89 ++++++------- platform/usageView/usageView.iml | 1 + 7 files changed, 170 insertions(+), 121 deletions(-) diff --git a/platform/indexing-impl/src/com/intellij/psi/impl/search/PsiSearchHelperImpl.java b/platform/indexing-impl/src/com/intellij/psi/impl/search/PsiSearchHelperImpl.java index d2843fca6464..e08030cfb7bf 100644 --- a/platform/indexing-impl/src/com/intellij/psi/impl/search/PsiSearchHelperImpl.java +++ b/platform/indexing-impl/src/com/intellij/psi/impl/search/PsiSearchHelperImpl.java @@ -25,6 +25,7 @@ import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.progress.ProcessCanceledException; import com.intellij.openapi.progress.ProgressIndicator; import com.intellij.openapi.progress.ProgressIndicatorProvider; +import com.intellij.openapi.progress.util.FindUsagesIndicator; import com.intellij.openapi.roots.FileIndexFacade; import com.intellij.openapi.util.*; import com.intellij.openapi.util.text.StringUtil; @@ -202,8 +203,12 @@ public class PsiSearchHelperImpl implements PsiSearchHelper { final AsyncFuture result = processPsiFileRootsAsync(fileSet, new Processor() { @Override - public boolean process(PsiElement psiRoot) { - return LowLevelSearchUtil.processElementsContainingWordInElement(processor, psiRoot, searcher, true, progress); + public boolean process(final PsiElement psiRoot) { + return ApplicationManager.getApplication().runReadAction(new Computable() { + public Boolean compute() { + return LowLevelSearchUtil.processElementsContainingWordInElement(processor, psiRoot, searcher, true, progress); + } + }); } }, progress); return new FinallyFuture(result, new Runnable() { @@ -238,32 +243,37 @@ public class PsiSearchHelperImpl implements PsiSearchHelper { }); if (file != null && !(file instanceof PsiBinaryFile)) { file.getViewProvider().getContents(); // load contents outside readaction - ApplicationManager.getApplication().runReadAction(new Runnable() { - @Override - public void run() { - try { - if (myManager.getProject().isDisposed()) throw new ProcessCanceledException(); - List psiRoots = file.getViewProvider().getAllFiles(); - Set processed = new THashSet(psiRoots.size() * 2, (float)0.5); - for (PsiElement psiRoot : psiRoots) { - if (progress != null) progress.checkCanceled(); - assert psiRoot != null : "One of the roots of file " + file + " is null. All roots: " + psiRoots + - "; ViewProvider: " + file.getViewProvider() + "; Virtual file: " + file.getViewProvider().getVirtualFile(); - if (!processed.add(psiRoot)) continue; - if (!psiRoot.isValid()) continue; - if (!psiRootProcessor.process(psiRoot)) { - canceled.set(true); - return; - } - } - myManager.dropResolveCaches(); + try { + if (myManager.getProject().isDisposed()) throw new ProcessCanceledException(); + List psiRoots = ApplicationManager.getApplication().runReadAction(new Computable>() { + public List compute() { + return file.getViewProvider().getAllFiles(); } - catch (ProcessCanceledException e) { + }); + Set processed = new THashSet(psiRoots.size() * 2, (float)0.5); + for (final PsiElement psiRoot : psiRoots) { + if (progress != null) progress.checkCanceled(); + assert psiRoot != null : "One of the roots of file " + file + " is null. All roots: " + psiRoots + + "; ViewProvider: " + file.getViewProvider() + "; Virtual file: " + file.getViewProvider().getVirtualFile(); + if (!processed.add(psiRoot)) continue; + if (!ApplicationManager.getApplication().runReadAction(new Computable() { + public Boolean compute() { + return psiRoot.isValid(); + } + })) { + continue; + } + if (!psiRootProcessor.process(psiRoot)) { canceled.set(true); - pceThrown.set(true); + break; } } - }); + myManager.dropResolveCaches(); + } + catch (ProcessCanceledException e) { + canceled.set(true); + pceThrown.set(true); + } } if (progress != null && progress.isRunning()) { double fraction = (double)counter.incrementAndGet() / size; @@ -396,6 +406,7 @@ public class PsiSearchHelperImpl implements PsiSearchHelper { }); final StringSearcher searcher = new StringSearcher(qName, true, true, false); + final int patternLength = searcher.getPattern().length(); if (progress != null) { progress.pushState(); @@ -417,25 +428,32 @@ public class PsiSearchHelperImpl implements PsiSearchHelper { final PsiFile psiFile = files[i]; if (psiFile instanceof PsiBinaryFile) continue; - ApplicationManager.getApplication().runReadAction(new Runnable() { - @Override - public void run() { - CharSequence text = psiFile.getViewProvider().getContents(); - final char[] textArray = CharArrayUtil.fromSequenceWithoutCopying(text); - for (int index = LowLevelSearchUtil.searchWord(text, textArray, 0, text.length(), searcher, progress); index >= 0;) { - PsiReference referenceAt = psiFile.findReferenceAt(index); - if (referenceAt == null || useScope == null || - !PsiSearchScopeUtil.isInScope(useScope.intersectWith(initialScope), psiFile)) { - if (!processor.process(psiFile, index, index + searcher.getPattern().length())) { - cancelled.set(Boolean.TRUE); - return; - } - } - - index = LowLevelSearchUtil.searchWord(text, textArray, index + searcher.getPattern().length(), text.length(), searcher, progress); - } + final CharSequence text = ApplicationManager.getApplication().runReadAction(new Computable() { + public CharSequence compute() { + return psiFile.getViewProvider().getContents(); } }); + final char[] textArray = ApplicationManager.getApplication().runReadAction(new Computable() { + public char[] compute() { + return CharArrayUtil.fromSequenceWithoutCopying(text); + } + }); + for (int index = LowLevelSearchUtil.searchWord(text, textArray, 0, text.length(), searcher, progress); index >= 0;) { + final int finalIndex = index; + boolean isReferenceOK = ApplicationManager.getApplication().runReadAction(new Computable() { + public Boolean compute() { + PsiReference referenceAt = psiFile.findReferenceAt(finalIndex); + return referenceAt == null || useScope == null || + !PsiSearchScopeUtil.isInScope(useScope.intersectWith(initialScope), psiFile); + } + }); + if (isReferenceOK && !processor.process(psiFile, index, index + patternLength)) { + cancelled.set(Boolean.TRUE); + break; + } + + index = LowLevelSearchUtil.searchWord(text, textArray, index + patternLength, text.length(), searcher, progress); + } if (cancelled.get()) break; if (progress != null) { progress.setFraction((double)(i + 1) / files.length); @@ -636,12 +654,23 @@ public class PsiSearchHelperImpl implements PsiSearchHelper { final AsyncFuture result = processPsiFileRootsAsync(new ArrayList(candidateFiles.keySet()), new Processor() { @Override - public boolean process(PsiElement psiRoot) { - final VirtualFile vfile = psiRoot.getContainingFile().getVirtualFile(); + public boolean process(final PsiElement psiRoot) { + if (progress instanceof FindUsagesIndicator) { + ((FindUsagesIndicator)progress).pauseProcessingIfTooManyUsages(); + } + final VirtualFile vfile = ApplicationManager.getApplication().runReadAction(new Computable() { + public VirtualFile compute() { + return psiRoot.getContainingFile().getVirtualFile(); + } + }); for (final RequestWithProcessor singleRequest : candidateFiles.get(vfile)) { - StringSearcher searcher = searchers.get(singleRequest); - TextOccurenceProcessor adapted = adaptProcessor(singleRequest.request, singleRequest.refProcessor); - if (!LowLevelSearchUtil.processElementsContainingWordInElement(adapted, psiRoot, searcher, true, progress)) { + final StringSearcher searcher = searchers.get(singleRequest); + final TextOccurenceProcessor adapted = adaptProcessor(singleRequest.request, singleRequest.refProcessor); + if (!ApplicationManager.getApplication().runReadAction(new Computable() { + public Boolean compute() { + return LowLevelSearchUtil.processElementsContainingWordInElement(adapted, psiRoot, searcher, true, progress); + } + })) { return false; } } diff --git a/platform/lang-impl/src/com/intellij/find/actions/ShowUsagesAction.java b/platform/lang-impl/src/com/intellij/find/actions/ShowUsagesAction.java index 803566f21b77..0eb2546c32e1 100644 --- a/platform/lang-impl/src/com/intellij/find/actions/ShowUsagesAction.java +++ b/platform/lang-impl/src/com/intellij/find/actions/ShowUsagesAction.java @@ -40,6 +40,7 @@ import com.intellij.openapi.ui.popup.JBPopup; import com.intellij.openapi.ui.popup.JBPopupFactory; import com.intellij.openapi.ui.popup.PopupChooserBuilder; import com.intellij.openapi.util.Comparing; +import com.intellij.openapi.util.Computable; import com.intellij.openapi.util.Condition; import com.intellij.openapi.util.Disposer; import com.intellij.openapi.vfs.VirtualFile; @@ -302,11 +303,15 @@ public class ShowUsagesAction extends AnAction implements PopupAction { Processor collect = new Processor() { private final UsageTarget[] myUsageTarget = {new PsiElement2UsageTargetAdapter(handler.getPsiElement())}; @Override - public boolean process(@NotNull Usage usage) { + public boolean process(@NotNull final Usage usage) { synchronized (usages) { if (visibleNodes.size() >= maxUsages) return false; if(UsageViewManager.isSelfUsage(usage, myUsageTarget)) return true; - UsageNode node = usageView.doAppendUsage(usage); + UsageNode node = ApplicationManager.getApplication().runReadAction(new Computable() { + public UsageNode compute() { + return usageView.doAppendUsage(usage); + } + }); usages.add(usage); if (node != null) { visibleNodes.add(node); diff --git a/platform/lang-impl/src/com/intellij/find/findUsages/FindUsagesManager.java b/platform/lang-impl/src/com/intellij/find/findUsages/FindUsagesManager.java index 9d559908eb54..5a0a71c35275 100644 --- a/platform/lang-impl/src/com/intellij/find/findUsages/FindUsagesManager.java +++ b/platform/lang-impl/src/com/intellij/find/findUsages/FindUsagesManager.java @@ -26,7 +26,6 @@ import com.intellij.openapi.actionSystem.ActionManager; import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.IdeActions; import com.intellij.openapi.application.ApplicationManager; -import com.intellij.openapi.application.ReadActionProcessor; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.editor.Document; import com.intellij.openapi.editor.Editor; @@ -391,8 +390,13 @@ public class FindUsagesManager implements JDOMExternalizable { } final Processor usageInfoProcessor = new CommonProcessors.UniqueProcessor(new Processor() { @Override - public boolean process(UsageInfo usageInfo) { - return processor.process(UsageInfoToUsageConverter.convert(descriptor, usageInfo)); + public boolean process(final UsageInfo usageInfo) { + Usage usage = ApplicationManager.getApplication().runReadAction(new Computable() { + public Usage compute() { + return UsageInfoToUsageConverter.convert(descriptor, usageInfo); + } + }); + return processor.process(usage); } }); final List elements = @@ -434,10 +438,16 @@ public class FindUsagesManager implements JDOMExternalizable { } }); PsiSearchHelper.SERVICE.getInstance(project) - .processRequests(options.fastTrack, new ReadActionProcessor() { + .processRequests(options.fastTrack, new Processor() { @Override - public boolean processInReadAction(final PsiReference ref) { - return !ref.getElement().isValid() || usageInfoProcessor.process(new UsageInfo(ref)); + public boolean process(final PsiReference ref) { + UsageInfo info = ApplicationManager.getApplication().runReadAction(new Computable() { + public UsageInfo compute() { + if (!ref.getElement().isValid()) return null; + return new UsageInfo(ref); + } + }); + return info == null || usageInfoProcessor.process(info); } }); } diff --git a/platform/lang-impl/src/com/intellij/refactoring/util/TextOccurrencesUtil.java b/platform/lang-impl/src/com/intellij/refactoring/util/TextOccurrencesUtil.java index 69a32036a13f..5400d04bb0b7 100644 --- a/platform/lang-impl/src/com/intellij/refactoring/util/TextOccurrencesUtil.java +++ b/platform/lang-impl/src/com/intellij/refactoring/util/TextOccurrencesUtil.java @@ -71,8 +71,12 @@ public class TextOccurrencesUtil { return helper.processUsagesInNonJavaFiles(element, stringToSearch, new PsiNonJavaFileReferenceProcessor() { @Override - public boolean process(PsiFile psiFile, int startOffset, int endOffset) { - UsageInfo usageInfo = factory.createUsageInfo(psiFile, startOffset, endOffset); + public boolean process(final PsiFile psiFile, final int startOffset, final int endOffset) { + UsageInfo usageInfo = ApplicationManager.getApplication().runReadAction(new Computable() { + public UsageInfo compute() { + return factory.createUsageInfo(psiFile, startOffset, endOffset); + } + }); return usageInfo == null || processor.process(usageInfo); } }, searchScope); diff --git a/platform/usageView/src/com/intellij/usages/impl/UsageViewImpl.java b/platform/usageView/src/com/intellij/usages/impl/UsageViewImpl.java index bd071d1160b6..6455e1ada72e 100644 --- a/platform/usageView/src/com/intellij/usages/impl/UsageViewImpl.java +++ b/platform/usageView/src/com/intellij/usages/impl/UsageViewImpl.java @@ -28,6 +28,7 @@ import com.intellij.openapi.ide.CopyPasteManager; import com.intellij.openapi.progress.ProgressIndicator; import com.intellij.openapi.progress.ProgressManager; import com.intellij.openapi.progress.Task; +import com.intellij.openapi.progress.util.FindUsagesIndicator; import com.intellij.openapi.project.DumbAware; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.Messages; @@ -73,8 +74,6 @@ import java.awt.event.*; import java.util.*; import java.util.List; import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; /** @@ -257,9 +256,9 @@ public class UsageViewImpl implements UsageView, UsageModelTracker.UsageModelTra protected boolean searchHasBeenCancelled() { return false; } - + protected void setCurrentSearchCancelled(boolean flag){} - + private void setupCentralPanel() { myCentralPanel.removeAll(); disposeUsageContextPanels(); @@ -750,14 +749,14 @@ public class UsageViewImpl implements UsageView, UsageModelTracker.UsageModelTra } private void doReRun() { - final AtomicInteger tooManyUsages = new AtomicInteger(); - final CountDownLatch waitWhileUserClick = new CountDownLatch(1); final AtomicInteger usageCountWithoutDefinition = new AtomicInteger(0); - ProgressManager.getInstance().run(new Task.Backgroundable(myProject, UsageViewManagerImpl.getProgressTitle(myPresentation)) { + final Project project = myProject; + final FindUsagesIndicator findUsagesIndicator = new FindUsagesIndicator(); + Task.Backgroundable task = new Task.Backgroundable(project, UsageViewManagerImpl.getProgressTitle(myPresentation)) { @Override public void run(@NotNull final ProgressIndicator indicator) { setSearchInProgress(true); - final com.intellij.usages.UsageViewManager usageViewManager = com.intellij.usages.UsageViewManager.getInstance(myProject); + setCurrentSearchCancelled(false); myChangesDetected = false; @@ -766,32 +765,30 @@ public class UsageViewImpl implements UsageView, UsageModelTracker.UsageModelTra @Override public boolean process(final Usage usage) { if (searchHasBeenCancelled()) return false; - if (tooManyUsages.get() == 1) { - try { - waitWhileUserClick.await(1, TimeUnit.SECONDS); - } - catch (InterruptedException ignored) { - } - } boolean incrementCounter = !com.intellij.usages.UsageViewManager.isSelfUsage(usage, myTargets); 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(), UsageViewImpl.this); + if (usageCount > UsageLimitUtil.USAGES_LIMIT) { + if (findUsagesIndicator.switchTooManyUsagesStatus()) { + UsageViewManagerImpl.showTooManyUsagesWarning(project, findUsagesIndicator, usageCountWithoutDefinition.get(), UsageViewImpl.this); + } } - appendUsage(usage); + ApplicationManager.getApplication().runReadAction(new Runnable() { + public void run() { + appendUsage(usage); + } + }); } - ProgressIndicator indicator = ProgressManager.getInstance().getProgressIndicator(); - return indicator == null || !indicator.isCanceled(); + return !findUsagesIndicator.isCanceled(); } }); drainQueuedUsageNodes(); setSearchInProgress(false); } - }); + }; + ProgressManager.getInstance().runProcessWithProgressAsynchronously(task, findUsagesIndicator); } private void reset() { diff --git a/platform/usageView/src/com/intellij/usages/impl/UsageViewManagerImpl.java b/platform/usageView/src/com/intellij/usages/impl/UsageViewManagerImpl.java index b4f1def6b5ea..6fcd6750db63 100644 --- a/platform/usageView/src/com/intellij/usages/impl/UsageViewManagerImpl.java +++ b/platform/usageView/src/com/intellij/usages/impl/UsageViewManagerImpl.java @@ -30,6 +30,8 @@ import com.intellij.openapi.progress.ProcessCanceledException; import com.intellij.openapi.progress.ProgressIndicator; import com.intellij.openapi.progress.ProgressManager; import com.intellij.openapi.progress.Task; +import com.intellij.openapi.progress.util.FindUsagesIndicator; +import com.intellij.openapi.progress.util.ProgressWrapper; import com.intellij.openapi.project.DumbModeAction; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.MessageType; @@ -65,8 +67,6 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.List; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicReference; @@ -141,10 +141,10 @@ public class UsageViewManagerImpl extends UsageViewManager { processPresentation.setShowNotFoundMessage(showNotFoundMessage); processPresentation.setShowPanelIfOnlyOneUsage(showPanelIfOnlyOneUsage); - Task task = new Task.Backgroundable(myProject, getProgressTitle(presentation), true, new SearchInBackgroundOption()) { + Task.Backgroundable task = new Task.Backgroundable(myProject, getProgressTitle(presentation), true, new SearchInBackgroundOption()) { @Override public void run(@NotNull final ProgressIndicator indicator) { - new SearchForUsagesRunnable(usageView, presentation, searchFor, searcherFactory, processPresentation, listener).run(); + new SearchForUsagesRunnable(UsageViewManagerImpl.this.myProject, usageView, presentation, searchFor, searcherFactory, processPresentation, listener).run(); } @Override @@ -159,7 +159,8 @@ public class UsageViewManagerImpl extends UsageViewManager { return new NotificationInfo("Find Usages", "Find Usages Finished", notification); } }; - ProgressManager.getInstance().run(task); + ProgressManager.getInstance().runProcessWithProgressAsynchronously(task, new FindUsagesIndicator()); + //ProgressManager.getInstance().run(task); return usageView.get(); } @@ -170,7 +171,7 @@ public class UsageViewManagerImpl extends UsageViewManager { @NotNull UsageViewPresentation presentation, @Nullable UsageViewStateListener listener) { final AtomicReference usageView = new AtomicReference(); - final SearchForUsagesRunnable runnable = new SearchForUsagesRunnable(usageView, presentation, searchFor, searcherFactory, processPresentation, listener); + final SearchForUsagesRunnable runnable = new SearchForUsagesRunnable(myProject, usageView, presentation, searchFor, searcherFactory, processPresentation, listener); final Factory progressIndicatorFactory = processPresentation.getProgressIndicatorFactory(); final ProgressIndicator progressIndicator = progressIndicatorFactory != null ? progressIndicatorFactory.create() : null; @@ -236,21 +237,21 @@ public class UsageViewManagerImpl extends UsageViewManager { } - public void showTooManyUsagesWarning(final ProgressIndicator indicator, - @NotNull final CountDownLatch waitWhileUserClick, - final int usageCount, - final UsageViewImpl usageView) { + public static void showTooManyUsagesWarning(@NotNull final Project project, + @NotNull final FindUsagesIndicator indicator, + final int usageCount, + final UsageViewImpl usageView) { UIUtil.invokeLaterIfNeeded(new Runnable() { @Override public void run() { - if (usageView != null && usageView.searchHasBeenCancelled() || indicator != null && indicator.isCanceled()) return; + if (usageView != null && usageView.searchHasBeenCancelled() || indicator.isCanceled()) return; String message = UsageViewBundle.message("find.excessive.usage.count.prompt", usageCount); - UsageLimitUtil.Result ret = UsageLimitUtil.showTooManyUsagesWarning(myProject, message); + UsageLimitUtil.Result ret = UsageLimitUtil.showTooManyUsagesWarning(project, message); if (ret == UsageLimitUtil.Result.ABORT && usageView != null) { usageView.setCurrentSearchCancelled(true); - if (indicator != null) indicator.cancel(); + indicator.cancel(); } - waitWhileUserClick.countDown(); + indicator.userResponded(); } }); } @@ -258,6 +259,7 @@ public class UsageViewManagerImpl extends UsageViewManager { private class SearchForUsagesRunnable implements Runnable { private final AtomicInteger myUsageCountWithoutDefinition = new AtomicInteger(0); private final AtomicReference myFirstUsage = new AtomicReference(); + @NotNull private final Project myProject; private final AtomicReference myUsageViewRef; private final UsageViewPresentation myPresentation; private final UsageTarget[] mySearchFor; @@ -266,12 +268,14 @@ public class UsageViewManagerImpl extends UsageViewManager { private final UsageViewStateListener myListener; private volatile boolean mySearchHasBeenCancelled; - private SearchForUsagesRunnable(@NotNull AtomicReference usageView, + private SearchForUsagesRunnable(@NotNull Project project, + @NotNull AtomicReference usageView, @NotNull UsageViewPresentation presentation, @NotNull UsageTarget[] searchFor, @NotNull Factory searcherFactory, @NotNull FindUsagesProcessPresentation processPresentation, @Nullable UsageViewStateListener listener) { + myProject = project; myUsageViewRef = usageView; myPresentation = presentation; mySearchFor = searchFor; @@ -286,7 +290,7 @@ public class UsageViewManagerImpl extends UsageViewManager { if (usageView != null) return usageView; int usageCount = myUsageCountWithoutDefinition.get(); if (usageCount >= 2 || usageCount == 1 && myProcessPresentation.isShowPanelIfOnlyOneUsage()) { - usageView = new MyUsageViewImpl(); + usageView = new MyUsageViewImpl(myProject); if (myUsageViewRef.compareAndSet(null, usageView)) { openView(usageView); Usage firstUsage = myFirstUsage.get(); @@ -327,26 +331,17 @@ public class UsageViewManagerImpl extends UsageViewManager { findUsagesStartedBalloon.addRequest(new Runnable() { @Override public void run() { - notifyByFindBalloon(null, MessageType.WARNING, myProcessPresentation,"Find Usages in progress..."); + notifyByFindBalloon(null, MessageType.WARNING, myProcessPresentation, UsageViewManagerImpl.this.myProject,"Find Usages in progress..."); findStartedBalloonShown.set(true); } }, 300, ModalityState.NON_MODAL); UsageSearcher usageSearcher = mySearcherFactory.create(); - final AtomicInteger tooManyUsages = new AtomicInteger(); - // 0: ok, 1:warning dialog shown; 2:user closed dialog - final CountDownLatch waitWhileUserClick = new CountDownLatch(1); + usageSearcher.generate(new Processor() { @Override public boolean process(final Usage usage) { - final ProgressIndicator indicator = ProgressManager.getInstance().getProgressIndicator(); + ProgressIndicator indicator = ProgressWrapper.unwrap(ProgressManager.getInstance().getProgressIndicator()); if (searchHasBeenCancelled() || indicator != null && indicator.isCanceled()) return false; - if (tooManyUsages.get() == 1) { - try { - waitWhileUserClick.await(1, TimeUnit.SECONDS); - } - catch (InterruptedException ignored) { - } - } boolean incrementCounter = !isSelfUsage(usage, mySearchFor); @@ -358,12 +353,19 @@ public class UsageViewManagerImpl extends UsageViewManager { final UsageViewImpl usageView = getUsageView(); - if (usageCount > UsageLimitUtil.USAGES_LIMIT && tooManyUsages.get() == 0 && tooManyUsages.compareAndSet(0, 1)) { - showTooManyUsagesWarning(indicator, waitWhileUserClick, myUsageCountWithoutDefinition.get(), usageView); + if (usageCount > UsageLimitUtil.USAGES_LIMIT) { + if (indicator instanceof FindUsagesIndicator && + ((FindUsagesIndicator)indicator).switchTooManyUsagesStatus()) { + showTooManyUsagesWarning(myProject, (FindUsagesIndicator)indicator, myUsageCountWithoutDefinition.get(), usageView); + } } if (usageView != null) { - usageView.appendUsage(usage); + ApplicationManager.getApplication().runReadAction(new Runnable() { + public void run() { + usageView.appendUsage(usage); + } + }); } } return indicator == null || !indicator.isCanceled(); @@ -413,7 +415,7 @@ public class UsageViewManagerImpl extends UsageViewManager { if (notFoundActions.isEmpty()) { notifyByFindBalloon(createGotToOptionsListener(mySearchFor), - MessageType.INFO, myProcessPresentation, StringUtil.escapeXml(message), createOptionsHtml()); + MessageType.INFO, myProcessPresentation, UsageViewManagerImpl.this.myProject, StringUtil.escapeXml(message), createOptionsHtml()); findStartedBalloonShown.set(false); } else { @@ -446,7 +448,7 @@ public class UsageViewManagerImpl extends UsageViewManager { flashUsageScriptaculously(usage); } notifyByFindBalloon(createGotToOptionsListener(mySearchFor), - MessageType.INFO, myProcessPresentation,"Only one usage found.", createOptionsHtml()); + MessageType.INFO, myProcessPresentation, UsageViewManagerImpl.this.myProject,"Only one usage found.", createOptionsHtml()); } }, ModalityState.NON_MODAL, myProject.getDisposed()); } @@ -460,7 +462,7 @@ public class UsageViewManagerImpl extends UsageViewManager { ApplicationManager.getApplication().invokeLater(new Runnable() { @Override public void run() { - notifyByFindBalloon(null, MessageType.INFO, myProcessPresentation); + notifyByFindBalloon(null, MessageType.INFO, myProcessPresentation, UsageViewManagerImpl.this.myProject); } }, ModalityState.NON_MODAL, myProject.getDisposed()); } @@ -472,8 +474,8 @@ public class UsageViewManagerImpl extends UsageViewManager { } private class MyUsageViewImpl extends UsageViewImpl { - public MyUsageViewImpl() { - super(myProject, SearchForUsagesRunnable.this.myPresentation, mySearchFor, mySearcherFactory); + private MyUsageViewImpl(@NotNull Project project) { + super(project, SearchForUsagesRunnable.this.myPresentation, mySearchFor, mySearcherFactory); } @Override @@ -494,11 +496,12 @@ public class UsageViewManagerImpl extends UsageViewManager { } } - private void notifyByFindBalloon(final HyperlinkListener listener, - @NotNull final MessageType info, - @NotNull FindUsagesProcessPresentation processPresentation, - @NotNull String... sLines) { - com.intellij.usageView.UsageViewManager.getInstance(myProject); // in case tool window not registered + private static void notifyByFindBalloon(final HyperlinkListener listener, + @NotNull final MessageType info, + @NotNull FindUsagesProcessPresentation processPresentation, + @NotNull final Project project, + @NotNull String... sLines) { + com.intellij.usageView.UsageViewManager.getInstance(project); // in case tool window not registered final List lines = new ArrayList(Arrays.asList(sLines)); final Collection largeFiles = processPresentation.getLargeFiles(); @@ -516,7 +519,7 @@ public class UsageViewManagerImpl extends UsageViewManager { String detailedMessage = detailedLargeFilesMessage(largeFiles); List strings = new ArrayList(lines); strings.add(detailedMessage); - ToolWindowManager.getInstance(myProject).notifyByBalloon(ToolWindowId.FIND, info, wrapInHtml(strings), AllIcons.Actions.Find, listener); + ToolWindowManager.getInstance(project).notifyByBalloon(ToolWindowId.FIND, info, wrapInHtml(strings), AllIcons.Actions.Find, listener); } else if (listener != null) { listener.hyperlinkUpdate(e); @@ -525,7 +528,7 @@ public class UsageViewManagerImpl extends UsageViewManager { }; } - ToolWindowManager.getInstance(myProject).notifyByBalloon(ToolWindowId.FIND, info, wrapInHtml(resultLines), AllIcons.Actions.Find, resultListener); + ToolWindowManager.getInstance(project).notifyByBalloon(ToolWindowId.FIND, info, wrapInHtml(resultLines), AllIcons.Actions.Find, resultListener); } @NotNull diff --git a/platform/usageView/usageView.iml b/platform/usageView/usageView.iml index fa62559a83b4..e3943e442779 100644 --- a/platform/usageView/usageView.iml +++ b/platform/usageView/usageView.iml @@ -8,6 +8,7 @@ +