Java tutorial
/* * Copyright (c) 2015 Vladimir Schneider <vladimir.schneider@gmail.com> * * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you 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.vladsch.idea.multimarkdown.settings; import com.google.common.io.Resources; import com.intellij.ide.ui.UISettings; import com.intellij.ide.ui.UISettingsListener; import com.intellij.openapi.Disposable; import com.intellij.openapi.components.*; import com.intellij.util.ui.UIUtil; import com.vladsch.idea.multimarkdown.MultiMarkdownPlugin; import com.vladsch.idea.multimarkdown.util.ListenerNotifier; import org.apache.commons.codec.Charsets; import org.jdom.Element; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.pegdown.Extensions; import java.io.IOException; import java.net.URL; @State(name = "MultiMarkdownSettings", storages = { @Storage(id = "shared", file = StoragePathMacros.APP_CONFIG + "/multimarkdown.shared.xml"), //@Storage(id = "other", file = StoragePathMacros.APP_CONFIG + "/multimarkdown.xml", roamingType = RoamingType.DISABLED) @Storage(id = "other", file = StoragePathMacros.APP_CONFIG + "/multimarkdown.xml", deprecated = true) }) public class MultiMarkdownGlobalSettings implements PersistentStateComponent<Element>, Disposable { final public static int HTML_THEME_DEFAULT = 0; final public static int HTML_THEME_DARCULA = 1; final public static int HTML_THEME_UI = 2; // follow the Appearance setting of the application UI @NonNls public static final String PREVIEW_STYLESHEET_LIGHT = "/com/vladsch/idea/multimarkdown/default.css"; public static final String PREVIEW_STYLESHEET_DARK = "/com/vladsch/idea/multimarkdown/darcula.css"; public static final String PREVIEW_FX_STYLESHEET_LAYOUT = "/com/vladsch/idea/multimarkdown/layout-fx.css"; public static final String PREVIEW_FX_STYLESHEET_LIGHT = "/com/vladsch/idea/multimarkdown/default-fx.css"; public static final String PREVIEW_FX_STYLESHEET_DARK = "/com/vladsch/idea/multimarkdown/darcula-fx.css"; public static final String PREVIEW_FX_HLJS_STYLESHEET_LIGHT = "/com/vladsch/idea/multimarkdown/hljs-default.css"; public static final String PREVIEW_FX_HLJS_STYLESHEET_DARK = "/com/vladsch/idea/multimarkdown/hljs-darcula.css"; public static final String PREVIEW_FX_HIGHLIGHT_JS = "/com/vladsch/idea/multimarkdown/highlight.pack.js"; public static final String NOTIFICATION_GROUP_ISSUES = "MultiMarkdown Alerts"; /** * A set of listeners to this object state changes. */ @Override public void dispose() { } protected final SettingsNotifier<MultiMarkdownGlobalSettings> notifier = new SettingsNotifier<MultiMarkdownGlobalSettings>( this); protected final Settings settings = new Settings(notifier); public MultiMarkdownGlobalSettings() { // register to settings change on behalf of our listeners. If the UI changes and htmlTheme is Application UI then notify them UISettings.getInstance().addUISettingsListener(new UISettingsListener() { @Override public void uiSettingsChanged(UISettings source) { if (htmlTheme.getValue() == HTML_THEME_UI) { notifier.notifyListeners( new ListenerNotifier.RunnableNotifier<SettingsListener<MultiMarkdownGlobalSettings>>() { @Override public boolean notify(SettingsListener<MultiMarkdownGlobalSettings> listener) { listener.handleSettingsChanged(MultiMarkdownGlobalSettings.this); return false; } }); } } }, this); } public static MultiMarkdownGlobalSettings getInstance() { return ServiceManager.getService(MultiMarkdownGlobalSettings.class); } // these self-add to the list of settings final public Settings.BooleanSetting abbreviations = settings.BooleanSetting(false, "abbreviations", Extensions.ABBREVIATIONS); final public Settings.BooleanSetting anchorLinks = settings.BooleanSetting(true, "anchorLinks", Extensions.ANCHORLINKS); final public Settings.BooleanSetting autoLinks = settings.BooleanSetting(true, "autoLinks", Extensions.AUTOLINKS); final public Settings.BooleanSetting definitions = settings.BooleanSetting(true, "definitions", Extensions.DEFINITIONS); final public Settings.BooleanSetting enableTrimSpaces = settings.BooleanSetting(false, "enableTrimSpaces", 0); final public Settings.BooleanSetting fencedCodeBlocks = settings.BooleanSetting(true, "fencedCodeBlocks", Extensions.FENCED_CODE_BLOCKS); final public Settings.BooleanSetting forceListPara = settings.BooleanSetting(false, "forceListPara", Extensions.FORCELISTITEMPARA); final public Settings.BooleanSetting hardWraps = settings.BooleanSetting(true, "hardWraps", Extensions.HARDWRAPS); final public Settings.BooleanSetting headerSpace = settings.BooleanSetting(false, "headerSpace", Extensions.ATXHEADERSPACE); final public Settings.BooleanSetting quotes = settings.BooleanSetting(false, "quotes", Extensions.QUOTES); final public Settings.BooleanSetting relaxedHRules = settings.BooleanSetting(true, "relaxedHRules", Extensions.RELAXEDHRULES); final public Settings.BooleanSetting showHtmlText = settings.BooleanSetting(true, "showHtmlText", 0); final public Settings.BooleanSetting showHtmlTextAsModified = settings.BooleanSetting(false, "showHtmlTextAsModified", 0); final public Settings.BooleanSetting smarts = settings.BooleanSetting(false, "smarts", Extensions.SMARTS); final public Settings.BooleanSetting strikethrough = settings.BooleanSetting(true, "strikethrough", Extensions.STRIKETHROUGH); final public Settings.BooleanSetting suppressHTMLBlocks = settings.BooleanSetting(false, "suppressHTMLBlocks", Extensions.SUPPRESS_HTML_BLOCKS); final public Settings.BooleanSetting suppressInlineHTML = settings.BooleanSetting(false, "suppressInlineHTML", Extensions.SUPPRESS_INLINE_HTML); final public Settings.BooleanSetting tables = settings.BooleanSetting(true, "tables", Extensions.TABLES); final public Settings.BooleanSetting taskLists = settings.BooleanSetting(true, "taskLists", Extensions.TASKLISTITEMS); final public Settings.BooleanSetting wikiLinks = settings.BooleanSetting(true, "wikiLinks", Extensions.WIKILINKS); final public Settings.BooleanSetting todoComments = settings.BooleanSetting(false, "todoComments", 0); final public Settings.BooleanSetting useCustomCss = settings.BooleanSetting(false, "useCustomCss", 0); final public Settings.BooleanSetting enableFirebug = settings.BooleanSetting(false, "enableFirebug", 0); final public Settings.BooleanSetting useHighlightJs = settings.BooleanSetting(true, "useHighlightJs", 0); final public Settings.BooleanSetting includesHljsCss = settings.BooleanSetting(false, "includesHljsCss", 0); final public Settings.BooleanSetting includesLayoutCss = settings.BooleanSetting(false, "includesLayoutCss", 0); final public Settings.BooleanSetting includesColorsCss = settings.BooleanSetting(true, "includesColorsCss", 0); final public Settings.BooleanSetting footnotes = settings.BooleanSetting(false, "footnotes", Extensions.FOOTNOTES); final public Settings.IntegerSetting htmlTheme = settings.IntegerSetting(HTML_THEME_UI, "htmlTheme"); final public Settings.IntegerSetting maxImgWidth = settings.IntegerSetting(900, "maxImgWidth"); final public Settings.IntegerSetting parsingTimeout = settings.IntegerSetting(200, "parsingTimeout"); final public Settings.DoubleSetting pageZoom = settings.DoubleSetting(1.0, "pageZoom"); final public Settings.IntegerSetting updateDelay = settings.IntegerSetting(1000, "updateDelay"); final public Settings.IntegerSetting tabbedPaneIndex = settings.IntegerSetting(0, "tabbedPaneIndex"); final public Settings.StringSetting customCss = settings.StringSetting("", "customCss"); final public Settings.StringSetting customFxCss = settings.StringSetting("", "customFxCss"); final public Settings.BooleanSetting useOldPreview = settings.BooleanSetting(false, "useOldPreview", 0); // TODO: add this option to pegdown final public Settings.BooleanSetting githubWikiLinks = settings.BooleanSetting(true, "githubWikiLinks", 0); // Local Application Level Settings Now final public Settings.ElementSetting customCssEditorState = settings.LocalElementSetting(null, "customCssEditorState"); final public Settings.ElementSetting customFxCssEditorState = settings.LocalElementSetting(null, "customFxCssEditorState"); // notifications that are only shown once final public Settings.BooleanSetting wasShownDarkBug = settings.LocalBooleanSetting(false, "wasShownDarkBug", 0, false); // when loading of classes fails for some earlier builds these are used to store the build number to avoid retrying until the build changes // caution: failed builds are always local final public Settings.FailedBuildSetting scratchFileServiceFailed = settings.FailedBuildSetting("", "scratchFileServiceFailed"); final public Settings.FailedBuildSetting lightParserFailedBuild = settings.FailedBuildSetting("", "lightParserFailedBuild"); final public Settings.FailedBuildSetting fxPreviewFailedBuild = settings.FailedBuildSetting("", "fxPreviewFailedBuild", true); //final public Settings.FailedBuildSetting fxPlatformFailedBuild = settings.FailedBuildSetting("", "fxPlatformFailedBuild", true); public boolean isFxHtmlPreview() { return isFxHtmlPreview; } public void setIsFxHtmlPreview(boolean isFxHtmlPreview) { MultiMarkdownGlobalSettings.isFxHtmlPreview = isFxHtmlPreview; } static boolean isFxHtmlPreview = false; @Nullable @Override public Element getState() { return getState(false); } @Override public void loadState(Element state) { loadState(state, null); } // HACK: persistence is now split for roaming and non-roaming settings by having another class handle the non-roaming storage. public Element getState(Boolean isRoamingDisabled) { // vsch: hardwire github wiki links githubWikiLinks.setValue(true); final Element element = new Element("MultiMarkdownSettings"); settings.getState(element, isRoamingDisabled); return element; } // HACK: persistence is now split for roaming and non-roaming settings by having another class handle the non-roaming storage. public void loadState(@NotNull Element element, Boolean isRoamingDisabled) { startGroupNotifications(); settings.loadState(element, isRoamingDisabled); // vsch: hardwire github wiki links githubWikiLinks.setValue(true); endGroupNotifications(); } public boolean isDarkHtmlPreview(int htmlTheme) { return (htmlTheme == HTML_THEME_DARCULA || htmlTheme == HTML_THEME_UI && UIUtil.isUnderDarcula()); } public boolean isDarkHtmlPreview() { return isDarkHtmlPreview(htmlTheme.getValue()); } public boolean isDarkUITheme() { return UIUtil.isUnderDarcula(); } public @NotNull String getCustomCssExternalForm(boolean isFxHtmlPreview) { String url = MultiMarkdownPlugin.getInstance().getUrlCustomFxCss(); if (url != null) return url; return getColorsCssExternalForm(isFxHtmlPreview); } @NotNull public String getColorsCssExternalForm(boolean cisFxHtmlPreview) { return isDarkHtmlPreview() ? MultiMarkdownPlugin.getInstance().getUrlDarculaFxCss() : MultiMarkdownPlugin.getInstance().getUrlDefaultFxCss(); } @NotNull public String getHljsCssExternalForm(boolean isFxHtmlPreview) { return isDarkHtmlPreview() ? MultiMarkdownPlugin.getInstance().getUrlHljsDarculaFxCss() : MultiMarkdownPlugin.getInstance().getUrlHljsDefaultFxCss(); } @NotNull public String getLayoutCssExternalForm(boolean isFxHtmlPreview) { return MultiMarkdownPlugin.getInstance().getUrlLayoutFxCss(); } @NotNull public String getHighlighJsExternalForm(boolean isFxHtmlPreview) { return MultiMarkdownPlugin.getInstance().getUrlHighlightJs(); } @Nullable public String getUrlCustomFont() { return MultiMarkdownPlugin.getInstance().getUrlCustomFont(); } @NotNull public String getCssFilePath(int htmlTheme, boolean isFxHtmlPreview) { if (isFxHtmlPreview) { return isDarkHtmlPreview(htmlTheme) ? PREVIEW_FX_STYLESHEET_DARK : PREVIEW_FX_STYLESHEET_LIGHT; } else { return isDarkHtmlPreview(htmlTheme) ? PREVIEW_STYLESHEET_DARK : PREVIEW_STYLESHEET_LIGHT; } } @Nullable public String getLayoutCssFilePath(boolean isFxHtmlPreview) { if (isFxHtmlPreview) { return PREVIEW_FX_STYLESHEET_LAYOUT; } else { return null; } } @Nullable public String getHljsCssFilePath(int htmlTheme, boolean isFxHtmlPreview) { if (isFxHtmlPreview) { return isDarkHtmlPreview(htmlTheme) ? PREVIEW_FX_HLJS_STYLESHEET_DARK : PREVIEW_FX_HLJS_STYLESHEET_LIGHT; } else { return null; } } @NotNull public java.net.URL getCssFileURL(int htmlTheme, boolean isFxHtmlPreview) { return MultiMarkdownGlobalSettings.class.getResource(getCssFilePath(htmlTheme, isFxHtmlPreview)); } @Nullable public java.net.URL getLayoutCssFileURL() { String layoutCssFilePath = getLayoutCssFilePath(isFxHtmlPreview); return layoutCssFilePath == null ? null : MultiMarkdownGlobalSettings.class.getResource(layoutCssFilePath); } @Nullable public java.net.URL getHljsCssFileURL(int htmlTheme, boolean isFxHtmlPreview) { String hljsCssFilePath = getHljsCssFilePath(htmlTheme, isFxHtmlPreview); return hljsCssFilePath == null ? null : MultiMarkdownGlobalSettings.class.getResource(hljsCssFilePath); } //public @NotNull java.net.URL getFirebugLiteFileURL() throws MalformedURLException { // return MultiMarkdownGlobalSettings.class.getResource("/src/firebug-lite.js"); //} @NotNull public String getCssFileText(int htmlTheme, boolean isFxHtmlPreview) { String htmlText = ""; try { htmlText = Resources.toString(getCssFileURL(htmlTheme, isFxHtmlPreview), Charsets.UTF_8); } catch (IOException ex) { ex.printStackTrace(); } return htmlText; } @NotNull public String getLayoutCssFileText() { String htmlText = ""; try { URL layoutCssFileURL = getLayoutCssFileURL(); if (layoutCssFileURL != null) htmlText = Resources.toString(layoutCssFileURL, Charsets.UTF_8); } catch (IOException ex) { ex.printStackTrace(); } return htmlText; } @NotNull public String getHljsCssFileText(int htmlTheme, boolean isFxHtmlPreview) { String htmlText = ""; try { URL hljsCssFileURL = getHljsCssFileURL(htmlTheme, isFxHtmlPreview); if (hljsCssFileURL != null) { htmlText = Resources.toString(hljsCssFileURL, Charsets.UTF_8); } else { htmlText = ""; } } catch (IOException ex) { ex.printStackTrace(); } return htmlText; } @NotNull public String getCssFilePath(boolean isFxHtmlPreview) { return getCssFilePath(htmlTheme.getValue(), isFxHtmlPreview); } @NotNull public java.net.URL getCssFileURL(boolean isFxHtmlPreview) { return getCssFileURL(htmlTheme.getValue(), isFxHtmlPreview); } @NotNull public String getCssFileText(boolean isFxHtmlPreview) { return getCssFileText(htmlTheme.getValue(), isFxHtmlPreview); } @NotNull public String getCssText(boolean isFxHtmlPreview) { return useCustomCss(isFxHtmlPreview) ? (isFxHtmlPreview ? customFxCss.getValue() : customCss.getValue()) : getCssFileText(htmlTheme.getValue(), isFxHtmlPreview); } public boolean useCustomCss(boolean isFxHtmlPreview) { return useCustomCss.getValue() && (isFxHtmlPreview ? customFxCss.getValue() : customCss.getValue()).trim().length() != 0; } public int getExtensionsValue() { int options = settings.getExtensionsValue(); return options | Extensions.INTELLIJ_DUMMY_IDENTIFIER | ((options & Extensions.ANCHORLINKS) != 0 ? Extensions.EXTANCHORLINKS : 0); } public void addListener(@NotNull final SettingsListener<MultiMarkdownGlobalSettings> listener) { notifier.addListener(listener); } public void removeListener(@NotNull final SettingsListener<MultiMarkdownGlobalSettings> listener) { notifier.removeListener(listener); } public void startGroupNotifications() { notifier.startGroupNotifications(); } public void endGroupNotifications() { notifier.endGroupNotifications(); } public void startSuspendNotifications() { notifier.startSuspendNotifications(); } public void endSuspendNotifications() { notifier.endSuspendNotifications(); } }