Another implementation of WI-450: "Mark as Plain Text" action.

This commit is contained in:
Rustam.Vishnyakov
2011-04-05 14:05:30 +04:00
parent 38981dba65
commit 2a205469d9
11 changed files with 453 additions and 62 deletions
@@ -0,0 +1,109 @@
/*
* Copyright 2000-2011 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.openapi.file.exclude;
import com.intellij.openapi.fileTypes.FileTypeConsumer;
import com.intellij.openapi.fileTypes.FileTypeFactory;
import com.intellij.openapi.fileTypes.ex.FileTypeIdentifiableByVirtualFile;
import com.intellij.openapi.util.IconLoader;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.ui.LayeredIcon;
import com.intellij.util.Icons;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
/**
* Registers text file type for particular virtual files rather than using .txt extension.
* @author Rustam Vishnyakov
*/
public class EnforcedPlainTextFileTypeFactory extends FileTypeFactory {
public static final LayeredIcon ENFORCED_PLAIN_TEXT_ICON = new LayeredIcon(2);
static {
ENFORCED_PLAIN_TEXT_ICON.setIcon(IconLoader.getIcon("/fileTypes/text.png"), 0);
ENFORCED_PLAIN_TEXT_ICON.setIcon(Icons.EXCLUDED_FROM_COMPILE_ICON, 1);
}
private final FileTypeIdentifiableByVirtualFile myFileType;
public EnforcedPlainTextFileTypeFactory() {
myFileType = new FileTypeIdentifiableByVirtualFile() {
@Override
public boolean isMyFileType(VirtualFile file) {
if (isMarkedAsPlainText(file)) {
return true;
}
return false;
}
@NotNull
@Override
public String getName() {
return "Enforced Plain Text";
}
@NotNull
@Override
public String getDescription() {
return "Enforced Plain Text";
}
@NotNull
@Override
public String getDefaultExtension() {
return "fakeTxt";
}
@Override
public Icon getIcon() {
return ENFORCED_PLAIN_TEXT_ICON;
}
@Override
public boolean isBinary() {
return false;
}
@Override
public boolean isReadOnly() {
return true;
}
@Override
public String getCharset(@NotNull VirtualFile file, byte[] content) {
return null;
}
};
}
public void createFileTypes(final @NotNull FileTypeConsumer consumer) {
consumer.consume(myFileType, "");
}
private static boolean isMarkedAsPlainText(VirtualFile file) {
EnforcedPlainTextFileTypeManager typeManager = EnforcedPlainTextFileTypeManager.getInstance();
if (typeManager == null) return false;
return typeManager.isMarkedAsPlainText(file);
}
}
@@ -0,0 +1,67 @@
/*
* Copyright 2000-2011 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.openapi.file.exclude;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.components.State;
import com.intellij.openapi.components.Storage;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.project.ProjectManager;
import com.intellij.openapi.roots.ex.ProjectRootManagerEx;
import com.intellij.openapi.util.EmptyRunnable;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.indexing.FileBasedIndex;
/**
* @author Rustam Vishnyakov
*/
@State(name = "EnforcedPlainTextFileTypeManager", storages = {@Storage(id = "default", file = "$APP_CONFIG$/plainTextFiles.xml")})
public class EnforcedPlainTextFileTypeManager extends PersistentFileSetManager {
public boolean isMarkedAsPlainText(VirtualFile file) {
return containsFile(file);
}
public void markAsPlainText(VirtualFile file) {
if (addFile(file)) {
updateIndex(file);
}
}
public void unmarkPlainText(VirtualFile file) {
if (removeFile(file)) {
updateIndex(file);
}
}
private static void updateIndex(VirtualFile file) {
FileBasedIndex.getInstance().requestReindex(file);
ApplicationManager.getApplication().runWriteAction(new Runnable() {
@Override
public void run() {
for (Project project : ProjectManager.getInstance().getOpenProjects()) {
ProjectRootManagerEx.getInstanceEx(project).makeRootsChange(EmptyRunnable.getInstance(), false, true);
}
}
});
}
public static EnforcedPlainTextFileTypeManager getInstance() {
return ServiceManager.getService(EnforcedPlainTextFileTypeManager.class);
}
}
@@ -0,0 +1,98 @@
/*
* Copyright 2000-2011 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.openapi.file.exclude;
import com.intellij.openapi.components.PersistentStateComponent;
import com.intellij.openapi.vfs.VfsUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.VirtualFileManager;
import com.intellij.util.containers.HashSet;
import org.jdom.Attribute;
import org.jdom.Element;
import java.util.*;
/**
* @author Rustam Vishnyakov
*/
public class PersistentFileSetManager implements PersistentStateComponent<Element> {
private final static String FILE_ELEMENT = "file";
private final static String PATH_ATTR = "url";
private final Set<VirtualFile> myFiles = new HashSet<VirtualFile>();
protected boolean addFile(VirtualFile file) {
if (file.isDirectory()) return false;
myFiles.add(file);
return true;
}
protected boolean containsFile(VirtualFile file) {
return myFiles.contains(file);
}
protected boolean removeFile(VirtualFile file) {
if (!myFiles.contains(file)) return false;
myFiles.remove(file);
return true;
}
public Collection<VirtualFile> getFiles() {
return myFiles;
}
public Collection<VirtualFile> getSortedFiles() {
List<VirtualFile> sortedFiles = new ArrayList<VirtualFile>();
sortedFiles.addAll(myFiles);
Collections.sort(sortedFiles, new Comparator<VirtualFile>() {
public int compare(final VirtualFile file1, final VirtualFile file2) {
return file1.getPath().toLowerCase().compareTo(file2.getPath().toLowerCase());
}
});
return sortedFiles;
}
@Override
public Element getState() {
final Element root = new Element("root");
for (VirtualFile vf : getSortedFiles()) {
final Element vfElement = new Element(FILE_ELEMENT);
final Attribute filePathAttr = new Attribute(PATH_ATTR, VfsUtil.pathToUrl(vf.getPath()));
vfElement.setAttribute(filePathAttr);
root.addContent(vfElement);
}
return root;
}
@Override
public void loadState(Element state) {
final VirtualFileManager vfManager = VirtualFileManager.getInstance();
for (Object child : state.getChildren(FILE_ELEMENT)) {
if (child instanceof Element) {
final Element fileElement = (Element)child;
final Attribute filePathAttr = fileElement.getAttribute(PATH_ATTR);
if (filePathAttr != null) {
final String filePath = filePathAttr.getValue();
VirtualFile vf = vfManager.findFileByUrl(filePath);
if (vf != null) {
myFiles.add(vf);
}
}
}
}
}
}
@@ -16,21 +16,14 @@
package com.intellij.openapi.file.exclude;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.components.PersistentStateComponent;
import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.components.State;
import com.intellij.openapi.components.Storage;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.ex.ProjectRootManagerEx;
import com.intellij.openapi.util.EmptyRunnable;
import com.intellij.openapi.vfs.VfsUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.VirtualFileManager;
import com.intellij.util.containers.HashSet;
import com.intellij.util.indexing.FileBasedIndex;
import org.jdom.Attribute;
import org.jdom.Element;
import org.jetbrains.annotations.NotNull;
import java.util.*;
@@ -39,12 +32,9 @@ import java.util.*;
* @author Rustam Vishnyakov
*/
@State(name = "ProjectFileExclusionManager", storages = {@Storage(id = "default", file = "$PROJECT_FILE$")})
public class ProjectFileExclusionManager implements PersistentStateComponent<Element> {
public class ProjectFileExclusionManager extends PersistentFileSetManager {
private final static String FILE_ELEMENT = "file";
private final static String PATH_ATTR = "url";
private final Set<VirtualFile> myExcludedFiles = new HashSet<VirtualFile>();
private final Project myProject;
public ProjectFileExclusionManager(Project project) {
@@ -52,15 +42,14 @@ public class ProjectFileExclusionManager implements PersistentStateComponent<Ele
}
public void addExclusion(VirtualFile file) {
if (file.isDirectory()) return;
myExcludedFiles.add(file);
FileBasedIndex.getInstance().requestReindexExcluded(file);
fireRootsChange(myProject);
if (addFile(file)) {
FileBasedIndex.getInstance().requestReindexExcluded(file);
fireRootsChange(myProject);
}
}
public void removeExclusion(VirtualFile file) {
if (myExcludedFiles.contains(file)) {
myExcludedFiles.remove(file);
if (removeFile(file)) {
FileBasedIndex.getInstance().requestReindex(file);
fireRootsChange(myProject);
}
@@ -76,53 +65,13 @@ public class ProjectFileExclusionManager implements PersistentStateComponent<Ele
}
public boolean isExcluded(VirtualFile file) {
return false; //myExcludedFiles.contains(file);
return containsFile(file);
}
public Collection<VirtualFile> getExcludedFiles() {
return myExcludedFiles;
return getFiles();
}
public Collection<VirtualFile> getSortedExcludedFiles() {
List<VirtualFile> excludedFiles = new ArrayList<VirtualFile>();
excludedFiles.addAll(myExcludedFiles);
Collections.sort(excludedFiles, new Comparator<VirtualFile>() {
public int compare(final VirtualFile file1, final VirtualFile file2) {
return file1.getPath().toLowerCase().compareTo(file2.getPath().toLowerCase());
}
});
return excludedFiles;
}
@Override
public Element getState() {
final Element root = new Element("root");
for (VirtualFile vf : getSortedExcludedFiles()) {
final Element vfElement = new Element(FILE_ELEMENT);
final Attribute filePathAttr = new Attribute(PATH_ATTR, VfsUtil.pathToUrl(vf.getPath()));
vfElement.setAttribute(filePathAttr);
root.addContent(vfElement);
}
return root;
}
@Override
public void loadState(Element state) {
final VirtualFileManager vfManager = VirtualFileManager.getInstance();
for (Object child : state.getChildren(FILE_ELEMENT)) {
if (child instanceof Element) {
final Element fileElement = (Element)child;
final Attribute filePathAttr = fileElement.getAttribute(PATH_ATTR);
if (filePathAttr != null) {
final String filePath = filePathAttr.getValue();
VirtualFile vf = vfManager.findFileByUrl(filePath);
if (vf != null) {
myExcludedFiles.add(vf);
}
}
}
}
}
public static ProjectFileExclusionManager getInstance(@NotNull Project project) {
return ServiceManager.getService(project, ProjectFileExclusionManager.class);
@@ -38,7 +38,7 @@ public class ExcludedFilesConfigurable implements SearchableConfigurable {
public ExcludedFilesConfigurable(Project project) {
myExclusionManager = ProjectFileExclusionManager.getInstance(project);
myExcludedFilesPanel = new ExcludedFilesPanel(myExclusionManager != null ? myExclusionManager.getSortedExcludedFiles() : null);
myExcludedFilesPanel = new ExcludedFilesPanel(myExclusionManager != null ? myExclusionManager.getSortedFiles() : null);
}
@NotNull
@@ -104,7 +104,7 @@ public class ExcludedFilesConfigurable implements SearchableConfigurable {
@Override
public void reset() {
myExcludedFilesPanel.resetFiles(myExclusionManager != null ? myExclusionManager.getSortedExcludedFiles() : null);
myExcludedFilesPanel.resetFiles(myExclusionManager != null ? myExclusionManager.getSortedFiles() : null);
}
@Override
@@ -0,0 +1,64 @@
/*
* Copyright 2000-2011 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.openapi.file.exclude.ui;
import com.intellij.idea.ActionsBundle;
import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.file.exclude.EnforcedPlainTextFileTypeManager;
import com.intellij.openapi.fileTypes.FileType;
import com.intellij.openapi.fileTypes.FileTypeManager;
import com.intellij.openapi.vfs.VirtualFile;
import org.jetbrains.annotations.NotNull;
/**
* @author Rustam Vishnyakov
*/
public class MarkAsOriginalTypeAction extends AnAction {
@Override
public void actionPerformed(AnActionEvent e) {
DataContext dataContext = e.getDataContext();
final VirtualFile file = PlatformDataKeys.VIRTUAL_FILE.getData(dataContext);
if (file == null || file.isDirectory()) return;
unmarkPlainText(file);
}
private static void unmarkPlainText(@NotNull VirtualFile file) {
EnforcedPlainTextFileTypeManager typeManager = EnforcedPlainTextFileTypeManager.getInstance();
if (typeManager != null) typeManager.unmarkPlainText(file);
}
@Override
public void update(AnActionEvent e) {
DataContext dataContext = e.getDataContext();
final VirtualFile file = PlatformDataKeys.VIRTUAL_FILE.getData(dataContext);
final Presentation presentation = e.getPresentation();
final EnforcedPlainTextFileTypeManager typeManager = EnforcedPlainTextFileTypeManager.getInstance();
if (typeManager == null || file == null || file.isDirectory()) {
presentation.setVisible(false);
return;
}
if (typeManager.isMarkedAsPlainText(file)) {
presentation.setVisible(true);
FileType originalType = FileTypeManager.getInstance().getFileTypeByFileName(file.getName());
presentation.setText(ActionsBundle.actionText("MarkAsOriginalTypeAction") + " " + originalType.getName());
presentation.setIcon(originalType.getIcon());
}
else {
presentation.setVisible(false);
}
}
}
@@ -0,0 +1,62 @@
/*
* Copyright 2000-2011 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.openapi.file.exclude.ui;
import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.file.exclude.EnforcedPlainTextFileTypeFactory;
import com.intellij.openapi.file.exclude.EnforcedPlainTextFileTypeManager;
import com.intellij.openapi.fileTypes.FileType;
import com.intellij.openapi.fileTypes.FileTypeManager;
import com.intellij.openapi.fileTypes.StdFileTypes;
import com.intellij.openapi.vfs.VirtualFile;
import org.jetbrains.annotations.NotNull;
/**
* @author Rustam Vishnyakov
*/
public class MarkAsPlainTextAction extends AnAction {
@Override
public void actionPerformed(AnActionEvent e) {
DataContext dataContext = e.getDataContext();
final VirtualFile file = PlatformDataKeys.VIRTUAL_FILE.getData(dataContext);
if (file == null || file.isDirectory()) return;
markAsPlainText(file);
}
private static void markAsPlainText(@NotNull VirtualFile file) {
EnforcedPlainTextFileTypeManager typeManager = EnforcedPlainTextFileTypeManager.getInstance();
if (typeManager != null) typeManager.markAsPlainText(file);
}
@Override
public void update(AnActionEvent e) {
DataContext dataContext = e.getDataContext();
final VirtualFile file = PlatformDataKeys.VIRTUAL_FILE.getData(dataContext);
final Presentation presentation = e.getPresentation();
final EnforcedPlainTextFileTypeManager typeManager = EnforcedPlainTextFileTypeManager.getInstance();
presentation.setVisible(false);
if (typeManager == null || file == null || file.isDirectory()) {
return;
}
if (!typeManager.isMarkedAsPlainText(file)) {
FileType originalType = FileTypeManager.getInstance().getFileTypeByFileName(file.getName());
if (originalType.isBinary() || originalType == StdFileTypes.PLAIN_TEXT) return;
presentation.setVisible(true);
presentation.setIcon(EnforcedPlainTextFileTypeFactory.ENFORCED_PLAIN_TEXT_ICON);
}
}
}
@@ -0,0 +1,32 @@
/*
* Copyright 2000-2011 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.openapi.file.exclude.ui;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.DefaultActionGroup;
import com.intellij.openapi.actionSystem.Presentation;
import com.intellij.openapi.file.exclude.EnforcedPlainTextFileTypeManager;
/**
* @author Rustam Vishnyakov
*/
public class MarkFileGroup extends DefaultActionGroup {
@Override
public void update(AnActionEvent e) {
final Presentation presentation = e.getPresentation();
presentation.setVisible(EnforcedPlainTextFileTypeManager.getInstance() != null);
}
}
@@ -1215,3 +1215,6 @@ action.CreateLauncherScript.text=Create Command-line Launcher
action.CreateLauncherScript.description=Create script for opening files and projects from the command line
group.EditorGutterPopupMenu.text=Editor Gutter Popup Menu
action.ExcludeFromProject.text=Exclude From Project...
group.MarkFileAs.text=Mark File As
action.MarkAsPlainTextAction.text=Mark as Plain Text
action.MarkAsOriginalTypeAction.text=Mark as
@@ -401,6 +401,10 @@
<group id="ProjectViewPopupMenuModifyGroup">
<reference ref="$Delete"/>
<action id="ExcludeFromProject" class="com.intellij.openapi.file.exclude.ui.ExcludeFromProjectAction"/>
<group id="MarkFileAs" class="com.intellij.openapi.file.exclude.ui.MarkFileGroup">
<action id="MarkAsPlainTextAction" class="com.intellij.openapi.file.exclude.ui.MarkAsPlainTextAction"/>
<action id="MarkAsOriginalTypeAction" class="com.intellij.openapi.file.exclude.ui.MarkAsOriginalTypeAction"/>
</group>
</group>
<group id="ProjectViewPopupMenuRunGroup">
+3
View File
@@ -1177,6 +1177,9 @@
serviceImplementation="com.intellij.openapi.file.exclude.ProjectFileExclusionManager"/>
<projectConfigurable instance="com.intellij.openapi.file.exclude.ui.ExcludedFilesConfigurable"/>
-->
<fileTypeFactory implementation="com.intellij.openapi.file.exclude.EnforcedPlainTextFileTypeFactory"/>
<applicationService serviceInterface="com.intellij.openapi.file.exclude.EnforcedPlainTextFileTypeManager"
serviceImplementation="com.intellij.openapi.file.exclude.EnforcedPlainTextFileTypeManager"/>
</extensions>