package org.jetbrains.plugins.clojure.actions;
import com.intellij.CommonBundle;
import com.intellij.facet.FacetManager;
import com.intellij.ide.IdeView;
import com.intellij.ide.actions.CreateElementActionBase;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.DataContext;
import com.intellij.openapi.actionSystem.DataKeys;
import com.intellij.openapi.actionSystem.Presentation;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.ProjectFileIndex;
import com.intellij.openapi.roots.ProjectRootManager;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.*;
import com.intellij.util.IncorrectOperationException;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.plugins.clojure.utils.ClojureUtils;
import org.jetbrains.plugins.clojure.utils.ClojureNamesUtil;
import org.jetbrains.plugins.clojure.ClojureBundle;
import org.jetbrains.plugins.clojure.config.ClojureFacetType;
import org.jetbrains.plugins.clojure.config.ClojureFacet;
import javax.swing.*;
/**
* @author ilyas
*/
public abstract class NewClojureActionBase extends CreateElementActionBase {
@NonNls
private static final String CLOJURE_EXTENSION = ".clj";
public NewClojureActionBase(String text, String description, Icon icon) {
super(text, description, icon);
}
@NotNull
protected final PsiElement[] invokeDialog(final Project project, final PsiDirectory directory) {
MyInputValidator validator = new MyInputValidator(project, directory);
Messages.showInputDialog(project, getDialogPrompt(), getDialogTitle(), Messages.getQuestionIcon(), "", validator);
return validator.getCreatedElements();
}
protected abstract String getDialogPrompt();
protected abstract String getDialogTitle();
public void update(final AnActionEvent event) {
super.update(event);
final Presentation presentation = event.getPresentation();
final DataContext context = event.getDataContext();
Module module = (Module) context.getData(DataKeys.MODULE.getName());
if (module == null) {
presentation.setEnabled(false);
presentation.setVisible(false);
return;
}
final FacetManager manager = FacetManager.getInstance(module);
final ClojureFacet facet = manager.getFacetByType(ClojureFacetType.INSTANCE.getId());
if (facet == null ||
!ClojureUtils.isSuitableModule(module) ||
!presentation.isEnabled() ||
!isUnderSourceRoots(event)) {
presentation.setEnabled(false);
presentation.setVisible(false);
} else {
presentation.setEnabled(true);
presentation.setVisible(true);
}
}
public static boolean isUnderSourceRoots(final AnActionEvent e) {
final DataContext context = e.getDataContext();
Module module = (Module) context.getData(DataKeys.MODULE.getName());
if (!ClojureUtils.isSuitableModule(module)) {
return false;
}
final IdeView view = (IdeView) context.getData(DataKeys.IDE_VIEW.getName());
final Project project = (Project) context.getData(DataKeys.PROJECT.getName());
if (view != null && project != null) {
ProjectFileIndex projectFileIndex = ProjectRootManager.getInstance(project).getFileIndex();
PsiDirectory[] dirs = view.getDirectories();
for (PsiDirectory dir : dirs) {
PsiPackage aPackage = JavaDirectoryService.getInstance().getPackage(dir);
if (projectFileIndex.isInSourceContent(dir.getVirtualFile()) && aPackage != null) {
return true;
}
}
}
return false;
}
@NotNull
protected PsiElement[] create(String newName, PsiDirectory directory) throws Exception {
return doCreate(newName, directory);
}
@NotNull
protected abstract PsiElement[] doCreate(String newName, PsiDirectory directory) throws Exception;
protected static PsiFile createFileFromTemplate(final PsiDirectory directory, String className, @NonNls String templateName,
@NonNls String... parameters) throws IncorrectOperationException {
final String name = StringUtil.trimEnd(className, CLOJURE_EXTENSION);
return ClojureTemplatesFactory.createFromTemplate(directory, name, name + CLOJURE_EXTENSION, templateName, parameters);
}
protected String getErrorTitle() {
return CommonBundle.getErrorTitle();
}
protected void checkBeforeCreate(String newName, PsiDirectory directory) throws IncorrectOperationException {
checkCreateFile(directory, newName);
}
public static void checkCreateFile(@NotNull PsiDirectory directory, String name) throws IncorrectOperationException {
final String trimmedName = StringUtil.trimEnd(name, CLOJURE_EXTENSION);
if (!ClojureNamesUtil.isIdentifier(trimmedName)) {
throw new IncorrectOperationException(ClojureBundle.message("0.is.not.an.identifier", name));
}
String fileName = trimmedName + "." + CLOJURE_EXTENSION;
directory.checkCreateFile(fileName);
PsiNameHelper helper = JavaPsiFacade.getInstance(directory.getProject()).getNameHelper();
PsiPackage aPackage = JavaDirectoryService.getInstance().getPackage(directory);
String qualifiedName = aPackage == null ? null : aPackage.getQualifiedName();
if (!StringUtil.isEmpty(qualifiedName) && !helper.isQualifiedName(qualifiedName)) {
throw new IncorrectOperationException("Cannot create class in invalid package: '" + qualifiedName + "'");
}
}
}