001package apps.systemconsole;
002
003import apps.SystemConsole;
004import java.awt.Font;
005import java.util.ArrayList;
006import java.util.Collection;
007import java.util.HashSet;
008import java.util.List;
009import java.util.Set;
010import java.util.prefs.BackingStoreException;
011import java.util.prefs.Preferences;
012import javax.annotation.Nonnull;
013import jmri.beans.Bean;
014import jmri.profile.Profile;
015import jmri.profile.ProfileUtils;
016import jmri.spi.PreferencesManager;
017import jmri.util.prefs.InitializationException;
018import org.openide.util.lookup.ServiceProvider;
019import org.slf4j.Logger;
020import org.slf4j.LoggerFactory;
021
022/**
023 * Manage preferences for the {@link apps.SystemConsole}.
024 *
025 * @author Randall Wood
026 */
027@ServiceProvider(service = PreferencesManager.class)
028public class SystemConsolePreferencesManager extends Bean implements PreferencesManager {
029
030    public static final String SCHEME = "scheme";
031    public static final String FONT_SIZE = "fontSize";
032    public static final String FONT_STYLE = "fontStyle";
033    public static final String WRAP_STYLE = "wrapStyle";
034
035    // default settings
036    private int scheme = 0; // Green on Black
037    private int fontSize = 12;
038    private int fontStyle = Font.PLAIN;
039    private int wrapStyle = SystemConsole.WRAP_STYLE_WORD;
040
041    /*
042     * Unlike most PreferencesProviders, the SystemConsole preferences should be
043     * per-application instead of per-profile.
044     */
045    private boolean initialized = false;
046    private final List<InitializationException> exceptions = new ArrayList<>();
047    private static final Logger log = LoggerFactory.getLogger(SystemConsolePreferencesManager.class);
048
049    @Override
050    public void initialize(Profile profile) throws InitializationException {
051        if (!this.initialized) {
052            Preferences preferences = ProfileUtils.getPreferences(profile, this.getClass(), true);
053            this.setFontSize(preferences.getInt(FONT_SIZE, this.getFontSize()));
054            this.setFontStyle(preferences.getInt(FONT_STYLE, this.getFontStyle()));
055            this.setScheme(preferences.getInt(SCHEME, this.getScheme()));
056            this.setWrapStyle(preferences.getInt(WRAP_STYLE, this.getWrapStyle()));
057            this.initialized = true;
058        }
059    }
060
061    @Override
062    public void savePreferences(Profile profile) {
063        Preferences preferences = ProfileUtils.getPreferences(profile, this.getClass(), true);
064        preferences.putInt(FONT_SIZE, this.getFontSize());
065        preferences.putInt(FONT_STYLE, this.getFontStyle());
066        preferences.putInt(SCHEME, this.getScheme());
067        preferences.putInt(WRAP_STYLE, this.getWrapStyle());
068        try {
069            preferences.sync();
070        } catch (BackingStoreException ex) {
071            log.error("Unable to save preferences.", ex);
072        }
073    }
074
075    @Override
076    public boolean isInitialized(Profile profile) {
077        return this.initialized && this.exceptions.isEmpty();
078    }
079
080    @Override
081    @Nonnull
082    public Collection<Class<? extends PreferencesManager>> getRequires() {
083        return new HashSet<>();
084    }
085
086    @Override
087    @Nonnull
088    public Iterable<Class<?>> getProvides() {
089        Set<Class<?>> provides = new HashSet<>();
090        provides.add(this.getClass());
091        return provides;
092    }
093
094    /**
095     * @return the scheme
096     */
097    public int getScheme() {
098        return scheme;
099    }
100
101    /**
102     * @param scheme the scheme to set
103     */
104    public void setScheme(int scheme) {
105        int oldScheme = this.scheme;
106        this.scheme = scheme;
107        this.firePropertyChange(SCHEME, oldScheme, scheme);
108        SystemConsole.getInstance().setScheme(scheme);
109    }
110
111    /**
112     * @return the fontSize
113     */
114    public int getFontSize() {
115        return fontSize;
116    }
117
118    /**
119     * Sets the fontSize.
120     * <p>
121     * If the parameter is less than 6, the fontSize is set to 6. If the
122     * parameter is greater than 24, the fontSize is set to 24.
123     *
124     * @param fontSize the fontSize to set
125     */
126    public void setFontSize(int fontSize) {
127        int oldFontSize = this.fontSize;
128        this.fontSize = fontSize < 6 ? 6 : fontSize > 24 ? 24 : fontSize;
129        if (this.fontSize != oldFontSize) {
130            this.firePropertyChange(FONT_SIZE, oldFontSize, this.fontSize);
131            SystemConsole.getInstance().setFontSize(this.fontSize);
132        }
133    }
134
135    /**
136     * @return the fontStyle
137     */
138    public int getFontStyle() {
139        return fontStyle;
140    }
141
142    /**
143     * @param fontStyle one of {@link Font#BOLD}, {@link Font#ITALIC}, or
144     *                  {@link Font#PLAIN}.
145     */
146    public void setFontStyle(int fontStyle) {
147        if (fontStyle == Font.BOLD || fontStyle == Font.ITALIC || fontStyle == Font.PLAIN || fontStyle == (Font.BOLD | Font.ITALIC)) {
148            int oldFontStyle = this.fontStyle;
149            this.fontStyle = fontStyle;
150            if (this.fontStyle != oldFontStyle) {
151                this.firePropertyChange(FONT_STYLE, oldFontStyle, fontStyle);
152                SystemConsole.getInstance().setFontStyle(this.fontStyle);
153            }
154        }
155    }
156
157    /**
158     * @return the wrapStyle
159     */
160    public int getWrapStyle() {
161        return wrapStyle;
162    }
163
164    /**
165     * @param wrapStyle One of
166     *                  {@link apps.SystemConsole#WRAP_STYLE_LINE}, {@link apps.SystemConsole#WRAP_STYLE_NONE},
167     *                  or {@link apps.SystemConsole#WRAP_STYLE_WORD}.
168     */
169    public void setWrapStyle(int wrapStyle) {
170        if (wrapStyle == SystemConsole.WRAP_STYLE_LINE
171                || wrapStyle == SystemConsole.WRAP_STYLE_NONE
172                || wrapStyle == SystemConsole.WRAP_STYLE_WORD) {
173            int oldWrapStyle = this.wrapStyle;
174            this.wrapStyle = wrapStyle;
175            this.firePropertyChange(WRAP_STYLE, oldWrapStyle, wrapStyle);
176            SystemConsole.getInstance().setWrapStyle(this.getWrapStyle());
177        }
178    }
179
180    @Override
181    public boolean isInitializedWithExceptions(Profile profile) {
182        return this.initialized && !this.exceptions.isEmpty();
183    }
184
185    @Override
186    @Nonnull
187    public List<Exception> getInitializationExceptions(Profile profile) {
188        return new ArrayList<>(this.exceptions);
189    }
190
191}