| /* |
| * 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 org.netbeans.modules.javascript2.editor.formatter; |
| |
| import java.awt.Component; |
| import java.awt.Container; |
| import java.awt.Rectangle; |
| import java.awt.event.ActionEvent; |
| import java.awt.event.ActionListener; |
| import java.util.Arrays; |
| import java.util.HashMap; |
| import java.util.HashSet; |
| import java.util.LinkedList; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.Set; |
| import java.util.logging.Level; |
| import java.util.logging.Logger; |
| import java.util.prefs.AbstractPreferences; |
| import java.util.prefs.BackingStoreException; |
| import java.util.prefs.Preferences; |
| import javax.swing.ComboBoxModel; |
| import javax.swing.DefaultComboBoxModel; |
| import javax.swing.JCheckBox; |
| import javax.swing.JComboBox; |
| import javax.swing.JComponent; |
| import javax.swing.JEditorPane; |
| import javax.swing.JPanel; |
| import javax.swing.JTextField; |
| import javax.swing.event.DocumentEvent; |
| import javax.swing.event.DocumentListener; |
| import javax.swing.text.BadLocationException; |
| import javax.swing.text.Document; |
| import org.netbeans.api.editor.document.AtomicLockDocument; |
| import org.netbeans.api.editor.document.LineDocumentUtils; |
| import org.netbeans.api.editor.settings.SimpleValueNames; |
| import org.netbeans.modules.editor.indent.api.Reformat; |
| import org.netbeans.modules.options.editor.spi.PreferencesCustomizer; |
| import org.netbeans.modules.options.editor.spi.PreviewProvider; |
| import org.netbeans.modules.javascript2.editor.formatter.CodeStyle.WrapStyle; |
| import org.openide.text.CloneableEditorSupport; |
| import org.openide.util.HelpCtx; |
| import org.openide.util.NbBundle; |
| |
| /** |
| * |
| * @author phrebejk |
| * |
| */ |
| public class FmtOptions { |
| |
| private static final Logger LOGGER = Logger.getLogger(FmtOptions.class.getName()); |
| |
| public static final String expandTabToSpaces = SimpleValueNames.EXPAND_TABS; |
| public static final String tabSize = SimpleValueNames.TAB_SIZE; |
| public static final String spacesPerTab = SimpleValueNames.SPACES_PER_TAB; |
| public static final String indentSize = SimpleValueNames.INDENT_SHIFT_WIDTH; |
| public static final String continuationIndentSize = "continuationIndentSize"; //NOI18N |
| public static final String itemsInArrayDeclarationIndentSize = "itemsInArrayDeclarationIndentSize"; //NOI18N |
| public static final String reformatComments = "reformatComments"; //NOI18N |
| public static final String indentHtml = "indentHtml"; //NOI18N |
| public static final String rightMargin = SimpleValueNames.TEXT_LIMIT_WIDTH; |
| public static final String initialIndent = "init.indent"; //NOI18N |
| |
| public static final String functionDeclBracePlacement = "functionDeclBracePlacement"; //NOI18N |
| public static final String classDeclBracePlacement = "classDeclBracePlacement"; //NOI18N |
| public static final String ifBracePlacement = "ifBracePlacement"; //NOI18N |
| public static final String forBracePlacement = "forBracePlacement"; //NOI18N |
| public static final String whileBracePlacement = "whileBracePlacement"; //NOI18N |
| public static final String switchBracePlacement = "switchBracePlacement"; //NOI18N |
| public static final String catchBracePlacement = "catchBracePlacement"; //NOI18N |
| public static final String withBracePlacement = "withBracePlacement"; //NOI18N |
| public static final String objectLiteralContinuation = "objectLiteralContinuation"; //NOI18N |
| |
| public static final String blankLinesBeforeNamespace = "blankLinesBeforeNamespace"; //NOI18N |
| public static final String blankLinesAfterNamespace = "blankLinesAfterNamespace"; //NOI18N |
| public static final String blankLinesBeforeUse = "blankLinesBeforeUse"; //NOI18N |
| public static final String blankLinesBeforeUseTrait = "blankLinesBeforeUseTrait"; //NOI18N |
| public static final String blankLinesAfterUse = "blankLinesAfterUse"; //NOI18N |
| public static final String blankLinesBeforeClass = "blankLinesBeforeClass"; //NOI18N |
| public static final String blankLinesBeforeClassEnd = "blankLinesBeforeClassEnd"; //NOI18N |
| public static final String blankLinesAfterClass = "blankLinesAfterClass"; //NOI18N |
| public static final String blankLinesAfterClassHeader = "blankLinesAfterClassHeader"; //NOI18N |
| public static final String blankLinesBeforeFields = "blankLinesBeforeField"; //NOI18N |
| public static final String blankLinesBetweenFields = "blankLinesBetweenField"; //NOI18N |
| public static final String blankLinesAfterFields = "blankLinesAfterField"; //NOI18N |
| public static final String blankLinesGroupFieldsWithoutDoc = "blankLinesGroupFieldsWithoutDoc"; //NOI18N |
| public static final String blankLinesBeforeFunction = "blankLinesBeforeFunction"; //NOI18N |
| public static final String blankLinesAfterFunction = "blankLinesAfterFunction"; //NOI18N |
| public static final String blankLinesBeforeFunctionEnd = "blankLinesBeforeFunctionEnd"; //NOI18N |
| public static final String blankLinesAfterOpenPHPTag = "blankLinesAfterOpenPHPTag"; //NOI18N |
| public static final String blankLinesAfterOpenPHPTagInHTML = "blankLinesAfterOpenPHPTagInHTML"; //NOI18N |
| public static final String blankLinesBeforeClosePHPTag = "blankLinesBeforeClosePHPTag"; //NOI18N |
| |
| public static final String spaceBeforeWhile = "spaceBeforeWhile"; //NOI18N |
| public static final String spaceBeforeElse = "spaceBeforeElse"; //NOI18N |
| public static final String spaceBeforeCatch = "spaceBeforeCatch"; //NOI18N |
| public static final String spaceBeforeFinally = "spaceBeforeFinally"; //NOI18N |
| public static final String spaceBeforeAnonMethodDeclParen = "spaceBeforeAnonMethodDeclParen"; //NOI18N |
| public static final String spaceBeforeMethodDeclParen = "spaceBeforeMethodDeclParen"; //NOI18N |
| public static final String spaceBeforeMethodCallParen = "spaceBeforeMethodCallParen"; //NOI18N |
| public static final String spaceBeforeIfParen = "spaceBeforeIfParen"; //NOI18N |
| public static final String spaceBeforeForParen = "spaceBeforeForParen"; //NOI18N |
| public static final String spaceBeforeWhileParen = "spaceBeforeWhileParen"; //NOI18N |
| public static final String spaceBeforeCatchParen = "spaceBeforeCatchParen"; //NOI18N |
| public static final String spaceBeforeSwitchParen = "spaceBeforeSwitchParen"; //NOI18N |
| public static final String spaceBeforeWithParen = "spaceBeforeWithParen"; //NOI18N |
| |
| public static final String spaceAroundUnaryOps = "spaceAroundUnaryOps"; //NOI18N |
| public static final String spaceAroundBinaryOps = "spaceAroundBinaryOps"; //NOI18N |
| public static final String spaceAroundTernaryOps = "spaceAroundTernaryOps"; //NOI18N |
| public static final String spaceAroundStringConcatOps = "spaceAroundStringConcatOps"; //NOI18N |
| public static final String spaceAroundAssignOps = "spaceAroundAssignOps"; //NOI18N |
| public static final String spaceAroundArrowOps = "spaceAroundArrowOps"; //NOI18N |
| public static final String spaceAroundKeyValueOps = "spaceAroundKeyValueOps"; //NOI18N |
| public static final String spaceAroundObjectOps = "spaceAroundObjectOps"; //NOI18N |
| public static final String spaceBeforeClassDeclLeftBrace = "spaceBeforeClassDeclLeftBrace"; //NOI18N |
| public static final String spaceBeforeMethodDeclLeftBrace = "spaceBeforeMethodDeclLeftBrace"; //NOI18N |
| public static final String spaceBeforeIfLeftBrace = "spaceBeforeIfLeftBrace"; //NOI18N |
| public static final String spaceBeforeElseLeftBrace = "spaceBeforeElseLeftBrace"; //NOI18N |
| public static final String spaceBeforeWhileLeftBrace = "spaceBeforeWhileLeftBrace"; //NOI18N |
| public static final String spaceBeforeForLeftBrace = "spaceBeforeForLeftBrace"; //NOI18N |
| public static final String spaceBeforeDoLeftBrace = "spaceBeforeDoLeftBrace"; //NOI18N |
| public static final String spaceBeforeSwitchLeftBrace = "spaceBeforeSwitchLeftBrace"; //NOI18N |
| public static final String spaceBeforeTryLeftBrace = "spaceBeforeTryLeftBrace"; //NOI18N |
| public static final String spaceBeforeCatchLeftBrace = "spaceBeforeCatchLeftBrace"; //NOI18N |
| public static final String spaceBeforeFinallyLeftBrace = "spaceBeforeFinallyLeftBrace"; //NOI18N |
| public static final String spaceBeforeWithLeftBrace = "spaceBeforeWithLeftBrace"; //NOI18N |
| // public static final String spaceBeforeSynchronizedLeftBrace = "spaceBeforeSynchronizedLeftBrace"; //NOI18N |
| // public static final String spaceBeforeStaticInitLeftBrace = "spaceBeforeStaticInitLeftBrace"; //NOI18N |
| // public static final String spaceBeforeArrayInitLeftBrace = "spaceBeforeArrayInitLeftBrace"; //NOI18N |
| public static final String spaceWithinParens = "spaceWithinParens"; //NOI18N |
| public static final String spaceWithinArrayDeclParens = "spaceWithinArrayDeclParens"; //NOI18N |
| public static final String spaceWithinMethodDeclParens = "spaceWithinMethodDeclParens"; //NOI18N |
| public static final String spaceWithinMethodCallParens = "spaceWithinMethodCallParens"; //NOI18N |
| public static final String spaceWithinIfParens = "spaceWithinIfParens"; //NOI18N |
| public static final String spaceWithinForParens = "spaceWithinForParens"; //NOI18N |
| public static final String spaceWithinWhileParens = "spaceWithinWhileParens"; //NOI18N |
| public static final String spaceWithinSwitchParens = "spaceWithinSwitchParens"; //NOI18N |
| public static final String spaceWithinCatchParens = "spaceWithinCatchParens"; //NOI18N |
| public static final String spaceWithinWithParens = "spaceWithinWithParens"; //NOI18N |
| // public static final String spaceWithinSynchronizedParens = "spaceWithinSynchronizedParens"; //NOI18N |
| public static final String spaceWithinTypeCastParens = "spaceWithinTypeCastParens"; //NOI18N |
| // public static final String spaceWithinAnnotationParens = "spaceWithinAnnotationParens"; //NOI18N |
| public static final String spaceWithinBraces = "spaceWithinBraces"; //NOI18N |
| public static final String spaceWithinArrayBrackets = "spaceWithinArrayBrackets"; //NOI18N |
| public static final String spaceBeforeComma = "spaceBeforeComma"; //NOI18N |
| public static final String spaceAfterComma = "spaceAfterComma"; //NOI18N |
| public static final String spaceBeforeSemi = "spaceBeforeSemi"; //NOI18N |
| public static final String spaceAfterSemi = "spaceAfterSemi"; //NOI18N |
| public static final String spaceBeforeColon = "spaceBeforeColon"; //NOI18N |
| public static final String spaceAfterColon = "spaceAfterColon"; //NOI18N |
| |
| public static final String placeElseOnNewLine = "placeElseOnNewLine"; //NOI18N |
| public static final String placeWhileOnNewLine = "placeWhileOnNewLine"; //NOI18N |
| public static final String placeCatchOnNewLine = "placeCatchOnNewLine"; //NOI18N |
| public static final String placeFinallyOnNewLine = "placeFinallyOnNewLine"; //NOI18N |
| public static final String alignMultilineMethodParams = "alignMultilineMethodParams"; //NOI18N |
| public static final String alignMultilineCallArgs = "alignMultilineCallArgs"; //NOI18N |
| public static final String alignMultilineImplements = "alignMultilineImplements"; //NOI18N |
| public static final String alignMultilineParenthesized = "alignMultilineParenthesized"; //NOI18N |
| public static final String alignMultilineBinaryOp = "alignMultilineBinaryOp"; //NOI18N |
| public static final String alignMultilineTernaryOp = "alignMultilineTernaryOp"; //NOI18N |
| public static final String alignMultilineAssignment = "alignMultilineAssignment"; //NOI18N |
| public static final String alignMultilineFor = "alignMultilineFor"; //NOI18N |
| public static final String alignMultilineArrayInit = "alignMultilineArrayInit"; //NOI18N |
| |
| public static final String groupAlignmentAssignment = "groupAlignmentAssignment"; //NOI18N |
| public static final String groupAlignmentArrayInit = "groupAlignmentArrayInit"; //NOI18N |
| |
| public static final String wrapStatement = "wrapStatement"; //NOI18N |
| public static final String wrapVariables = "wrapVariables"; //NOI18N |
| public static final String wrapMethodParams = "wrapMethodParams"; //NOI18N |
| public static final String wrapMethodCallArgs = "wrapMethodCallArgs"; //NOI18N |
| public static final String wrapChainedMethodCalls = "wrapChainedMethodCalls"; //NOI18N |
| public static final String wrapAfterDotInChainedMethodCalls = "wrapAfterDotInChainedMethodCalls"; //NOI18N |
| public static final String wrapArrayInit = "wrapArrayInit"; //NOI18N |
| public static final String wrapArrayInitItems = "wrapArrayInitItems"; //NOI18N |
| public static final String wrapFor = "wrapFor"; //NOI18N |
| public static final String wrapForStatement = "wrapForStatement"; //NOI18N |
| public static final String wrapIfStatement = "wrapIfStatement"; //NOI18N |
| public static final String wrapWhileStatement = "wrapWhileStatement"; //NOI18N |
| public static final String wrapDoWhileStatement = "wrapDoWhileStatement"; //NOI18N |
| public static final String wrapWithStatement = "wrapWithStatement"; //NOI18N |
| public static final String wrapBinaryOps = "wrapBinaryOps"; //NOI18N |
| public static final String wrapAfterBinaryOps = "wrapAfterBinaryOps"; //NOI18N |
| public static final String wrapTernaryOps = "wrapTernaryOps"; //NOI18N |
| public static final String wrapAfterTernaryOps = "wrapAfterTernaryOps"; //NOI18N |
| public static final String wrapAssignOps = "wrapAssignOps"; //NOI18N |
| public static final String wrapArrowOps = "wrapArrowOps"; //NOI18N |
| public static final String wrapBlockBraces = "wrapBlockBraces"; //NOI18N |
| public static final String wrapStatementsOnTheLine = "wrapStateMentsOnTheLine"; // NOI18N |
| public static final String wrapObjects = "wrapObjects"; // NOI18N |
| public static final String wrapProperties = "wrapProperties"; // NOI18N |
| public static final String wrapDecorators = "wrapDecorators"; // NOI18N |
| public static final String wrapClasses = "wrapClasses"; // NOI18N |
| public static final String wrapElements = "wrapElements"; // NOI18N |
| public static final String wrapClassExtends = "wrapClassExtends"; // NOI18N |
| |
| public static final String maxPreservedClassLines = "maxPreservedClassLines"; // NOI18N |
| public static final String maxPreservedObjectLines = "maxPreservedObjectLines"; // NOI18N |
| public static final String maxPreservedArrayLines = "maxPreservedArrayLines"; // NOI18N |
| public static final String maxPreservedCodeLines = "maxPreservedCodeLines"; // NOI18N |
| |
| public static final String preferFullyQualifiedNames = "preferFullyQualifiedNames"; //NOI18N |
| public static final String preferMultipleUseStatementsCombined = "preferMultipleUseStatementsCombined"; //NOI18N |
| public static final String startUseWithNamespaceSeparator = "startUseWithNamespaceSeparator"; //NOI18N |
| |
| private FmtOptions() {} |
| |
| private static int getDefaultAsInt(String key) { |
| return Integer.parseInt(defaults.get(key)); |
| } |
| |
| private static boolean getDefaultAsBoolean(String key) { |
| return Boolean.parseBoolean(defaults.get(key)); |
| } |
| |
| private static String getDefaultAsString(String key) { |
| return defaults.get(key); |
| } |
| |
| // Private section --------------------------------------------------------- |
| |
| private static final String TRUE = "true"; // NOI18N |
| private static final String FALSE = "false"; // NOI18N |
| |
| //opening brace styles |
| public static final String OBRACE_NEWLINE = CodeStyle.BracePlacement.NEW_LINE.name(); |
| public static final String OBRACE_SAMELINE = CodeStyle.BracePlacement.SAME_LINE.name(); |
| public static final String OBRACE_PRESERVE = CodeStyle.BracePlacement.PRESERVE_EXISTING.name(); |
| public static final String OBRACE_NEWLINE_INDENTED = CodeStyle.BracePlacement.NEW_LINE_INDENTED.name(); |
| |
| public static final String WRAP_ALWAYS = CodeStyle.WrapStyle.WRAP_ALWAYS.name(); |
| public static final String WRAP_IF_LONG = CodeStyle.WrapStyle.WRAP_IF_LONG.name(); |
| public static final String WRAP_NEVER = CodeStyle.WrapStyle.WRAP_NEVER.name(); |
| |
| private static Map<String,String> defaults; |
| |
| static { |
| createDefaults(); |
| } |
| |
| private static void createDefaults() { |
| String defaultValues[][] = { |
| { expandTabToSpaces, TRUE}, //NOI18N |
| { tabSize, "8"}, //NOI18N |
| { indentSize, "4"}, //NOI18N |
| { continuationIndentSize, "8"}, //NOI18N |
| { itemsInArrayDeclarationIndentSize, "4"}, // NOI18N |
| { reformatComments, FALSE }, //NOI18N |
| { indentHtml, TRUE }, //NOI18N |
| { rightMargin, "80"}, //NOI18N |
| { initialIndent, "0"}, //NOI18N |
| |
| { functionDeclBracePlacement, OBRACE_PRESERVE }, |
| { classDeclBracePlacement, OBRACE_PRESERVE }, |
| { ifBracePlacement, OBRACE_PRESERVE }, |
| { forBracePlacement, OBRACE_PRESERVE }, |
| { whileBracePlacement, OBRACE_PRESERVE }, |
| { switchBracePlacement, OBRACE_PRESERVE }, |
| { catchBracePlacement, OBRACE_PRESERVE }, |
| { withBracePlacement, OBRACE_PRESERVE }, |
| { objectLiteralContinuation, TRUE}, |
| |
| { blankLinesBeforeNamespace, "1"}, //NOI18N |
| { blankLinesAfterNamespace, "1"}, //NOI18N |
| { blankLinesBeforeUse, "1"}, //NOI18N |
| { blankLinesBeforeUseTrait, "1"}, //NOI18N |
| { blankLinesAfterUse, "1"}, //NOI18N |
| { blankLinesBeforeClass, "1"}, //NOI18N |
| { blankLinesAfterClass, "1"}, //NOI18N |
| { blankLinesAfterClassHeader, "0"}, //NOI18N |
| { blankLinesBeforeClassEnd, "0"}, //NOI18N |
| { blankLinesBeforeFields, "1"}, //NOI18N |
| { blankLinesGroupFieldsWithoutDoc, TRUE}, //NOI18N |
| { blankLinesBetweenFields, "1"}, //NOI18N |
| { blankLinesAfterFields, "1"}, //NOI18N |
| { blankLinesBeforeFunction, "1"}, //NOI18N |
| { blankLinesAfterFunction, "1"}, //NOI18N |
| { blankLinesBeforeFunctionEnd, "0"}, //NOI18N |
| { blankLinesAfterOpenPHPTag, "1"}, //NOI18N |
| { blankLinesAfterOpenPHPTagInHTML, "0"}, //NOI18N |
| { blankLinesBeforeClosePHPTag, "0"}, //NOI18N |
| |
| { spaceBeforeWhile, TRUE}, |
| { spaceBeforeElse, TRUE}, |
| { spaceBeforeCatch, TRUE}, |
| { spaceBeforeFinally, TRUE}, |
| { spaceBeforeAnonMethodDeclParen, TRUE}, |
| { spaceBeforeMethodDeclParen, FALSE}, |
| { spaceBeforeMethodCallParen, FALSE}, |
| { spaceBeforeIfParen, TRUE}, |
| { spaceBeforeForParen, TRUE}, |
| { spaceBeforeWhileParen, TRUE}, |
| { spaceBeforeCatchParen, TRUE}, |
| { spaceBeforeSwitchParen, TRUE}, |
| { spaceBeforeWithParen, TRUE}, |
| { spaceAroundUnaryOps, FALSE}, |
| { spaceAroundBinaryOps, TRUE}, |
| { spaceAroundTernaryOps, TRUE}, |
| { spaceAroundStringConcatOps, TRUE}, |
| { spaceAroundKeyValueOps, TRUE}, |
| { spaceAroundAssignOps, TRUE}, |
| { spaceAroundArrowOps, TRUE}, |
| { spaceAroundObjectOps, FALSE}, |
| { spaceBeforeClassDeclLeftBrace, TRUE}, |
| { spaceBeforeMethodDeclLeftBrace, TRUE}, |
| { spaceBeforeIfLeftBrace, TRUE}, |
| { spaceBeforeElseLeftBrace, TRUE}, |
| { spaceBeforeWhileLeftBrace, TRUE}, |
| { spaceBeforeForLeftBrace, TRUE}, |
| { spaceBeforeDoLeftBrace, TRUE}, |
| { spaceBeforeSwitchLeftBrace, TRUE}, |
| { spaceBeforeTryLeftBrace, TRUE}, |
| { spaceBeforeCatchLeftBrace, TRUE}, |
| { spaceBeforeFinallyLeftBrace, TRUE}, |
| { spaceBeforeWithLeftBrace, TRUE}, |
| // { spaceBeforeSynchronizedLeftBrace, TRUE}, |
| // { spaceBeforeStaticInitLeftBrace, TRUE}, |
| // { spaceBeforeArrayInitLeftBrace, FALSE}, |
| { spaceWithinParens, FALSE}, |
| { spaceWithinArrayDeclParens, FALSE}, |
| { spaceWithinMethodDeclParens, FALSE}, |
| { spaceWithinMethodCallParens, FALSE}, |
| { spaceWithinIfParens, FALSE}, |
| { spaceWithinForParens, FALSE}, |
| { spaceWithinWhileParens, FALSE}, |
| { spaceWithinSwitchParens, FALSE}, |
| { spaceWithinCatchParens, FALSE}, |
| { spaceWithinWithParens, FALSE}, |
| // { spaceWithinSynchronizedParens, FALSE}, |
| { spaceWithinTypeCastParens, FALSE}, |
| // { spaceWithinAnnotationParens, FALSE}, |
| { spaceWithinBraces, FALSE}, |
| { spaceWithinArrayBrackets, FALSE}, |
| { spaceBeforeComma, FALSE}, |
| { spaceAfterComma, TRUE}, |
| { spaceBeforeSemi, FALSE}, |
| { spaceAfterSemi, TRUE}, |
| { spaceBeforeColon, FALSE}, |
| { spaceAfterColon, TRUE}, |
| |
| { alignMultilineMethodParams, FALSE}, //NOI18N |
| { alignMultilineCallArgs, FALSE}, //NOI18N |
| { alignMultilineImplements, FALSE}, //NOI18N |
| { alignMultilineParenthesized, FALSE}, //NOI18N |
| { alignMultilineBinaryOp, FALSE}, //NOI18N |
| { alignMultilineTernaryOp, FALSE}, //NOI18N |
| { alignMultilineAssignment, FALSE}, //NOI18N |
| { alignMultilineFor, FALSE}, //NOI18N |
| { alignMultilineArrayInit, FALSE}, //NOI18N |
| { placeElseOnNewLine, FALSE}, //NOI18N |
| { placeWhileOnNewLine, FALSE}, //NOI18N |
| { placeCatchOnNewLine, FALSE}, //NOI18N |
| { placeFinallyOnNewLine, FALSE}, //NOI18N |
| |
| {groupAlignmentArrayInit, FALSE}, |
| {groupAlignmentAssignment, FALSE}, |
| |
| { wrapStatement, WRAP_ALWAYS}, //NOI18N |
| { wrapVariables, WRAP_NEVER}, //NOI18N |
| { wrapMethodParams, WRAP_NEVER}, //NOI18N |
| { wrapMethodCallArgs, WRAP_NEVER}, //NOI18N |
| { wrapChainedMethodCalls, WRAP_NEVER}, //NOI18N |
| { wrapAfterDotInChainedMethodCalls, TRUE}, //NOI18N |
| { wrapArrayInit, WRAP_NEVER}, //NOI18N |
| { wrapArrayInitItems, WRAP_NEVER}, //NOI18N |
| { wrapFor, WRAP_NEVER}, //NOI18N |
| { wrapForStatement, WRAP_ALWAYS}, //NOI18N |
| { wrapIfStatement, WRAP_ALWAYS}, //NOI18N |
| { wrapWhileStatement, WRAP_ALWAYS}, //NOI18N |
| { wrapDoWhileStatement, WRAP_ALWAYS}, //NOI18N |
| { wrapWithStatement, WRAP_ALWAYS}, //NOI18N |
| { wrapBinaryOps, WRAP_NEVER}, //NOI18N |
| { wrapAfterBinaryOps, FALSE}, //NOI18N |
| { wrapTernaryOps, WRAP_NEVER}, |
| { wrapAfterTernaryOps, FALSE}, //NOI18N |
| { wrapAssignOps, WRAP_NEVER}, |
| { wrapArrowOps, WRAP_NEVER}, |
| { wrapBlockBraces, TRUE}, |
| { wrapStatementsOnTheLine, TRUE}, |
| { wrapObjects, WRAP_NEVER}, |
| { wrapProperties, WRAP_NEVER}, |
| { wrapDecorators, WRAP_ALWAYS}, |
| { wrapClasses, WRAP_ALWAYS}, |
| { wrapElements, WRAP_ALWAYS}, |
| { wrapClassExtends, WRAP_NEVER}, |
| |
| { maxPreservedClassLines, "1"}, |
| { maxPreservedObjectLines, "1"}, |
| { maxPreservedArrayLines, "1"}, |
| { maxPreservedCodeLines, "1"}, |
| |
| { preferFullyQualifiedNames, FALSE}, |
| { preferMultipleUseStatementsCombined, FALSE}, |
| { startUseWithNamespaceSeparator, FALSE} |
| }; |
| |
| defaults = new HashMap<>(); |
| |
| for (java.lang.String[] strings : defaultValues) { |
| defaults.put(strings[0], strings[1]); |
| } |
| |
| } |
| |
| // Support section --------------------------------------------------------- |
| |
| public static class CategorySupport implements ActionListener, DocumentListener, PreviewProvider, PreferencesCustomizer { |
| |
| public static final String OPTION_ID = "org.netbeans.modules.javascript2.editor.formatter.FormatingOptions.ID"; |
| |
| private static final int LOAD = 0; |
| private static final int STORE = 1; |
| private static final int ADD_LISTENERS = 2; |
| |
| private static final ComboItem bracePlacement[] = new ComboItem[] { |
| new ComboItem( OBRACE_NEWLINE, "LBL_bp_NEWLINE" ), // NOI18N |
| new ComboItem( OBRACE_NEWLINE_INDENTED, "LBL_bp_NEWLINE_INDENTED" ), // NOI18N |
| new ComboItem( OBRACE_SAMELINE, "LBL_bp_SAMELINE" ), // NOI18N |
| new ComboItem( OBRACE_PRESERVE, "LBL_bp_PRESERVE" ), // NOI18N |
| }; |
| |
| private static final ComboItem wrap[] = new ComboItem[] { |
| new ComboItem( WrapStyle.WRAP_ALWAYS.name(), "LBL_wrp_WRAP_ALWAYS" ), // NOI18N |
| new ComboItem( WrapStyle.WRAP_IF_LONG.name(), "LBL_wrp_WRAP_IF_LONG" ), // NOI18N |
| new ComboItem( WrapStyle.WRAP_NEVER.name(), "LBL_wrp_WRAP_NEVER" ) // NOI18N |
| }; |
| |
| private final String previewText; |
| // private String forcedOptions[][]; |
| |
| // private boolean changed = false; |
| // private boolean loaded = false; |
| private final String id; |
| protected final JPanel panel; |
| private final List<JComponent> components = new LinkedList<>(); |
| private JEditorPane previewPane; |
| |
| protected final Defaults.Provider provider; |
| |
| private final Preferences preferences; |
| private final Preferences previewPrefs; |
| private final String mimeType; |
| |
| protected CategorySupport(String mimeType, Defaults.Provider provider, Preferences preferences, String id, |
| JPanel panel, String previewText, String[]... forcedOptions) { |
| this.mimeType = mimeType; |
| this.provider = provider; |
| this.preferences = preferences; |
| this.id = id; |
| this.panel = panel; |
| this.previewText = previewText != null ? previewText : NbBundle.getMessage(FmtOptions.class, "SAMPLE_Default"); //NOI18N |
| |
| // Scan the panel for its components |
| scan(panel, components); |
| |
| // Initialize the preview preferences |
| Preferences forcedPrefs = new PreviewPreferences(); |
| for (String[] option : forcedOptions) { |
| forcedPrefs.put( option[0], option[1]); |
| } |
| this.previewPrefs = new ProxyPreferences(preferences, forcedPrefs); |
| |
| // Load and hook up all the components |
| loadFrom(preferences); |
| addListeners(); |
| } |
| |
| protected void addListeners() { |
| scan(ADD_LISTENERS, null); |
| } |
| |
| protected void loadFrom(Preferences preferences) { |
| // loaded = true; |
| scan(LOAD, preferences); |
| // loaded = false; |
| } |
| // |
| // public void applyChanges() { |
| // storeTo(preferences); |
| // } |
| // |
| protected void storeTo(Preferences p) { |
| scan(STORE, p); |
| } |
| |
| public void notifyChanged() { |
| // if (loaded) |
| // return; |
| storeTo(preferences); |
| refreshPreview(); |
| } |
| |
| // ActionListener implementation --------------------------------------- |
| |
| @Override |
| public void actionPerformed(ActionEvent e) { |
| notifyChanged(); |
| } |
| |
| // DocumentListener implementation ------------------------------------- |
| |
| @Override |
| public void insertUpdate(DocumentEvent e) { |
| notifyChanged(); |
| } |
| |
| @Override |
| public void removeUpdate(DocumentEvent e) { |
| notifyChanged(); |
| } |
| |
| @Override |
| public void changedUpdate(DocumentEvent e) { |
| notifyChanged(); |
| } |
| |
| // PreviewProvider methods ----------------------------------------------------- |
| |
| @Override |
| public JComponent getPreviewComponent() { |
| if (previewPane == null) { |
| previewPane = new JEditorPane(); |
| previewPane.getAccessibleContext().setAccessibleName(NbBundle.getMessage(FmtOptions.class, "AN_Preview")); //NOI18N |
| previewPane.getAccessibleContext().setAccessibleDescription(NbBundle.getMessage(FmtOptions.class, "AD_Preview")); //NOI18N |
| //previewPane.putClientProperty("HighlightsLayerIncludes", "^org\\.netbeans\\.modules\\.editor\\.lib2\\.highlighting\\.SyntaxHighlighting$"); //NOI18N |
| previewPane.setEditorKit(CloneableEditorSupport.getEditorKit(mimeType)); |
| previewPane.setEditable(false); |
| } |
| return previewPane; |
| } |
| |
| @Override |
| public void refreshPreview() { |
| JEditorPane pane = (JEditorPane) getPreviewComponent(); |
| try { |
| int rm = previewPrefs.getInt(rightMargin, provider.getDefaultAsInt(rightMargin)); |
| pane.putClientProperty("TextLimitLine", rm); //NOI18N |
| } |
| catch( NumberFormatException e ) { |
| // Ignore it |
| } |
| |
| Rectangle visibleRectangle = pane.getVisibleRect(); |
| pane.setText(previewText); |
| pane.setIgnoreRepaint(true); |
| |
| final Document doc = pane.getDocument(); |
| final AtomicLockDocument ald = LineDocumentUtils.as(doc, AtomicLockDocument.class); |
| if (ald != null) { |
| final Reformat reformat = Reformat.get(doc); |
| reformat.lock(); |
| try { |
| ald.runAtomic(() -> { |
| try { |
| reformat.reformat(0, doc.getLength()); |
| } catch (BadLocationException ble) { |
| LOGGER.log(Level.WARNING, null, ble); |
| } |
| }); |
| } finally { |
| reformat.unlock(); |
| } |
| } else { |
| LOGGER.warning(String.format("Can't format %s; it's not BaseDocument.", doc)); //NOI18N |
| } |
| pane.setIgnoreRepaint(false); |
| pane.scrollRectToVisible(visibleRectangle); |
| pane.repaint(100); |
| |
| } |
| |
| // PreferencesCustomizer implementation -------------------------------- |
| |
| @Override |
| public JComponent getComponent() { |
| return panel; |
| } |
| |
| @Override |
| public String getDisplayName() { |
| return panel.getName(); |
| } |
| |
| @Override |
| public String getId() { |
| return id; |
| } |
| |
| @Override |
| public HelpCtx getHelpCtx() { |
| return null; |
| } |
| |
| // PreferencesCustomizer.Factory implementation ------------------------ |
| |
| public static final class Factory implements PreferencesCustomizer.Factory { |
| |
| private final String mimeType; |
| private final Defaults.Provider provider; |
| private final String id; |
| private final Class<? extends JPanel> panelClass; |
| private final String previewText; |
| private final String[][] forcedOptions; |
| |
| public Factory(String mimeType, String id, Class<? extends JPanel> panelClass, |
| String previewText, String[]... forcedOptions) { |
| this.mimeType = mimeType; |
| this.provider = Defaults.getInstance(mimeType); |
| this.id = id; |
| this.panelClass = panelClass; |
| this.previewText = previewText; |
| this.forcedOptions = forcedOptions; |
| } |
| |
| @Override |
| public PreferencesCustomizer create(Preferences preferences) { |
| try { |
| return new CategorySupport(mimeType, provider, preferences, id, panelClass.newInstance(), previewText, forcedOptions); |
| } catch (RuntimeException | IllegalAccessException | InstantiationException e) { |
| LOGGER.log(Level.WARNING, "Exception during creating formatter customiezer", e); |
| return null; |
| } |
| } |
| } // End of CategorySupport.Factory class |
| |
| // Private methods ----------------------------------------------------- |
| |
| private void performOperation(int operation, JComponent jc, String optionID, Preferences p) { |
| switch (operation) { |
| case LOAD: |
| loadData(jc, optionID, p); |
| break; |
| case STORE: |
| storeData(jc, optionID, p); |
| break; |
| case ADD_LISTENERS: |
| addListener(jc); |
| break; |
| default: |
| LOGGER.log(Level.WARNING, "Unknown operation value {0}", operation); |
| break; |
| } |
| } |
| |
| private void scan(int what, Preferences p ) { |
| for (JComponent jc : components) { |
| Object o = jc.getClientProperty(OPTION_ID); |
| if (o instanceof String) { |
| performOperation(what, jc, (String)o, p); |
| } else if (o instanceof String[]) { |
| for(String oid : (String[])o) { |
| performOperation(what, jc, oid, p); |
| } |
| } |
| } |
| } |
| |
| private void scan(Container container, List<JComponent> components) { |
| for (Component c : container.getComponents()) { |
| if (c instanceof JComponent) { |
| JComponent jc = (JComponent)c; |
| Object o = jc.getClientProperty(OPTION_ID); |
| if (o instanceof String || o instanceof String[]) |
| components.add(jc); |
| } |
| if (c instanceof Container) |
| scan((Container)c, components); |
| } |
| } |
| |
| /** Very smart method which tries to set the values in the components correctly |
| */ |
| private void loadData( JComponent jc, String optionID, Preferences node ) { |
| |
| if ( jc instanceof JTextField ) { |
| JTextField field = (JTextField)jc; |
| field.setText( node.get(optionID, provider.getDefaultAsString(optionID)) ); |
| } |
| else if ( jc instanceof JCheckBox ) { |
| JCheckBox checkBox = (JCheckBox)jc; |
| boolean df = provider.getDefaultAsBoolean(optionID); |
| checkBox.setSelected( node.getBoolean(optionID, df)); |
| } |
| else if ( jc instanceof JComboBox) { |
| JComboBox cb = (JComboBox)jc; |
| String value = node.get(optionID, provider.getDefaultAsString(optionID) ); |
| ComboBoxModel model = createModel(value); |
| cb.setModel(model); |
| ComboItem item = whichItem(value, model); |
| cb.setSelectedItem(item); |
| } |
| |
| } |
| |
| private void storeData( JComponent jc, String optionID, Preferences node ) { |
| |
| if ( jc instanceof JTextField ) { |
| JTextField field = (JTextField)jc; |
| |
| String text = field.getText(); |
| |
| // XXX test for numbers |
| if ( isInteger(optionID) ) { |
| try { |
| Integer.parseInt(text); |
| } catch (NumberFormatException e) { |
| return; |
| } |
| } |
| |
| // XXX: watch out, tabSize, spacesPerTab, indentSize and expandTabToSpaces |
| // fall back on getGlopalXXX() values and not getDefaultAsXXX value, |
| // which is why we must not remove them. Proper solution would be to |
| // store formatting preferences to MimeLookup and not use NbPreferences. |
| // The problem currently is that MimeLookup based Preferences do not support subnodes. |
| if (!optionID.equals(tabSize) && |
| !optionID.equals(spacesPerTab) && !optionID.equals(indentSize) && |
| provider.getDefaultAsString(optionID).equals(text) |
| ) { |
| node.remove(optionID); |
| } else { |
| node.put(optionID, text); |
| } |
| } |
| else if ( jc instanceof JCheckBox ) { |
| JCheckBox checkBox = (JCheckBox)jc; |
| if (!optionID.equals(expandTabToSpaces) && provider.getDefaultAsBoolean(optionID) == checkBox.isSelected()) |
| node.remove(optionID); |
| else |
| node.putBoolean(optionID, checkBox.isSelected()); |
| } |
| else if ( jc instanceof JComboBox) { |
| JComboBox cb = (JComboBox)jc; |
| ComboItem comboItem = ((ComboItem) cb.getSelectedItem()); |
| String value = comboItem == null ? provider.getDefaultAsString(optionID) : comboItem.value; |
| |
| if (provider.getDefaultAsString(optionID).equals(value)) |
| node.remove(optionID); |
| else |
| node.put(optionID,value); |
| } |
| } |
| |
| private void addListener( JComponent jc ) { |
| if ( jc instanceof JTextField ) { |
| JTextField field = (JTextField)jc; |
| field.addActionListener(this); |
| field.getDocument().addDocumentListener(this); |
| } |
| else if ( jc instanceof JCheckBox ) { |
| JCheckBox checkBox = (JCheckBox)jc; |
| checkBox.addActionListener(this); |
| } |
| else if ( jc instanceof JComboBox) { |
| JComboBox cb = (JComboBox)jc; |
| cb.addActionListener(this); |
| } |
| } |
| |
| |
| private ComboBoxModel createModel( String value ) { |
| |
| // is it braces placement? |
| for (ComboItem comboItem : bracePlacement) { |
| if ( value.equals( comboItem.value) ) { |
| return new DefaultComboBoxModel( bracePlacement ); |
| } |
| } |
| |
| // is it wrap |
| for (ComboItem comboItem : wrap) { |
| if ( value.equals( comboItem.value) ) { |
| return new DefaultComboBoxModel( wrap ); |
| } |
| } |
| |
| return null; |
| } |
| |
| private static ComboItem whichItem(String value, ComboBoxModel model) { |
| |
| for (int i = 0; i < model.getSize(); i++) { |
| ComboItem item = (ComboItem)model.getElementAt(i); |
| if ( value.equals(item.value)) { |
| return item; |
| } |
| } |
| return null; |
| } |
| |
| private static class ComboItem { |
| |
| String value; |
| String displayName; |
| |
| public ComboItem(String value, String key) { |
| this.value = value; |
| this.displayName = NbBundle.getMessage(FmtOptions.class, key); |
| } |
| |
| @Override |
| public String toString() { |
| return displayName; |
| } |
| |
| } |
| } |
| |
| public static class PreviewPreferences extends AbstractPreferences { |
| |
| private final Map<String,Object> map = new HashMap<>(); |
| |
| public PreviewPreferences() { |
| super(null, ""); // NOI18N |
| } |
| |
| @Override |
| protected void putSpi(String key, String value) { |
| map.put(key, value); |
| } |
| |
| @Override |
| protected String getSpi(String key) { |
| return (String)map.get(key); |
| } |
| |
| @Override |
| protected void removeSpi(String key) { |
| map.remove(key); |
| } |
| |
| @Override |
| protected void removeNodeSpi() throws BackingStoreException { |
| throw new UnsupportedOperationException("Not supported yet."); |
| } |
| |
| @Override |
| protected String[] keysSpi() throws BackingStoreException { |
| String array[] = new String[map.keySet().size()]; |
| return map.keySet().toArray( array ); |
| } |
| |
| @Override |
| protected String[] childrenNamesSpi() throws BackingStoreException { |
| throw new UnsupportedOperationException("Not supported yet."); |
| } |
| |
| @Override |
| protected AbstractPreferences childSpi(String name) { |
| throw new UnsupportedOperationException("Not supported yet."); |
| } |
| |
| @Override |
| protected void syncSpi() throws BackingStoreException { |
| throw new UnsupportedOperationException("Not supported yet."); |
| } |
| |
| @Override |
| protected void flushSpi() throws BackingStoreException { |
| throw new UnsupportedOperationException("Not supported yet."); |
| } |
| } |
| |
| // read-only, no subnodes |
| public static final class ProxyPreferences extends AbstractPreferences { |
| |
| private final Preferences[] delegates; |
| |
| public ProxyPreferences(Preferences... delegates) { |
| super(null, ""); // NOI18N |
| this.delegates = delegates; |
| } |
| |
| @Override |
| protected void putSpi(String key, String value) { |
| throw new UnsupportedOperationException("Not supported yet."); |
| } |
| |
| @Override |
| protected String getSpi(String key) { |
| for(Preferences p : delegates) { |
| String value = p.get(key, null); |
| if (value != null) { |
| return value; |
| } |
| } |
| return null; |
| } |
| |
| @Override |
| protected void removeSpi(String key) { |
| throw new UnsupportedOperationException("Not supported yet."); |
| } |
| |
| @Override |
| protected void removeNodeSpi() throws BackingStoreException { |
| throw new UnsupportedOperationException("Not supported yet."); |
| } |
| |
| @Override |
| protected String[] keysSpi() throws BackingStoreException { |
| Set<String> keys = new HashSet<>(); |
| for(Preferences p : delegates) { |
| keys.addAll(Arrays.asList(p.keys())); |
| } |
| return keys.toArray(new String[0]); |
| } |
| |
| @Override |
| protected String[] childrenNamesSpi() throws BackingStoreException { |
| throw new UnsupportedOperationException("Not supported yet."); |
| } |
| |
| @Override |
| protected AbstractPreferences childSpi(String name) { |
| throw new UnsupportedOperationException("Not supported yet."); |
| } |
| |
| @Override |
| protected void syncSpi() throws BackingStoreException { |
| throw new UnsupportedOperationException("Not supported yet."); |
| } |
| |
| @Override |
| protected void flushSpi() throws BackingStoreException { |
| throw new UnsupportedOperationException("Not supported yet."); |
| } |
| } // End of ProxyPreferences class |
| |
| public static class BasicDefaultsProvider implements Defaults.Provider { |
| |
| @Override |
| public int getDefaultAsInt(String key) { |
| return FmtOptions.getDefaultAsInt(key); |
| } |
| |
| @Override |
| public boolean getDefaultAsBoolean(String key) { |
| return FmtOptions.getDefaultAsBoolean(key); |
| } |
| |
| @Override |
| public String getDefaultAsString(String key) { |
| return FmtOptions.getDefaultAsString(key); |
| } |
| |
| } |
| |
| public static boolean isInteger(String optionID) { |
| String value = defaults.get(optionID); |
| |
| try { |
| Integer.parseInt(value); |
| return true; |
| } catch (NumberFormatException numberFormatException) { |
| return false; |
| } |
| } |
| } |