| /* |
| * Copyright 2000-2014 JetBrains s.r.o. |
| * |
| * Licensed 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.intellij.application.options; |
| |
| import com.intellij.lang.Language; |
| import com.intellij.openapi.application.ApplicationBundle; |
| import com.intellij.openapi.diagnostic.Logger; |
| import com.intellij.openapi.editor.colors.EditorColorsScheme; |
| import com.intellij.openapi.editor.highlighter.EditorHighlighter; |
| import com.intellij.openapi.editor.highlighter.EditorHighlighterFactory; |
| import com.intellij.openapi.extensions.Extensions; |
| import com.intellij.openapi.fileTypes.FileType; |
| import com.intellij.openapi.fileTypes.FileTypes; |
| import com.intellij.openapi.fileTypes.LanguageFileType; |
| import com.intellij.openapi.project.ProjectManager; |
| import com.intellij.openapi.ui.MessageType; |
| import com.intellij.openapi.ui.popup.Balloon; |
| import com.intellij.openapi.ui.popup.BalloonBuilder; |
| import com.intellij.openapi.ui.popup.JBPopupFactory; |
| import com.intellij.openapi.util.Comparing; |
| import com.intellij.openapi.util.Disposer; |
| import com.intellij.openapi.util.text.StringUtil; |
| import com.intellij.psi.PsiFile; |
| import com.intellij.psi.codeStyle.CodeStyleSettings; |
| import com.intellij.psi.codeStyle.DisplayPriority; |
| import com.intellij.psi.codeStyle.FileTypeIndentOptionsProvider; |
| import com.intellij.psi.codeStyle.LanguageCodeStyleSettingsProvider; |
| import com.intellij.ui.IdeBorderFactory; |
| import com.intellij.ui.awt.RelativePoint; |
| import com.intellij.ui.components.JBLabel; |
| import com.intellij.ui.components.JBScrollPane; |
| import org.jetbrains.annotations.NotNull; |
| import org.jetbrains.annotations.Nullable; |
| |
| import javax.swing.*; |
| import java.awt.*; |
| import java.awt.event.ActionEvent; |
| import java.awt.event.ActionListener; |
| import java.util.Arrays; |
| import java.util.Collections; |
| import java.util.Comparator; |
| import java.util.List; |
| import java.util.regex.Pattern; |
| import java.util.regex.PatternSyntaxException; |
| |
| public class GeneralCodeStylePanel extends CodeStyleAbstractPanel { |
| @SuppressWarnings("UnusedDeclaration") |
| private static final Logger LOG = Logger.getInstance("#com.intellij.application.options.GeneralCodeStylePanel"); |
| |
| private static final String SYSTEM_DEPENDANT_STRING = ApplicationBundle.message("combobox.crlf.system.dependent"); |
| private static final String UNIX_STRING = ApplicationBundle.message("combobox.crlf.unix"); |
| private static final String WINDOWS_STRING = ApplicationBundle.message("combobox.crlf.windows"); |
| private static final String MACINTOSH_STRING = ApplicationBundle.message("combobox.crlf.mac"); |
| |
| |
| private JSpinner myRightMarginSpinner; |
| private JComboBox myLineSeparatorCombo; |
| private JPanel myPanel; |
| private JCheckBox myCbWrapWhenTypingReachesRightMargin; |
| private JPanel myDefaultIndentOptionsPanel; |
| private JCheckBox myEnableFormatterTags; |
| private JTextField myFormatterOnTagField; |
| private JTextField myFormatterOffTagField; |
| private JCheckBox myAcceptRegularExpressionsCheckBox; |
| private JPanel myMarkersPanel; |
| private JBLabel myFormatterOffLabel; |
| private JBLabel myFormatterOnLabel; |
| private JPanel myMarkerOptionsPanel; |
| private final SmartIndentOptionsEditor myIndentOptionsEditor; |
| private final JBScrollPane myScrollPane; |
| |
| |
| public GeneralCodeStylePanel(CodeStyleSettings settings) { |
| super(settings); |
| |
| final List<FileTypeIndentOptionsProvider> indentOptionsProviders = |
| Arrays.asList(Extensions.getExtensions(FileTypeIndentOptionsProvider.EP_NAME)); |
| Collections.sort(indentOptionsProviders, new Comparator<FileTypeIndentOptionsProvider>() { |
| @Override |
| public int compare(FileTypeIndentOptionsProvider p1, FileTypeIndentOptionsProvider p2) { |
| Language lang1 = getLanguage(p1.getFileType()); |
| if (lang1 == null) return -1; |
| Language lang2 = getLanguage(p2.getFileType()); |
| if (lang2 == null) return 1; |
| DisplayPriority priority1 = LanguageCodeStyleSettingsProvider.getDisplayPriority(lang1); |
| DisplayPriority priority2 = LanguageCodeStyleSettingsProvider.getDisplayPriority(lang2); |
| if (priority1.equals(priority2)) { |
| return lang1.getDisplayName().compareTo(lang2.getDisplayName()); |
| } |
| return priority1.compareTo(priority2); |
| } |
| }); |
| |
| myLineSeparatorCombo.addItem(SYSTEM_DEPENDANT_STRING); |
| myLineSeparatorCombo.addItem(UNIX_STRING); |
| myLineSeparatorCombo.addItem(WINDOWS_STRING); |
| myLineSeparatorCombo.addItem(MACINTOSH_STRING); |
| addPanelToWatch(myPanel); |
| |
| myRightMarginSpinner.setModel(new SpinnerNumberModel(settings.RIGHT_MARGIN, 1, 1000000, 1)); |
| |
| myIndentOptionsEditor = new SmartIndentOptionsEditor(); |
| myDefaultIndentOptionsPanel.add(myIndentOptionsEditor.createPanel(), BorderLayout.CENTER); |
| |
| myEnableFormatterTags.addActionListener(new ActionListener() { |
| @Override |
| public void actionPerformed(ActionEvent e) { |
| boolean tagsEnabled = myEnableFormatterTags.isSelected(); |
| setFormatterTagControlsEnabled(tagsEnabled); |
| } |
| }); |
| |
| myMarkersPanel.setBorder(IdeBorderFactory.createTitledBorder( |
| ApplicationBundle.message("settings.code.style.general.formatter.marker.title"), true)); |
| myMarkerOptionsPanel.setBorder( |
| IdeBorderFactory.createTitledBorder(ApplicationBundle.message("settings.code.style.general.formatter.marker.options.title"), true)); |
| myScrollPane = new JBScrollPane(myPanel, |
| ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER); |
| myScrollPane.setBorder(IdeBorderFactory.createEmptyBorder()); |
| } |
| |
| @Nullable |
| private static Language getLanguage(FileType fileType) { |
| return fileType instanceof LanguageFileType ? ((LanguageFileType)fileType).getLanguage() : null; |
| } |
| |
| @Override |
| protected void somethingChanged() { |
| super.somethingChanged(); |
| } |
| |
| |
| @Override |
| protected int getRightMargin() { |
| return ((Number) myRightMarginSpinner.getValue()).intValue(); |
| } |
| |
| @Override |
| @NotNull |
| protected FileType getFileType() { |
| return FileTypes.PLAIN_TEXT; |
| } |
| |
| @Override |
| protected String getPreviewText() { |
| return ""; |
| } |
| |
| |
| @Override |
| public void apply(CodeStyleSettings settings) { |
| settings.LINE_SEPARATOR = getSelectedLineSeparator(); |
| |
| settings.RIGHT_MARGIN = ((Number) myRightMarginSpinner.getValue()).intValue(); |
| settings.WRAP_WHEN_TYPING_REACHES_RIGHT_MARGIN = myCbWrapWhenTypingReachesRightMargin.isSelected(); |
| myIndentOptionsEditor.setEnabled(true); |
| myIndentOptionsEditor.apply(settings, settings.OTHER_INDENT_OPTIONS); |
| |
| settings.FORMATTER_TAGS_ENABLED = myEnableFormatterTags.isSelected(); |
| settings.FORMATTER_TAGS_ACCEPT_REGEXP = myAcceptRegularExpressionsCheckBox.isSelected(); |
| |
| settings.FORMATTER_OFF_TAG = getTagText(myFormatterOffTagField, settings.FORMATTER_OFF_TAG); |
| settings.setFormatterOffPattern(compilePattern(settings, myFormatterOffTagField, settings.FORMATTER_OFF_TAG)); |
| |
| settings.FORMATTER_ON_TAG = getTagText(myFormatterOnTagField, settings.FORMATTER_ON_TAG); |
| settings.setFormatterOnPattern(compilePattern(settings, myFormatterOnTagField, settings.FORMATTER_ON_TAG)); |
| } |
| |
| @Nullable |
| private static Pattern compilePattern(CodeStyleSettings settings, JTextField field, String patternText) { |
| try { |
| return Pattern.compile(patternText); |
| } |
| catch (PatternSyntaxException pse) { |
| settings.FORMATTER_TAGS_ACCEPT_REGEXP = false; |
| showError(field, ApplicationBundle.message("settings.code.style.general.formatter.marker.invalid.regexp")); |
| return null; |
| } |
| } |
| |
| private static String getTagText(JTextField field, String defualtValue) { |
| String fieldText = field.getText(); |
| if (StringUtil.isEmpty(field.getText())) { |
| field.setText(defualtValue); |
| return defualtValue; |
| } |
| return fieldText; |
| } |
| |
| @Nullable |
| private String getSelectedLineSeparator() { |
| if (UNIX_STRING.equals(myLineSeparatorCombo.getSelectedItem())) { |
| return "\n"; |
| } |
| else if (MACINTOSH_STRING.equals(myLineSeparatorCombo.getSelectedItem())) { |
| return "\r"; |
| } |
| else if (WINDOWS_STRING.equals(myLineSeparatorCombo.getSelectedItem())) { |
| return "\r\n"; |
| } |
| return null; |
| } |
| |
| |
| @Override |
| public boolean isModified(CodeStyleSettings settings) { |
| if (!Comparing.equal(getSelectedLineSeparator(), settings.LINE_SEPARATOR)) { |
| return true; |
| } |
| |
| if (settings.WRAP_WHEN_TYPING_REACHES_RIGHT_MARGIN ^ myCbWrapWhenTypingReachesRightMargin.isSelected()) { |
| return true; |
| } |
| |
| if (!Comparing.equal(myRightMarginSpinner.getValue(), settings.RIGHT_MARGIN)) return true; |
| myIndentOptionsEditor.setEnabled(true); |
| |
| if (myEnableFormatterTags.isSelected()) { |
| if ( |
| !settings.FORMATTER_TAGS_ENABLED || |
| settings.FORMATTER_TAGS_ACCEPT_REGEXP != myAcceptRegularExpressionsCheckBox.isSelected() || |
| !StringUtil.equals(myFormatterOffTagField.getText(), settings.FORMATTER_OFF_TAG) || |
| !StringUtil.equals(myFormatterOnTagField.getText(), settings.FORMATTER_ON_TAG)) return true; |
| } |
| else { |
| if (settings.FORMATTER_TAGS_ENABLED) return true; |
| } |
| |
| return myIndentOptionsEditor.isModified(settings, settings.OTHER_INDENT_OPTIONS); |
| } |
| |
| @Override |
| public JComponent getPanel() { |
| return myScrollPane; |
| } |
| |
| @Override |
| protected void resetImpl(final CodeStyleSettings settings) { |
| |
| String lineSeparator = settings.LINE_SEPARATOR; |
| if ("\n".equals(lineSeparator)) { |
| myLineSeparatorCombo.setSelectedItem(UNIX_STRING); |
| } |
| else if ("\r\n".equals(lineSeparator)) { |
| myLineSeparatorCombo.setSelectedItem(WINDOWS_STRING); |
| } |
| else if ("\r".equals(lineSeparator)) { |
| myLineSeparatorCombo.setSelectedItem(MACINTOSH_STRING); |
| } |
| else { |
| myLineSeparatorCombo.setSelectedItem(SYSTEM_DEPENDANT_STRING); |
| } |
| |
| myRightMarginSpinner.setValue(settings.RIGHT_MARGIN); |
| myCbWrapWhenTypingReachesRightMargin.setSelected(settings.WRAP_WHEN_TYPING_REACHES_RIGHT_MARGIN); |
| myIndentOptionsEditor.reset(settings, settings.OTHER_INDENT_OPTIONS); |
| myIndentOptionsEditor.setEnabled(true); |
| |
| myAcceptRegularExpressionsCheckBox.setSelected(settings.FORMATTER_TAGS_ACCEPT_REGEXP); |
| myEnableFormatterTags.setSelected(settings.FORMATTER_TAGS_ENABLED); |
| |
| myFormatterOnTagField.setText(settings.FORMATTER_ON_TAG); |
| myFormatterOffTagField.setText(settings.FORMATTER_OFF_TAG); |
| |
| setFormatterTagControlsEnabled(settings.FORMATTER_TAGS_ENABLED); |
| } |
| |
| private void setFormatterTagControlsEnabled(boolean isEnabled) { |
| myFormatterOffTagField.setEnabled(isEnabled); |
| myFormatterOnTagField.setEnabled(isEnabled); |
| myMarkersPanel.setEnabled(isEnabled); |
| myAcceptRegularExpressionsCheckBox.setEnabled(isEnabled); |
| myFormatterOffLabel.setEnabled(isEnabled); |
| myFormatterOnLabel.setEnabled(isEnabled); |
| myMarkerOptionsPanel.setEnabled(isEnabled); |
| } |
| |
| @Override |
| protected EditorHighlighter createHighlighter(final EditorColorsScheme scheme) { |
| //noinspection NullableProblems |
| return EditorHighlighterFactory.getInstance().createEditorHighlighter(getFileType(), scheme, null); |
| } |
| |
| @Override |
| protected void prepareForReformat(final PsiFile psiFile) { |
| } |
| |
| |
| @Override |
| public Language getDefaultLanguage() { |
| return null; |
| } |
| |
| private static void showError(final JTextField field, final String message) { |
| BalloonBuilder balloonBuilder = JBPopupFactory.getInstance() |
| .createHtmlTextBalloonBuilder(message, MessageType.ERROR.getDefaultIcon(), MessageType.ERROR.getPopupBackground(), null); |
| balloonBuilder.setFadeoutTime(1500); |
| final Balloon balloon = balloonBuilder.createBalloon(); |
| final Rectangle rect = field.getBounds(); |
| final Point p = new Point(0, rect.height); |
| final RelativePoint point = new RelativePoint(field, p); |
| balloon.show(point, Balloon.Position.below); |
| Disposer.register(ProjectManager.getInstance().getDefaultProject(), balloon); |
| } |
| } |