blob: 38411d1bddae5bab641cc258b8ad0781a789fb45 [file] [log] [blame]
/*
* 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;
}
}