| /* |
| * Copyright 2000-2014 JetBrains s.r.o. |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package com.intellij.ide.favoritesTreeView.actions; |
| |
| import com.intellij.ide.favoritesTreeView.FavoriteNodeProvider; |
| import com.intellij.ide.favoritesTreeView.FavoritesManager; |
| import com.intellij.ide.favoritesTreeView.FavoritesTreeViewPanel; |
| import com.intellij.ide.projectView.ProjectView; |
| import com.intellij.ide.projectView.ProjectViewNode; |
| import com.intellij.ide.projectView.ViewSettings; |
| import com.intellij.ide.projectView.impl.AbstractProjectViewPane; |
| import com.intellij.ide.projectView.impl.ModuleGroup; |
| import com.intellij.ide.projectView.impl.nodes.*; |
| import com.intellij.ide.util.treeView.AbstractTreeNode; |
| import com.intellij.openapi.actionSystem.*; |
| import com.intellij.openapi.diagnostic.Logger; |
| import com.intellij.openapi.extensions.Extensions; |
| import com.intellij.openapi.module.Module; |
| import com.intellij.openapi.project.DumbAware; |
| import com.intellij.openapi.project.Project; |
| import com.intellij.openapi.vfs.VirtualFile; |
| import com.intellij.psi.PsiDirectory; |
| import com.intellij.psi.PsiElement; |
| import com.intellij.psi.PsiFile; |
| import com.intellij.psi.PsiManager; |
| import com.intellij.psi.util.PsiTreeUtil; |
| import org.jetbrains.annotations.NotNull; |
| |
| import java.util.ArrayList; |
| import java.util.Collection; |
| import java.util.Collections; |
| |
| /** |
| * User: anna |
| * Date: Feb 15, 2005 |
| */ |
| public class AddToFavoritesAction extends AnAction implements DumbAware { |
| private static final Logger LOG = Logger.getInstance("com.intellij.ide.favoritesTreeView.actions.AddToFavoritesAction"); |
| |
| private final String myFavoritesListName; |
| |
| public AddToFavoritesAction(String choosenList) { |
| getTemplatePresentation().setText(choosenList, false); |
| myFavoritesListName = choosenList; |
| } |
| |
| @Override |
| public void actionPerformed(AnActionEvent e) { |
| final DataContext dataContext = e.getDataContext(); |
| |
| Collection<AbstractTreeNode> nodesToAdd = getNodesToAdd(dataContext, true); |
| |
| if (nodesToAdd != null && !nodesToAdd.isEmpty()) { |
| Project project = e.getData(CommonDataKeys.PROJECT); |
| FavoritesManager.getInstance(project).addRoots(myFavoritesListName, nodesToAdd); |
| } |
| } |
| |
| public static Collection<AbstractTreeNode> getNodesToAdd(final DataContext dataContext, final boolean inProjectView) { |
| Project project = CommonDataKeys.PROJECT.getData(dataContext); |
| |
| if (project == null) return Collections.emptyList(); |
| |
| Module moduleContext = LangDataKeys.MODULE_CONTEXT.getData(dataContext); |
| |
| Collection<AbstractTreeNode> nodesToAdd = null; |
| for (FavoriteNodeProvider provider : Extensions.getExtensions(FavoriteNodeProvider.EP_NAME, project)) { |
| nodesToAdd = provider.getFavoriteNodes(dataContext, ViewSettings.DEFAULT); |
| if (nodesToAdd != null) { |
| break; |
| } |
| } |
| |
| if (nodesToAdd == null) { |
| Object elements = collectSelectedElements(dataContext); |
| if (elements != null) { |
| nodesToAdd = createNodes(project, moduleContext, elements, inProjectView, ViewSettings.DEFAULT); |
| } |
| } |
| return nodesToAdd; |
| } |
| |
| @Override |
| public void update(AnActionEvent e) { |
| e.getPresentation().setEnabled(canCreateNodes(e)); |
| } |
| |
| public static boolean canCreateNodes(AnActionEvent e) { |
| DataContext dataContext = e.getDataContext(); |
| if (e.getProject() == null) { |
| return false; |
| } |
| if (e.getPlace().equals(ActionPlaces.FAVORITES_VIEW_POPUP) |
| && FavoritesTreeViewPanel.FAVORITES_LIST_NAME_DATA_KEY.getData(dataContext) == null) { |
| return false; |
| } |
| final boolean inProjectView = e.getPlace().equals(ActionPlaces.J2EE_VIEW_POPUP) || |
| e.getPlace().equals(ActionPlaces.STRUCTURE_VIEW_POPUP) || |
| e.getPlace().equals(ActionPlaces.PROJECT_VIEW_POPUP); |
| //com.intellij.openapi.actionSystem.ActionPlaces.USAGE_VIEW_TOOLBAR |
| return getNodesToAdd(dataContext, inProjectView) != null; |
| } |
| |
| static Object retrieveData(Object object, Object data) { |
| return object == null ? data : object; |
| } |
| |
| private static Object collectSelectedElements(final DataContext dataContext) { |
| Object elements = retrieveData(null, CommonDataKeys.PSI_ELEMENT.getData(dataContext)); |
| elements = retrieveData(elements, LangDataKeys.PSI_ELEMENT_ARRAY.getData(dataContext)); |
| elements = retrieveData(elements, CommonDataKeys.PSI_FILE.getData(dataContext)); |
| elements = retrieveData(elements, ModuleGroup.ARRAY_DATA_KEY.getData(dataContext)); |
| elements = retrieveData(elements, LangDataKeys.MODULE_CONTEXT_ARRAY.getData(dataContext)); |
| elements = retrieveData(elements, LibraryGroupElement.ARRAY_DATA_KEY.getData(dataContext)); |
| elements = retrieveData(elements, NamedLibraryElement.ARRAY_DATA_KEY.getData(dataContext)); |
| elements = retrieveData(elements, CommonDataKeys.VIRTUAL_FILE.getData(dataContext)); |
| elements = retrieveData(elements, CommonDataKeys.VIRTUAL_FILE_ARRAY.getData(dataContext)); |
| return elements; |
| } |
| |
| public static |
| @NotNull |
| Collection<AbstractTreeNode> createNodes(Project project, |
| Module moduleContext, |
| Object object, |
| boolean inProjectView, |
| ViewSettings favoritesConfig) { |
| if (project == null) return Collections.emptyList(); |
| ArrayList<AbstractTreeNode> result = new ArrayList<AbstractTreeNode>(); |
| for (FavoriteNodeProvider provider : Extensions.getExtensions(FavoriteNodeProvider.EP_NAME, project)) { |
| final AbstractTreeNode treeNode = provider.createNode(project, object, favoritesConfig); |
| if (treeNode != null) { |
| result.add(treeNode); |
| return result; |
| } |
| } |
| final PsiManager psiManager = PsiManager.getInstance(project); |
| |
| final String currentViewId = ProjectView.getInstance(project).getCurrentViewId(); |
| AbstractProjectViewPane pane = ProjectView.getInstance(project).getProjectViewPaneById(currentViewId); |
| |
| |
| //on psi elements |
| if (object instanceof PsiElement[]) { |
| for (PsiElement psiElement : (PsiElement[])object) { |
| addPsiElementNode(psiElement, project, result, favoritesConfig); |
| } |
| return result; |
| } |
| |
| //on psi element |
| if (object instanceof PsiElement) { |
| Module containingModule = null; |
| if (inProjectView && ProjectView.getInstance(project).isShowModules(currentViewId)) { |
| if (pane != null && pane.getSelectedDescriptor() != null && pane.getSelectedDescriptor().getElement() instanceof AbstractTreeNode) { |
| AbstractTreeNode abstractTreeNode = ((AbstractTreeNode)pane.getSelectedDescriptor().getElement()); |
| while (abstractTreeNode != null && !(abstractTreeNode.getParent() instanceof AbstractModuleNode)) { |
| abstractTreeNode = abstractTreeNode.getParent(); |
| } |
| if (abstractTreeNode != null) { |
| containingModule = ((AbstractModuleNode)abstractTreeNode.getParent()).getValue(); |
| } |
| } |
| } |
| addPsiElementNode((PsiElement)object, project, result, favoritesConfig); |
| return result; |
| } |
| |
| if (object instanceof VirtualFile[]) { |
| for (VirtualFile vFile : (VirtualFile[])object) { |
| PsiElement element = psiManager.findFile(vFile); |
| if (element == null) element = psiManager.findDirectory(vFile); |
| addPsiElementNode(element, |
| project, |
| result, |
| favoritesConfig); |
| } |
| return result; |
| } |
| |
| //on form in editor |
| if (object instanceof VirtualFile) { |
| final VirtualFile vFile = (VirtualFile)object; |
| final PsiFile psiFile = psiManager.findFile(vFile); |
| addPsiElementNode(psiFile, project, result, favoritesConfig); |
| return result; |
| } |
| |
| //on module groups |
| if (object instanceof ModuleGroup[]) { |
| for (ModuleGroup moduleGroup : (ModuleGroup[])object) { |
| result.add(new ProjectViewModuleGroupNode(project, moduleGroup, favoritesConfig)); |
| } |
| return result; |
| } |
| |
| //on module nodes |
| if (object instanceof Module) object = new Module[]{(Module)object}; |
| if (object instanceof Module[]) { |
| for (Module module1 : (Module[])object) { |
| result.add(new ProjectViewModuleNode(project, module1, favoritesConfig)); |
| } |
| return result; |
| } |
| |
| //on library group node |
| if (object instanceof LibraryGroupElement[]) { |
| for (LibraryGroupElement libraryGroup : (LibraryGroupElement[])object) { |
| result.add(new LibraryGroupNode(project, libraryGroup, favoritesConfig)); |
| } |
| return result; |
| } |
| |
| //on named library node |
| if (object instanceof NamedLibraryElement[]) { |
| for (NamedLibraryElement namedLibrary : (NamedLibraryElement[])object) { |
| result.add(new NamedLibraryElementNode(project, namedLibrary, favoritesConfig)); |
| } |
| return result; |
| } |
| return result; |
| } |
| |
| private static void addPsiElementNode(PsiElement psiElement, |
| final Project project, |
| final ArrayList<AbstractTreeNode> result, |
| final ViewSettings favoritesConfig) { |
| |
| Class<? extends AbstractTreeNode> klass = getPsiElementNodeClass(psiElement); |
| if (klass == null) { |
| psiElement = PsiTreeUtil.getParentOfType(psiElement, PsiFile.class); |
| if (psiElement != null) { |
| klass = PsiFileNode.class; |
| } |
| } |
| |
| final Object value = psiElement; |
| try { |
| if (klass != null && value != null) { |
| result.add(ProjectViewNode.createTreeNode(klass, project, value, favoritesConfig)); |
| } |
| } |
| catch (Exception e) { |
| LOG.error(e); |
| } |
| } |
| |
| |
| private static Class<? extends AbstractTreeNode> getPsiElementNodeClass(PsiElement psiElement) { |
| Class<? extends AbstractTreeNode> klass = null; |
| if (psiElement instanceof PsiFile) { |
| klass = PsiFileNode.class; |
| } |
| else if (psiElement instanceof PsiDirectory) { |
| klass = PsiDirectoryNode.class; |
| } |
| return klass; |
| } |
| } |