diff --git a/platform/usageView/src/com/intellij/usages/impl/SearchForUsagesRunnable.java b/platform/usageView/src/com/intellij/usages/impl/SearchForUsagesRunnable.java index 6b913dbe974b..226ce4e540c1 100644 --- a/platform/usageView/src/com/intellij/usages/impl/SearchForUsagesRunnable.java +++ b/platform/usageView/src/com/intellij/usages/impl/SearchForUsagesRunnable.java @@ -79,7 +79,7 @@ class SearchForUsagesRunnable implements Runnable { private final AtomicReference myFirstUsage = new AtomicReference<>(); @NotNull private final Project myProject; - private final AtomicReference myUsageViewRef; + private final AtomicReference myUsageViewRef; private final UsageViewPresentation myPresentation; private final UsageTarget[] mySearchFor; private final Factory mySearcherFactory; @@ -91,7 +91,7 @@ class SearchForUsagesRunnable implements Runnable { SearchForUsagesRunnable(@NotNull UsageViewManagerImpl usageViewManager, @NotNull Project project, - @NotNull AtomicReference usageViewRef, + @NotNull AtomicReference usageViewRef, @NotNull UsageViewPresentation presentation, @NotNull UsageTarget[] searchFor, @NotNull Factory searcherFactory, @@ -303,19 +303,19 @@ class SearchForUsagesRunnable implements Runnable { rangeBlinker.startBlinking(); } - private UsageViewImpl getUsageView(@NotNull ProgressIndicator indicator) { - UsageViewImpl usageView = myUsageViewRef.get(); + private UsageViewEx getUsageView(@NotNull ProgressIndicator indicator) { + UsageViewEx usageView = myUsageViewRef.get(); if (usageView != null) return usageView; int usageCount = myUsageCountWithoutDefinition.get(); if (usageCount >= 2 || usageCount == 1 && myProcessPresentation.isShowPanelIfOnlyOneUsage()) { - usageView = new UsageViewImpl(myProject, myPresentation, mySearchFor, mySearcherFactory); + usageView = myUsageViewManager.createEmptyUsageView(mySearchFor, myPresentation, mySearcherFactory); usageView.associateProgress(indicator); if (myUsageViewRef.compareAndSet(null, usageView)) { if (myProcessPresentation.isShowFindOptionsPrompt()) { openView(usageView); } else { - UsageViewImpl finalView = usageView; + UsageViewEx finalView = usageView; SwingUtilities.invokeLater(() -> { if (myProject.isDisposed()) return; if (myListener != null) { @@ -325,12 +325,12 @@ class SearchForUsagesRunnable implements Runnable { } final Usage firstUsage = myFirstUsage.get(); if (firstUsage != null) { - final UsageViewImpl finalUsageView = usageView; + final UsageViewEx finalUsageView = usageView; ApplicationManager.getApplication().runReadAction(() -> finalUsageView.appendUsage(firstUsage)); } } else { - UsageViewImpl finalUsageView = usageView; + UsageViewEx finalUsageView = usageView; // later because dispose does some sort of swing magic e.g. AnAction.unregisterCustomShortcutSet() UIUtil.invokeLaterIfNeeded(() -> Disposer.dispose(finalUsageView)); } @@ -339,10 +339,10 @@ class SearchForUsagesRunnable implements Runnable { return null; } - private void openView(@NotNull final UsageViewImpl usageView) { + private void openView(@NotNull final UsageViewEx usageView) { SwingUtilities.invokeLater(() -> { if (myProject.isDisposed()) return; - myUsageViewManager.addContent(usageView, myPresentation); + myUsageViewManager.showUsageView(usageView, myPresentation); if (myListener != null) { myListener.usageViewCreated(usageView); } @@ -394,7 +394,7 @@ class SearchForUsagesRunnable implements Runnable { myFirstUsage.compareAndSet(null, usage); } - final UsageViewImpl usageView = getUsageView(indicator1); + final UsageViewEx usageView = getUsageView(indicator1); TooManyUsagesStatus tooManyUsagesStatus= TooManyUsagesStatus.getFrom(indicator1); if (usageCount > UsageLimitUtil.USAGES_LIMIT && tooManyUsagesStatus.switchTooManyUsagesStatus()) { @@ -470,12 +470,8 @@ class SearchForUsagesRunnable implements Runnable { }, ModalityState.NON_MODAL, myProject.getDisposed()); } else { - final UsageViewImpl usageView = myUsageViewRef.get(); - if (usageView != null) { - usageView.drainQueuedUsageNodes(); - usageView.setSearchInProgress(false); - } - + final UsageViewEx usageView = myUsageViewRef.get(); + usageView.searchFinished(); final List lines; final HyperlinkListener hyperlinkListener; if (myOutOfScopeUsages.get() == 0 || getPsiElement(mySearchFor)==null) { @@ -498,7 +494,7 @@ class SearchForUsagesRunnable implements Runnable { } } - UsageViewImpl usageView = myUsageViewRef.get(); + UsageViewEx usageView = myUsageViewRef.get(); if (usageView != null) { usageView.waitForUpdateRequestsCompletion(); } diff --git a/platform/usageView/src/com/intellij/usages/impl/UsageViewEx.java b/platform/usageView/src/com/intellij/usages/impl/UsageViewEx.java new file mode 100644 index 000000000000..1f74b87aaaa3 --- /dev/null +++ b/platform/usageView/src/com/intellij/usages/impl/UsageViewEx.java @@ -0,0 +1,25 @@ +// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. +package com.intellij.usages.impl; + +import com.intellij.openapi.progress.ProgressIndicator; +import com.intellij.usages.Usage; +import com.intellij.usages.UsageView; +import org.jetbrains.annotations.NotNull; + +import java.util.Collection; + +public interface UsageViewEx extends UsageView { + boolean searchHasBeenCancelled(); + + void cancelCurrentSearch(); + + void associateProgress(@NotNull ProgressIndicator indicator); + + void waitForUpdateRequestsCompletion(); + + void appendUsagesInBulk(@NotNull Collection usages); + + void setSearchInProgress(boolean searchInProgress); + + void searchFinished(); +} diff --git a/platform/usageView/src/com/intellij/usages/impl/UsageViewImpl.java b/platform/usageView/src/com/intellij/usages/impl/UsageViewImpl.java index f9b050246f7d..92fd39842593 100644 --- a/platform/usageView/src/com/intellij/usages/impl/UsageViewImpl.java +++ b/platform/usageView/src/com/intellij/usages/impl/UsageViewImpl.java @@ -83,12 +83,10 @@ import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; import java.util.stream.Stream; -import com.intellij.util.containers.Queue; - /** * @author max */ -public class UsageViewImpl implements UsageView { +public class UsageViewImpl implements UsageViewEx { @NonNls public static final String SHOW_RECENT_FIND_USAGES_ACTION_ID = "UsageView.ShowRecentFindUsages"; private final UsageNodeTreeBuilder myBuilder; @@ -458,14 +456,20 @@ public class UsageViewImpl implements UsageView { indicesToFire.clear(); } } + @Override + public void searchFinished() { + drainQueuedUsageNodes(); + setSearchInProgress(false); + } - - boolean searchHasBeenCancelled() { + @Override + public boolean searchHasBeenCancelled() { ProgressIndicator progress = associatedProgress; return progress != null && progress.isCanceled(); } - void cancelCurrentSearch() { + @Override + public void cancelCurrentSearch() { ProgressIndicator progress = associatedProgress; if (progress != null) { ProgressWrapper.unwrap(progress).cancel(); @@ -1042,7 +1046,8 @@ public class UsageViewImpl implements UsageView { return configurableTarget == null ? getShowUsagesWithSettingsShortcut() : configurableTarget.getShortcut(); } - void associateProgress(@NotNull ProgressIndicator indicator) { + @Override + public void associateProgress(@NotNull ProgressIndicator indicator) { associatedProgress = indicator; } @@ -1135,7 +1140,8 @@ public class UsageViewImpl implements UsageView { } } - void waitForUpdateRequestsCompletion() { + @Override + public void waitForUpdateRequestsCompletion() { assert !ApplicationManager.getApplication().isDispatchThread(); while (true) { Future request; @@ -1152,7 +1158,7 @@ public class UsageViewImpl implements UsageView { } } - @SuppressWarnings("WeakerAccess") + @Override public void appendUsagesInBulk(@NotNull Collection usages) { addUpdateRequest(ApplicationManager.getApplication().executeOnPooledThread(() -> ReadAction.run(() -> { for (Usage usage : usages) { @@ -1200,7 +1206,7 @@ public class UsageViewImpl implements UsageView { .collect(Collectors.toSet()); } }; - myUsageNodes.keySet().removeIf(usage -> usages.contains(usage) || + myUsageNodes.keySet().removeIf(usage -> usages.contains(usage) || usage instanceof UsageInfo2UsageAdapter && mergedInfos.getValue().contains(((UsageInfo2UsageAdapter)usage).getUsageInfo())); if (!nodes.isEmpty() && !myPresentation.isDetachedMode()) { @@ -1414,6 +1420,7 @@ public class UsageViewImpl implements UsageView { return mySearchInProgress; } + @Override public void setSearchInProgress(boolean searchInProgress) { mySearchInProgress = searchInProgress; if (!myPresentation.isDetachedMode()) { diff --git a/platform/usageView/src/com/intellij/usages/impl/UsageViewManagerImpl.java b/platform/usageView/src/com/intellij/usages/impl/UsageViewManagerImpl.java index 6174d30b4d7c..a1a2605887dd 100644 --- a/platform/usageView/src/com/intellij/usages/impl/UsageViewManagerImpl.java +++ b/platform/usageView/src/com/intellij/usages/impl/UsageViewManagerImpl.java @@ -61,13 +61,21 @@ public class UsageViewManagerImpl extends UsageViewManager { myProject = project; } + + @NotNull + protected UsageViewEx createEmptyUsageView(@NotNull UsageTarget[] targets, + @NotNull UsageViewPresentation presentation, + Factory usageSearcherFactory) { + return new UsageViewImpl(myProject, presentation, targets, usageSearcherFactory); + } + @Override @NotNull - public UsageView createUsageView(@NotNull UsageTarget[] targets, + public UsageViewEx createUsageView(@NotNull UsageTarget[] targets, @NotNull Usage[] usages, @NotNull UsageViewPresentation presentation, Factory usageSearcherFactory) { - UsageViewImpl usageView = new UsageViewImpl(myProject, presentation, targets, usageSearcherFactory); + UsageViewEx usageView = createEmptyUsageView(targets, presentation, usageSearcherFactory); usageView.appendUsagesInBulk(Arrays.asList(usages)); ProgressManager.getInstance().run(new Task.Modal(myProject, "Waiting For Usages", false) { @Override @@ -86,14 +94,16 @@ public class UsageViewManagerImpl extends UsageViewManager { @NotNull Usage[] foundUsages, @NotNull UsageViewPresentation presentation, Factory factory) { - UsageView usageView = createUsageView(searchedFor, foundUsages, presentation, factory); - addContent((UsageViewImpl)usageView, presentation); - showToolWindow(true); - UIUtil.invokeLaterIfNeeded(() -> { - if (!((UsageViewImpl)usageView).isDisposed()) { - ((UsageViewImpl)usageView).expandRoot(); - } - }); + UsageViewEx usageView = createUsageView(searchedFor, foundUsages, presentation, factory); + if (usageView instanceof UsageViewImpl) { + showToolWindow(true); + UIUtil.invokeLaterIfNeeded(() -> { + if (!((UsageViewImpl)usageView).isDisposed()) { + ((UsageViewImpl)usageView).expandRoot(); + } + }); + } + showUsageView(usageView, presentation); return usageView; } @@ -103,7 +113,7 @@ public class UsageViewManagerImpl extends UsageViewManager { return showUsages(searchedFor, foundUsages, presentation, null); } - void addContent(@NotNull UsageViewImpl usageView, @NotNull UsageViewPresentation presentation) { + void showUsageView(@NotNull UsageViewEx usageView, @NotNull UsageViewPresentation presentation) { Content content = com.intellij.usageView.UsageViewManager.getInstance(myProject).addContent( presentation.getTabText(), presentation.getTabName(), @@ -113,7 +123,7 @@ public class UsageViewManagerImpl extends UsageViewManager { presentation.isOpenInNewTab(), true ); - usageView.setContent(content); + ((UsageViewImpl)usageView).setContent(content); content.putUserData(USAGE_VIEW_KEY, usageView); } @@ -140,7 +150,7 @@ public class UsageViewManagerImpl extends UsageViewManager { throw new IllegalStateException("Can't start find usages from under write action. Please consider Application.invokeLater() it instead."); } final SearchScope searchScopeToWarnOfFallingOutOf = getMaxSearchScopeToWarnOfFallingOutOf(searchFor); - final AtomicReference usageViewRef = new AtomicReference<>(); + final AtomicReference usageViewRef = new AtomicReference<>(); long start = System.currentTimeMillis(); Task.Backgroundable task = new Task.Backgroundable(myProject, getProgressTitle(presentation), true, new SearchInBackgroundOption()) { @Override @@ -152,7 +162,7 @@ public class UsageViewManagerImpl extends UsageViewManager { @NotNull @Override public NotificationInfo getNotificationInfo() { - UsageViewImpl usageView = usageViewRef.get(); + UsageViewEx usageView = usageViewRef.get(); int count = usageView == null ? 0 : usageView.getUsagesCount(); String notification = StringUtil.capitalizeWords(UsageViewBundle.message("usages.n", count), true); LOG.debug(notification +" in "+(System.currentTimeMillis()-start) +"ms."); @@ -219,10 +229,10 @@ public class UsageViewManagerImpl extends UsageViewManager { @NotNull final ProgressIndicator indicator, @NotNull final UsageViewPresentation presentation, final int usageCount, - @Nullable final UsageViewImpl usageView) { + @Nullable final UsageViewEx usageView) { UIUtil.invokeLaterIfNeeded(() -> { if (usageView != null && usageView.searchHasBeenCancelled() || indicator.isCanceled()) return; - int shownUsageCount = usageView == null ? usageCount : usageView.getRoot().getRecursiveUsageCount(); + int shownUsageCount = usageView instanceof UsageViewImpl ? ((UsageViewImpl)usageView).getRoot().getRecursiveUsageCount() : usageCount; String message = UsageViewBundle.message("find.excessive.usage.count.prompt", shownUsageCount, StringUtil.pluralize(presentation.getUsagesWord())); UsageLimitUtil.Result ret = UsageLimitUtil.showTooManyUsagesWarning(project, message, presentation); if (ret == UsageLimitUtil.Result.ABORT) {