com.vladsch.idea.multimarkdown.settings.MultiMarkdownGlobalSettings.java Source code

Java tutorial

Introduction

Here is the source code for com.vladsch.idea.multimarkdown.settings.MultiMarkdownGlobalSettings.java

Source

/*
 * 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();
    }
}