From 09ff2cd7003bbfb5871519a3802c4fabffe68340 Mon Sep 17 00:00:00 2001 From: "Gregory.Shrago" Date: Mon, 26 Jan 2015 21:18:40 +0300 Subject: [PATCH] Select-in: scratches- & scopes-related fixes --- .../search/scope/ProjectProductionScope.java | 1 + .../ide/impl/ProjectViewSelectInTarget.java | 18 +++++-- .../ide/impl/SelectInTargetPsiWrapper.java | 29 +++++++--- .../intellij/ide/projectView/ProjectView.java | 3 ++ .../ide/projectView/impl/ProjectViewImpl.java | 16 ++++-- .../scopeView/ScopePaneSelectInTarget.java | 54 +++++++++++-------- .../intellij/ide/scopeView/ScopeViewPane.java | 51 +++++++++++------- 7 files changed, 119 insertions(+), 53 deletions(-) diff --git a/platform/analysis-api/src/com/intellij/psi/search/scope/ProjectProductionScope.java b/platform/analysis-api/src/com/intellij/psi/search/scope/ProjectProductionScope.java index 19788a0bd3d7..6aa1c933824c 100644 --- a/platform/analysis-api/src/com/intellij/psi/search/scope/ProjectProductionScope.java +++ b/platform/analysis-api/src/com/intellij/psi/search/scope/ProjectProductionScope.java @@ -43,6 +43,7 @@ public class ProjectProductionScope extends NamedScope { public boolean contains(VirtualFile file, @NotNull Project project, @Nullable NamedScopesHolder holder) { final ProjectFileIndex index = ProjectRootManager.getInstance(project).getFileIndex(); return file != null + && index.isInSource(file) && !index.isInTestSourceContent(file) && !index.isInLibraryClasses(file) && !index.isInLibrarySource(file); diff --git a/platform/lang-impl/src/com/intellij/ide/impl/ProjectViewSelectInTarget.java b/platform/lang-impl/src/com/intellij/ide/impl/ProjectViewSelectInTarget.java index b510dc98bf1f..2ed96628b1f5 100644 --- a/platform/lang-impl/src/com/intellij/ide/impl/ProjectViewSelectInTarget.java +++ b/platform/lang-impl/src/com/intellij/ide/impl/ProjectViewSelectInTarget.java @@ -35,6 +35,7 @@ import com.intellij.openapi.wm.ToolWindowId; import com.intellij.openapi.wm.ToolWindowManager; import com.intellij.psi.*; import com.intellij.psi.util.PsiUtilBase; +import com.intellij.util.ObjectUtils; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -77,11 +78,18 @@ public abstract class ProjectViewSelectInTarget extends SelectInTargetPsiWrapper final Runnable runnable = new Runnable() { @Override public void run() { + Runnable r = new Runnable() { + @Override + public void run() { + projectView.selectCB(toSelect, virtualFile, requestFocus).notify(result); + } + }; if (requestFocus) { - projectView.changeView(viewId, subviewId); + projectView.changeViewCB(ObjectUtils.chooseNotNull(viewId, ProjectViewPane.ID), subviewId).doWhenProcessed(r); + } + else { + r.run(); } - - projectView.selectCB(toSelect, virtualFile, requestFocus).notify(result); } }; @@ -167,4 +175,8 @@ public abstract class ProjectViewSelectInTarget extends SelectInTargetPsiWrapper public final void setSubId(String subId) { mySubId = subId; } + + public final String getSubId() { + return mySubId; + } } diff --git a/platform/lang-impl/src/com/intellij/ide/impl/SelectInTargetPsiWrapper.java b/platform/lang-impl/src/com/intellij/ide/impl/SelectInTargetPsiWrapper.java index 06f23a090e8d..234a729c29fc 100644 --- a/platform/lang-impl/src/com/intellij/ide/impl/SelectInTargetPsiWrapper.java +++ b/platform/lang-impl/src/com/intellij/ide/impl/SelectInTargetPsiWrapper.java @@ -24,6 +24,7 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.*; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; public abstract class SelectInTargetPsiWrapper implements SelectInTarget { @@ -38,12 +39,27 @@ public abstract class SelectInTargetPsiWrapper implements SelectInTarget { protected abstract boolean canSelect(PsiFileSystemItem file); @Override - public final boolean canSelect(SelectInContext context) { + public final boolean canSelect(@NotNull SelectInContext context) { + if (!isContextValid(context)) return false; + + return canWorkWithCustomObjects() || canSelectInner(context); + } + + protected boolean canSelectInner(@NotNull SelectInContext context) { + PsiFileSystemItem psiFile = getContextPsiFile(context); + return psiFile != null && canSelect(psiFile); + } + + private boolean isContextValid(SelectInContext context) { if (myProject.isDisposed()) return false; VirtualFile virtualFile = context.getVirtualFile(); - if (!virtualFile.isValid()) return false; + return virtualFile.isValid(); + } + @Nullable + protected PsiFileSystemItem getContextPsiFile(@NotNull SelectInContext context) { + VirtualFile virtualFile = context.getVirtualFile(); final Document document = FileDocumentManager.getInstance().getDocument(virtualFile); final PsiFileSystemItem psiFile; if (document != null) { @@ -58,11 +74,11 @@ public abstract class SelectInTargetPsiWrapper implements SelectInTarget { else { psiFile = PsiManager.getInstance(myProject).findFile(virtualFile); } - return psiFile != null && canSelect(psiFile) || canWorkWithCustomObjects(); + return psiFile; } @Override - public final void selectIn(SelectInContext context, final boolean requestFocus) { + public final void selectIn(@NotNull SelectInContext context, boolean requestFocus) { VirtualFile file = context.getVirtualFile(); Object selector = context.getSelectorInFile(); if (selector == null) { @@ -72,12 +88,13 @@ public abstract class SelectInTargetPsiWrapper implements SelectInTarget { if (selector instanceof PsiElement) { select(((PsiElement)selector).getOriginalElement(), requestFocus); - } else { + } + else { select(selector, file, requestFocus); } } - protected abstract void select(final Object selector, VirtualFile virtualFile, final boolean requestFocus); + protected abstract void select(Object selector, VirtualFile virtualFile, boolean requestFocus); protected abstract boolean canWorkWithCustomObjects(); diff --git a/platform/lang-impl/src/com/intellij/ide/projectView/ProjectView.java b/platform/lang-impl/src/com/intellij/ide/projectView/ProjectView.java index 63ad2741af48..493c333787a8 100644 --- a/platform/lang-impl/src/com/intellij/ide/projectView/ProjectView.java +++ b/platform/lang-impl/src/com/intellij/ide/projectView/ProjectView.java @@ -38,6 +38,9 @@ public abstract class ProjectView { @NotNull public abstract ActionCallback selectCB(Object element, VirtualFile file, boolean requestFocus); + @NotNull + public abstract ActionCallback changeViewCB(@NotNull String viewId, String subId); + @Nullable public abstract PsiElement getParentOfCurrentSelection(); diff --git a/platform/lang-impl/src/com/intellij/ide/projectView/impl/ProjectViewImpl.java b/platform/lang-impl/src/com/intellij/ide/projectView/impl/ProjectViewImpl.java index b366744126ee..6467edcd13b7 100644 --- a/platform/lang-impl/src/com/intellij/ide/projectView/impl/ProjectViewImpl.java +++ b/platform/lang-impl/src/com/intellij/ide/projectView/impl/ProjectViewImpl.java @@ -579,12 +579,15 @@ public class ProjectViewImpl extends ProjectView implements PersistentStateCompo } } }); + viewSelectionChanged(); } private void ensurePanesLoaded() { if (myExtensionsLoaded) return; myExtensionsLoaded = true; - for(AbstractProjectViewPane pane: Extensions.getExtensions(AbstractProjectViewPane.EP_NAME, myProject)) { + AbstractProjectViewPane[] extensions = Extensions.getExtensions(AbstractProjectViewPane.EP_NAME, myProject); + Arrays.sort(extensions, PANE_WEIGHT_COMPARATOR); + for(AbstractProjectViewPane pane: extensions) { if (myUninitializedPaneState.containsKey(pane.getId())) { try { pane.readExternal(myUninitializedPaneState.get(pane.getId())); @@ -897,18 +900,23 @@ public class ProjectViewImpl extends ProjectView implements PersistentStateCompo @Override public void changeView(@NotNull String viewId, @Nullable String subId) { + changeViewCB(viewId, subId); + } + + @NotNull + @Override + public ActionCallback changeViewCB(@NotNull String viewId, String subId) { AbstractProjectViewPane pane = getProjectViewPaneById(viewId); LOG.assertTrue(pane != null, "Project view pane not found: " + viewId + "; subId:" + subId); if (!viewId.equals(getCurrentViewId()) || subId != null && !subId.equals(pane.getSubId())) { for (Content content : myContentManager.getContents()) { if (viewId.equals(content.getUserData(ID_KEY)) && StringUtil.equals(subId, content.getUserData(SUB_ID_KEY))) { - myContentManager.setSelectedContent(content); - break; + return myContentManager.setSelectedContentCB(content); } } - viewSelectionChanged(); } + return ActionCallback.REJECTED; } private final class MyDeletePSIElementProvider implements DeleteProvider { diff --git a/platform/lang-impl/src/com/intellij/ide/scopeView/ScopePaneSelectInTarget.java b/platform/lang-impl/src/com/intellij/ide/scopeView/ScopePaneSelectInTarget.java index eb969af3d182..78d612f36939 100644 --- a/platform/lang-impl/src/com/intellij/ide/scopeView/ScopePaneSelectInTarget.java +++ b/platform/lang-impl/src/com/intellij/ide/scopeView/ScopePaneSelectInTarget.java @@ -21,12 +21,15 @@ import com.intellij.ide.SelectInManager; import com.intellij.ide.StandardTargetWeights; import com.intellij.ide.impl.ProjectViewSelectInTarget; import com.intellij.openapi.project.Project; -import com.intellij.openapi.vfs.VirtualFile; import com.intellij.packageDependencies.DependencyValidationManager; +import com.intellij.psi.PsiElement; import com.intellij.psi.PsiFile; import com.intellij.psi.PsiFileSystemItem; -import com.intellij.psi.search.scope.packageSet.*; -import com.intellij.util.ArrayUtil; +import com.intellij.psi.search.scope.packageSet.NamedScope; +import com.intellij.psi.search.scope.packageSet.NamedScopesHolder; +import com.intellij.psi.search.scope.packageSet.PackageSet; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; /** * @author cdr @@ -44,15 +47,29 @@ public class ScopePaneSelectInTarget extends ProjectViewSelectInTarget { public boolean canSelect(PsiFileSystemItem fileSystemItem) { if (!super.canSelect(fileSystemItem)) return false; if (!(fileSystemItem instanceof PsiFile)) return false; - PsiFile file = (PsiFile) fileSystemItem; + return getContainingScope((PsiFile)fileSystemItem) != null; + } + + @Nullable + private NamedScope getContainingScope(PsiFile file) { NamedScopesHolder scopesHolder = DependencyValidationManager.getInstance(myProject); - NamedScope[] allScopes = scopesHolder.getScopes(); - allScopes = ArrayUtil.mergeArrays(allScopes, NamedScopeManager.getInstance(myProject).getScopes()); - for (NamedScope scope : allScopes) { + for (NamedScope scope : ScopeViewPane.getShownScopes(myProject)) { PackageSet packageSet = scope.getValue(); - if (packageSet != null && packageSet.contains(file, scopesHolder)) return true; + if (packageSet != null && packageSet.contains(file, scopesHolder)) { + return scope; + } } - return false; + return null; + } + + @Override + public void select(PsiElement element, boolean requestFocus) { + if (getSubId() == null) { + NamedScope scope = getContainingScope(element.getContainingFile()); + if (scope == null) return; + setSubId(scope.getName()); + } + super.select(element, requestFocus); } @Override @@ -71,18 +88,13 @@ public class ScopePaneSelectInTarget extends ProjectViewSelectInTarget { } @Override - public boolean isSubIdSelectable(String subId, SelectInContext context) { - if (context == null) return false; + public boolean isSubIdSelectable(@NotNull String subId, @NotNull SelectInContext context) { + PsiFileSystemItem file = getContextPsiFile(context); + if (!(file instanceof PsiFile)) return false; final NamedScope scope = NamedScopesHolder.getScope(myProject, subId); - if (scope == null) return false; - PackageSet packageSet = scope.getValue(); - final VirtualFile virtualFile = context.getVirtualFile(); - if (packageSet != null) { - final NamedScopesHolder holder = NamedScopesHolder.getHolder(myProject, subId, DependencyValidationManager.getInstance(myProject)); - if (packageSet instanceof PackageSetBase ? ((PackageSetBase)packageSet).contains(virtualFile, myProject, holder) : packageSet.contains(PackageSetBase.getPsiFile(virtualFile, myProject), holder)) { - return true; - } - } - return false; + PackageSet packageSet = scope != null ? scope.getValue() : null; + if (packageSet == null) return false; + NamedScopesHolder holder = NamedScopesHolder.getHolder(myProject, subId, DependencyValidationManager.getInstance(myProject)); + return packageSet.contains((PsiFile)file, holder); } } diff --git a/platform/lang-impl/src/com/intellij/ide/scopeView/ScopeViewPane.java b/platform/lang-impl/src/com/intellij/ide/scopeView/ScopeViewPane.java index dc47793401e0..183ada37ec94 100644 --- a/platform/lang-impl/src/com/intellij/ide/scopeView/ScopeViewPane.java +++ b/platform/lang-impl/src/com/intellij/ide/scopeView/ScopeViewPane.java @@ -41,12 +41,15 @@ import com.intellij.psi.PsiManager; import com.intellij.psi.search.scope.NonProjectFilesScope; import com.intellij.psi.search.scope.packageSet.*; import com.intellij.util.Alarm; -import com.intellij.util.ArrayUtil; +import com.intellij.util.Function; +import com.intellij.util.containers.ContainerUtil; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import javax.swing.*; import javax.swing.tree.DefaultMutableTreeNode; +import java.util.Collection; +import java.util.List; /** * @author cdr @@ -135,21 +138,32 @@ public class ScopeViewPane extends AbstractProjectViewPane { @Override @NotNull public String[] getSubIds() { - NamedScope[] scopes = getShownScopes(); - String[] ids = new String[scopes.length]; - for (int i = 0; i < scopes.length; i++) { - final NamedScope scope = scopes[i]; - ids[i] = scope.getName(); - } - return ids; + return ContainerUtil.map2Array(getShownScopes(), String.class, new Function() { + @Override + public String fun(NamedScope scope) { + return scope.getName(); + } + }); } - private NamedScope[] getShownScopes() { - NamedScope[] scopes = myDependencyValidationManager.getScopes(); - scopes = ArrayUtil.mergeArrays(scopes, myNamedScopeManager.getScopes()); - scopes = NonProjectFilesScope.removeFromList(scopes); - scopes = ArrayUtil.remove(scopes, CustomScopesProviderEx.getAllScope()); - return scopes; + @NotNull + public static Collection getShownScopes(@NotNull Project project) { + return getShownScopes(DependencyValidationManager.getInstance(project), NamedScopeManager.getInstance(project)); + } + + private Collection getShownScopes() { + return getShownScopes(myDependencyValidationManager, myNamedScopeManager); + } + + @NotNull + private static Collection getShownScopes(DependencyValidationManager dependencyValidationManager, NamedScopeManager namedScopeManager) { + List list = ContainerUtil.newArrayList(); + for (NamedScope scope : ContainerUtil.concat(dependencyValidationManager.getScopes(), namedScopeManager.getScopes())) { + if (scope instanceof NonProjectFilesScope) continue; + if (scope == CustomScopesProviderEx.getAllScope()) continue; + list.add(scope); + } + return list; } @Override @@ -187,13 +201,12 @@ public class ScopeViewPane extends AbstractProjectViewPane { if (psiFile == null) return; if (!(element instanceof PsiElement)) return; - NamedScope[] allScopes = getShownScopes(); - for (int i = 0; i < allScopes.length; i++) { - final NamedScope scope = allScopes[i]; + List allScopes = ContainerUtil.newArrayList(getShownScopes()); + for (NamedScope scope : allScopes) { String name = scope.getName(); if (name.equals(getSubId())) { - allScopes[i] = allScopes[0]; - allScopes[0] = scope; + allScopes.remove(scope); + allScopes.add(0, scope); break; } }