package org.f2o.absurdum.puck.gui.panels.code; import java.io.IOException; import java.util.Collections; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import org.f2o.absurdum.puck.gui.config.PuckConfiguration; import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea; import org.fife.ui.rsyntaxtextarea.Theme; /**A configuration option that applies to a range of RSyntaxTextAreas.*/ public class RSyntaxOption { private String configOptionName; private boolean enabled; /**This is the object that actually knows how to make the option take real effect in a text area.*/ private RSyntaxOptionApplier toggler; //Possible scopes of options (which text areas they affect) public static int ALL_AREAS = 0; public static int SMALL_AREAS = 1; public static int LARGE_AREAS = 2; private int optionScope; private static Map instances = Collections.synchronizedMap( new HashMap() ); private static Map optionScopes = Collections.synchronizedMap( new HashMap() ); private static Map optionTogglers = Collections.synchronizedMap( new HashMap() ); //maybe move to RSyntaxThemeUtil: private static String[] themeNames = new String[] { "default","default-alt","dark","eclipse","high-contrast","idea","vs" }; private static Theme[] themes = new Theme[themeNames.length]; private static String themePackage = "org/f2o/absurdum/puck/staticconf/rsthemes"; static { optionScopes.put("rsyntaxWordWrap", ALL_AREAS); //optionScopes.put("rsyntaxShowLineNumbers", ALL_AREAS); //scroll pane optionScopes.put("rsyntaxShowTabLines", ALL_AREAS); optionScopes.put("rsyntaxTabsEmulated", ALL_AREAS); optionTogglers.put("rsyntaxWordWrap", new RSyntaxOptionApplier() { public void setOptionEnabled(RSyntaxTextArea ta, boolean enabled) { ta.setLineWrap(enabled); } }); optionTogglers.put("rsyntaxShowTabLines", new RSyntaxOptionApplier() { public void setOptionEnabled(RSyntaxTextArea ta, boolean enabled) { ta.setPaintTabLines(enabled); } }); optionTogglers.put("rsyntaxTabsEmulated", new RSyntaxOptionApplier() { public void setOptionEnabled(RSyntaxTextArea ta, boolean enabled) { if ( enabled ) ta.convertTabsToSpaces(); else ta.convertSpacesToTabs(); ta.setTabsEmulated(enabled); } }); //load themes for ( int i = 0 ; i < themeNames.length ; i++ ) { final String themeName = themeNames[i]; try { Theme theme = Theme.load(RSyntaxOption.class.getClassLoader().getResourceAsStream(themePackage+"/"+themeName+".xml")); themes[i] = theme; } catch ( IOException ioe ) { System.err.println("Could not load theme " + themePackage+"/"+themeName+".xml"); } } //theme option togglers for ( int i = 0 ; i < themes.length ; i++ ) { final String themeName = themeNames[i]; final Theme theme = themes[i]; if ( theme != null ) { optionTogglers.put("rsyntaxTheme"+themeName, new RSyntaxOptionApplier() { public void setOptionEnabled(RSyntaxTextArea ta, boolean enabled) { if ( enabled ) { RSyntaxThemeUtil.applyTheme ( theme , ta ); } } } ); } } } private RSyntaxOption ( String configOptionName , int optionScope , RSyntaxOptionApplier toggler ) { this.toggler = toggler; this.configOptionName = configOptionName; this.optionScope = optionScope; enabled = PuckConfiguration.getInstance().getBooleanProperty(configOptionName); } public static RSyntaxOption getInstanceFor ( String configOptionName ) { RSyntaxOption instance; instance = (RSyntaxOption) instances.get(configOptionName); if ( instance != null ) return instance; //no instance yet for this config property: create and register it int optionScope; Integer optionScopeInteger = (Integer)optionScopes.get(configOptionName); if ( optionScopeInteger == null ) optionScope = ALL_AREAS; else optionScope = optionScopeInteger.intValue(); RSyntaxOptionApplier toggler = (RSyntaxOptionApplier) optionTogglers.get(configOptionName); instance = new RSyntaxOption ( configOptionName , optionScope , toggler ); instances.put(configOptionName, instance); return instance; } /** * Returns whether the option is currently enabled. * @return */ public boolean isOptionEnabled() { return enabled; } /** * Sets the option as enabled or disabled in the text areas.. */ public void setOptionEnabled(boolean enabled) { if ( optionScope == SMALL_AREAS || optionScope == ALL_AREAS ) { List smallAreas = RSyntaxTextAreaRegistry.getInstance().getSmallTextAreas(); for ( Iterator it = smallAreas.iterator() ; it.hasNext(); ) { RSyntaxTextArea area = (RSyntaxTextArea) it.next(); toggler.setOptionEnabled(area,enabled); } } if ( optionScope == LARGE_AREAS || optionScope == ALL_AREAS ) { List largeAreas = RSyntaxTextAreaRegistry.getInstance().getLargeTextAreas(); for ( Iterator it = largeAreas.iterator() ; it.hasNext(); ) { RSyntaxTextArea area = (RSyntaxTextArea) it.next(); toggler.setOptionEnabled(area,enabled); } } this.enabled = enabled; } /** * Returns the supported theme names. * @return */ public static String[] getThemeNames () { return themeNames; } }