blob: ac2326da6dac8d9c6bc8ed6aa3122c64b9b4b55f [file] [log] [blame]
/*
* Copyright 2000-2010 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.projectView.actions;
import com.intellij.ide.projectView.impl.ProjectRootsUtil;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.CommonDataKeys;
import com.intellij.openapi.actionSystem.LangDataKeys;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.project.DumbAwareAction;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.*;
import com.intellij.openapi.roots.impl.DirectoryIndex;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.vfs.VfsUtilCore;
import com.intellij.openapi.vfs.VirtualFile;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.List;
/**
* @author yole
*/
public abstract class MarkRootActionBase extends DumbAwareAction {
@Override
public void actionPerformed(AnActionEvent e) {
VirtualFile[] files = e.getData(CommonDataKeys.VIRTUAL_FILE_ARRAY);
final Module module = getModule(e, files);
if (module == null) {
return;
}
final ModifiableRootModel model = ModuleRootManager.getInstance(module).getModifiableModel();
for (VirtualFile file : files) {
ContentEntry entry = findContentEntry(model, file);
if (entry != null) {
final SourceFolder[] sourceFolders = entry.getSourceFolders();
for (SourceFolder sourceFolder : sourceFolders) {
if (Comparing.equal(sourceFolder.getFile(), file)) {
entry.removeSourceFolder(sourceFolder);
break;
}
}
modifyRoots(file, entry);
}
}
ApplicationManager.getApplication().runWriteAction(new Runnable() {
@Override
public void run() {
model.commit();
module.getProject().save();
}
});
}
protected abstract void modifyRoots(VirtualFile file, ContentEntry entry);
@Nullable
public static ContentEntry findContentEntry(@NotNull ModuleRootModel model, @NotNull VirtualFile vFile) {
final ContentEntry[] contentEntries = model.getContentEntries();
for (ContentEntry contentEntry : contentEntries) {
final VirtualFile contentEntryFile = contentEntry.getFile();
if (contentEntryFile != null && VfsUtilCore.isAncestor(contentEntryFile, vFile, false)) {
return contentEntry;
}
}
return null;
}
@Override
public void update(AnActionEvent e) {
RootsSelection selection = getSelection(e);
doUpdate(e, e.getData(LangDataKeys.MODULE), selection);
}
protected void doUpdate(@NotNull AnActionEvent e, @Nullable Module module, @NotNull RootsSelection selection) {
boolean enabled = module != null && (!selection.mySelectedRoots.isEmpty() || !selection.mySelectedDirectories.isEmpty())
&& selection.mySelectedExcludeRoots.isEmpty() && isEnabled(selection, module);
e.getPresentation().setEnabledAndVisible(enabled);
}
protected abstract boolean isEnabled(@NotNull RootsSelection selection, @NotNull Module module);
protected static RootsSelection getSelection(AnActionEvent e) {
VirtualFile[] files = e.getData(CommonDataKeys.VIRTUAL_FILE_ARRAY);
Module module = getModule(e, files);
if (module == null) return RootsSelection.EMPTY;
RootsSelection selection = new RootsSelection();
final ProjectFileIndex fileIndex = ProjectRootManager.getInstance(module.getProject()).getFileIndex();
for (VirtualFile file : files) {
if (!file.isDirectory()) {
return RootsSelection.EMPTY;
}
if (!fileIndex.isInContent(file)) {
ExcludeFolder excludeFolder = ProjectRootsUtil.findExcludeFolder(module, file);
if (excludeFolder != null) {
selection.mySelectedExcludeRoots.add(excludeFolder);
continue;
}
else {
return RootsSelection.EMPTY;
}
}
SourceFolder folder;
if (Comparing.equal(fileIndex.getSourceRootForFile(file), file) && ((folder = ProjectRootsUtil.findSourceFolder(module, file)) != null)) {
selection.mySelectedRoots.add(folder);
}
else {
selection.mySelectedDirectories.add(file);
if (fileIndex.isInSourceContent(file)) {
selection.myHaveSelectedFilesUnderSourceRoots = true;
}
}
}
return selection;
}
@Nullable
private static Module getModule(@NotNull AnActionEvent e, @Nullable VirtualFile[] files) {
if (files == null) return null;
Module module = e.getData(LangDataKeys.MODULE);
if (module == null) {
module = findParentModule(e.getProject(), files);
}
return module;
}
@Nullable
private static Module findParentModule(@Nullable Project project, @NotNull VirtualFile[] files) {
if (project == null) return null;
Module result = null;
DirectoryIndex index = DirectoryIndex.getInstance(project);
for (VirtualFile file : files) {
Module module = index.getInfoForFile(file).getModule();
if (module == null) return null;
if (result == null) {
result = module;
}
else if (!result.equals(module)) {
return null;
}
}
return result;
}
protected static class RootsSelection {
public static final RootsSelection EMPTY = new RootsSelection();
public List<SourceFolder> mySelectedRoots = new ArrayList<SourceFolder>();
public List<ExcludeFolder> mySelectedExcludeRoots = new ArrayList<ExcludeFolder>();
public List<VirtualFile> mySelectedDirectories = new ArrayList<VirtualFile>();
public boolean myHaveSelectedFilesUnderSourceRoots;
}
}