c03d3921e67039149deb5fc302ada02d23801e62
[idea/community.git] / platform / lang-impl / src / com / intellij / ide / projectView / actions / MarkRootAction.java
1 /*
2  * Copyright 2000-2010 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 package com.intellij.ide.projectView.actions;
17
18 import com.intellij.openapi.actionSystem.AnAction;
19 import com.intellij.openapi.actionSystem.AnActionEvent;
20 import com.intellij.openapi.actionSystem.LangDataKeys;
21 import com.intellij.openapi.actionSystem.PlatformDataKeys;
22 import com.intellij.openapi.application.ApplicationManager;
23 import com.intellij.openapi.module.Module;
24 import com.intellij.openapi.roots.*;
25 import com.intellij.openapi.util.Ref;
26 import com.intellij.openapi.vfs.VfsUtil;
27 import com.intellij.openapi.vfs.VirtualFile;
28 import org.jetbrains.annotations.Nullable;
29
30 /**
31  * @author yole
32  */
33 public class MarkRootAction extends AnAction {
34   private final boolean myMarkAsTestSources;
35   private final boolean myMarkAsExcluded;
36   private final boolean myUnmark;
37
38   public MarkRootAction() {
39     myMarkAsTestSources = false;
40     myMarkAsExcluded = false;
41     myUnmark = false;
42   }
43
44   protected MarkRootAction(boolean markAsTestSources, boolean markAsExcluded) {
45     myMarkAsTestSources = markAsTestSources;
46     myMarkAsExcluded = markAsExcluded;
47     myUnmark = false;
48   }
49
50   protected MarkRootAction(boolean unmark) {
51     myMarkAsTestSources = false;
52     myMarkAsExcluded = false;
53     myUnmark = true;
54   }
55
56   @Override
57   public void actionPerformed(AnActionEvent e) {
58     Module module = e.getData(LangDataKeys.MODULE);
59     VirtualFile[] vFiles = e.getData(PlatformDataKeys.VIRTUAL_FILE_ARRAY);
60     assert vFiles != null;
61     final ModifiableRootModel model = ModuleRootManager.getInstance(module).getModifiableModel();
62     for (VirtualFile vFile : vFiles) {
63       ContentEntry entry = findContentEntry(model, vFile);
64       if (entry != null) {
65         final SourceFolder[] sourceFolders = entry.getSourceFolders();
66         for (SourceFolder sourceFolder : sourceFolders) {
67           if (sourceFolder.getFile() == vFile) {
68             entry.removeSourceFolder(sourceFolder);
69             break;
70           }
71         }
72         if (!myUnmark) {
73           if (myMarkAsExcluded) {
74             entry.addExcludeFolder(vFile);
75           }
76           else {
77             entry.addSourceFolder(vFile, myMarkAsTestSources);
78           }
79         }
80       }
81     }
82     ApplicationManager.getApplication().runWriteAction(new Runnable() {
83       @Override
84       public void run() {
85         model.commit();
86       }
87     });
88   }
89
90   @Nullable
91   private static ContentEntry findContentEntry(ModifiableRootModel model, VirtualFile vFile) {
92     final ContentEntry[] contentEntries = model.getContentEntries();
93     for (ContentEntry contentEntry : contentEntries) {
94       final VirtualFile contentEntryFile = contentEntry.getFile();
95       if (contentEntryFile != null && VfsUtil.isAncestor(contentEntryFile, vFile, false)) {
96         return contentEntry;
97       }
98     }
99     return null;
100   }
101
102   @Override
103   public void update(AnActionEvent e) {
104     boolean enabled = canMark(e, myMarkAsTestSources || myMarkAsExcluded || myUnmark, !myMarkAsTestSources || myMarkAsExcluded || myUnmark, null);
105     e.getPresentation().setVisible(enabled);
106     e.getPresentation().setEnabled(enabled);
107   }
108
109   public static boolean canMark(AnActionEvent e, boolean acceptSourceRoot, boolean acceptTestSourceRoot, Ref<Boolean> rootType) {
110     Module module = e.getData(LangDataKeys.MODULE);
111     VirtualFile[] vFiles = e.getData(PlatformDataKeys.VIRTUAL_FILE_ARRAY);
112     if (module == null || vFiles == null) {
113       return false;
114     }
115     final ProjectFileIndex fileIndex = ProjectRootManager.getInstance(module.getProject()).getFileIndex();
116     for (VirtualFile vFile : vFiles) {
117       if (!vFile.isDirectory()) {
118         return false;
119       }
120       if (!fileIndex.isInContent(vFile)) {
121         return false;
122       }
123       if (fileIndex.getSourceRootForFile(vFile) == vFile) {
124         boolean isTestSourceRoot = fileIndex.isInTestSourceContent(vFile);
125         if (acceptSourceRoot && !isTestSourceRoot) {
126           if (rootType != null) rootType.set(true);
127           return true;
128         }
129         if (acceptTestSourceRoot && isTestSourceRoot) {
130           if (rootType != null) rootType.set(false);
131           return true;
132         }
133       }
134       if (fileIndex.isInSourceContent(vFile)) {
135         return false;
136       }
137     }
138     return true;
139   }
140 }