2ed96628b1f57355be28f91ca6357282515ed0fb
[idea/community.git] / platform / lang-impl / src / com / intellij / ide / impl / ProjectViewSelectInTarget.java
1 /*
2  * Copyright 2000-2014 JetBrains s.r.o.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 package com.intellij.ide.impl;
18
19 import com.intellij.ide.CompositeSelectInTarget;
20 import com.intellij.ide.SelectInContext;
21 import com.intellij.ide.SelectInTarget;
22 import com.intellij.ide.projectView.ProjectView;
23 import com.intellij.ide.projectView.SelectableTreeStructureProvider;
24 import com.intellij.ide.projectView.TreeStructureProvider;
25 import com.intellij.ide.projectView.impl.AbstractProjectViewPane;
26 import com.intellij.ide.projectView.impl.ProjectViewPane;
27 import com.intellij.openapi.application.ApplicationManager;
28 import com.intellij.openapi.extensions.Extensions;
29 import com.intellij.openapi.project.DumbService;
30 import com.intellij.openapi.project.Project;
31 import com.intellij.openapi.util.ActionCallback;
32 import com.intellij.openapi.vfs.VirtualFile;
33 import com.intellij.openapi.wm.ToolWindow;
34 import com.intellij.openapi.wm.ToolWindowId;
35 import com.intellij.openapi.wm.ToolWindowManager;
36 import com.intellij.psi.*;
37 import com.intellij.psi.util.PsiUtilBase;
38 import com.intellij.util.ObjectUtils;
39 import org.jetbrains.annotations.NotNull;
40 import org.jetbrains.annotations.Nullable;
41
42 import java.util.ArrayList;
43 import java.util.Arrays;
44 import java.util.Collection;
45 import java.util.List;
46
47 public abstract class ProjectViewSelectInTarget extends SelectInTargetPsiWrapper implements CompositeSelectInTarget {
48   private String mySubId;
49
50   protected ProjectViewSelectInTarget(Project project) {
51     super(project);
52   }
53
54   @Override
55   protected final void select(final Object selector, final VirtualFile virtualFile, final boolean requestFocus) {
56     select(myProject, selector, getMinorViewId(), mySubId, virtualFile, requestFocus);
57   }
58
59   @NotNull
60   public static ActionCallback select(@NotNull Project project,
61                                       final Object toSelect,
62                                       @Nullable final String viewId,
63                                       @Nullable final String subviewId,
64                                       final VirtualFile virtualFile,
65                                       final boolean requestFocus) {
66     final ActionCallback result = new ActionCallback();
67
68
69     final ProjectView projectView = ProjectView.getInstance(project);
70     if (ApplicationManager.getApplication().isUnitTestMode()) {
71       AbstractProjectViewPane pane = projectView.getProjectViewPaneById(ProjectViewPane.ID);
72       pane.select(toSelect, virtualFile, requestFocus);
73       return result;
74     }
75
76     ToolWindowManager windowManager = ToolWindowManager.getInstance(project);
77     final ToolWindow projectViewToolWindow = windowManager.getToolWindow(ToolWindowId.PROJECT_VIEW);
78     final Runnable runnable = new Runnable() {
79       @Override
80       public void run() {
81         Runnable r = new Runnable() {
82           @Override
83           public void run() {
84             projectView.selectCB(toSelect, virtualFile, requestFocus).notify(result);
85           }
86         };
87         if (requestFocus) {
88           projectView.changeViewCB(ObjectUtils.chooseNotNull(viewId, ProjectViewPane.ID), subviewId).doWhenProcessed(r);
89         }
90         else {
91           r.run();
92         }
93       }
94     };
95
96     if (requestFocus) {
97       projectViewToolWindow.activate(runnable, false);
98     }
99     else {
100       projectViewToolWindow.show(runnable);
101     }
102
103     return result;
104   }
105
106
107   @Override
108   @NotNull
109   public Collection<SelectInTarget> getSubTargets(@NotNull SelectInContext context) {
110     List<SelectInTarget> result = new ArrayList<SelectInTarget>();
111     AbstractProjectViewPane pane = ProjectView.getInstance(myProject).getProjectViewPaneById(getMinorViewId());
112     int index = 0;
113     for (String subId : pane.getSubIds()) {
114       result.add(new ProjectSubViewSelectInTarget(this, subId, index++));
115     }
116     return result;
117   }
118
119   public boolean isSubIdSelectable(String subId, SelectInContext context) {
120     return false;
121   }
122
123   @Override
124   protected boolean canSelect(PsiFileSystemItem file) {
125     return true;
126   }
127
128   public String getSubIdPresentableName(String subId) {
129     AbstractProjectViewPane pane = ProjectView.getInstance(myProject).getProjectViewPaneById(getMinorViewId());
130     return pane.getPresentableSubIdName(subId);
131   }
132
133   @Override
134   public void select(PsiElement element, final boolean requestFocus) {
135     PsiElement toSelect = null;
136     for (TreeStructureProvider provider : getProvidersDumbAware()) {
137       if (provider instanceof SelectableTreeStructureProvider) {
138         toSelect = ((SelectableTreeStructureProvider) provider).getTopLevelElement(element);
139       }
140       if (toSelect != null) break;
141     }
142     if (toSelect == null) {
143       if (element instanceof PsiFile || element instanceof PsiDirectory) {
144         toSelect = element;
145       }
146       else {
147         final PsiFile containingFile = element.getContainingFile();
148         if (containingFile == null) return;
149         final FileViewProvider viewProvider = containingFile.getViewProvider();
150         toSelect = viewProvider.getPsi(viewProvider.getBaseLanguage());
151       }
152     }
153     if (toSelect == null) return;
154     PsiElement originalElement = toSelect.getOriginalElement();
155     final VirtualFile virtualFile = PsiUtilBase.getVirtualFile(originalElement);
156     select(originalElement, virtualFile, requestFocus);
157   }
158
159   private TreeStructureProvider[] getProvidersDumbAware() {
160     List<TreeStructureProvider> allProviders = Arrays.asList(Extensions.getExtensions(TreeStructureProvider.EP_NAME, myProject));
161     List<TreeStructureProvider> dumbAware = DumbService.getInstance(myProject).filterByDumbAwareness(allProviders);
162     return dumbAware.toArray(new TreeStructureProvider[dumbAware.size()]);
163   }
164
165   @Override
166   public final String getToolWindowId() {
167     return ToolWindowId.PROJECT_VIEW;
168   }
169
170   @Override
171   protected boolean canWorkWithCustomObjects() {
172     return true;
173   }
174
175   public final void setSubId(String subId) {
176     mySubId = subId;
177   }
178
179   public final String getSubId() {
180     return mySubId;
181   }
182 }