diff --git a/platform/lang-api/src/com/intellij/psi/search/scope/TestsScope.java b/platform/lang-api/src/com/intellij/psi/search/scope/TestsScope.java index a84c87c4ce9d..36b828c3468a 100644 --- a/platform/lang-api/src/com/intellij/psi/search/scope/TestsScope.java +++ b/platform/lang-api/src/com/intellij/psi/search/scope/TestsScope.java @@ -30,7 +30,7 @@ import org.jetbrains.annotations.NotNull; /** * @author Konstantin Bulenkov */ -@Colored(color = "ff0000") +@Colored(color = "e7fadb") public class TestsScope extends NamedScope { public static final String NAME = IdeBundle.message("predefined.scope.tests.name"); public TestsScope(@NotNull Project project) { diff --git a/platform/lang-impl/src/com/intellij/packageDependencies/DefaultScopesProvider.java b/platform/lang-impl/src/com/intellij/packageDependencies/DefaultScopesProvider.java index 2ac268e09718..2eb4cc1da320 100644 --- a/platform/lang-impl/src/com/intellij/packageDependencies/DefaultScopesProvider.java +++ b/platform/lang-impl/src/com/intellij/packageDependencies/DefaultScopesProvider.java @@ -22,6 +22,7 @@ import com.intellij.problems.WolfTheProblemSolver; import com.intellij.psi.PsiFile; import com.intellij.psi.search.scope.packageSet.*; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.util.ArrayList; import java.util.Arrays; @@ -80,4 +81,14 @@ public class DefaultScopesProvider implements CustomScopesProvider { } return scopes; } + + @Nullable + public NamedScope findCustomScope(String name) { + for (NamedScope scope : getAllCustomScopes()) { + if (name.equals(scope.getName())) { + return scope; + } + } + return null; + } } diff --git a/platform/lang-impl/src/com/intellij/ui/tabs/FileColorConfigurationEditDialog.java b/platform/lang-impl/src/com/intellij/ui/tabs/FileColorConfigurationEditDialog.java index 24898ff53b1c..5fed04b922a6 100644 --- a/platform/lang-impl/src/com/intellij/ui/tabs/FileColorConfigurationEditDialog.java +++ b/platform/lang-impl/src/com/intellij/ui/tabs/FileColorConfigurationEditDialog.java @@ -19,7 +19,6 @@ package com.intellij.ui.tabs; import com.intellij.notification.impl.ui.StickyButton; import com.intellij.notification.impl.ui.StickyButtonUI; import com.intellij.openapi.ui.DialogWrapper; -import com.intellij.packageDependencies.NonProjectFilesScope; import com.intellij.psi.search.scope.packageSet.NamedScope; import com.intellij.psi.search.scope.packageSet.NamedScopeManager; import com.intellij.psi.search.scope.packageSet.NamedScopesHolder; @@ -35,9 +34,7 @@ import javax.swing.plaf.ButtonUI; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; -import java.util.Arrays; import java.util.Collection; -import java.util.Comparator; import java.util.Map; /** @@ -79,14 +76,7 @@ public class FileColorConfigurationEditDialog extends DialogWrapper { } } - final String[] names = ArrayUtil.toStringArray(myScopeNames.keySet()); - Arrays.sort(names, new Comparator() { - @Override - public int compare(String o1, String o2) { - return o1 == NonProjectFilesScope.NAME ? 1 : o2 == NonProjectFilesScope.NAME ? -1 : 0; - } - }); - myScopeComboBox = new JComboBox(names); + myScopeComboBox = new JComboBox(ArrayUtil.toStringArray(myScopeNames.keySet())); myScopeComboBox.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { updateCustomButton(); diff --git a/platform/lang-impl/src/com/intellij/ui/tabs/FileColorManagerImpl.java b/platform/lang-impl/src/com/intellij/ui/tabs/FileColorManagerImpl.java index 384e3a6e947e..839af348ada3 100644 --- a/platform/lang-impl/src/com/intellij/ui/tabs/FileColorManagerImpl.java +++ b/platform/lang-impl/src/com/intellij/ui/tabs/FileColorManagerImpl.java @@ -16,6 +16,7 @@ package com.intellij.ui.tabs; +import com.intellij.ide.util.PropertiesComponent; import com.intellij.openapi.components.PersistentStateComponent; import com.intellij.openapi.components.ServiceManager; import com.intellij.openapi.components.State; @@ -23,7 +24,6 @@ import com.intellij.openapi.components.Storage; import com.intellij.openapi.fileEditor.FileEditorManager; import com.intellij.openapi.project.Project; import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.packageDependencies.NonProjectFilesScope; import com.intellij.psi.PsiFile; import com.intellij.psi.PsiManager; import com.intellij.ui.ColorUtil; @@ -46,12 +46,11 @@ import java.util.List; name = "FileColors", storages = {@Storage(id = "other", file = "$WORKSPACE_FILE$")}) public class FileColorManagerImpl extends FileColorManager implements PersistentStateComponent { + public static final String FC_ENABLED = "FileColorsEnabled"; + public static final String FC_TABS_ENABLED = "FileColorsForTabsEnabled"; private final Project myProject; private final FileColorsModel myModel; private FileColorSharedConfigurationManager mySharedConfigurationManager; - private boolean myEnabled = true; - private boolean myEnabledForTabs = true; - private boolean myEnabledForNonProject = true; private static final Map ourDefaultColors; @@ -77,39 +76,39 @@ public class FileColorManagerImpl extends FileColorManager implements Persistent } public boolean isEnabled() { - return myEnabled; + return PropertiesComponent.getInstance().getBoolean(FC_ENABLED, true); } public void setEnabled(boolean enabled) { - myEnabled = enabled; + PropertiesComponent.getInstance().setValue(FC_ENABLED, Boolean.toString(enabled)); } - public void setEnabledForTabs(boolean b) { - myEnabledForTabs = b; + public void setEnabledForTabs(boolean enabled) { + PropertiesComponent.getInstance().setValue(FC_TABS_ENABLED, Boolean.toString(enabled)); } public boolean isEnabledForTabs() { - return myEnabledForTabs; + return PropertiesComponent.getInstance().getBoolean(FC_TABS_ENABLED, true); } public Element getState(final boolean shared) { Element element = new Element("state"); - if (!shared) { - element.setAttribute("enabled", Boolean.toString(myEnabled)); - element.setAttribute("enabledForTabs", Boolean.toString(myEnabledForTabs)); - } + //if (!shared) { + // element.setAttribute("enabled", Boolean.toString(myEnabled)); + // element.setAttribute("enabledForTabs", Boolean.toString(myEnabledForTabs)); + //} myModel.save(element, shared); - if (!shared) { - final boolean exists = findConfigurationByName(NonProjectFilesScope.NAME, myModel.getLocalConfigurations()) != null; - if (myEnabledForNonProject && !exists) { - myEnabledForNonProject = false; - } else if (!myEnabledForNonProject && exists) { - myEnabledForNonProject = true; - } - - element.setAttribute("showNonProject", Boolean.toString(myEnabledForNonProject)); - } + //if (!shared) { + // final boolean exists = findConfigurationByName(NonProjectFilesScope.NAME, myModel.getLocalConfigurations()) != null; + // if (myEnabledForNonProject && !exists) { + // myEnabledForNonProject = false; + // } else if (!myEnabledForNonProject && exists) { + // myEnabledForNonProject = true; + // } + // + // element.setAttribute("showNonProject", Boolean.toString(myEnabledForNonProject)); + //} return element; } @@ -129,21 +128,21 @@ public class FileColorManagerImpl extends FileColorManager implements Persistent @SuppressWarnings({"AutoUnboxing"}) void loadState(Element state, final boolean shared) { if (!shared) { - final String enabled = state.getAttributeValue("enabled"); - myEnabled = enabled == null ? true : Boolean.valueOf(enabled); + //final String enabled = state.getAttributeValue("enabled"); + //myEnabled = enabled == null ? true : Boolean.valueOf(enabled); + // + //final String enabledForTabs = state.getAttributeValue("enabledForTabs"); + //myEnabledForTabs = enabledForTabs == null ? true : Boolean.valueOf(enabledForTabs); - final String enabledForTabs = state.getAttributeValue("enabledForTabs"); - myEnabledForTabs = enabledForTabs == null ? true : Boolean.valueOf(enabledForTabs); - - final String showNonProject = state.getAttributeValue("showNonProject"); - myEnabledForNonProject = showNonProject == null ? true : Boolean.valueOf(showNonProject); + //final String showNonProject = state.getAttributeValue("showNonProject"); + //myEnabledForNonProject = showNonProject == null ? true : Boolean.valueOf(showNonProject); } myModel.load(state, shared); - final List local = myModel.getLocalConfigurations(); - if (!shared && myEnabledForNonProject && findConfigurationByName(NonProjectFilesScope.NAME, local) == null) { - local.add(new FileColorConfiguration(NonProjectFilesScope.NAME, NonProjectFilesScope.DEFAULT_COLOR)); - } + //final List local = myModel.getLocalConfigurations(); + //if (!shared && myEnabledForNonProject && findConfigurationByName(NonProjectFilesScope.NAME, local) == null) { + // local.add(new FileColorConfiguration(NonProjectFilesScope.NAME, NonProjectFilesScope.DEFAULT_COLOR)); + //} } @SuppressWarnings({"MethodMayBeStatic"}) diff --git a/platform/lang-impl/src/com/intellij/ui/tabs/FileColorsModel.java b/platform/lang-impl/src/com/intellij/ui/tabs/FileColorsModel.java index 345c4937d583..73aa4d318b59 100644 --- a/platform/lang-impl/src/com/intellij/ui/tabs/FileColorsModel.java +++ b/platform/lang-impl/src/com/intellij/ui/tabs/FileColorsModel.java @@ -16,17 +16,25 @@ package com.intellij.ui.tabs; +import com.intellij.ide.util.PropertiesComponent; import com.intellij.openapi.project.Project; +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.NamedScope; import com.intellij.psi.search.scope.packageSet.NamedScopeManager; import com.intellij.psi.search.scope.packageSet.NamedScopesHolder; +import com.intellij.ui.ColorUtil; import org.jdom.Element; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.awt.*; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Map; /** * @author spleaner @@ -38,6 +46,15 @@ public class FileColorsModel implements Cloneable { private final List myConfigurations; private final List mySharedConfigurations; + private static final Map globalScopes; + private static Map globalScopesColors; + static { + globalScopes = new HashMap(); + globalScopes.put(NonProjectFilesScope.NAME, "file.colors.enable.non.project"); + globalScopes.put(TestsScope.NAME, "file.colors.enable.tests"); + + globalScopesColors = new HashMap(); + } private final Project myProject; @@ -45,20 +62,51 @@ public class FileColorsModel implements Cloneable { myProject = project; myConfigurations = new ArrayList(); mySharedConfigurations = 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"; + globalScopesColors.put(scopeName, ColorUtil.toHex(color)); + } + } + initGlobalScopes(); } private FileColorsModel(@NotNull final Project project, @NotNull final List regular, @NotNull final List shared) { myProject = project; - myConfigurations = regular; - mySharedConfigurations = shared; + myConfigurations = new ArrayList(); + mySharedConfigurations = new ArrayList(); + myConfigurations.addAll(regular); + mySharedConfigurations.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) { + myConfigurations.add(new FileColorConfiguration(scopeName, color)); + } + } + } } public void save(final Element e, final boolean shared) { final List configurations = shared ? mySharedConfigurations : myConfigurations; for (final FileColorConfiguration configuration : configurations) { - configuration.save(e); + final String name = configuration.getScopeName(); + if (!shared && globalScopes.containsKey(name)) { + PropertiesComponent.getInstance().setValue(name, configuration.getColorName()); + } else { + configuration.save(e); + } } } @@ -68,12 +116,29 @@ public class FileColorsModel implements Cloneable { configurations.clear(); final List list = (List)e.getChildren(FILE_COLOR); + final Map global = new HashMap(globalScopes); for (Element child : list) { final FileColorConfiguration configuration = FileColorConfiguration.load(child); if (configuration != null) { + if (!shared) { + final String name = configuration.getScopeName(); + if (globalScopes.get(name) != null) { + global.remove(name); + } + } configurations.add(configuration); } } + + if (!shared) { + final PropertiesComponent properties = PropertiesComponent.getInstance(); + for (String scope : global.keySet()) { + final String colorName = properties.getValue(scope); + if (colorName != null) { + configurations.add(new FileColorConfiguration(scope, colorName)); + } + } + } } public FileColorsModel clone() throws CloneNotSupportedException { @@ -105,15 +170,6 @@ public class FileColorsModel implements Cloneable { add(configuration, shared); } - public void remove(@NotNull final String scopeName, boolean shared) { - final List configurations = shared ? mySharedConfigurations : myConfigurations; - final FileColorConfiguration configuration = findConfiguration(scopeName, shared); - - if (configuration != null) { - configurations.remove(configuration); - } - } - @Nullable private FileColorConfiguration findConfiguration(final String scopeName, final boolean shared) { final List configurations = shared ? mySharedConfigurations : myConfigurations; @@ -172,11 +228,6 @@ public class FileColorsModel implements Cloneable { return mySharedConfigurations.contains(configuration); } - public void remove(FileColorConfiguration configuration, boolean shared) { - final List configurations = shared ? mySharedConfigurations : myConfigurations; - configurations.remove(configuration); - } - public void setConfigurations(final List configurations, final boolean shared) { if (shared) { mySharedConfigurations.clear(); @@ -184,7 +235,18 @@ public class FileColorsModel implements Cloneable { } else { myConfigurations.clear(); - myConfigurations.addAll(configurations); + final HashMap global = new HashMap(globalScopes); + for (FileColorConfiguration configuration : configurations) { + myConfigurations.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), ""); + } } } diff --git a/platform/platform-api/src/com/intellij/ide/util/PropertiesComponent.java b/platform/platform-api/src/com/intellij/ide/util/PropertiesComponent.java index 33a5f7858cdb..20b65c0f86bb 100644 --- a/platform/platform-api/src/com/intellij/ide/util/PropertiesComponent.java +++ b/platform/platform-api/src/com/intellij/ide/util/PropertiesComponent.java @@ -32,6 +32,10 @@ public abstract class PropertiesComponent { return Boolean.valueOf(getValue(name)).booleanValue(); } + public final boolean getBoolean(@NonNls String name, boolean defaultValue) { + return isValueSet(name) ? isTrueValue(name) : defaultValue; + } + public abstract boolean isValueSet(String name); public abstract String getValue(@NonNls String name); diff --git a/platform/util/src/com/intellij/ui/Colored.java b/platform/util/src/com/intellij/ui/Colored.java index 8c0b7fc5537d..bf1a48982bbf 100644 --- a/platform/util/src/com/intellij/ui/Colored.java +++ b/platform/util/src/com/intellij/ui/Colored.java @@ -35,5 +35,5 @@ public @interface Colored { * @return color as hex-string */ @RegExp(prefix = "[0-9a-f]{6}") - String color() default "ffffff"; + String color(); }