| /******************************************************************************* |
| * Copyright (c) 2007, 2015 David Green and others. |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License v1.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/epl-v10.html |
| * |
| * Contributors: |
| * David Green - initial API and implementation |
| *******************************************************************************/ |
| package org.eclipse.mylyn.internal.wikitext.ui.editor.preferences; |
| |
| import java.io.IOException; |
| import java.io.Reader; |
| import java.util.Collections; |
| import java.util.LinkedHashMap; |
| import java.util.Map; |
| import java.util.regex.Pattern; |
| |
| import org.eclipse.jface.preference.IPreferenceStore; |
| import org.eclipse.mylyn.internal.wikitext.ui.WikiTextUiPlugin; |
| import org.eclipse.mylyn.internal.wikitext.ui.viewer.HtmlTextPresentationParser; |
| import org.eclipse.mylyn.wikitext.parser.css.CssParser; |
| import org.eclipse.mylyn.wikitext.parser.css.Stylesheet; |
| |
| import com.google.common.io.CharStreams; |
| |
| /** |
| * @see WikiTextUiPlugin#getPreferences() |
| * @author David Green |
| */ |
| public class Preferences implements Cloneable { |
| |
| private static final String KEY_MARKUP_VIEWER_CSS = "preview.css"; //$NON-NLS-1$ |
| |
| private static final String KEY_EDITOR_FOLDING = "editorFolding"; //$NON-NLS-1$ |
| |
| private static final Pattern BAD_CHAR_PATTERN = Pattern.compile("[^a-zA-Z0-9]"); //$NON-NLS-1$ |
| |
| public static final String PHRASE_CODE = "@code@"; //$NON-NLS-1$ |
| |
| public static final String PHRASE_SPAN = "%span%"; //$NON-NLS-1$ |
| |
| public static final String PHRASE_SUBSCRIPT = "~subscript~"; //$NON-NLS-1$ |
| |
| public static final String PHRASE_SUPERSCRIPT = "^superscript^"; //$NON-NLS-1$ |
| |
| public static final String PHRASE_INSERTED_TEXT = "+inserted text+"; //$NON-NLS-1$ |
| |
| public static final String PHRASE_DELETED_TEXT = "-deleted text-"; //$NON-NLS-1$ |
| |
| public static final String PHRASE_CITATION = "??citation??"; //$NON-NLS-1$ |
| |
| public static final String PHRASE_BOLD = "**bold**"; //$NON-NLS-1$ |
| |
| public static final String PHRASE_ITALIC = "__italic__"; //$NON-NLS-1$ |
| |
| public static final String PHRASE_STRONG = "*strong*"; //$NON-NLS-1$ |
| |
| public static final String PHRASE_EMPHASIS = "_emphasis_"; //$NON-NLS-1$ |
| |
| public static final String PHRASE_MONOSPACE = "monospace"; //$NON-NLS-1$ |
| |
| public static final String PHRASE_UNDERLINED = "underlined"; //$NON-NLS-1$ |
| |
| public static final String PHRASE_QUOTE = "quote"; //$NON-NLS-1$ |
| |
| public static final String PHRASE_MARK = "mark"; //$NON-NLS-1$ |
| |
| public static final String BLOCK_QUOTE = "bq."; //$NON-NLS-1$ |
| |
| public static final String BLOCK_PRE = "pre."; //$NON-NLS-1$ |
| |
| public static final String BLOCK_BC = "bc."; //$NON-NLS-1$ |
| |
| public static final String BLOCK_H6 = "h6."; //$NON-NLS-1$ |
| |
| public static final String BLOCK_H5 = "h5."; //$NON-NLS-1$ |
| |
| public static final String BLOCK_H4 = "h4."; //$NON-NLS-1$ |
| |
| public static final String BLOCK_H3 = "h3."; //$NON-NLS-1$ |
| |
| public static final String BLOCK_H2 = "h2."; //$NON-NLS-1$ |
| |
| public static final String BLOCK_H1 = "h1."; //$NON-NLS-1$ |
| |
| public static final String BLOCK_DT = "dt"; //$NON-NLS-1$ |
| |
| /** |
| * heading preferences key indexed by level (0 is null, 1 is {@link #BLOCK_H1}, etc.) |
| */ |
| public static final String[] HEADING_PREFERENCES = new String[] { null, BLOCK_H1, BLOCK_H2, BLOCK_H3, BLOCK_H4, |
| BLOCK_H5, BLOCK_H6 }; |
| |
| private Map<String, String> cssByBlockModifierType = new LinkedHashMap<>(); |
| |
| { |
| cssByBlockModifierType.put(BLOCK_H1, "font-size: 120%; font-weight: bold; color: #172f47;"); //$NON-NLS-1$ |
| cssByBlockModifierType.put(BLOCK_H2, "font-size: 110%; font-weight: bold; color: #172f47;"); //$NON-NLS-1$ |
| cssByBlockModifierType.put(BLOCK_H3, "font-size: 105%; font-weight: bold; color: #172f47;"); //$NON-NLS-1$ |
| cssByBlockModifierType.put(BLOCK_H4, "font-weight: bold; color: #172f47;"); //$NON-NLS-1$ |
| cssByBlockModifierType.put(BLOCK_H5, "font-size: 90%; font-weight: bold; color: #172f47;"); //$NON-NLS-1$ |
| cssByBlockModifierType.put(BLOCK_H6, "font-size: 80%; font-weight: bold; color: #172f47;"); //$NON-NLS-1$ |
| cssByBlockModifierType.put(BLOCK_BC, "font-family: monospace; color: #4444CC;"); //$NON-NLS-1$ |
| cssByBlockModifierType.put(BLOCK_PRE, "font-family: monospace;"); //$NON-NLS-1$ |
| cssByBlockModifierType.put(BLOCK_QUOTE, "color: rgb(38,86,145);"); //$NON-NLS-1$ |
| cssByBlockModifierType.put(BLOCK_DT, "font-weight: bold;"); //$NON-NLS-1$ |
| } |
| |
| private Map<String, String> cssByPhraseModifierType = new LinkedHashMap<>(); |
| |
| { |
| |
| cssByPhraseModifierType.put(PHRASE_EMPHASIS, "font-style: italic;"); //$NON-NLS-1$ |
| cssByPhraseModifierType.put(PHRASE_STRONG, "font-weight: bold;"); //$NON-NLS-1$ |
| cssByPhraseModifierType.put(PHRASE_ITALIC, "font-style: italic;"); //$NON-NLS-1$ |
| cssByPhraseModifierType.put(PHRASE_BOLD, "font-weight: bold;"); //$NON-NLS-1$ |
| cssByPhraseModifierType.put(PHRASE_CITATION, "font-style: italic;"); //$NON-NLS-1$ |
| cssByPhraseModifierType.put(PHRASE_DELETED_TEXT, "text-decoration: line-through;"); //$NON-NLS-1$ |
| cssByPhraseModifierType.put(PHRASE_INSERTED_TEXT, "text-decoration: underline;"); //$NON-NLS-1$ |
| cssByPhraseModifierType.put(PHRASE_SUPERSCRIPT, "font-size: smaller; vertical-align: super;"); //$NON-NLS-1$ |
| cssByPhraseModifierType.put(PHRASE_SUBSCRIPT, "font-size: smaller; vertical-align: sub;"); //$NON-NLS-1$ |
| cssByPhraseModifierType.put(PHRASE_SPAN, ""); //$NON-NLS-1$ |
| cssByPhraseModifierType.put(PHRASE_CODE, "font-family: monospace; color: #4444CC;"); //$NON-NLS-1$ |
| cssByPhraseModifierType.put(PHRASE_MONOSPACE, "font-family: monospace;"); //$NON-NLS-1$ |
| cssByPhraseModifierType.put(PHRASE_UNDERLINED, "text-decoration: underline;"); //$NON-NLS-1$ |
| cssByPhraseModifierType.put(PHRASE_QUOTE, "color: rgb(38,86,145);"); //$NON-NLS-1$ |
| cssByPhraseModifierType.put(PHRASE_MARK, "background-color: yellow;"); //$NON-NLS-1$ |
| } |
| |
| private boolean editorFolding = true; |
| |
| private String markupViewerCss; |
| |
| private Stylesheet stylesheet; |
| |
| private boolean mutable = true; |
| |
| public Map<String, String> getCssByBlockModifierType() { |
| return cssByBlockModifierType; |
| } |
| |
| public Map<String, String> getCssByPhraseModifierType() { |
| return cssByPhraseModifierType; |
| } |
| |
| /** |
| * indicate if editor folding is enabled |
| */ |
| public boolean isEditorFolding() { |
| return editorFolding; |
| } |
| |
| /** |
| * indicate if editor folding is enabled |
| */ |
| public void setEditorFolding(boolean editorFolding) { |
| if (!mutable) { |
| throw new UnsupportedOperationException(); |
| } |
| this.editorFolding = editorFolding; |
| } |
| |
| /** |
| * get the CSS content used to render the markup viewer |
| */ |
| public String getMarkupViewerCss() { |
| if (markupViewerCss == null) { |
| markupViewerCss = getDefaultMarkupViewerCss(); |
| } |
| return markupViewerCss; |
| } |
| |
| /** |
| * set the CSS content used to render the markup viewer |
| */ |
| public void setMarkupViewerCss(String markupViewerCss) { |
| if (!mutable) { |
| throw new UnsupportedOperationException(); |
| } |
| this.markupViewerCss = markupViewerCss; |
| stylesheet = null; |
| } |
| |
| public Stylesheet getStylesheet() { |
| if (stylesheet == null) { |
| stylesheet = new CssParser().parse(getMarkupViewerCss()); |
| } |
| return stylesheet; |
| } |
| |
| /** |
| * indicate if this preferences is mutable |
| * |
| * @see #makeImmutable() |
| */ |
| public boolean isMutable() { |
| return mutable; |
| } |
| |
| /** |
| * @see #isMutable() |
| */ |
| public void makeImmutable() { |
| if (mutable) { |
| mutable = false; |
| cssByBlockModifierType = Collections.unmodifiableMap(cssByBlockModifierType); |
| cssByPhraseModifierType = Collections.unmodifiableMap(cssByPhraseModifierType); |
| } |
| } |
| |
| /** |
| * Save the settings to the given store |
| * |
| * @param store |
| * the store to which the settings should be saved |
| * @param asDefault |
| * if true, then the settings are saved as defaults. |
| */ |
| public void save(IPreferenceStore store, boolean asDefault) { |
| for (Map.Entry<String, String> ent : cssByBlockModifierType.entrySet()) { |
| String propKey = toPreferenceKey(ent.getKey(), true); |
| if (asDefault) { |
| store.setDefault(propKey, ent.getValue()); |
| } else { |
| store.setValue(propKey, ent.getValue()); |
| } |
| } |
| for (Map.Entry<String, String> ent : cssByPhraseModifierType.entrySet()) { |
| String propKey = toPreferenceKey(ent.getKey(), false); |
| if (asDefault) { |
| store.setDefault(propKey, ent.getValue()); |
| } else { |
| store.setValue(propKey, ent.getValue()); |
| } |
| } |
| if (asDefault) { |
| store.setDefault(KEY_EDITOR_FOLDING, editorFolding); |
| store.setDefault(KEY_MARKUP_VIEWER_CSS, getDefaultMarkupViewerCss()); |
| } else { |
| store.setValue(KEY_EDITOR_FOLDING, editorFolding); |
| store.setValue(KEY_MARKUP_VIEWER_CSS, markupViewerCss); |
| } |
| } |
| |
| public static String toPreferenceKey(String key, boolean block) { |
| String propKey = (block ? "block-" : "phrase-") + BAD_CHAR_PATTERN.matcher(key).replaceAll(""); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ |
| return propKey; |
| } |
| |
| public void load(IPreferenceStore store) { |
| if (!mutable) { |
| throw new UnsupportedOperationException(); |
| } |
| for (Map.Entry<String, String> ent : cssByBlockModifierType.entrySet()) { |
| String propKey = toPreferenceKey(ent.getKey(), true); |
| |
| String value = store.getString(propKey); |
| if (value != null) { |
| ent.setValue(value); |
| } |
| } |
| for (Map.Entry<String, String> ent : cssByPhraseModifierType.entrySet()) { |
| String propKey = toPreferenceKey(ent.getKey(), false); |
| String value = store.getString(propKey); |
| if (value != null) { |
| ent.setValue(value); |
| } |
| } |
| editorFolding = store.getBoolean(KEY_EDITOR_FOLDING); |
| markupViewerCss = store.getString(KEY_MARKUP_VIEWER_CSS); |
| if (isEmpty(markupViewerCss)) { |
| markupViewerCss = getDefaultMarkupViewerCss(); |
| } |
| stylesheet = null; |
| } |
| |
| private String getDefaultMarkupViewerCss() { |
| try (Reader reader = HtmlTextPresentationParser.getDefaultStylesheetContent()) { |
| return CharStreams.toString(reader); |
| } catch (IOException e) { |
| WikiTextUiPlugin.getDefault().log(e); |
| return ""; //$NON-NLS-1$ |
| } |
| } |
| |
| private boolean isEmpty(String text) { |
| if (text == null || text.length() == 0) { |
| return true; |
| } |
| final int length = text.length(); |
| for (int x = 0; x < length; ++x) { |
| char c = text.charAt(x); |
| if (!Character.isWhitespace(c)) { |
| return false; |
| } |
| } |
| return true; |
| } |
| |
| /** |
| * clone the preferences, returning a mutable copy. |
| */ |
| @Override |
| public Preferences clone() { |
| try { |
| Preferences copy = (Preferences) super.clone(); |
| copy.mutable = true; |
| return copy; |
| } catch (CloneNotSupportedException e) { |
| throw new IllegalStateException(); |
| } |
| } |
| } |