From f81ebf39b3a949d8f59ce6aec787bb7f69d4120d Mon Sep 17 00:00:00 2001 From: anna Date: Thu, 6 Dec 2012 13:19:03 +0100 Subject: [PATCH] search for yet non-loaded elements in list in background --- .../daemon/impl/PsiElementListNavigator.java | 7 +++- .../hint/ImplementationViewComponent.java | 12 +++--- .../actions/ShowImplementationsAction.java | 14 ++++--- .../navigation/BackgroundUpdaterTask.java | 22 ++++++++++- .../navigation/GotoTargetHandler.java | 8 ++-- .../src/com/intellij/find/FindUtil.java | 37 +++++++++++++++---- .../intellij/usages/impl/UsageViewImpl.java | 4 ++ 7 files changed, 77 insertions(+), 27 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/PsiElementListNavigator.java b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/PsiElementListNavigator.java index 9192cb3cfb9b..2b08187fab0f 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/PsiElementListNavigator.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/PsiElementListNavigator.java @@ -25,12 +25,14 @@ import com.intellij.openapi.progress.ProgressManager; import com.intellij.openapi.ui.popup.JBPopup; import com.intellij.openapi.ui.popup.PopupChooserBuilder; import com.intellij.openapi.util.Computable; +import com.intellij.openapi.util.Ref; import com.intellij.psi.NavigatablePsiElement; import com.intellij.psi.PsiElement; import com.intellij.ui.CollectionListModel; import com.intellij.ui.JBListWithHintProvider; import com.intellij.ui.awt.RelativePoint; import com.intellij.ui.popup.AbstractPopup; +import com.intellij.usages.UsageView; import com.intellij.util.Processor; import org.jetbrains.annotations.Nullable; @@ -113,12 +115,13 @@ public class PsiElementListNavigator { return true; } }); + final Ref usageView = new Ref(); if (findUsagesTitle != null) { popupChooserBuilder = popupChooserBuilder.setCouldPin(new Processor() { @Override public boolean process(JBPopup popup) { final List items = model.getItems(); - FindUtil.showInUsageView(null, items.toArray(new PsiElement[items.size()]), findUsagesTitle, targets[0].getProject()); + usageView.set(FindUtil.showInUsageView(null, items.toArray(new PsiElement[items.size()]), findUsagesTitle, targets[0].getProject())); popup.cancel(); return false; } @@ -127,7 +130,7 @@ public class PsiElementListNavigator { final JBPopup popup = popupChooserBuilder.createPopup(); if (listUpdaterTask != null) { - listUpdaterTask.init((AbstractPopup)popup, list); + listUpdaterTask.init((AbstractPopup)popup, list, usageView); ProgressManager.getInstance().run(listUpdaterTask); } diff --git a/platform/lang-impl/src/com/intellij/codeInsight/hint/ImplementationViewComponent.java b/platform/lang-impl/src/com/intellij/codeInsight/hint/ImplementationViewComponent.java index 0ba7901aa413..cd167714cfc8 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/hint/ImplementationViewComponent.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/hint/ImplementationViewComponent.java @@ -45,6 +45,7 @@ import com.intellij.ui.IdeBorderFactory; import com.intellij.ui.ListCellRendererWrapper; import com.intellij.ui.SideBorder; import com.intellij.ui.components.JBScrollPane; +import com.intellij.usages.UsageView; import com.intellij.util.PairFunction; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; @@ -337,7 +338,7 @@ public class ImplementationViewComponent extends JPanel { if (file == null) continue; final PsiElement parent = element.getParent(); files.add(new FileDescriptor(file, names.size() > 1 || parent == file ? element : parent)); - candidates.add(element.getNavigationElement()); + candidates.add(element); } fun.fun(PsiUtilCore.toPsiElementArray(candidates), files); @@ -367,7 +368,7 @@ public class ImplementationViewComponent extends JPanel { private void updateEditorText() { disposeNonTextEditor(); - final PsiElement elt = myElements[myIndex]; + final PsiElement elt = myElements[myIndex].getNavigationElement(); Project project = elt.getProject(); PsiFile psiFile = getContainingFile(elt); final VirtualFile vFile = psiFile.getVirtualFile(); @@ -498,11 +499,8 @@ public class ImplementationViewComponent extends JPanel { return myElements; } - public void showInUsageView() { - FindUtil.showInUsageView(null, collectNonBinaryElements(), myTitle, myEditor.getProject()); - if (myHint.isVisible()) { - myHint.cancel(); - } + public UsageView showInUsageView() { + return FindUtil.showInUsageView(null, collectNonBinaryElements(), myTitle, myEditor.getProject()); } private class BackAction extends AnAction implements HintManagerImpl.ActionToIgnore { diff --git a/platform/lang-impl/src/com/intellij/codeInsight/hint/actions/ShowImplementationsAction.java b/platform/lang-impl/src/com/intellij/codeInsight/hint/actions/ShowImplementationsAction.java index 214f623202dc..c4a632ec0f53 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/hint/actions/ShowImplementationsAction.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/hint/actions/ShowImplementationsAction.java @@ -36,6 +36,7 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.popup.JBPopup; import com.intellij.openapi.ui.popup.JBPopupFactory; import com.intellij.openapi.util.Computable; +import com.intellij.openapi.util.Ref; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.pom.PomTargetPsiElement; import com.intellij.psi.*; @@ -46,6 +47,7 @@ import com.intellij.ui.popup.AbstractPopup; import com.intellij.ui.popup.NotLookupOrSearchCondition; import com.intellij.ui.popup.PopupPositionManager; import com.intellij.ui.popup.PopupUpdateProcessor; +import com.intellij.usages.UsageView; import com.intellij.util.Processor; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; @@ -204,6 +206,7 @@ public class ShowImplementationsAction extends AnAction implements PopupAction { } } + final Ref usageView = new Ref(); final String title = CodeInsightBundle.message("implementation.view.title", text); if (myPopupRef != null) { final JBPopup popup = myPopupRef.get(); @@ -211,7 +214,7 @@ public class ShowImplementationsAction extends AnAction implements PopupAction { final ImplementationViewComponent component = (ImplementationViewComponent) ((AbstractPopup)popup).getComponent(); ((AbstractPopup)popup).setCaption(title); component.update(impls, index); - updateInBackground(editor, element, component, title, (AbstractPopup)popup); + updateInBackground(editor, element, component, title, (AbstractPopup)popup, usageView); if (invokedByShortcut) { ((AbstractPopup)popup).focusPreferredComponent(); } @@ -242,13 +245,14 @@ public class ShowImplementationsAction extends AnAction implements PopupAction { .setCouldPin(new Processor() { @Override public boolean process(JBPopup popup) { - component.showInUsageView(); + usageView.set(component.showInUsageView()); + popup.cancel(); return false; } }) .createPopup(); - updateInBackground(editor, element, component, title, (AbstractPopup)popup); + updateInBackground(editor, element, component, title, (AbstractPopup)popup, usageView); PopupPositionManager.positionPopupInBestPosition(popup, editor, DataManager.getInstance().getDataContext()); component.setHint(popup, title); @@ -261,7 +265,7 @@ public class ShowImplementationsAction extends AnAction implements PopupAction { @Nullable PsiElement element, ImplementationViewComponent component, String title, - AbstractPopup popup) { + AbstractPopup popup, Ref usageView) { if (myTaskRef != null) { final BackgroundUpdaterTask updaterTask = myTaskRef.get(); if (updaterTask != null) { @@ -271,7 +275,7 @@ public class ShowImplementationsAction extends AnAction implements PopupAction { if (element == null) return; //already found final ImplementationsUpdaterTask task = new ImplementationsUpdaterTask(element, editor, title); - task.init(popup, component); + task.init(popup, component, usageView); myTaskRef = new WeakReference(task); ProgressManager.getInstance().run(task); diff --git a/platform/lang-impl/src/com/intellij/codeInsight/navigation/BackgroundUpdaterTask.java b/platform/lang-impl/src/com/intellij/codeInsight/navigation/BackgroundUpdaterTask.java index 20075ac26341..9e76cfeb7945 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/navigation/BackgroundUpdaterTask.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/navigation/BackgroundUpdaterTask.java @@ -15,6 +15,7 @@ */ package com.intellij.codeInsight.navigation; +import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.application.ModalityState; import com.intellij.openapi.progress.PerformInBackgroundOption; import com.intellij.openapi.progress.ProgressIndicator; @@ -22,8 +23,13 @@ import com.intellij.openapi.progress.Task; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.popup.JBPopupAdapter; import com.intellij.openapi.ui.popup.LightweightWindowEvent; +import com.intellij.openapi.util.Ref; import com.intellij.psi.PsiElement; import com.intellij.ui.popup.AbstractPopup; +import com.intellij.usageView.UsageInfo; +import com.intellij.usages.UsageInfo2UsageAdapter; +import com.intellij.usages.UsageView; +import com.intellij.usages.impl.UsageViewImpl; import com.intellij.util.Alarm; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -39,6 +45,7 @@ import java.util.List; public abstract class BackgroundUpdaterTask extends Task.Backgroundable { protected AbstractPopup myPopup; protected T myComponent; + private Ref myUsageView; private final List myData = new ArrayList(); private final Alarm myAlarm = new Alarm(Alarm.ThreadToUse.SWING_THREAD); @@ -61,9 +68,10 @@ public abstract class BackgroundUpdaterTask extends Task.Backgroundable { super(project, title, canBeCancelled, backgroundOption); } - public void init(@NotNull AbstractPopup popup, T component) { + public void init(@NotNull AbstractPopup popup, T component, Ref usageView) { myPopup = popup; myComponent = component; + myUsageView = usageView; myPopup.addPopupListener(new JBPopupAdapter() { @Override @@ -83,7 +91,17 @@ public abstract class BackgroundUpdaterTask extends Task.Backgroundable { return canceled; } - public boolean updateComponent(PsiElement element, @Nullable final Comparator comparator) { + public boolean updateComponent(final PsiElement element, @Nullable final Comparator comparator) { + final UsageView view = myUsageView.get(); + if (view != null && !((UsageViewImpl)view).isDisposed()) { + ApplicationManager.getApplication().runReadAction(new Runnable() { + public void run() { + view.appendUsage(new UsageInfo2UsageAdapter(new UsageInfo(element))); + } + }); + return true; + } + if (myCanceled) return false; if (myPopup.isDisposed()) return false; diff --git a/platform/lang-impl/src/com/intellij/codeInsight/navigation/GotoTargetHandler.java b/platform/lang-impl/src/com/intellij/codeInsight/navigation/GotoTargetHandler.java index 59514c711663..ca970d93e49e 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/navigation/GotoTargetHandler.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/navigation/GotoTargetHandler.java @@ -34,6 +34,7 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.popup.JBPopup; import com.intellij.openapi.ui.popup.PopupChooserBuilder; import com.intellij.openapi.util.Computable; +import com.intellij.openapi.util.Ref; import com.intellij.pom.Navigatable; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiFile; @@ -41,6 +42,7 @@ import com.intellij.psi.PsiNamedElement; import com.intellij.ui.CollectionListModel; import com.intellij.ui.JBListWithHintProvider; import com.intellij.ui.popup.AbstractPopup; +import com.intellij.usages.UsageView; import com.intellij.util.ArrayUtil; import com.intellij.util.Function; import com.intellij.util.Processor; @@ -169,6 +171,7 @@ public abstract class GotoTargetHandler implements CodeInsightActionHandler { } }); + final Ref usageView = new Ref(); final JBPopup popup = builder. setTitle(title). setItemChoosenCallback(runnable). @@ -183,8 +186,7 @@ public abstract class GotoTargetHandler implements CodeInsightActionHandler { setCouldPin(new Processor() { @Override public boolean process(JBPopup popup) { - FindUtil.showInUsageView(gotoData.source, gotoData.targets, - getFindUsagesTitle(gotoData.source, name, gotoData.targets.length), project); + usageView.set(FindUtil.showInUsageView(gotoData.source, gotoData.targets, getFindUsagesTitle(gotoData.source, name, gotoData.targets.length), project)); popup.cancel(); return false; } @@ -192,7 +194,7 @@ public abstract class GotoTargetHandler implements CodeInsightActionHandler { setAdText(getAdText(gotoData.source, targets.length)). createPopup(); if (gotoData.listUpdaterTask != null) { - gotoData.listUpdaterTask.init((AbstractPopup)popup, list); + gotoData.listUpdaterTask.init((AbstractPopup)popup, list, usageView); ProgressManager.getInstance().run(gotoData.listUpdaterTask); } popup.showInBestPositionFor(editor); diff --git a/platform/lang-impl/src/com/intellij/find/FindUtil.java b/platform/lang-impl/src/com/intellij/find/FindUtil.java index 6425c34af124..dc8653bc95ae 100644 --- a/platform/lang-impl/src/com/intellij/find/FindUtil.java +++ b/platform/lang-impl/src/com/intellij/find/FindUtil.java @@ -46,6 +46,9 @@ import com.intellij.openapi.fileEditor.FileEditor; import com.intellij.openapi.fileEditor.TextEditor; import com.intellij.openapi.fileEditor.ex.IdeDocumentHistory; import com.intellij.openapi.keymap.KeymapUtil; +import com.intellij.openapi.progress.ProgressIndicator; +import com.intellij.openapi.progress.ProgressManager; +import com.intellij.openapi.progress.Task; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.Messages; import com.intellij.openapi.util.JDOMUtil; @@ -60,6 +63,7 @@ import com.intellij.psi.PsiFile; import com.intellij.ui.LightweightHint; import com.intellij.usageView.UsageInfo; import com.intellij.usages.*; +import com.intellij.usages.impl.UsageViewImpl; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -910,19 +914,36 @@ public class FindUtil { boolean shouldReplace(TextRange range, String replace); } - public static void showInUsageView(PsiElement sourceElement, PsiElement[] targets, String title, Project project) { + public static UsageView showInUsageView(PsiElement sourceElement, final PsiElement[] targets, String title, Project project) { final UsageViewPresentation presentation = new UsageViewPresentation(); presentation.setCodeUsagesString(title); presentation.setTabName(title); presentation.setTabText(title); - final UsageInfo[] usages = new UsageInfo[targets.length]; - for (int i = 0; i < targets.length; i++) { - usages[i] = new UsageInfo(targets[i]); - } final UsageTarget[] usageTargets = sourceElement == null ? UsageTarget.EMPTY_ARRAY : new UsageTarget[]{new PsiElement2UsageTargetAdapter(sourceElement)}; - final Usage[] foundUsages = UsageInfoToUsageConverter.convert( - new UsageInfoToUsageConverter.TargetElementsDescriptor(targets), usages); - UsageViewManager.getInstance(project).showUsages(usageTargets, foundUsages, presentation); + + final UsageInfoToUsageConverter.TargetElementsDescriptor targetElementsDescriptor = + sourceElement != null ? new UsageInfoToUsageConverter.TargetElementsDescriptor(sourceElement) + : new UsageInfoToUsageConverter.TargetElementsDescriptor(PsiElement.EMPTY_ARRAY); + final Usage[] usages = {UsageInfoToUsageConverter.convert(targetElementsDescriptor, new UsageInfo(targets[0]))}; + final UsageView view = + UsageViewManager.getInstance(project).showUsages(usageTargets, usages, presentation); + ProgressManager.getInstance().run(new Task.Backgroundable(project, "Updating Usage View ...") { + @Override + public void run(@NotNull ProgressIndicator indicator) { + + for (int i = 1; i < targets.length; i++) { + if (((UsageViewImpl)view).isDisposed()) break; + final PsiElement target = targets[i]; + ApplicationManager.getApplication().runReadAction(new Runnable() { + public void run() { + final Usage usage = UsageInfoToUsageConverter.convert(targetElementsDescriptor, new UsageInfo(target)); + view.appendUsage(usage); + } + }); + } + } + }); + return view; } } diff --git a/platform/usageView/src/com/intellij/usages/impl/UsageViewImpl.java b/platform/usageView/src/com/intellij/usages/impl/UsageViewImpl.java index b7510034f5a4..d61735b307db 100644 --- a/platform/usageView/src/com/intellij/usages/impl/UsageViewImpl.java +++ b/platform/usageView/src/com/intellij/usages/impl/UsageViewImpl.java @@ -985,6 +985,10 @@ public class UsageViewImpl implements UsageView, UsageModelTracker.UsageModelTra } } + public boolean isDisposed() { + return isDisposed; + } + private void showNode(@NotNull final UsageNode node) { if (!myPresentation.isDetachedMode()) { UIUtil.invokeLaterIfNeeded(new Runnable() {