/* * Copyright 2000-2009 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.ui.tabs; import com.intellij.ide.util.PropertiesComponent; import com.intellij.openapi.project.Project; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.packageDependencies.DefaultScopesProvider; import com.intellij.psi.PsiFile; import com.intellij.psi.search.scope.NonProjectFilesScope; import com.intellij.psi.search.scope.TestsScope; import com.intellij.psi.search.scope.packageSet.*; import com.intellij.ui.ColorUtil; import com.intellij.util.containers.ContainerUtil; import consulo.psi.search.scope.TestResourcesScope; import org.jdom.Element; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.awt.*; import java.util.*; import java.util.List; /** * @author spleaner * @author Konstantin Bulenkov */ // todo[spL]: listen to scope rename public class FileColorsModel implements Cloneable { public static final String FILE_COLOR = "fileColor"; private final List<FileColorConfiguration> myApplicationLevelConfigurations; private final List<FileColorConfiguration> myProjectLevelConfigurations; private static final Map<String, String> globalScopes; private static Map<String, String> globalScopesColors; static { globalScopes = new LinkedHashMap<>(4); globalScopes.put(NonProjectFilesScope.NAME, "file.colors.enable.non.project"); globalScopes.put(TestsScope.NAME, "file.colors.enable.tests"); globalScopes.put(TestResourcesScope.NAME, "file.colors.enable.tests"); //globalScopes.put(ResourcesScope.NAME, "file.colors.enable.sources"); //globalScopes.put(SourcesScope.NAME, "file.colors.enable.sources"); globalScopesColors = new LinkedHashMap<>(4); } private final Project myProject; FileColorsModel(@NotNull final Project project) { myProject = project; myProjectLevelConfigurations = new ArrayList<>(); myApplicationLevelConfigurations = new ArrayList<>(); if (globalScopesColors.size() < globalScopes.size()) { final DefaultScopesProvider defaultScopesProvider = DefaultScopesProvider.getInstance(project); for (String scopeName : globalScopes.keySet()) { final NamedScope scope = defaultScopesProvider.findCustomScope(scopeName); assert scope != null : "There is no custom scope with name " + scopeName; final Color color = ColorUtil.getColor(scope.getClass()); assert color != null : scope.getClass().getName() + " is not annotated with @Colored"; final String colorName = FileColorManagerImpl.getColorName(color); globalScopesColors.put(scopeName, colorName == null ? ColorUtil.toHex(color) : colorName); } } initGlobalScopes(); } private FileColorsModel(@NotNull final Project project, @NotNull final List<FileColorConfiguration> regular, @NotNull final List<FileColorConfiguration> shared) { myProject = project; myProjectLevelConfigurations = new ArrayList<>(); myApplicationLevelConfigurations = new ArrayList<>(); myProjectLevelConfigurations.addAll(regular); myApplicationLevelConfigurations.addAll(shared); initGlobalScopes(); } private void initGlobalScopes() { for (String scopeName : globalScopes.keySet()) { if (findConfiguration(scopeName, false) == null) { final String color = PropertiesComponent.getInstance().getOrInit(globalScopes.get(scopeName), globalScopesColors.get(scopeName)); if (color.length() != 0) { final Color col = ColorUtil.fromHex(color, null); final String name = col == null ? null : FileColorManagerImpl.getColorName(col); myProjectLevelConfigurations.add(new FileColorConfiguration(scopeName, name == null ? color : name)); } } } } public void save(final Element e, final boolean shared) { final List<FileColorConfiguration> configurations = shared ? myApplicationLevelConfigurations : myProjectLevelConfigurations; for (final FileColorConfiguration configuration : configurations) { final String name = configuration.getScopeName(); if (globalScopes.containsKey(name)) { PropertiesComponent.getInstance().setValue(name, configuration.getColorName()); } configuration.save(e); } } public void load(final Element e, final boolean shared) { List<FileColorConfiguration> configurations = shared ? myApplicationLevelConfigurations : myProjectLevelConfigurations; configurations.clear(); final List<Element> list = e.getChildren(FILE_COLOR); for (Element child : list) { final FileColorConfiguration configuration = FileColorConfiguration.load(child); if (configuration != null) { final String name = configuration.getScopeName(); if (globalScopes.get(name) != null) { final PropertiesComponent properties = PropertiesComponent.getInstance(); final String colorName = properties.getValue(name); if (colorName != null) { configurations.add(new FileColorConfiguration(name, colorName)); } continue; } configurations.add(configuration); } } } @Override public FileColorsModel clone() throws CloneNotSupportedException { final List<FileColorConfiguration> regular = new ArrayList<>(); for (final FileColorConfiguration configuration : myProjectLevelConfigurations) { regular.add(configuration.clone()); } final ArrayList<FileColorConfiguration> shared = new ArrayList<>(); for (final FileColorConfiguration sharedConfiguration : myApplicationLevelConfigurations) { shared.add(sharedConfiguration.clone()); } return new FileColorsModel(myProject, regular, shared); } public void add(@NotNull final FileColorConfiguration configuration, boolean shared) { final List<FileColorConfiguration> configurations = shared ? myApplicationLevelConfigurations : myProjectLevelConfigurations; if (!configurations.contains(configuration)) { configurations.add(configuration); } } public void add(@NotNull final String scopeName, @NotNull final String colorName, boolean shared) { final FileColorConfiguration configuration = new FileColorConfiguration(); configuration.setScopeName(scopeName); configuration.setColorName(colorName); add(configuration, shared); } @Nullable private FileColorConfiguration findConfiguration(final String scopeName, final boolean shared) { final List<FileColorConfiguration> configurations = shared ? myApplicationLevelConfigurations : myProjectLevelConfigurations; for (final FileColorConfiguration configuration : configurations) { if (scopeName.equals(configuration.getScopeName())) { return configuration; } } return null; } public boolean isShared(@NotNull final String scopeName) { return findConfiguration(scopeName, true) != null; } @Nullable public String getColor(@NotNull PsiFile psiFile) { if (!psiFile.isValid()) { return null; } final FileColorConfiguration configuration = findConfiguration(psiFile); if (configuration != null && configuration.isValid(psiFile.getProject())) { return configuration.getColorName(); } return null; } @Nullable public String getColor(@NotNull VirtualFile file, Project project) { if (!file.isValid()) { return null; } final FileColorConfiguration configuration = findConfiguration(file); if (configuration != null && configuration.isValid(project)) { return configuration.getColorName(); } return null; } @Nullable public String getScopeColor(@NotNull String scopeName, Project project) { FileColorConfiguration configuration = null; for (FileColorConfiguration each : getConfigurations()) { if (scopeName.equals(each.getScopeName())) { configuration = each; break; } } if (configuration != null && configuration.isValid(project)) { return configuration.getColorName(); } return null; } @Nullable private FileColorConfiguration findConfiguration(@NotNull final PsiFile colored) { for (final FileColorConfiguration configuration : myProjectLevelConfigurations) { final NamedScope scope = NamedScopeManager.getScope(myProject, configuration.getScopeName()); if (scope != null) { final NamedScopesHolder namedScopesHolder = NamedScopeManager.getHolder(myProject, configuration.getScopeName(), null); if (scope.getValue() != null && namedScopesHolder != null && scope.getValue().contains(colored, namedScopesHolder)) { return configuration; } } } for (FileColorConfiguration configuration : myApplicationLevelConfigurations) { final NamedScope scope = NamedScopeManager.getScope(myProject, configuration.getScopeName()); if (scope != null) { final NamedScopesHolder namedScopesHolder = NamedScopeManager.getHolder(myProject, configuration.getScopeName(), null); if (scope.getValue() != null && namedScopesHolder != null && scope.getValue().contains(colored, namedScopesHolder)) { return configuration; } } } return null; } @Nullable private FileColorConfiguration findConfiguration(@NotNull final VirtualFile colored) { for (final FileColorConfiguration configuration : myProjectLevelConfigurations) { final NamedScope scope = NamedScopesHolder.getScope(myProject, configuration.getScopeName()); if (scope != null) { final NamedScopesHolder namedScopesHolder = NamedScopesHolder.getHolder(myProject, configuration.getScopeName(), null); final PackageSet packageSet = scope.getValue(); if (packageSet instanceof PackageSetBase && namedScopesHolder != null && ((PackageSetBase)packageSet).contains(colored, namedScopesHolder)) { return configuration; } } } for (FileColorConfiguration configuration : myApplicationLevelConfigurations) { final NamedScope scope = NamedScopesHolder.getScope(myProject, configuration.getScopeName()); if (scope != null) { final NamedScopesHolder namedScopesHolder = NamedScopesHolder.getHolder(myProject, configuration.getScopeName(), null); final PackageSet packageSet = scope.getValue(); if (packageSet instanceof PackageSetBase && namedScopesHolder != null && ((PackageSetBase)packageSet).contains(colored, namedScopesHolder)) { return configuration; } } } return null; } public boolean isShared(FileColorConfiguration configuration) { return myApplicationLevelConfigurations.contains(configuration); } @NotNull private List<FileColorConfiguration> getConfigurations() { return ContainerUtil.concat(myApplicationLevelConfigurations, myProjectLevelConfigurations); } public void setConfigurations(final List<FileColorConfiguration> configurations, final boolean shared) { if (shared) { myApplicationLevelConfigurations.clear(); myApplicationLevelConfigurations.addAll(configurations); } else { myProjectLevelConfigurations.clear(); final HashMap<String, String> global = new HashMap<>(globalScopes); for (FileColorConfiguration configuration : configurations) { myProjectLevelConfigurations.add(configuration); final String name = configuration.getScopeName(); if (global.containsKey(name)) { PropertiesComponent.getInstance().setValue(global.get(name), configuration.getColorName()); global.remove(name); } } for (String name : global.keySet()) { PropertiesComponent.getInstance().setValue(global.get(name), ""); } } } public boolean isColored(String scopeName, boolean shared) { return findConfiguration(scopeName, shared) != null; } public List<FileColorConfiguration> getProjectLevelConfigurations() { return myProjectLevelConfigurations; } public List<FileColorConfiguration> getLocalConfigurations() { return myApplicationLevelConfigurations; } }