/* * 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.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.application.ModalityState; import com.intellij.openapi.options.SearchableConfigurable; import com.intellij.ui.EditorTextField; import com.vladsch.idea.multimarkdown.MultiMarkdownFileType; import com.vladsch.idea.multimarkdown.MultiMarkdownIcons; import org.jetbrains.annotations.Nls; import org.jetbrains.annotations.NotNull; import javax.swing.*; import java.util.ArrayList; public class MultiMarkdownGlobalSettingsConfigurable implements SearchableConfigurable { protected MultiMarkdownGlobalSettings globalSettings; protected MultiMarkdownSettingsPanel settingsPanel; @NotNull public String getId() { return MultiMarkdownFileType.INSTANCE.getName(); } final private ArrayList<ComponentSetting> componentSettings = new ArrayList<ComponentSetting>(50); public MultiMarkdownGlobalSettingsConfigurable() { globalSettings = MultiMarkdownGlobalSettings.getInstance(); componentSettings.add(new CheckBoxComponent("abbreviationsCheckBox", globalSettings.abbreviations)); componentSettings.add(new CheckBoxComponent("anchorLinksCheckBox", globalSettings.anchorLinks)); componentSettings.add(new CheckBoxComponent("autoLinksCheckBox", globalSettings.autoLinks)); componentSettings.add(new CheckBoxComponent("definitionsCheckBox", globalSettings.definitions)); componentSettings.add(new CheckBoxComponent("fencedCodeBlocksCheckBox", globalSettings.fencedCodeBlocks)); componentSettings.add(new CheckBoxComponent("forceListParaCheckBox", globalSettings.forceListPara)); componentSettings.add(new CheckBoxComponent("hardWrapsCheckBox", globalSettings.hardWraps)); componentSettings.add(new CheckBoxComponent("headerSpaceCheckBox", globalSettings.headerSpace)); componentSettings.add(new CheckBoxComponent("relaxedHRulesCheckBox", globalSettings.relaxedHRules)); componentSettings.add(new CheckBoxComponent("showHtmlTextAsModifiedCheckBox", globalSettings.showHtmlTextAsModified)); componentSettings.add(new CheckBoxComponent("showHtmlTextCheckBox", globalSettings.showHtmlText)); componentSettings.add(new CheckBoxComponent("smartsCheckBox", globalSettings.smarts)); componentSettings.add(new CheckBoxComponent("strikethroughCheckBox", globalSettings.strikethrough)); componentSettings.add(new CheckBoxComponent("enableTrimSpacesCheckBox", globalSettings.enableTrimSpaces)); componentSettings.add(new CheckBoxComponent("suppressHTMLBlocksCheckBox", globalSettings.suppressHTMLBlocks)); componentSettings.add(new CheckBoxComponent("suppressInlineHTMLCheckBox", globalSettings.suppressInlineHTML)); componentSettings.add(new CheckBoxComponent("tablesCheckBox", globalSettings.tables)); componentSettings.add(new CheckBoxComponent("taskListsCheckBox", globalSettings.taskLists)); componentSettings.add(new CheckBoxComponent("wikiLinksCheckBox", globalSettings.wikiLinks)); componentSettings.add(new CheckBoxComponent("useCustomCssCheckBox", globalSettings.useCustomCss)); componentSettings.add(new CheckBoxComponent("quotesCheckBox", globalSettings.quotes)); componentSettings.add(new CheckBoxComponent("useOldPreviewCheckBox", globalSettings.useOldPreview)); componentSettings.add(new CheckBoxComponent("enableFirebugCheckBox", globalSettings.enableFirebug)); componentSettings.add(new CheckBoxComponent("useHighlightJsCheckBox", globalSettings.useHighlightJs)); componentSettings.add(new CheckBoxComponent("includesHljsCssCheckBox", globalSettings.includesHljsCss)); componentSettings.add(new CheckBoxComponent("includesLayoutCssCheckBox", globalSettings.includesLayoutCss)); componentSettings.add(new CheckBoxComponent("includesColorsCssCheckBox", globalSettings.includesColorsCss)); componentSettings.add(new CheckBoxComponent("githubWikiLinksCheckBox", globalSettings.githubWikiLinks)); componentSettings.add(new CheckBoxComponent("footnotesCheckBox", globalSettings.footnotes)); componentSettings.add(new SpinnerIntegerComponent("updateDelaySpinner", globalSettings.updateDelay)); componentSettings.add(new SpinnerIntegerComponent("maxImgWidthSpinner", globalSettings.maxImgWidth)); componentSettings.add(new SpinnerIntegerComponent("parsingTimeoutSpinner", globalSettings.parsingTimeout)); componentSettings.add(new TabbedPaneIntegerComponent("tabbedPane", globalSettings.tabbedPaneIndex)); componentSettings.add(new SpinnerDoubleComponent("pageZoomSpinner", globalSettings.pageZoom)); //componentSettings.add(new ComboBoxComponent("htmlThemeComboBox", globalSettings.htmlTheme)); componentSettings.add(new ListComponent("htmlThemeList", globalSettings.htmlTheme)); componentSettings.add(new EditorTextFieldComponent("textCustomCss", globalSettings.customCss, false)); componentSettings.add(new EditorTextFieldComponent("textCustomCss", globalSettings.customFxCss, true)); componentSettings.add(new SettingsComponentState("textCustomCss", globalSettings.customCssEditorState, false)); componentSettings.add(new SettingsComponentState("textCustomCss", globalSettings.customFxCssEditorState, true)); } public Runnable enableSearch(String s) { return null; } @Nls public String getDisplayName() { return getId(); } public Icon getIcon() { return MultiMarkdownIcons.FILE; } public String getHelpTopic() { return getId(); } public JComponent createComponent() { if (settingsPanel == null) settingsPanel = new MultiMarkdownSettingsPanel(); if (settingsPanel.haveCustomizableEditor) { reset(); } return settingsPanel.panel; } public boolean isModified() { if (settingsPanel == null) return true; for (ComponentSetting componentSetting : componentSettings) { if (componentSetting.isChanged()) return true; } return false; } public void apply() { runInDispatchThread(new Runnable() { @Override public void run() { applyRaw(); } }, false); } protected void applyRaw() { if (settingsPanel == null) return; globalSettings.startGroupNotifications(); for (ComponentSetting componentSetting : componentSettings) { componentSetting.setValue(); } // vsch: hardwire github wiki links globalSettings.githubWikiLinks.setValue(true); globalSettings.endGroupNotifications(); } protected void runInDispatchThread(Runnable runnable, boolean wait) { if (ApplicationManager.getApplication().isDispatchThread()) { runnable.run(); } else if (wait) { ApplicationManager.getApplication().invokeLater(runnable, ModalityState.any()); } else { ApplicationManager.getApplication().invokeLater(runnable, ModalityState.any()); } } public void reset() { runInDispatchThread(new Runnable() { @Override public void run() { resetRaw(); } }, false); } protected void resetRaw() { if (settingsPanel == null) return; // vsch: hardwire github wiki links globalSettings.githubWikiLinks.setValue(true); for (ComponentSetting componentSetting : componentSettings) { componentSetting.reset(); } } public void disposeUIResources() { settingsPanel = null; } abstract class ComponentSetting<T, S> { String componentName; S setting; ComponentSetting(String componentName, S setting) { this.componentName = componentName; this.setting = setting; } public boolean isChanged() { try { T component = (T) settingsPanel.getComponent(componentName); if (component != null) return isChanged(component); } catch (ClassCastException ex) { //ex.printStackTrace(); } return false; } public void setValue() { try { T component = (T) settingsPanel.getComponent(componentName); if (component != null) setValue(component); } catch (ClassCastException ex) { //ex.printStackTrace(); } } public void reset() { try { T component = (T) settingsPanel.getComponent(componentName); if (component != null) reset(component); } catch (ClassCastException ex) { //ex.printStackTrace(); } } abstract public boolean isChanged(T component); abstract public void setValue(T component); abstract public void reset(T component); } class EditorTextFieldComponent extends ComponentSetting<EditorTextField, Settings.StringSetting> { private final Boolean isFxPreviewState; EditorTextFieldComponent(String component, Settings.StringSetting setting) { super(component, setting); this.isFxPreviewState = null; } EditorTextFieldComponent(String component, Settings.StringSetting setting, boolean isFxPreviewState) { super(component, setting); this.isFxPreviewState = isFxPreviewState; } @Override public boolean isChanged(EditorTextField component) { if ((component instanceof CustomizableEditorTextField) && (isFxPreviewState == null || MultiMarkdownGlobalSettings.isFxHtmlPreview == isFxPreviewState)) { return setting.isChanged(component); } return false; } @Override public void setValue(EditorTextField component) { if ((component instanceof CustomizableEditorTextField) && (isFxPreviewState == null || MultiMarkdownGlobalSettings.isFxHtmlPreview == isFxPreviewState)) { setting.setValue(component); } } @Override public void reset(EditorTextField component) { if ((component instanceof CustomizableEditorTextField) && isFxPreviewState == null || MultiMarkdownGlobalSettings.isFxHtmlPreview == isFxPreviewState) { setting.reset(component); } } } class TextAreaComponent extends ComponentSetting<JTextArea, Settings.StringSetting> { TextAreaComponent(String component, Settings.StringSetting setting) { super(component, setting); } @Override public boolean isChanged(JTextArea component) { return setting.isChanged(component); } @Override public void setValue(JTextArea component) { setting.setValue(component); } @Override public void reset(JTextArea component) { setting.reset(component); } } class SettingsComponentState extends ComponentSetting<ComponentState, Settings.ElementSetting> { private final Boolean isFxPreviewState; SettingsComponentState(String component, Settings.ElementSetting setting) { super(component, setting); this.isFxPreviewState = null; } SettingsComponentState(String component, Settings.ElementSetting setting, boolean isFxPreview) { super(component, setting); this.isFxPreviewState = isFxPreview; } @Override public boolean isChanged(ComponentState component) { if (isFxPreviewState == null || MultiMarkdownGlobalSettings.isFxHtmlPreview == isFxPreviewState) { return setting.getValue() == null || component.isChanged(setting.getValue()); } return false; } @Override public void setValue(ComponentState component) { if (isFxPreviewState == null || MultiMarkdownGlobalSettings.isFxHtmlPreview == isFxPreviewState) { setting.setValue(component.getState(setting.persistName)); } } @Override public void reset(ComponentState component) { if (isFxPreviewState == null || MultiMarkdownGlobalSettings.isFxHtmlPreview == isFxPreviewState) { if (setting.getValue() != null) component.loadState(setting.getValue()); } } } class SpinnerIntegerComponent extends ComponentSetting<JSpinner, Settings.IntegerSetting> { SpinnerIntegerComponent(String componentName, Settings.IntegerSetting setting) { super(componentName, setting); } @Override public boolean isChanged(JSpinner component) { return setting.isChanged(component); } @Override public void setValue(JSpinner component) { setting.setValue(component); } @Override public void reset(JSpinner component) { setting.reset(component); } } class TabbedPaneIntegerComponent extends ComponentSetting<JTabbedPane, Settings.IntegerSetting> { TabbedPaneIntegerComponent(String componentName, Settings.IntegerSetting setting) { super(componentName, setting); } @Override public boolean isChanged(JTabbedPane component) { return setting.isChanged(component); } @Override public void setValue(JTabbedPane component) { setting.setValue(component); } @Override public void reset(JTabbedPane component) { setting.reset(component); } } class SpinnerDoubleComponent extends ComponentSetting<JSpinner, Settings.DoubleSetting> { SpinnerDoubleComponent(String componentName, Settings.DoubleSetting setting) { super(componentName, setting); } @Override public boolean isChanged(JSpinner component) { return setting.isChanged(component); } @Override public void setValue(JSpinner component) { setting.setValue(component); } @Override public void reset(JSpinner component) { setting.reset(component); } } class ComboBoxComponent extends ComponentSetting<JComboBox, Settings.IntegerSetting> { ComboBoxComponent(String componentName, Settings.IntegerSetting setting) { super(componentName, setting); } @Override public boolean isChanged(JComboBox component) { return setting.isChanged(component); } @Override public void setValue(JComboBox component) { setting.setValue(component); } @Override public void reset(JComboBox component) { setting.reset(component); } } class ListComponent extends ComponentSetting<JList, Settings.IntegerSetting> { ListComponent(String componentName, Settings.IntegerSetting setting) { super(componentName, setting); } @Override public boolean isChanged(JList component) { return setting.isChanged(component); } @Override public void setValue(JList component) { setting.setValue(component); } @Override public void reset(JList component) { setting.reset(component); } } class CheckBoxComponent extends ComponentSetting<JCheckBox, Settings.BooleanSetting> { CheckBoxComponent(String componentName, Settings.BooleanSetting setting) { super(componentName, setting); } @Override public boolean isChanged(JCheckBox component) { return setting.isChanged(component); } @Override public void setValue(JCheckBox component) { setting.setValue(component); } @Override public void reset(JCheckBox component) { setting.reset(component); } } }