don't use children of deleted scheme directory to remove schemes — dir is invalid at this moment

get rid of currentSchemeName — instance is enough
simplify scheme manager — client can just call setCurrent instead of implementing own logic to notify "current scheme changed"
This commit is contained in:
Vladimir Krivosheev
2015-07-07 12:45:39 +02:00
parent 756d1df8eb
commit 49ed56f2ed
17 changed files with 163 additions and 135 deletions
@@ -41,7 +41,7 @@ public abstract class BaseSchemeProcessor<T extends ExternalizableScheme> implem
}
@Override
public void onCurrentSchemeChanged(Scheme newCurrentScheme) {
public void onCurrentSchemeChanged(@Nullable Scheme oldScheme) {
}
@Nullable
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
* Copyright 2000-2015 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.
@@ -21,6 +21,7 @@ import org.jdom.Document;
import org.jdom.JDOMException;
import org.jdom.Parent;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.IOException;
@@ -45,5 +46,5 @@ public interface SchemeProcessor<T extends ExternalizableScheme> {
void onSchemeDeleted(@NotNull T scheme);
void onCurrentSchemeChanged(final Scheme oldCurrentScheme);
void onCurrentSchemeChanged(@Nullable Scheme oldScheme);
}
@@ -25,6 +25,7 @@ import java.io.File;
import java.util.Collection;
import java.util.List;
@SuppressWarnings("UnusedParameters")
public abstract class SchemesManager<T extends Scheme, E extends ExternalizableScheme> {
@NotNull
public abstract Collection<E> loadSchemes();
@@ -40,13 +41,28 @@ public abstract class SchemesManager<T extends Scheme, E extends ExternalizableS
*/
public abstract void clearAllSchemes();
@SuppressWarnings("NullableProblems")
@NotNull
public abstract List<T> getAllSchemes();
@Nullable
public abstract T findSchemeByName(@NotNull String schemeName);
public abstract void setCurrentSchemeName(@Nullable String schemeName);
@Deprecated
/**
* @deprecated Use {@link #setCurrent}
*/
public void setCurrentSchemeName(@Nullable String schemeName) {
}
public final void setCurrent(@Nullable T scheme) {
setCurrent(scheme, true);
}
public void setCurrent(@Nullable T scheme, boolean notify) {
//noinspection deprecation
setCurrentSchemeName(scheme == null ? null : scheme.getName());
}
@Nullable
public abstract T getCurrentScheme();
@@ -65,10 +81,10 @@ public abstract class SchemesManager<T extends Scheme, E extends ExternalizableS
}
public void setSchemes(@NotNull List<T> schemes) {
setSchemes(schemes, null);
setSchemes(schemes, null, null);
}
public void setSchemes(@NotNull List<T> schemes, @Nullable Condition<T> removeCondition) {
public void setSchemes(@NotNull List<T> newSchemes, @Nullable T newCurrentScheme, @Nullable Condition<T> removeCondition) {
}
/**
@@ -0,0 +1,18 @@
/*
* Copyright 2000-2015 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.components
public inline fun <reified T: Any> service(): T? = ServiceManager.getService(javaClass<T>())
@@ -48,10 +48,6 @@ public class EmptySchemesManager extends SchemesManager {
return null;
}
@Override
public void setCurrentSchemeName(String schemeName) {
}
@Override
public Scheme getCurrentScheme() {
return null;
@@ -20,6 +20,7 @@ import com.intellij.openapi.editor.colors.EditorColorsScheme;
import com.intellij.openapi.editor.colors.impl.DefaultColorsScheme;
import org.jdom.Element;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
@@ -57,10 +58,16 @@ public class DefaultColorSchemesManager implements PersistentStateComponent<Elem
}
}
@NotNull
public DefaultColorsScheme[] getAllSchemes() {
return mySchemes.toArray(new DefaultColorsScheme[mySchemes.size()]);
}
@NotNull
public DefaultColorsScheme getFirstScheme() {
return mySchemes.get(0);
}
@Nullable
public EditorColorsScheme getScheme(String name) {
for (DefaultColorsScheme scheme : mySchemes) {
@@ -66,6 +66,7 @@ public abstract class CodeStyleSchemes {
public abstract void addScheme(@NotNull CodeStyleScheme currentScheme);
@Deprecated
public abstract void setSchemes(@NotNull List<CodeStyleScheme> schemes);
}
@@ -21,6 +21,7 @@ import com.intellij.psi.codeStyle.CodeStyleSchemes;
import com.intellij.psi.codeStyle.CodeStyleSettings;
import com.intellij.psi.codeStyle.CodeStyleSettingsManager;
import com.intellij.psi.impl.source.codeStyle.CodeStyleSchemeImpl;
import com.intellij.psi.impl.source.codeStyle.CodeStyleSchemesImpl;
import com.intellij.util.EventDispatcher;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
@@ -164,8 +165,7 @@ public class CodeStyleSchemesModel {
myUsePerProjectSettings || myGlobalSelected == null ? null : myGlobalSelected.getName();
projectSettingsManager.PER_PROJECT_SETTINGS = myProjectScheme.getCodeStyleSettings();
CodeStyleSchemes.getInstance().setSchemes(mySchemes);
CodeStyleSchemes.getInstance().setCurrentScheme(myGlobalSelected);
((CodeStyleSchemesImpl)CodeStyleSchemes.getInstance()).getSchemeManager().setSchemes(mySchemes, myGlobalSelected, null);
// We want to avoid the situation when 'real code style' differs from the copy stored here (e.g. when 'real code style' changes
// are 'committed' by pressing 'Apply' button). So, we reset the copies here assuming that this method is called on 'Apply'
@@ -131,10 +131,10 @@ public class InspectionProfileManagerImpl extends InspectionProfileManager imple
}
@Override
public void onCurrentSchemeChanged(final Scheme oldCurrentScheme) {
public void onCurrentSchemeChanged(@Nullable Scheme oldScheme) {
Profile current = mySchemesManager.getCurrentScheme();
if (current != null) {
fireProfileChanged((Profile)oldCurrentScheme, current, null);
fireProfileChanged((Profile)oldScheme, current, null);
}
onProfilesChanged();
}
@@ -287,9 +287,10 @@ public class InspectionProfileManagerImpl extends InspectionProfileManager imple
public void setRootProfile(String rootProfile) {
Profile current = mySchemesManager.getCurrentScheme();
if (current != null && !Comparing.strEqual(rootProfile, current.getName())) {
fireProfileChanged(current, getProfile(rootProfile), null);
Profile scheme = getProfile(rootProfile);
fireProfileChanged(current, scheme, null);
mySchemesManager.setCurrent(scheme, false);
}
mySchemesManager.setCurrentSchemeName(rootProfile);
}
@Override
@@ -40,7 +40,8 @@ public class ProjectInspectionToolsConfigurable extends InspectionToolsConfigura
protected void applyRootProfile(String name, boolean isShared) {
if (isShared) {
myProjectProfileManager.setProjectProfile(name);
} else {
}
else {
myProfileManager.setRootProfile(name);
myProjectProfileManager.setProjectProfile(null);
}
@@ -37,8 +37,6 @@ public abstract class CodeStyleSchemesImpl extends CodeStyleSchemes {
@NonNls
static final String CODE_STYLES_DIR_PATH = StoragePathMacros.ROOT_CONFIG + "/codestyles";
public String CURRENT_SCHEME_NAME = DEFAULT_SCHEME_NAME;
protected final SchemesManager<CodeStyleScheme, CodeStyleSchemeImpl> mySchemesManager;
public CodeStyleSchemesImpl(@NotNull SchemesManagerFactory schemesManagerFactory) {
@@ -87,9 +85,7 @@ public abstract class CodeStyleSchemesImpl extends CodeStyleSchemes {
@Override
public void setCurrentScheme(CodeStyleScheme scheme) {
String schemeName = scheme == null ? null : scheme.getName();
mySchemesManager.setCurrentSchemeName(schemeName);
CURRENT_SCHEME_NAME = schemeName;
mySchemesManager.setCurrent(scheme);
}
@SuppressWarnings("ForLoopThatDoesntUseLoopVariable")
@@ -140,6 +136,11 @@ public abstract class CodeStyleSchemesImpl extends CodeStyleSchemes {
mySchemesManager.setSchemes(schemes);
}
@NotNull
public SchemesManager<CodeStyleScheme, CodeStyleSchemeImpl> getSchemeManager() {
return mySchemesManager;
}
@Override
public CodeStyleScheme getDefaultScheme() {
return findSchemeByName(DEFAULT_SCHEME_NAME);
@@ -40,6 +40,8 @@ import org.jetbrains.annotations.Nullable;
additionalExportFile = CodeStyleSchemesImpl.CODE_STYLES_DIR_PATH
)
class PersistableCodeStyleSchemes extends CodeStyleSchemesImpl implements PersistentStateComponent<Element> {
public String CURRENT_SCHEME_NAME = DEFAULT_SCHEME_NAME;
public PersistableCodeStyleSchemes(@NotNull SchemesManagerFactory schemesManagerFactory) {
super(schemesManagerFactory);
}
@@ -47,6 +49,8 @@ class PersistableCodeStyleSchemes extends CodeStyleSchemesImpl implements Persis
@Nullable
@Override
public Element getState() {
CodeStyleScheme currentScheme = getCurrentScheme();
CURRENT_SCHEME_NAME = currentScheme == null ? null : currentScheme.getName();
return XmlSerializer.serialize(this, new SerializationFilter() {
@Override
public boolean accepts(@NotNull Accessor accessor, @NotNull Object bean) {
@@ -102,7 +102,10 @@ public class EditorColorsManagerImpl extends EditorColorsManager implements Pers
}
@Override
public void onCurrentSchemeChanged(final Scheme newCurrentScheme) {
public void onCurrentSchemeChanged(@Nullable Scheme oldScheme) {
LafManager.getInstance().updateUI();
EditorFactory.getInstance().refreshAllEditors();
fireChanges(mySchemesManager.getCurrentScheme());
}
@@ -235,21 +238,16 @@ public class EditorColorsManagerImpl extends EditorColorsManager implements Pers
@Override
public void setGlobalScheme(@Nullable EditorColorsScheme scheme) {
setGlobalSchemeInner(scheme);
LafManager.getInstance().updateUI();
EditorFactory.getInstance().refreshAllEditors();
fireChanges(scheme);
mySchemesManager.setCurrent(scheme == null ? getDefaultScheme() : scheme);
}
private void setGlobalSchemeInner(@Nullable EditorColorsScheme scheme) {
mySchemesManager.setCurrentSchemeName(scheme == null ? getDefaultScheme().getName() : scheme.getName());
mySchemesManager.setCurrent(scheme == null ? getDefaultScheme() : scheme, false);
}
@NotNull
private DefaultColorsScheme getDefaultScheme() {
return myDefaultColorSchemesManager.getAllSchemes()[0];
return myDefaultColorSchemesManager.getFirstScheme();
}
@NotNull
@@ -23,6 +23,7 @@ import com.intellij.openapi.keymap.Keymap;
import com.intellij.openapi.keymap.KeymapManagerListener;
import com.intellij.openapi.keymap.ex.KeymapManagerEx;
import com.intellij.openapi.options.BaseSchemeProcessor;
import com.intellij.openapi.options.Scheme;
import com.intellij.openapi.options.SchemesManager;
import com.intellij.openapi.options.SchemesManagerFactory;
import com.intellij.openapi.util.*;
@@ -74,6 +75,14 @@ public class KeymapManagerImpl extends KeymapManagerEx implements PersistentStat
public State getState(@NotNull KeymapImpl scheme) {
return scheme.canModify() ? State.POSSIBLY_CHANGED : State.NON_PERSISTENT;
}
@Override
public void onCurrentSchemeChanged(@Nullable Scheme oldScheme) {
Keymap keymap = mySchemesManager.getCurrentScheme();
for (KeymapManagerListener listener : myListeners) {
listener.activeKeymapChanged(keymap);
}
}
};
mySchemesManager = factory.createSchemesManager(KEYMAPS_DIR_PATH, schemeProcessor, RoamingType.PER_USER);
@@ -137,13 +146,7 @@ public class KeymapManagerImpl extends KeymapManagerEx implements PersistentStat
@Override
public void setActiveKeymap(@Nullable Keymap keymap) {
Keymap previousActive = mySchemesManager.getCurrentScheme();
mySchemesManager.setCurrentSchemeName(keymap == null ? null : keymap.getName());
if (keymap != previousActive) {
for (KeymapManagerListener listener : myListeners) {
listener.activeKeymapChanged(keymap);
}
}
mySchemesManager.setCurrent(keymap);
}
@Override
@@ -177,8 +180,8 @@ public class KeymapManagerImpl extends KeymapManagerEx implements PersistentStat
return mySchemesManager;
}
public void setKeymaps(@NotNull List<Keymap> keymaps, @Nullable Condition<Keymap> removeCondition) {
mySchemesManager.setSchemes(keymaps, removeCondition);
public void setKeymaps(@NotNull List<Keymap> keymaps, @Nullable Keymap active, @Nullable Condition<Keymap> removeCondition) {
mySchemesManager.setSchemes(keymaps, active, removeCondition);
}
@Override
@@ -777,8 +777,7 @@ public class KeymapPanel extends JPanel implements SearchableConfigurable, Confi
ensureUniqueKeymapNames();
KeymapManagerImpl keymapManager = (KeymapManagerImpl)KeymapManager.getInstance();
// we must specify the same filter, which was used to get original items
keymapManager.setKeymaps(myEditor.apply(), KEYMAP_FILTER);
keymapManager.setActiveKeymap(myEditor.getModel().getSelected());
keymapManager.setKeymaps(myEditor.apply(), myEditor.getModel().getSelected(), KEYMAP_FILTER);
ActionToolbarImpl.updateAllToolbarsImmediately();
}
@@ -21,11 +21,11 @@ import com.intellij.openapi.application.WriteAction
import com.intellij.openapi.application.ex.DecodeDefaultsUtil
import com.intellij.openapi.application.runWriteAction
import com.intellij.openapi.components.RoamingType
import com.intellij.openapi.components.ServiceManager
import com.intellij.openapi.components.impl.stores.DirectoryBasedStorage
import com.intellij.openapi.components.impl.stores.DirectoryStorageData
import com.intellij.openapi.components.impl.stores.StorageUtil
import com.intellij.openapi.components.impl.stores.StreamProvider
import com.intellij.openapi.components.service
import com.intellij.openapi.diagnostic.Logger
import com.intellij.openapi.extensions.AbstractExtensionPointBean
import com.intellij.openapi.util.Comparing
@@ -64,7 +64,6 @@ public class SchemeManagerImpl<T : Scheme, E : ExternalizableScheme>(private val
private val readOnlyExternalizableSchemes = THashMap<String, E>()
private var currentScheme: T? = null
private var currentSchemeName: String? = null
private var directory: VirtualFile? = null
@@ -86,56 +85,55 @@ public class SchemeManagerImpl<T : Scheme, E : ExternalizableScheme>(private val
updateExtension = false
}
val virtualFileTracker = if (provider != null && provider.enabled) null else ServiceManager.getService(javaClass<VirtualFileTracker>())
if (virtualFileTracker != null) {
val baseDirPath = ioDirectory.getAbsolutePath().replace(File.separatorChar, '/')
virtualFileTracker.addTracker(LocalFileSystem.PROTOCOL_PREFIX + baseDirPath, object : VirtualFileAdapter() {
if (provider == null || !provider.enabled) {
service<VirtualFileTracker>()?.addTracker("${LocalFileSystem.PROTOCOL_PREFIX}${ioDirectory.getAbsolutePath().replace(File.separatorChar, '/')}", object : VirtualFileAdapter() {
override fun contentsChanged(event: VirtualFileEvent) {
if (event.getRequestor() != null || !isMy(event)) {
return
}
val scheme = findExternalizableSchemeByFileName(event.getFile().getName())
val oldScheme = findExternalizableSchemeByFileName(event.getFile().getName())
var oldCurrentScheme: T? = null
if (scheme != null) {
oldCurrentScheme = getCurrentScheme()
if (oldScheme != null) {
oldCurrentScheme = currentScheme
@suppress("UNCHECKED_CAST")
removeScheme(scheme as T)
processor.onSchemeDeleted(scheme)
removeScheme(oldScheme as T)
processor.onSchemeDeleted(oldScheme)
}
val readScheme = readSchemeFromFile(event.getFile(), false)
if (readScheme != null) {
processor.initScheme(readScheme)
processor.onSchemeAdded(readScheme)
val newScheme = readSchemeFromFile(event.getFile(), false)
if (newScheme != null) {
processor.initScheme(newScheme)
processor.onSchemeAdded(newScheme)
var newCurrentScheme = getCurrentScheme()
if (oldCurrentScheme != null && newCurrentScheme == null) {
setCurrentSchemeName(readScheme.getName())
newCurrentScheme = getCurrentScheme()
}
updateCurrentScheme(oldCurrentScheme, newScheme)
}
}
if (oldCurrentScheme !== newCurrentScheme) {
processor.onCurrentSchemeChanged(oldCurrentScheme)
}
private fun updateCurrentScheme(oldCurrentScheme: T?, newCurrentScheme: E? = null) {
if (oldCurrentScheme != currentScheme && currentScheme == null) {
@suppress("UNCHECKED_CAST")
setCurrent(newCurrentScheme as T? ?: schemes.firstOrNull())
}
}
override fun fileCreated(event: VirtualFileEvent) {
if (event.getRequestor() == null) {
if (event.getFile().isDirectory()) {
val dir = getDirectory()
if (event.getFile() == dir) {
for (file in dir!!.getChildren()) {
if (isMy(file)) {
schemeCreatedExternally(file)
}
if (event.getRequestor() != null) {
return
}
if (event.getFile().isDirectory()) {
val dir = getDirectory()
if (event.getFile() == dir) {
for (file in dir!!.getChildren()) {
if (isMy(file)) {
schemeCreatedExternally(file)
}
}
}
else if (isMy(event)) {
schemeCreatedExternally(event.getFile())
}
}
else if (isMy(event)) {
schemeCreatedExternally(event.getFile())
}
}
@@ -148,45 +146,26 @@ public class SchemeManagerImpl<T : Scheme, E : ExternalizableScheme>(private val
}
override fun fileDeleted(event: VirtualFileEvent) {
if (event.getRequestor() == null) {
if (event.getFile().isDirectory()) {
val dir = directory
if (event.getFile() == dir) {
directory = null
for (file in dir!!.getChildren()) {
if (isMy(file)) {
schemeDeletedExternally(file)
}
}
}
}
else if (isMy(event)) {
schemeDeletedExternally(event.getFile())
if (event.getRequestor() != null) {
return
}
var oldCurrentScheme = currentScheme
if (event.getFile().isDirectory()) {
val dir = directory
if (event.getFile() == dir) {
directory = null
removeExternalizableSchemes()
}
}
}
private fun schemeDeletedExternally(file: VirtualFile) {
val scheme = findExternalizableSchemeByFileName(file.getName())
var oldCurrentScheme: T? = null
if (scheme != null) {
oldCurrentScheme = getCurrentScheme()
else if (isMy(event)) {
val scheme = findExternalizableSchemeByFileName(event.getFile().getName()) ?: return
@suppress("UNCHECKED_CAST")
removeScheme(scheme as T)
processor.onSchemeDeleted(scheme)
}
var newCurrentScheme = getCurrentScheme()
if (oldCurrentScheme != null && newCurrentScheme == null) {
if (!schemes.isEmpty()) {
setCurrentSchemeName(schemes.get(0).getName())
newCurrentScheme = getCurrentScheme()
}
}
if (oldCurrentScheme !== newCurrentScheme) {
processor.onCurrentSchemeChanged(oldCurrentScheme)
}
updateCurrentScheme(oldCurrentScheme)
}
}, false, ApplicationManager.getApplication())
}
@@ -279,20 +258,25 @@ public class SchemeManagerImpl<T : Scheme, E : ExternalizableScheme>(private val
public fun reload() {
// we must not remove non-persistent (e.g. predefined) schemes, because we cannot load it (obviously)
removeExternalizableSchemes()
loadSchemes()
}
private fun removeExternalizableSchemes() {
// todo check is bundled/read-only schemes correctly handled
for (i in schemes.indices.reversed()) {
val scheme = schemes.get(i)
@suppress("UNCHECKED_CAST")
if (scheme is ExternalizableScheme && getState(scheme as E) != BaseSchemeProcessor.State.NON_PERSISTENT) {
schemes.remove(i)
if (scheme === currentScheme) {
if (scheme == currentScheme) {
currentScheme = null
}
processor.onSchemeDeleted(scheme as E)
}
}
retainExternalInfo(schemes)
loadSchemes()
}
private fun findExternalizableSchemeByFileName(fileName: String): E? {
@@ -620,7 +604,8 @@ public class SchemeManagerImpl<T : Scheme, E : ExternalizableScheme>(private val
override fun getRootDirectory() = ioDirectory
override fun setSchemes(newSchemes: List<T>, removeCondition: Condition<T>?) {
override fun setSchemes(newSchemes: List<T>, newCurrentScheme: T?, removeCondition: Condition<T>?) {
val oldCurrentScheme = currentScheme
if (removeCondition == null) {
schemes.clear()
}
@@ -636,15 +621,18 @@ public class SchemeManagerImpl<T : Scheme, E : ExternalizableScheme>(private val
schemes.addAll(newSchemes)
if (currentSchemeName != null) {
currentScheme = findSchemeByName(currentSchemeName!!)
if (currentScheme != null) {
return
if (oldCurrentScheme != newCurrentScheme) {
if (newCurrentScheme != null) {
currentScheme = newCurrentScheme
}
else if (oldCurrentScheme != null && !schemes.contains(oldCurrentScheme)) {
currentScheme = schemes.firstOrNull()
}
if (oldCurrentScheme != currentScheme) {
processor.onCurrentSchemeChanged(oldCurrentScheme)
}
}
currentScheme = schemes.firstOrNull()
currentSchemeName = currentScheme?.getName()
}
private fun retainExternalInfo(newSchemes: List<T>) {
@@ -745,21 +733,15 @@ public class SchemeManagerImpl<T : Scheme, E : ExternalizableScheme>(private val
return null
}
override fun setCurrentSchemeName(schemeName: String?) {
currentSchemeName = schemeName
currentScheme = null
override fun setCurrent(scheme: T?, notify: Boolean) {
val oldCurrent = currentScheme
currentScheme = scheme
if (notify && oldCurrent != scheme) {
processor.onCurrentSchemeChanged(oldCurrent)
}
}
override fun getCurrentScheme(): T? {
var scheme = currentScheme
if (scheme == null && currentSchemeName != null) {
scheme = findSchemeByName(currentSchemeName!!)
if (scheme != null) {
currentScheme = scheme
}
}
return scheme
}
override fun getCurrentScheme() = currentScheme
override fun removeScheme(scheme: T) {
for (i in schemes.size() - 1 downTo 0) {
@@ -577,7 +577,7 @@ class EditVarConstraintsDialog extends DialogWrapper {
settings.setRightMarginShown(false);
settings.setLineMarkerAreaShown(false);
settings.setIndentGuidesShown(false);
((EditorEx)editor).setHighlighter(HighlighterFactory.createHighlighter(fileType, DefaultColorSchemesManager.getInstance().getAllSchemes()[0], project));
((EditorEx)editor).setHighlighter(HighlighterFactory.createHighlighter(fileType, DefaultColorSchemesManager.getInstance().getFirstScheme(), project));
return editor;
}