diff --git a/platform/lang-impl/src/com/intellij/openapi/file/exclude/EnforcedPlainTextFileTypeManager.java b/platform/lang-impl/src/com/intellij/openapi/file/exclude/EnforcedPlainTextFileTypeManager.java index 44b8a5089ef2..a0fba8f81ffc 100644 --- a/platform/lang-impl/src/com/intellij/openapi/file/exclude/EnforcedPlainTextFileTypeManager.java +++ b/platform/lang-impl/src/com/intellij/openapi/file/exclude/EnforcedPlainTextFileTypeManager.java @@ -26,21 +26,51 @@ import com.intellij.openapi.fileTypes.FileTypes; import com.intellij.openapi.fileTypes.StdFileTypes; import com.intellij.openapi.project.Project; import com.intellij.openapi.project.ProjectManager; +import com.intellij.openapi.project.ProjectManagerListener; import com.intellij.openapi.roots.ex.ProjectRootManagerEx; +import com.intellij.openapi.roots.impl.DirectoryIndex; import com.intellij.openapi.util.EmptyRunnable; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.util.indexing.FileBasedIndex; +import java.util.*; + /** + * Maintains a list of files marked as plain text in a local environment (configuration). Every time a project is loaded/open, it reads + * files marked as plain text from a project into local environment (configuration). User actions (mark/unmark as plain text) are + * synchronized between local and project configurations. + * * @author Rustam Vishnyakov */ @State(name = "EnforcedPlainTextFileTypeManager", storages = {@Storage( file = StoragePathMacros.APP_CONFIG + "/plainTextFiles.xml")}) -public class EnforcedPlainTextFileTypeManager extends PersistentFileSetManager { - +public class EnforcedPlainTextFileTypeManager extends PersistentFileSetManager implements ProjectManagerListener { + + private Set myProcessedProjects = new HashSet(); + private boolean myNeedsSync = true; + + public EnforcedPlainTextFileTypeManager() { + ProjectManager.getInstance().addProjectManagerListener(this); + } + public boolean isMarkedAsPlainText(VirtualFile file) { + if (myNeedsSync) { + myNeedsSync = !syncWithOpenProject(); + } return containsFile(file); } + public boolean syncWithOpenProject() { + Project[] openProjects = ProjectManager.getInstance().getOpenProjects(); + if (openProjects.length > 0) { + Project firstOpenProject = openProjects[0]; + if (!myProcessedProjects.contains(firstOpenProject)) { + return syncWithProject(firstOpenProject); + } + return true; + } + return false; + } + public static boolean isApplicableFor(VirtualFile file) { if (file.isDirectory()) return false; FileType originalType = FileTypeManager.getInstance().getFileTypeByFileName(file.getName()); @@ -53,29 +83,44 @@ public class EnforcedPlainTextFileTypeManager extends PersistentFileSetManager { } public void markAsPlainText(VirtualFile... files) { + List filesToSync = new ArrayList(); for (VirtualFile file : files) { if (addFile(file)) { + filesToSync.add(file); FileBasedIndex.getInstance().requestReindex(file); } } - fireRootsChanged(); + fireRootsChanged(filesToSync, true); } public void unmarkPlainText(VirtualFile... files) { + List filesToSync = new ArrayList(); for (VirtualFile file : files) { if (removeFile(file)) { + filesToSync.add(file); FileBasedIndex.getInstance().requestReindex(file); } } - fireRootsChanged(); + fireRootsChanged(filesToSync, false); } - private static void fireRootsChanged() { + private static void fireRootsChanged(final Collection files, final boolean isAdded) { ApplicationManager.getApplication().runWriteAction(new Runnable() { @Override public void run() { for (Project project : ProjectManager.getInstance().getOpenProjects()) { ProjectRootManagerEx.getInstanceEx(project).makeRootsChange(EmptyRunnable.getInstance(), false, true); + ProjectPlainTextFileTypeManager projectPlainTextFileTypeManager = ProjectPlainTextFileTypeManager.getInstance(project); + for (VirtualFile file : files) { + if (projectPlainTextFileTypeManager.hasProjectContaining(file)) { + if (isAdded) { + projectPlainTextFileTypeManager.addFile(file); + } + else { + projectPlainTextFileTypeManager.removeFile(file); + } + } + } } } }); @@ -89,4 +134,40 @@ public class EnforcedPlainTextFileTypeManager extends PersistentFileSetManager { } return ourInstance; } + + @Override + public void projectOpened(Project project) { + syncWithProject(project); + } + + @Override + public boolean canCloseProject(Project project) { + return true; + } + + @Override + public void projectClosed(Project project) { + if (myProcessedProjects.contains(project)) { + myProcessedProjects.remove(project); + } + } + + @Override + public void projectClosing(Project project) { + } + + private boolean syncWithProject(Project project) { + if (!DirectoryIndex.getInstance(project).isInitialized()) return false; + myProcessedProjects.add(project); + ProjectPlainTextFileTypeManager projectPlainTextFileTypeManager = ProjectPlainTextFileTypeManager.getInstance(project); + for (VirtualFile file : projectPlainTextFileTypeManager.getFiles()) { + addFile(file); + } + for (VirtualFile file : getFiles()) { + if (projectPlainTextFileTypeManager.hasProjectContaining(file)) { + projectPlainTextFileTypeManager.addFile(file); + } + } + return true; + } } diff --git a/platform/lang-impl/src/com/intellij/openapi/file/exclude/ProjectPlainTextFileTypeManager.java b/platform/lang-impl/src/com/intellij/openapi/file/exclude/ProjectPlainTextFileTypeManager.java new file mode 100644 index 000000000000..ba74997c8433 --- /dev/null +++ b/platform/lang-impl/src/com/intellij/openapi/file/exclude/ProjectPlainTextFileTypeManager.java @@ -0,0 +1,46 @@ +/* + * Copyright 2000-2012 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.ServiceManager; +import com.intellij.openapi.components.State; +import com.intellij.openapi.components.Storage; +import com.intellij.openapi.components.StoragePathMacros; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.roots.ProjectFileIndex; +import com.intellij.openapi.roots.ProjectRootManager; +import com.intellij.openapi.vfs.VirtualFile; + +/** + * @author Rustam Vishnyakov + */ +@State(name = "ProjectPlainTextFileTypeManager", storages = {@Storage( file = StoragePathMacros.PROJECT_FILE)}) +public class ProjectPlainTextFileTypeManager extends PersistentFileSetManager { + private ProjectFileIndex myIndex; + + public ProjectPlainTextFileTypeManager(Project project) { + myIndex = ProjectRootManager.getInstance(project).getFileIndex(); + } + + public boolean hasProjectContaining(VirtualFile file) { + return myIndex.isInContent(file); + } + + public static ProjectPlainTextFileTypeManager getInstance(Project project) { + return ServiceManager.getService(project, ProjectPlainTextFileTypeManager.class); + } + +} diff --git a/resources/src/idea/RichPlatformPlugin.xml b/resources/src/idea/RichPlatformPlugin.xml index a39cc8a889e2..1abfbfa9a576 100644 --- a/resources/src/idea/RichPlatformPlugin.xml +++ b/resources/src/idea/RichPlatformPlugin.xml @@ -371,6 +371,8 @@ +