mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
do not write unmodified user copy of editor color scheme
This commit is contained in:
@@ -204,7 +204,7 @@ open class DirectoryBasedStorage(private val dir: Path,
|
||||
storeElement.setAttribute(FileStorageCoreUtil.NAME, storage.componentName!!)
|
||||
storeElement.addContent(element)
|
||||
|
||||
val file = getFile(fileName, dir, this)
|
||||
val file = dir.getOrCreateChild(fileName, this)
|
||||
// we don't write xml prolog due to historical reasons (and should not in any case)
|
||||
writeFile(null, this, file, storeElement, LineSeparator.fromString(if (file.exists()) loadFile(file).second else SystemProperties.getLineSeparator()), false)
|
||||
}
|
||||
|
||||
@@ -25,26 +25,25 @@ import com.intellij.openapi.components.impl.stores.FileStorageCoreUtil.DEFAULT_E
|
||||
import com.intellij.openapi.diagnostic.catchAndLog
|
||||
import com.intellij.openapi.extensions.AbstractExtensionPointBean
|
||||
import com.intellij.openapi.options.*
|
||||
import com.intellij.openapi.project.ProjectBundle
|
||||
import com.intellij.openapi.util.Condition
|
||||
import com.intellij.openapi.util.JDOMUtil
|
||||
import com.intellij.openapi.util.WriteExternalException
|
||||
import com.intellij.openapi.util.io.FileUtil
|
||||
import com.intellij.openapi.util.text.StringUtilRt
|
||||
import com.intellij.openapi.vfs.*
|
||||
import com.intellij.openapi.vfs.LocalFileSystem
|
||||
import com.intellij.openapi.vfs.SafeWriteRequestor
|
||||
import com.intellij.openapi.vfs.VirtualFile
|
||||
import com.intellij.openapi.vfs.VirtualFileManager
|
||||
import com.intellij.openapi.vfs.newvfs.BulkFileListener
|
||||
import com.intellij.openapi.vfs.newvfs.NewVirtualFile
|
||||
import com.intellij.openapi.vfs.newvfs.events.VFileContentChangeEvent
|
||||
import com.intellij.openapi.vfs.newvfs.events.VFileCreateEvent
|
||||
import com.intellij.openapi.vfs.newvfs.events.VFileDeleteEvent
|
||||
import com.intellij.openapi.vfs.newvfs.events.VFileEvent
|
||||
import com.intellij.util.PathUtil
|
||||
import com.intellij.util.PathUtilRt
|
||||
import com.intellij.util.SmartList
|
||||
import com.intellij.util.*
|
||||
import com.intellij.util.containers.ConcurrentList
|
||||
import com.intellij.util.containers.ContainerUtil
|
||||
import com.intellij.util.containers.catch
|
||||
import com.intellij.util.io.*
|
||||
import com.intellij.util.loadElement
|
||||
import com.intellij.util.messages.MessageBus
|
||||
import com.intellij.util.text.UniqueNameGenerator
|
||||
import gnu.trove.THashSet
|
||||
@@ -575,7 +574,7 @@ class SchemeManagerImpl<T : Scheme, MUTABLE_SCHEME : T>(val fileSpec: String,
|
||||
val currentFileNameWithoutExtension = externalInfo?.fileNameWithoutExtension
|
||||
val parent = processor.writeScheme(scheme)
|
||||
val element = if (parent is Element) parent else (parent as Document).detachRootElement()
|
||||
if (JDOMUtil.isEmpty(element)) {
|
||||
if (element.isEmpty()) {
|
||||
externalInfo?.scheduleDelete()
|
||||
return
|
||||
}
|
||||
@@ -591,9 +590,7 @@ class SchemeManagerImpl<T : Scheme, MUTABLE_SCHEME : T>(val fileSpec: String,
|
||||
}
|
||||
|
||||
// save only if scheme differs from bundled
|
||||
val bundledScheme = readOnlyExternalizableSchemes.get(scheme.name)
|
||||
if (bundledScheme != null && schemeToInfo.get(bundledScheme)?.isDigestEquals(newDigest) ?: false) {
|
||||
externalInfo?.scheduleDelete()
|
||||
if (isEqualToBundledScheme(externalInfo, newDigest, scheme)) {
|
||||
return
|
||||
}
|
||||
|
||||
@@ -642,7 +639,7 @@ class SchemeManagerImpl<T : Scheme, MUTABLE_SCHEME : T>(val fileSpec: String,
|
||||
}
|
||||
|
||||
if (file == null) {
|
||||
file = getFile(fileName, dir, this)
|
||||
file = dir.getOrCreateChild(fileName, this)
|
||||
}
|
||||
|
||||
runWriteAction {
|
||||
@@ -676,6 +673,38 @@ class SchemeManagerImpl<T : Scheme, MUTABLE_SCHEME : T>(val fileSpec: String,
|
||||
externalInfo.schemeName = scheme.name
|
||||
}
|
||||
|
||||
private fun isEqualToBundledScheme(externalInfo: ExternalInfo?, newDigest: ByteArray, scheme: MUTABLE_SCHEME): Boolean {
|
||||
fun serializeIfPossible(scheme: T): Element? {
|
||||
LOG.catchAndLog {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
val bundledAsMutable = scheme as? MUTABLE_SCHEME ?: return null
|
||||
return processor.writeScheme(bundledAsMutable) as Element
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
val bundledScheme = readOnlyExternalizableSchemes.get(scheme.name)
|
||||
if (bundledScheme == null) {
|
||||
if ((processor as? LazySchemeProcessor)?.let { it.isSchemeEqualToBundled(scheme) } ?: false) {
|
||||
externalInfo?.scheduleDelete()
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
val bundledExternalInfo = schemeToInfo.get(bundledScheme) ?: return false
|
||||
if (bundledExternalInfo.digest == null) {
|
||||
serializeIfPossible(bundledScheme)?.let {
|
||||
bundledExternalInfo.digest = it.digest()
|
||||
} ?: return false
|
||||
}
|
||||
if (bundledExternalInfo.isDigestEquals(newDigest)) {
|
||||
externalInfo?.scheduleDelete()
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
private fun ExternalInfo.scheduleDelete() {
|
||||
filesToDelete.add(fileName)
|
||||
}
|
||||
@@ -930,25 +959,6 @@ class SchemeManagerImpl<T : Scheme, MUTABLE_SCHEME : T>(val fileSpec: String,
|
||||
|
||||
override fun isMetadataEditable(scheme: T) = !readOnlyExternalizableSchemes.containsKey(scheme.name)
|
||||
|
||||
private class ExternalInfo(var fileNameWithoutExtension: String, var fileExtension: String?) {
|
||||
// we keep it to detect rename
|
||||
var schemeName: String? = null
|
||||
|
||||
var digest: ByteArray? = null
|
||||
|
||||
val fileName: String
|
||||
get() = "$fileNameWithoutExtension$fileExtension"
|
||||
|
||||
fun setFileNameWithoutExtension(nameWithoutExtension: String, extension: String) {
|
||||
fileNameWithoutExtension = nameWithoutExtension
|
||||
fileExtension = extension
|
||||
}
|
||||
|
||||
fun isDigestEquals(newDigest: ByteArray) = Arrays.equals(digest, newDigest)
|
||||
|
||||
override fun toString() = fileName
|
||||
}
|
||||
|
||||
override fun toString() = fileSpec
|
||||
}
|
||||
|
||||
@@ -959,26 +969,6 @@ private fun ExternalizableScheme.renameScheme(newName: String) {
|
||||
}
|
||||
}
|
||||
|
||||
private inline fun MutableList<Throwable>.catch(runnable: () -> Unit) {
|
||||
try {
|
||||
runnable()
|
||||
}
|
||||
catch (e: Throwable) {
|
||||
add(e)
|
||||
}
|
||||
}
|
||||
|
||||
fun createDir(ioDir: Path, requestor: Any): VirtualFile {
|
||||
ioDir.createDirectories()
|
||||
val parentFile = ioDir.parent
|
||||
val parentVirtualFile = (if (parentFile == null) null else VfsUtil.createDirectoryIfMissing(parentFile.systemIndependentPath)) ?: throw IOException(ProjectBundle.message("project.configuration.save.file.not.found", parentFile))
|
||||
return getFile(ioDir.fileName.toString(), parentVirtualFile, requestor)
|
||||
}
|
||||
|
||||
fun getFile(fileName: String, parent: VirtualFile, requestor: Any): VirtualFile {
|
||||
return parent.findChild(fileName) ?: runWriteAction { parent.createChildData(requestor, fileName) }
|
||||
}
|
||||
|
||||
private inline fun catchAndLog(fileName: String, runnable: (fileName: String) -> Unit) {
|
||||
try {
|
||||
runnable(fileName)
|
||||
|
||||
@@ -1,7 +1,16 @@
|
||||
package com.intellij.configurationStore
|
||||
|
||||
import com.intellij.openapi.application.runWriteAction
|
||||
import com.intellij.openapi.project.ProjectBundle
|
||||
import com.intellij.openapi.vfs.VfsUtil
|
||||
import com.intellij.openapi.vfs.VirtualFile
|
||||
import com.intellij.util.io.createDirectories
|
||||
import com.intellij.util.io.systemIndependentPath
|
||||
import org.xmlpull.mxp1.MXParser
|
||||
import org.xmlpull.v1.XmlPullParser
|
||||
import java.io.IOException
|
||||
import java.nio.file.Path
|
||||
import java.util.*
|
||||
|
||||
internal inline fun lazyPreloadScheme(bytes: ByteArray, isUseOldFileNameSanitize: Boolean, consumer: (name: String?, parser: XmlPullParser) -> Unit) {
|
||||
val parser = MXParser()
|
||||
@@ -49,4 +58,35 @@ private fun preload(isUseOldFileNameSanitize: Boolean, parser: MXParser): String
|
||||
}
|
||||
while (eventType != XmlPullParser.END_DOCUMENT)
|
||||
return null
|
||||
}
|
||||
|
||||
internal class ExternalInfo(var fileNameWithoutExtension: String, var fileExtension: String?) {
|
||||
// we keep it to detect rename
|
||||
var schemeName: String? = null
|
||||
|
||||
var digest: ByteArray? = null
|
||||
|
||||
val fileName: String
|
||||
get() = "$fileNameWithoutExtension$fileExtension"
|
||||
|
||||
fun setFileNameWithoutExtension(nameWithoutExtension: String, extension: String) {
|
||||
fileNameWithoutExtension = nameWithoutExtension
|
||||
fileExtension = extension
|
||||
}
|
||||
|
||||
fun isDigestEquals(newDigest: ByteArray) = Arrays.equals(digest, newDigest)
|
||||
|
||||
override fun toString() = fileName
|
||||
}
|
||||
|
||||
internal fun VirtualFile.getOrCreateChild(fileName: String, requestor: Any): VirtualFile {
|
||||
return findChild(fileName) ?: runWriteAction { createChildData(requestor, fileName) }
|
||||
}
|
||||
|
||||
internal fun createDir(ioDir: Path, requestor: Any): VirtualFile {
|
||||
ioDir.createDirectories()
|
||||
val parentFile = ioDir.parent
|
||||
val parentVirtualFile = (if (parentFile == null) null else VfsUtil.createDirectoryIfMissing(parentFile.systemIndependentPath))
|
||||
?: throw IOException(ProjectBundle.message("project.configuration.save.file.not.found", parentFile))
|
||||
return parentVirtualFile.getOrCreateChild(ioDir.fileName.toString(), requestor)
|
||||
}
|
||||
+74
-34
@@ -17,6 +17,7 @@
|
||||
package com.intellij.openapi.editor.colors.impl;
|
||||
|
||||
import com.intellij.application.options.EditorFontsConstants;
|
||||
import com.intellij.configurationStore.SerializableScheme;
|
||||
import com.intellij.ide.ui.ColorBlindness;
|
||||
import com.intellij.ide.ui.UISettings;
|
||||
import com.intellij.openapi.application.ex.ApplicationInfoEx;
|
||||
@@ -26,6 +27,7 @@ import com.intellij.openapi.editor.colors.ex.DefaultColorSchemesManager;
|
||||
import com.intellij.openapi.editor.markup.EffectType;
|
||||
import com.intellij.openapi.editor.markup.TextAttributes;
|
||||
import com.intellij.openapi.options.FontSize;
|
||||
import com.intellij.openapi.options.SchemeManager;
|
||||
import com.intellij.openapi.util.Comparing;
|
||||
import com.intellij.openapi.util.Couple;
|
||||
import com.intellij.openapi.util.WriteExternalException;
|
||||
@@ -49,7 +51,7 @@ import static com.intellij.openapi.editor.colors.EditorColors.*;
|
||||
import static com.intellij.openapi.util.Couple.of;
|
||||
import static com.intellij.ui.ColorUtil.fromHex;
|
||||
|
||||
public abstract class AbstractColorsScheme implements EditorColorsScheme {
|
||||
public abstract class AbstractColorsScheme implements EditorColorsScheme, SerializableScheme {
|
||||
private static final int CURR_VERSION = 142;
|
||||
|
||||
private static final FontSize DEFAULT_FONT_SIZE = FontSize.SMALL;
|
||||
@@ -340,28 +342,28 @@ public abstract class AbstractColorsScheme implements EditorColorsScheme {
|
||||
}
|
||||
|
||||
myMetaInfo.clear();
|
||||
for (final Object o : node.getChildren()) {
|
||||
Element childNode = (Element)o;
|
||||
for (Element childNode : node.getChildren()) {
|
||||
String childName = childNode.getName();
|
||||
if (OPTION_ELEMENT.equals(childName)) {
|
||||
readSettings(childNode, isDefault);
|
||||
switch (childName) {
|
||||
case OPTION_ELEMENT:
|
||||
readSettings(childNode, isDefault);
|
||||
break;
|
||||
case EDITOR_FONT:
|
||||
readFontSettings(childNode, myFontPreferences, isDefault);
|
||||
break;
|
||||
case CONSOLE_FONT:
|
||||
readFontSettings(childNode, myConsoleFontPreferences, isDefault);
|
||||
break;
|
||||
case COLORS_ELEMENT:
|
||||
readColors(childNode);
|
||||
break;
|
||||
case ATTRIBUTES_ELEMENT:
|
||||
readAttributes(childNode);
|
||||
break;
|
||||
case META_INFO_ELEMENT:
|
||||
readMetaInfo(childNode);
|
||||
break;
|
||||
}
|
||||
else if (EDITOR_FONT.equals(childName)) {
|
||||
readFontSettings(childNode, myFontPreferences, isDefault);
|
||||
}
|
||||
else if (CONSOLE_FONT.equals(childName)) {
|
||||
readFontSettings(childNode, myConsoleFontPreferences, isDefault);
|
||||
}
|
||||
else if (COLORS_ELEMENT.equals(childName)) {
|
||||
readColors(childNode);
|
||||
}
|
||||
else if (ATTRIBUTES_ELEMENT.equals(childName)) {
|
||||
readAttributes(childNode);
|
||||
}
|
||||
else if(META_INFO_ELEMENT.equals(childName)) {
|
||||
readMetaInfo(childNode);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (myDeprecatedBackgroundColor != null) {
|
||||
@@ -526,8 +528,7 @@ public abstract class AbstractColorsScheme implements EditorColorsScheme {
|
||||
}
|
||||
}
|
||||
|
||||
public void
|
||||
writeExternal(Element parentNode) throws WriteExternalException {
|
||||
public void writeExternal(Element parentNode) {
|
||||
parentNode.setAttribute(NAME_ATTR, getName());
|
||||
parentNode.setAttribute(VERSION_ATTR, Integer.toString(myVersion));
|
||||
|
||||
@@ -606,10 +607,10 @@ public abstract class AbstractColorsScheme implements EditorColorsScheme {
|
||||
writeColors(colorElements);
|
||||
writeAttributes(attrElements);
|
||||
|
||||
if (colorElements.getChildren().size() > 0) {
|
||||
if (!colorElements.getChildren().isEmpty()) {
|
||||
parentNode.addContent(colorElements);
|
||||
}
|
||||
if (attrElements.getChildren().size() > 0) {
|
||||
if (!attrElements.getChildren().isEmpty()) {
|
||||
parentNode.addContent(attrElements);
|
||||
}
|
||||
|
||||
@@ -676,9 +677,8 @@ public abstract class AbstractColorsScheme implements EditorColorsScheme {
|
||||
private Element metaInfoToElement() {
|
||||
Element metaInfoElement = new Element(META_INFO_ELEMENT);
|
||||
myMetaInfo.setProperty(META_INFO_MODIFIED_TIME, META_INFO_DATE_FORMAT.format(new Date()));
|
||||
ArrayList<String> sortedPropertyNames = new ArrayList<>(myMetaInfo.size());
|
||||
sortedPropertyNames.addAll(myMetaInfo.stringPropertyNames());
|
||||
Collections.sort(sortedPropertyNames);
|
||||
List<String> sortedPropertyNames = new ArrayList<>(myMetaInfo.stringPropertyNames());
|
||||
sortedPropertyNames.sort(null);
|
||||
for (String propertyName : sortedPropertyNames) {
|
||||
String value = myMetaInfo.getProperty(propertyName);
|
||||
Element propertyInfo = new Element(PROPERTY_ELEMENT);
|
||||
@@ -704,8 +704,7 @@ public abstract class AbstractColorsScheme implements EditorColorsScheme {
|
||||
|
||||
private void writeColors(Element colorElements) {
|
||||
List<ColorKey> list = new ArrayList<>(myColorsMap.keySet());
|
||||
Collections.sort(list);
|
||||
|
||||
list.sort(null);
|
||||
for (ColorKey key : list) {
|
||||
if (haveToWrite(key)) {
|
||||
Color value = myColorsMap.get(key);
|
||||
@@ -857,12 +856,11 @@ public abstract class AbstractColorsScheme implements EditorColorsScheme {
|
||||
public static String getDisplayName(@NotNull EditorColorsScheme scheme) {
|
||||
String schemeName = scheme.getName();
|
||||
return
|
||||
schemeName.startsWith(DefaultColorsScheme.EDITABLE_COPY_PREFIX) ?
|
||||
schemeName.substring(DefaultColorsScheme.EDITABLE_COPY_PREFIX.length()) :
|
||||
schemeName.startsWith(SchemeManager.EDITABLE_COPY_PREFIX) ?
|
||||
schemeName.substring(SchemeManager.EDITABLE_COPY_PREFIX.length()) :
|
||||
schemeName;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Nullable
|
||||
public AbstractColorsScheme getOriginal() {
|
||||
String originalSchemeName = getMetaProperties().getProperty(META_INFO_ORIGINAL);
|
||||
@@ -872,4 +870,46 @@ public abstract class AbstractColorsScheme implements EditorColorsScheme {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Element writeScheme() {
|
||||
Element root = new Element("scheme");
|
||||
writeExternal(root);
|
||||
return root;
|
||||
}
|
||||
|
||||
public boolean isEqualToBundled(AbstractColorsScheme bundledScheme) {
|
||||
// parent is used only for default schemes (e.g. Darcula — bundled in all ide (opposite to IDE-specific, like Cobalt))
|
||||
if (myParentScheme != bundledScheme.myParentScheme && myParentScheme != bundledScheme) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (String propertyName : myMetaInfo.stringPropertyNames()) {
|
||||
if (propertyName.equals(META_INFO_CREATION_TIME) ||
|
||||
propertyName.equals(META_INFO_MODIFIED_TIME) ||
|
||||
propertyName.equals(META_INFO_IDE) ||
|
||||
propertyName.equals(META_INFO_IDE_VERSION) ||
|
||||
propertyName.equals(META_INFO_ORIGINAL)
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!Comparing.equal(myMetaInfo.getProperty(propertyName), bundledScheme.myMetaInfo.getProperty(propertyName))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return getLineSpacing() == bundledScheme.getLineSpacing() &&
|
||||
getConsoleLineSpacing() == bundledScheme.getConsoleLineSpacing() &&
|
||||
getQuickDocFontSize() == bundledScheme.getQuickDocFontSize() &&
|
||||
myFontPreferences.getRealFontFamilies().equals(bundledScheme.myFontPreferences.getRealFontFamilies()) &&
|
||||
myFontPreferences.useLigatures() == bundledScheme.myFontPreferences.useLigatures() &&
|
||||
myConsoleFontPreferences.useLigatures() == bundledScheme.myConsoleFontPreferences.useLigatures() &&
|
||||
myConsoleFontPreferences.getRealFontFamilies().equals(bundledScheme.myConsoleFontPreferences.getRealFontFamilies()) &&
|
||||
myColorsMap.equals(bundledScheme.myColorsMap) &&
|
||||
myAttributesMap.equals(bundledScheme.myAttributesMap) &&
|
||||
myFontPreferences.equals(bundledScheme.myFontPreferences) &&
|
||||
myConsoleFontPreferences.equals(bundledScheme.myConsoleFontPreferences);
|
||||
}
|
||||
}
|
||||
|
||||
+3
-5
@@ -20,6 +20,7 @@ import com.intellij.openapi.editor.colors.ColorKey;
|
||||
import com.intellij.openapi.editor.colors.EditorFontType;
|
||||
import com.intellij.openapi.editor.colors.TextAttributesKey;
|
||||
import com.intellij.openapi.editor.markup.TextAttributes;
|
||||
import com.intellij.openapi.options.SchemeManager;
|
||||
import org.jdom.Element;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -27,9 +28,6 @@ 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() {
|
||||
@@ -77,7 +75,7 @@ public class DefaultColorsScheme extends AbstractColorsScheme implements ReadOnl
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAttributes(TextAttributesKey key, TextAttributes attributes) {
|
||||
public void setAttributes(@NotNull TextAttributesKey key, TextAttributes attributes) {
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -107,7 +105,7 @@ public class DefaultColorsScheme extends AbstractColorsScheme implements ReadOnl
|
||||
}
|
||||
|
||||
public String getEditableCopyName() {
|
||||
return EDITABLE_COPY_PREFIX + myName;
|
||||
return SchemeManager.EDITABLE_COPY_PREFIX + myName;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+34
-26
@@ -15,14 +15,12 @@
|
||||
*/
|
||||
package com.intellij.openapi.editor.colors.impl;
|
||||
|
||||
import com.intellij.configurationStore.SerializableScheme;
|
||||
import com.intellij.openapi.editor.colors.ColorKey;
|
||||
import com.intellij.openapi.editor.colors.EditorColorsScheme;
|
||||
import com.intellij.openapi.editor.colors.TextAttributesKey;
|
||||
import com.intellij.openapi.editor.markup.TextAttributes;
|
||||
import com.intellij.openapi.options.ExternalizableScheme;
|
||||
import com.intellij.openapi.util.Comparing;
|
||||
import org.jdom.Element;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -31,16 +29,24 @@ import java.awt.*;
|
||||
/**
|
||||
* @author Yura Cangea
|
||||
*/
|
||||
public class EditorColorsSchemeImpl extends AbstractColorsScheme implements ExternalizableScheme, SerializableScheme {
|
||||
public class EditorColorsSchemeImpl extends AbstractColorsScheme implements ExternalizableScheme {
|
||||
public EditorColorsSchemeImpl(EditorColorsScheme parentScheme) {
|
||||
super(parentScheme);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAttributes(TextAttributesKey key, TextAttributes attributes) {
|
||||
if (attributes != getAttributes(key)) {
|
||||
myAttributesMap.put(key, attributes);
|
||||
public void setAttributes(@NotNull TextAttributesKey key, TextAttributes attributes) {
|
||||
TextAttributes ownAttributes = getOwnAttributes(key);
|
||||
if (ownAttributes != null && ownAttributes.equals(attributes)) {
|
||||
return;
|
||||
}
|
||||
TextAttributes parentAttributes = myParentScheme.getAttributes(key);
|
||||
if (parentAttributes != null && parentAttributes.equals(attributes)) {
|
||||
myAttributesMap.remove(key);
|
||||
return;
|
||||
}
|
||||
|
||||
myAttributesMap.put(key, attributes);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -51,20 +57,30 @@ public class EditorColorsSchemeImpl extends AbstractColorsScheme implements Exte
|
||||
}
|
||||
|
||||
@Override
|
||||
public TextAttributes getAttributes(TextAttributesKey key) {
|
||||
if (key != null) {
|
||||
TextAttributesKey fallbackKey = key.getFallbackAttributeKey();
|
||||
TextAttributes attributes = getDirectlyDefinedAttributes(key);
|
||||
if (fallbackKey == null) {
|
||||
if (containsValue(attributes)) return attributes;
|
||||
}
|
||||
else {
|
||||
if (containsValue(attributes) && !attributes.isFallbackEnabled()) return attributes;
|
||||
attributes = getFallbackAttributes(fallbackKey);
|
||||
if (containsValue(attributes)) return attributes;
|
||||
public TextAttributes getAttributes(@Nullable TextAttributesKey key) {
|
||||
TextAttributes attributes = key == null ? null : getOwnAttributes(key);
|
||||
return attributes == null ? myParentScheme.getAttributes(key) : attributes;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private TextAttributes getOwnAttributes(@NotNull TextAttributesKey key) {
|
||||
TextAttributesKey fallbackKey = key.getFallbackAttributeKey();
|
||||
TextAttributes attributes = getDirectlyDefinedAttributes(key);
|
||||
if (fallbackKey == null) {
|
||||
if (containsValue(attributes)) {
|
||||
return attributes;
|
||||
}
|
||||
}
|
||||
return myParentScheme.getAttributes(key);
|
||||
else {
|
||||
if (containsValue(attributes) && !attributes.isFallbackEnabled()) {
|
||||
return attributes;
|
||||
}
|
||||
attributes = getFallbackAttributes(fallbackKey);
|
||||
if (containsValue(attributes)) {
|
||||
return attributes;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@@ -86,12 +102,4 @@ public class EditorColorsSchemeImpl extends AbstractColorsScheme implements Exte
|
||||
newScheme.setDefaultMetaInfo(this);
|
||||
return newScheme;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Element writeScheme() {
|
||||
Element root = new Element("scheme");
|
||||
writeExternal(root);
|
||||
return root;
|
||||
}
|
||||
}
|
||||
|
||||
+19
-20
@@ -27,7 +27,6 @@ import com.intellij.ide.util.PropertiesComponent;
|
||||
import com.intellij.openapi.Disposable;
|
||||
import com.intellij.openapi.application.ApplicationBundle;
|
||||
import com.intellij.openapi.application.ApplicationNamesInfo;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.editor.colors.*;
|
||||
import com.intellij.openapi.editor.colors.impl.*;
|
||||
import com.intellij.openapi.editor.markup.EffectType;
|
||||
@@ -74,8 +73,6 @@ import java.util.List;
|
||||
public class ColorAndFontOptions extends SearchableConfigurable.Parent.Abstract implements EditorOptionsProvider {
|
||||
public static final String ID = "reference.settingsdialog.IDE.editor.colors";
|
||||
|
||||
private static Logger LOG = Logger.getInstance("#" + ColorAndFontOptions.class.getName());
|
||||
|
||||
private Map<String, MyColorScheme> mySchemes;
|
||||
private MyColorScheme mySelectedScheme;
|
||||
|
||||
@@ -208,7 +205,7 @@ public class ColorAndFontOptions extends SearchableConfigurable.Parent.Abstract
|
||||
|
||||
EditorColorsScheme clone = (EditorColorsScheme)scheme.getOriginalScheme().clone();
|
||||
|
||||
scheme.apply(clone);
|
||||
scheme.apply(clone, false);
|
||||
|
||||
clone.setName(name);
|
||||
MyColorScheme newScheme = new MyColorScheme(clone);
|
||||
@@ -279,12 +276,9 @@ public class ColorAndFontOptions extends SearchableConfigurable.Parent.Abstract
|
||||
boolean activeSchemeModified = false;
|
||||
EditorColorsScheme activeOriginalScheme = mySelectedScheme.getOriginalScheme();
|
||||
for (MyColorScheme scheme : mySchemes.values()) {
|
||||
if (!activeSchemeModified && activeOriginalScheme == scheme.getOriginalScheme()) {
|
||||
activeSchemeModified = scheme.isModified();
|
||||
}
|
||||
|
||||
if (!scheme.isDefault()) {
|
||||
scheme.apply();
|
||||
boolean isModified = scheme.apply();
|
||||
if (isModified && !activeSchemeModified && activeOriginalScheme == scheme.getOriginalScheme()) {
|
||||
activeSchemeModified = true;
|
||||
}
|
||||
result.add(scheme.getOriginalScheme());
|
||||
}
|
||||
@@ -842,7 +836,9 @@ public class ColorAndFontOptions extends SearchableConfigurable.Parent.Abstract
|
||||
|
||||
@Override
|
||||
public void apply(EditorColorsScheme scheme) {
|
||||
if (scheme == null) scheme = getScheme();
|
||||
if (scheme == null) {
|
||||
scheme = getScheme();
|
||||
}
|
||||
scheme.setAttributes(key, isInherited() ? new TextAttributes() : getTextAttributes());
|
||||
}
|
||||
|
||||
@@ -1086,10 +1082,6 @@ public class ColorAndFontOptions extends SearchableConfigurable.Parent.Abstract
|
||||
return myDescriptors;
|
||||
}
|
||||
|
||||
public boolean isDefault() {
|
||||
return myParentScheme instanceof DefaultColorsScheme;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isReadOnly() {
|
||||
return myParentScheme instanceof ReadOnlyColorsScheme;
|
||||
@@ -1123,13 +1115,16 @@ public class ColorAndFontOptions extends SearchableConfigurable.Parent.Abstract
|
||||
return getConsoleLineSpacing() != myParentScheme.getConsoleLineSpacing();
|
||||
}
|
||||
|
||||
public void apply() {
|
||||
private boolean apply() {
|
||||
if (!(myParentScheme instanceof ReadOnlyColorsScheme)) {
|
||||
apply(myParentScheme);
|
||||
return apply(myParentScheme, true);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public void apply(@NotNull EditorColorsScheme scheme) {
|
||||
private boolean apply(@NotNull EditorColorsScheme scheme, boolean onlyIfModified) {
|
||||
boolean isModified = isFontModified() || isConsoleFontModified();
|
||||
|
||||
scheme.setFontPreferences(getFontPreferences());
|
||||
scheme.setLineSpacing(myLineSpacing);
|
||||
scheme.setQuickDocFontSize(getQuickDocFontSize());
|
||||
@@ -1137,12 +1132,16 @@ public class ColorAndFontOptions extends SearchableConfigurable.Parent.Abstract
|
||||
scheme.setConsoleLineSpacing(getConsoleLineSpacing());
|
||||
|
||||
for (EditorSchemeAttributeDescriptor descriptor : myDescriptors) {
|
||||
descriptor.apply(scheme);
|
||||
if (!onlyIfModified || descriptor.isModified()) {
|
||||
isModified = true;
|
||||
descriptor.apply(scheme);
|
||||
}
|
||||
}
|
||||
|
||||
if (scheme instanceof AbstractColorsScheme) {
|
||||
if (isModified && scheme instanceof AbstractColorsScheme) {
|
||||
((AbstractColorsScheme)scheme).setSaveNeeded(true);
|
||||
}
|
||||
return isModified;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -21,12 +21,12 @@ import com.intellij.application.options.SaveSchemeDialog;
|
||||
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.*;
|
||||
import com.intellij.openapi.editor.colors.impl.AbstractColorsScheme;
|
||||
import com.intellij.openapi.editor.colors.impl.EditorColorsSchemeImpl;
|
||||
import com.intellij.openapi.editor.colors.impl.EmptyColorScheme;
|
||||
import com.intellij.openapi.editor.colors.impl.ReadOnlyColorsScheme;
|
||||
import com.intellij.openapi.extensions.Extensions;
|
||||
import com.intellij.openapi.options.SchemeImportException;
|
||||
import com.intellij.openapi.options.SchemeImportUtil;
|
||||
import com.intellij.openapi.options.SchemeImporter;
|
||||
import com.intellij.openapi.options.SchemeImporterEP;
|
||||
import com.intellij.openapi.options.*;
|
||||
import com.intellij.openapi.project.DefaultProjectFactory;
|
||||
import com.intellij.openapi.ui.ComboBox;
|
||||
import com.intellij.openapi.ui.MessageType;
|
||||
@@ -83,7 +83,7 @@ public class SchemesPanel extends JPanel implements SkipSelfSearchComponent {
|
||||
selected instanceof AbstractColorsScheme ? ((AbstractColorsScheme)selected).getOriginal() : null;
|
||||
myResetButton.setEnabled(
|
||||
!readOnly &&
|
||||
selectedName.startsWith(DefaultColorsScheme.EDITABLE_COPY_PREFIX) &&
|
||||
selectedName.startsWith(SchemeManager.EDITABLE_COPY_PREFIX) &&
|
||||
originalScheme instanceof ReadOnlyColorsScheme);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@ 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.options.SchemeManager;
|
||||
import com.intellij.openapi.ui.DialogWrapper;
|
||||
import com.intellij.openapi.ui.Messages;
|
||||
import com.intellij.util.text.UniqueNameGenerator;
|
||||
@@ -79,7 +80,7 @@ public class SaveSchemeDialog extends DialogWrapper {
|
||||
}
|
||||
else if (
|
||||
isDefaultSchemeName(schemeName) ||
|
||||
schemeName.startsWith(DefaultColorsScheme.EDITABLE_COPY_PREFIX)) {
|
||||
schemeName.startsWith(SchemeManager.EDITABLE_COPY_PREFIX)) {
|
||||
Messages.showMessageDialog(getContentPane(), ApplicationBundle.message("error.illegal.scheme.name"),
|
||||
CommonBundle.getErrorTitle(), Messages.getErrorIcon());
|
||||
return;
|
||||
|
||||
+23
-5
@@ -88,8 +88,12 @@ public class EditorColorsManagerImpl extends EditorColorsManager implements Pers
|
||||
EditorColorsSchemeImpl scheme = isBundled ? new BundledScheme() : new EditorColorsSchemeImpl(null);
|
||||
// todo be lazy
|
||||
scheme.readExternal(dataHolder.read());
|
||||
// https://gist.github.com/develar/6efc34c5f11ad50346e8eaef020b0ee4
|
||||
//dataHolder.updateDigest(scheme);
|
||||
// we don't need to update digest for bundled scheme because
|
||||
// 1) it can be computed on demand later (because bundled scheme is not mutable)
|
||||
// 2) in the future user copy of bundled scheme will use bundled scheme as parent (not as full copy)
|
||||
if (!isBundled) {
|
||||
//dataHolder.updateDigest(scheme);
|
||||
}
|
||||
return scheme;
|
||||
}
|
||||
|
||||
@@ -116,6 +120,21 @@ public class EditorColorsManagerImpl extends EditorColorsManager implements Pers
|
||||
public String getSchemeExtension() {
|
||||
return ".icls";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSchemeEqualToBundled(@NotNull EditorColorsSchemeImpl scheme) {
|
||||
if (!scheme.getName().startsWith(SchemeManager.EDITABLE_COPY_PREFIX)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
AbstractColorsScheme bundledScheme =
|
||||
(AbstractColorsScheme)mySchemeManager.findSchemeByName(scheme.getName().substring(SchemeManager.EDITABLE_COPY_PREFIX.length()));
|
||||
if (bundledScheme == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return scheme.isEqualToBundled(bundledScheme);
|
||||
}
|
||||
}
|
||||
mySchemeManager = schemeManagerFactory.create(FILE_SPEC, new EditorColorSchemeProcessor());
|
||||
|
||||
@@ -142,7 +161,6 @@ public class EditorColorsManagerImpl extends EditorColorsManager implements Pers
|
||||
loadAdditionalTextAttributes();
|
||||
}
|
||||
|
||||
|
||||
private void initEditableDefaultSchemesCopies() {
|
||||
for (DefaultColorsScheme defaultScheme : myDefaultColorSchemeManager.getAllSchemes()) {
|
||||
if (defaultScheme.hasEditableCopy()) {
|
||||
@@ -172,7 +190,7 @@ public class EditorColorsManagerImpl extends EditorColorsManager implements Pers
|
||||
if (editableCopy == null) {
|
||||
editableCopy = (AbstractColorsScheme)initialScheme.clone();
|
||||
editableCopy.setName(editableCopyName);
|
||||
addColorsScheme(editableCopy);
|
||||
mySchemeManager.addScheme(editableCopy);
|
||||
}
|
||||
editableCopy.setCanBeDeleted(false);
|
||||
}
|
||||
@@ -205,7 +223,7 @@ public class EditorColorsManagerImpl extends EditorColorsManager implements Pers
|
||||
}
|
||||
|
||||
public String getEditableCopyName() {
|
||||
return DefaultColorsScheme.EDITABLE_COPY_PREFIX + getName();
|
||||
return SchemeManager.EDITABLE_COPY_PREFIX + getName();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -121,4 +121,13 @@ fun <T> Stream<T>?.getIfSingle(): T? =
|
||||
*
|
||||
* Also see [Stream.concat] documentation for other possible issues of concatenating large number of streams.
|
||||
*/
|
||||
fun <T> concat(vararg streams: Stream<T>): Stream<T> = Stream.of(*streams).reduce(Stream.empty()) { a, b -> Stream.concat(a, b) }
|
||||
fun <T> concat(vararg streams: Stream<T>): Stream<T> = Stream.of(*streams).reduce(Stream.empty()) { a, b -> Stream.concat(a, b) }
|
||||
|
||||
inline fun MutableList<Throwable>.catch(runnable: () -> Unit) {
|
||||
try {
|
||||
runnable()
|
||||
}
|
||||
catch (e: Throwable) {
|
||||
add(e)
|
||||
}
|
||||
}
|
||||
@@ -62,12 +62,13 @@ abstract class LazySchemeProcessor<SCHEME : Scheme, MUTABLE_SCHEME : SCHEME>(pri
|
||||
name: String,
|
||||
attributeProvider: Function<String, String?>,
|
||||
isBundled: Boolean = false): MUTABLE_SCHEME
|
||||
|
||||
override final fun writeScheme(scheme: MUTABLE_SCHEME) = (scheme as SerializableScheme).writeScheme()
|
||||
|
||||
open fun isSchemeFile(name: CharSequence) = true
|
||||
|
||||
open fun isSchemeDefault(scheme: MUTABLE_SCHEME, digest: ByteArray) = false
|
||||
|
||||
open fun isSchemeEqualToBundled(scheme: MUTABLE_SCHEME) = false
|
||||
}
|
||||
|
||||
class DigestOutputStream(val digest: MessageDigest) : OutputStream() {
|
||||
@@ -79,9 +80,7 @@ class DigestOutputStream(val digest: MessageDigest) : OutputStream() {
|
||||
digest.update(b, off, len)
|
||||
}
|
||||
|
||||
override fun toString(): String {
|
||||
return "[Digest Output Stream] " + digest.toString()
|
||||
}
|
||||
override fun toString() = "[Digest Output Stream] $digest"
|
||||
}
|
||||
|
||||
fun Element.digest(): ByteArray {
|
||||
|
||||
@@ -25,6 +25,8 @@ import java.util.List;
|
||||
|
||||
@SuppressWarnings("UnusedParameters")
|
||||
public abstract class SchemeManager<T extends Scheme> {
|
||||
public final static String EDITABLE_COPY_PREFIX = "_@user_";
|
||||
|
||||
@NotNull
|
||||
public abstract Collection<T> loadSchemes();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user