IDEA-102869 Automatically create a copy of default scheme for chaging

This commit is contained in:
Rustam Vishnyakov
2016-09-14 15:43:36 +03:00
parent e0f00070d4
commit a3aa0fbe87
7 changed files with 155 additions and 18 deletions
@@ -70,6 +70,8 @@ public abstract class AbstractColorsScheme implements EditorColorsScheme {
private float myConsoleLineSpacing = -1;
private boolean myIsSaveNeeded;
private boolean myCanBeDeleted = true;
// version influences XML format and triggers migration
private int myVersion = CURR_VERSION;
@@ -835,4 +837,20 @@ public abstract class AbstractColorsScheme implements EditorColorsScheme {
public Properties getMetaProperties() {
return myMetaInfo;
}
public boolean canBeDeleted() {
return myCanBeDeleted;
}
public void setCanBeDeleted(boolean canBeDeleted) {
myCanBeDeleted = canBeDeleted;
}
public boolean isVisible() {
return true;
}
public static boolean isVisible(@NotNull EditorColorsScheme scheme) {
return !(scheme instanceof AbstractColorsScheme) || ((AbstractColorsScheme)scheme).isVisible();
}
}
@@ -27,6 +27,9 @@ import org.jetbrains.annotations.Nullable;
import java.awt.*;
public class DefaultColorsScheme extends AbstractColorsScheme implements ReadOnlyColorsScheme {
public final static String EDITABLE_COPY_PREFIX = "#_user_";
private String myName;
public DefaultColorsScheme() {
@@ -93,4 +96,22 @@ public class DefaultColorsScheme extends AbstractColorsScheme implements ReadOnl
newScheme.setDefaultMetaInfo(this);
return newScheme;
}
/**
* Tells if there is an editable user copy of the scheme to be edited.
*
* @return True if the editable copy shall exist, false if the scheme is non-editable.
*/
public boolean hasEditableCopy() {
return true;
}
public String getEditableCopyName() {
return EDITABLE_COPY_PREFIX + myName;
}
@Override
public boolean isVisible() {
return false;
}
}
@@ -58,4 +58,9 @@ public class EmptyColorScheme extends DefaultColorsScheme {
public String getName() {
return NAME;
}
@Override
public boolean hasEditableCopy() {
return false;
}
}
@@ -32,7 +32,10 @@ import com.intellij.openapi.editor.colors.impl.*;
import com.intellij.openapi.editor.markup.EffectType;
import com.intellij.openapi.editor.markup.TextAttributes;
import com.intellij.openapi.extensions.Extensions;
import com.intellij.openapi.options.*;
import com.intellij.openapi.options.Configurable;
import com.intellij.openapi.options.ConfigurationException;
import com.intellij.openapi.options.SchemeManager;
import com.intellij.openapi.options.SearchableConfigurable;
import com.intellij.openapi.options.colors.*;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.project.ProjectManager;
@@ -136,7 +139,7 @@ public class ColorAndFontOptions extends SearchableConfigurable.Parent.Abstract
return mySelectedScheme;
}
private MyColorScheme getScheme(String name) {
MyColorScheme getScheme(String name) {
return mySchemes.get(name);
}
@@ -168,6 +171,10 @@ public class ColorAndFontOptions extends SearchableConfigurable.Parent.Abstract
public static boolean isReadOnly(@NotNull final EditorColorsScheme scheme) {
return ((MyColorScheme)scheme).isReadOnly();
}
public static boolean canBeDeleted(@NotNull final EditorColorsScheme scheme) {
return scheme instanceof MyColorScheme && ((MyColorScheme)scheme).canBeDeleted();
}
@NotNull
public String[] getSchemeNames() {
@@ -265,7 +272,7 @@ public class ColorAndFontOptions extends SearchableConfigurable.Parent.Abstract
// refresh only if scheme is not switched
boolean refreshEditors = activeSchemeModified && schemeManager.getCurrentScheme() == activeOriginalScheme;
schemeManager.setSchemes(result, activeOriginalScheme);
schemeManager.setSchemes(includingInvisible(result, schemeManager), activeOriginalScheme);
if (refreshEditors) {
EditorColorsManagerImpl.schemeChangedOrSwitched();
}
@@ -280,6 +287,16 @@ public class ColorAndFontOptions extends SearchableConfigurable.Parent.Abstract
}
}
private static List<EditorColorsScheme> includingInvisible(@NotNull List<EditorColorsScheme> schemeList,
@NotNull SchemeManager<EditorColorsScheme> schemeManager) {
for (EditorColorsScheme scheme : schemeManager.getAllSchemes()) {
if (!AbstractColorsScheme.isVisible(scheme)) {
schemeList.add(scheme);
}
}
return schemeList;
}
private static void changeLafIfNecessary(boolean isDarkEditorTheme) {
String propKey = "change.laf.on.editor.theme.change";
String value = PropertiesComponent.getInstance().getValue(propKey);
@@ -1071,6 +1088,11 @@ public class ColorAndFontOptions extends SearchableConfigurable.Parent.Abstract
return false;
}
@Override
public boolean canBeDeleted() {
return (myParentScheme instanceof AbstractColorsScheme) && ((AbstractColorsScheme)myParentScheme).canBeDeleted();
}
private boolean isFontModified() {
if (!getFontPreferences().equals(myParentScheme.getFontPreferences())) return true;
if (getLineSpacing() != myParentScheme.getLineSpacing()) return true;
@@ -22,6 +22,7 @@ import com.intellij.application.options.SkipSelfSearchComponent;
import com.intellij.openapi.application.ApplicationBundle;
import com.intellij.openapi.editor.colors.EditorColorsScheme;
import com.intellij.openapi.editor.colors.impl.AbstractColorsScheme;
import com.intellij.openapi.editor.colors.impl.DefaultColorsScheme;
import com.intellij.openapi.editor.colors.impl.EditorColorsSchemeImpl;
import com.intellij.openapi.editor.colors.impl.EmptyColorScheme;
import com.intellij.openapi.extensions.Extensions;
@@ -37,6 +38,7 @@ import com.intellij.util.EventDispatcher;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.ui.JBInsets;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.awt.*;
@@ -47,7 +49,7 @@ import java.util.List;
public class SchemesPanel extends JPanel implements SkipSelfSearchComponent {
private final ColorAndFontOptions myOptions;
private ComboBox<String> mySchemeComboBox;
private ComboBox<MySchemeItem> mySchemeComboBox;
private JButton myDeleteButton;
private JButton myImportButton;
@@ -69,10 +71,11 @@ public class SchemesPanel extends JPanel implements SkipSelfSearchComponent {
mySchemeComboBox.addActionListener(new ActionListener() {
@Override
public void actionPerformed(@NotNull ActionEvent e) {
if (mySchemeComboBox.getSelectedIndex() != -1) {
EditorColorsScheme selected = myOptions.selectScheme((String)mySchemeComboBox.getSelectedItem());
String selectedName = getSelectedSchemeName();
if (selectedName != null) {
EditorColorsScheme selected = myOptions.selectScheme(selectedName);
final boolean readOnly = ColorAndFontOptions.isReadOnly(selected);
myDeleteButton.setEnabled(!readOnly);
myDeleteButton.setEnabled(!readOnly && ColorAndFontOptions.canBeDeleted(selected));
myHintLabel.setVisible(readOnly);
if (areSchemesLoaded()) {
myDispatcher.getMulticaster().schemeChanged(SchemesPanel.this);
@@ -117,8 +120,9 @@ public class SchemesPanel extends JPanel implements SkipSelfSearchComponent {
myDeleteButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(@NotNull ActionEvent e) {
if (mySchemeComboBox.getSelectedIndex() != -1) {
myOptions.removeScheme((String)mySchemeComboBox.getSelectedItem());
String selectedName = getSelectedSchemeName();
if (selectedName != null) {
myOptions.removeScheme(selectedName);
}
}
});
@@ -165,7 +169,7 @@ public class SchemesPanel extends JPanel implements SkipSelfSearchComponent {
private void showSaveAsDialog() {
List<String> names = ContainerUtil.newArrayList(myOptions.getSchemeNames());
String selectedName = myOptions.getSelectedScheme().getName();
String selectedName = getSchemeDisplayName(myOptions.getSelectedScheme().getName());
SaveSchemeDialog dialog = new SaveSchemeDialog(this, ApplicationBundle.message("title.save.color.scheme.as"), names, selectedName);
if (dialog.showAndGet()) {
myOptions.saveSchemeAs(dialog.getSchemeName());
@@ -187,20 +191,29 @@ public class SchemesPanel extends JPanel implements SkipSelfSearchComponent {
if (this != source) {
setListLoaded(false);
String selectedSchemeBackup = myOptions.getSelectedScheme().getName();
EditorColorsScheme selectedSchemeBackup = myOptions.getSelectedScheme();
mySchemeComboBox.removeAllItems();
String[] schemeNames = myOptions.getSchemeNames();
MySchemeItem itemToSelect = null;
for (String schemeName : schemeNames) {
mySchemeComboBox.addItem(schemeName);
EditorColorsScheme scheme = myOptions.getScheme(schemeName);
MySchemeItem item = new MySchemeItem(scheme);
if (scheme == selectedSchemeBackup) itemToSelect = item;
mySchemeComboBox.addItem(item);
}
mySchemeComboBox.setSelectedItem(selectedSchemeBackup);
mySchemeComboBox.setSelectedItem(itemToSelect);
setListLoaded(true);
myDispatcher.getMulticaster().schemeChanged(this);
}
}
@Nullable
private String getSelectedSchemeName() {
return mySchemeComboBox.getSelectedIndex() != -1 ? ((MySchemeItem)mySchemeComboBox.getSelectedItem()).getSchemeName() : null;
}
private void setListLoaded(final boolean b) {
myListLoaded = b;
@@ -247,4 +260,28 @@ public class SchemesPanel extends JPanel implements SkipSelfSearchComponent {
private static boolean isImportAvailable() {
return !SchemeImporterEP.getExtensions(EditorColorsScheme.class).isEmpty();
}
private final static class MySchemeItem {
private EditorColorsScheme myScheme;
public MySchemeItem(EditorColorsScheme scheme) {
myScheme = scheme;
}
public String getSchemeName() {
return myScheme.getName();
}
@Override
public String toString() {
return getSchemeDisplayName(getSchemeName());
}
}
private final static String getSchemeDisplayName(@NotNull String schemeName) {
return
schemeName.startsWith(DefaultColorsScheme.EDITABLE_COPY_PREFIX) ?
schemeName.substring(DefaultColorsScheme.EDITABLE_COPY_PREFIX.length()) :
schemeName;
}
}
@@ -18,6 +18,8 @@ package com.intellij.application.options;
import com.intellij.CommonBundle;
import com.intellij.openapi.application.ApplicationBundle;
import com.intellij.openapi.editor.colors.ex.DefaultColorSchemesManager;
import com.intellij.openapi.editor.colors.impl.DefaultColorsScheme;
import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.openapi.ui.Messages;
import com.intellij.util.text.UniqueNameGenerator;
@@ -69,12 +71,15 @@ public class SaveSchemeDialog extends DialogWrapper {
@Override
protected void doOKAction() {
if (getSchemeName().trim().isEmpty()) {
final String schemeName = getSchemeName();
if (schemeName.trim().isEmpty()) {
Messages.showMessageDialog(getContentPane(), ApplicationBundle.message("error.scheme.must.have.a.name"),
CommonBundle.getErrorTitle(), Messages.getErrorIcon());
return;
}
else if ("default".equals(getSchemeName())) {
else if (
isDefaultSchemeName(schemeName) ||
schemeName.startsWith(DefaultColorsScheme.EDITABLE_COPY_PREFIX)) {
Messages.showMessageDialog(getContentPane(), ApplicationBundle.message("error.illegal.scheme.name"),
CommonBundle.getErrorTitle(), Messages.getErrorIcon());
return;
@@ -90,6 +95,13 @@ public class SaveSchemeDialog extends DialogWrapper {
}
super.doOKAction();
}
private static boolean isDefaultSchemeName(@NotNull String schemeName) {
for (DefaultColorsScheme defaultScheme : DefaultColorSchemesManager.getInstance().getAllSchemes()) {
if (schemeName.equalsIgnoreCase(defaultScheme.getName())) return true;
}
return false;
}
@Override
protected JComponent createCenterPanel() {
@@ -137,6 +137,8 @@ public class EditorColorsManagerImpl extends EditorColorsManager implements Pers
scheme = getScheme(wizardEditorScheme);
LOG.assertTrue(scheme != null, "Wizard scheme " + wizardEditorScheme + " not found");
}
initEditableDefaultSchemesCopies();
setGlobalSchemeInner(scheme == null ? getDefaultScheme() : scheme);
}
@@ -147,6 +149,22 @@ public class EditorColorsManagerImpl extends EditorColorsManager implements Pers
loadAdditionalTextAttributes();
}
private void initEditableDefaultSchemesCopies() {
for (DefaultColorsScheme defaultScheme : myDefaultColorSchemeManager.getAllSchemes()) {
if (defaultScheme.hasEditableCopy()) {
String editableCopyName = defaultScheme.getEditableCopyName();
AbstractColorsScheme editableCopy = (AbstractColorsScheme)getScheme(editableCopyName);
if (editableCopy == null) {
editableCopy = (AbstractColorsScheme)defaultScheme.clone();
editableCopy.setName(editableCopyName);
addColorsScheme(editableCopy);
}
editableCopy.setCanBeDeleted(false);
}
}
}
private void loadBundledSchemes() {
if (!isUnitTestOrHeadlessMode()) {
for (BundledColorSchemeEP ep : BundledColorSchemeEP.EP_NAME.getExtensions()) {
@@ -246,7 +264,7 @@ public class EditorColorsManagerImpl extends EditorColorsManager implements Pers
private static EditorColorsScheme[] getAllVisibleSchemes(@NotNull Collection<EditorColorsScheme> schemes) {
List<EditorColorsScheme> visibleSchemes = new ArrayList<>(schemes.size() - 1);
for (EditorColorsScheme scheme : schemes) {
if (!(scheme instanceof EmptyColorScheme)) {
if (AbstractColorsScheme.isVisible(scheme)) {
visibleSchemes.add(scheme);
}
}
@@ -263,8 +281,12 @@ public class EditorColorsManagerImpl extends EditorColorsManager implements Pers
}
@NotNull
private DefaultColorsScheme getDefaultScheme() {
return myDefaultColorSchemeManager.getFirstScheme();
private EditorColorsScheme getDefaultScheme() {
DefaultColorsScheme defaultScheme = myDefaultColorSchemeManager.getFirstScheme();
String editableCopyName = defaultScheme.getEditableCopyName();
EditorColorsScheme editableCopy = getScheme(editableCopyName);
assert editableCopy != null : "An editable copy of " + defaultScheme.getName() + " has not been initialized.";
return editableCopy;
}
@NotNull