1 /******************************************************************************* 2 * Copyright (c) 2014 IBM Corporation and others. 3 * 4 * This program and the accompanying materials 5 * are made available under the terms of the Eclipse Public License 2.0 6 * which accompanies this distribution, and is available at 7 * https://www.eclipse.org/legal/epl-2.0/ 8 * 9 * SPDX-License-Identifier: EPL-2.0 10 * 11 * Contributors: 12 * IBM Corporation - initial API and implementation 13 *******************************************************************************/ 14 package org.eclipse.e4.ui.css.swt.helpers; 15 16 import java.util.ArrayList; 17 import java.util.Collections; 18 import java.util.List; 19 import org.eclipse.core.runtime.preferences.IEclipsePreferences; 20 import org.eclipse.core.runtime.preferences.IEclipsePreferences.IPreferenceChangeListener; 21 import org.eclipse.core.runtime.preferences.IEclipsePreferences.PreferenceChangeEvent; 22 import org.osgi.service.prefs.Preferences; 23 24 public class EclipsePreferencesHelper { 25 public static final String PROPS_OVERRIDDEN_BY_CSS_PROP = "overriddenByCSS"; 26 27 public static final String SEPARATOR = ","; 28 29 private static final String MULTI_VALUE_FORMATTER = "%s%s" + SEPARATOR; 30 31 private static IPreferenceChangeListener preferenceChangeListener; 32 33 private static String previousThemeId; 34 35 private static String currentThemeId; 36 appendOverriddenPropertyName( IEclipsePreferences preferences, String name)37 public static void appendOverriddenPropertyName( 38 IEclipsePreferences preferences, String name) { 39 String value = preferences.get(PROPS_OVERRIDDEN_BY_CSS_PROP, SEPARATOR); 40 if (value.equals(SEPARATOR)) { 41 preferences 42 .addPreferenceChangeListener(getPreferenceChangeListener()); 43 } 44 if (!isOverriddenByCSS(value, name)) { 45 preferences.put(PROPS_OVERRIDDEN_BY_CSS_PROP, 46 String.format(MULTI_VALUE_FORMATTER, value, name)); 47 } 48 } 49 getPreferenceChangeListener()50 public static IPreferenceChangeListener getPreferenceChangeListener() { 51 if (preferenceChangeListener == null) { 52 preferenceChangeListener = new PreferenceOverriddenByCssChangeListener(); 53 } 54 return preferenceChangeListener; 55 } 56 isOverriddenByCSS(String propertiesOverriddenByCSS, String property)57 private static boolean isOverriddenByCSS(String propertiesOverriddenByCSS, 58 String property) { 59 return propertiesOverriddenByCSS.contains(SEPARATOR + property 60 + SEPARATOR); 61 } 62 getOverriddenPropertyNames( IEclipsePreferences preferences)63 public static List<String> getOverriddenPropertyNames( 64 IEclipsePreferences preferences) { 65 String value = preferences.get(PROPS_OVERRIDDEN_BY_CSS_PROP, null); 66 if (value == null) { 67 return Collections.emptyList(); 68 } 69 List<String> result = new ArrayList<>(); 70 for (String name : value.split(SEPARATOR)) { 71 if (name != null && !name.isEmpty()) { 72 result.add(name); 73 } 74 } 75 return result; 76 } 77 removeOverriddenPropertyNames( IEclipsePreferences preferences)78 public static void removeOverriddenPropertyNames( 79 IEclipsePreferences preferences) { 80 preferences.remove(PROPS_OVERRIDDEN_BY_CSS_PROP); 81 preferences 82 .removePreferenceChangeListener(getPreferenceChangeListener()); 83 } 84 removeOverriddenByCssProperty( IEclipsePreferences preferences, String preferenceToRemove)85 public static void removeOverriddenByCssProperty( 86 IEclipsePreferences preferences, String preferenceToRemove) { 87 StringBuilder overriddenByCSS = new StringBuilder(SEPARATOR); 88 for (String preference : getOverriddenPropertyNames(preferences)) { 89 if (!preference.equals(preferenceToRemove)) { 90 overriddenByCSS.append(preference).append(SEPARATOR); 91 } 92 } 93 preferences.put(PROPS_OVERRIDDEN_BY_CSS_PROP, 94 overriddenByCSS.toString()); 95 } 96 setPreviousThemeId(String themeId)97 public static void setPreviousThemeId(String themeId) { 98 previousThemeId = themeId; 99 } 100 setCurrentThemeId(String themeId)101 public static void setCurrentThemeId(String themeId) { 102 currentThemeId = themeId; 103 } 104 isThemeChanged()105 public static boolean isThemeChanged() { 106 return currentThemeId != null && !currentThemeId.equals(previousThemeId); 107 } 108 109 public static class PreferenceOverriddenByCssChangeListener implements 110 IPreferenceChangeListener { 111 @Override preferenceChange(PreferenceChangeEvent event)112 public void preferenceChange(PreferenceChangeEvent event) { 113 if (isModified(event) && isRelatedToOverriddenByCss(event)) { 114 removeOverriddenByCssProperty(event); 115 } 116 } 117 isModified(PreferenceChangeEvent event)118 private boolean isModified(PreferenceChangeEvent event) { 119 return event.getOldValue() != null && event.getNewValue() != null; 120 } 121 isRelatedToOverriddenByCss(PreferenceChangeEvent event)122 private boolean isRelatedToOverriddenByCss(PreferenceChangeEvent event) { 123 return isOverriddenByCSS( 124 event.getNode() 125 .get(PROPS_OVERRIDDEN_BY_CSS_PROP, SEPARATOR), 126 event.getKey()); 127 } 128 removeOverriddenByCssProperty(PreferenceChangeEvent event)129 protected void removeOverriddenByCssProperty(PreferenceChangeEvent event) { 130 Preferences preferences = event.getNode(); 131 if (preferences instanceof IEclipsePreferences) { 132 EclipsePreferencesHelper.removeOverriddenByCssProperty( 133 (IEclipsePreferences) preferences, event.getKey()); 134 } 135 } 136 } 137 } 138