/*
* Copyright 2003-2013 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 jetbrains.mps.nodeEditor;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.ui.ComboBox;
import com.intellij.ui.FontComboBox;
import com.intellij.ui.IdeBorderFactory;
import com.intellij.ui.components.JBLabel;
import com.intellij.ui.components.JBRadioButton;
import com.intellij.ui.components.panels.HorizontalLayout;
import com.intellij.uiDesigner.core.GridConstraints;
import com.intellij.uiDesigner.core.GridLayoutManager;
import com.intellij.util.ui.JBInsets;
import com.intellij.util.ui.UIUtil;
import jetbrains.mps.nodeEditor.resources.EditorSettingsBundle;
import javax.swing.ButtonGroup;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JCheckBox;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSpinner;
import javax.swing.JTextField;
import javax.swing.SpinnerNumberModel;
import java.awt.BorderLayout;
import java.awt.Font;
import java.awt.GridLayout;
class EditorSettingsPreferencesPage implements Disposable {
private static final double LINE_SPACING_MIN = 0.6;
private static final double LINE_SPACING_MAX = 3.0;
private static final double LINE_SPACING_STEP = 0.1;
private static final int RIGHT_MARGIN_MIN = 1;
private static final int RIGHT_MARGIN_MAX = 1000;
private static final int RIGHT_MARGIN_STEP = 20;
private static final int INDENT_SIZE_MIN = 0;
private static final int INDENT_SIZE_MAX = 100;
private static final int INDENT_SIZE_STEP = 2;
private JPanel myEditorSettingsPanel;
private final FontComboBox myFontsComboBox;
private final JSpinner myLineSpacing;
private final ComboBox myFontSizesComboBox;
private final JSpinner myRightMargin;
private final JSpinner myIndentSize;
private final JCheckBox myAntialiasingCheckBox;
private final JCheckBox myPowerSaveModeCheckBox;
private final JCheckBox myAutoQuickFixCheckBox;
private final JCheckBox myUseBraces;
private final JCheckBox myShowContextAssistant;
private final JSpinner myCaretBlinkPeriod;
private final JBRadioButton myDontShow;
private final JBRadioButton myTabPerAspect;
private final JBRadioButton myTabPerNode;
private final JBRadioButton myAllTabs;
private JBRadioButton myFirstSelection;
private final EditorSettings mySettings;
public EditorSettingsPreferencesPage(EditorSettings settings) {
mySettings = settings;
final int gap = 5;
final JBInsets insets = new JBInsets(gap, gap, gap, gap);
JPanel panel = new JPanel(new GridLayoutManager(4, 1, insets, gap, gap));
ButtonGroup group = new ButtonGroup();
JPanel editorTabsRB = new JPanel(new GridLayout(4, 1));
editorTabsRB.setBorder(IdeBorderFactory.createTitledBorder(EditorSettingsBundle.message("border.title.aspect.tabs"), true));
myDontShow = new JBRadioButton(EditorSettingsBundle.message("radiobutton.aspect.tabs.do.not.show"));
editorTabsRB.add(myDontShow);
group.add(myDontShow);
myTabPerAspect = new JBRadioButton(EditorSettingsBundle.message("radiobutton.aspect.tabs.for.aspect"));
editorTabsRB.add(myTabPerAspect);
group.add(myTabPerAspect);
myTabPerNode = new JBRadioButton(EditorSettingsBundle.message("radiobutton.aspect.tabs.for.node"));
editorTabsRB.add(myTabPerNode);
group.add(myTabPerNode);
myAllTabs = new JBRadioButton(EditorSettingsBundle.message("radiobutton.aspect.tabs.for.non.existing"));
editorTabsRB.add(myAllTabs);
group.add(myAllTabs);
myFirstSelection = myTabPerAspect;
myFirstSelection.setSelected(true);
panel.add(editorTabsRB,
new GridConstraints(0, 0, 1, 1, GridConstraints.ANCHOR_NORTHWEST, GridConstraints.FILL_HORIZONTAL, GridConstraints.SIZEPOLICY_CAN_GROW,
GridConstraints.SIZEPOLICY_FIXED, null, null, null));
JPanel fontPropertiesPanel = new JPanel(new GridLayoutManager(5, 2, insets, gap, gap));
fontPropertiesPanel.add(new JBLabel(EditorSettingsBundle.message("label.font.name")), getLabelConstraint(0));
myFontsComboBox = new FontComboBox();
fontPropertiesPanel.add(myFontsComboBox, getEditorConstraint(0));
fontPropertiesPanel.add(new JLabel(EditorSettingsBundle.message("label.font.size")), getLabelConstraint(1));
//noinspection unchecked
myFontSizesComboBox = new ComboBox(new DefaultComboBoxModel(UIUtil.getStandardFontSizes()));
myFontSizesComboBox.setEditable(true);
fontPropertiesPanel.add(myFontSizesComboBox, getEditorConstraint(1));
fontPropertiesPanel.add(new JLabel(EditorSettingsBundle.message("label.line.spacing")), getLabelConstraint(2));
myLineSpacing = new JSpinner(new SpinnerNumberModel(LINE_SPACING_MIN, LINE_SPACING_MIN, LINE_SPACING_MAX, LINE_SPACING_STEP));
((JSpinner.DefaultEditor) myLineSpacing.getEditor()).getTextField().setHorizontalAlignment(JTextField.LEFT);
fontPropertiesPanel.add(myLineSpacing, getEditorConstraint(2));
fontPropertiesPanel.add(new JLabel(EditorSettingsBundle.message("label.text.width")), getLabelConstraint(3));
myRightMargin = new JSpinner(new SpinnerNumberModel(RIGHT_MARGIN_MIN, RIGHT_MARGIN_MIN, RIGHT_MARGIN_MAX, RIGHT_MARGIN_STEP));
((JSpinner.DefaultEditor) myRightMargin.getEditor()).getTextField().setHorizontalAlignment(JTextField.LEFT);
fontPropertiesPanel.add(myRightMargin, getEditorConstraint(3));
fontPropertiesPanel.add(new JLabel(EditorSettingsBundle.message("label.indent.size")), getLabelConstraint(4));
myIndentSize = new JSpinner(new SpinnerNumberModel(INDENT_SIZE_MIN, INDENT_SIZE_MIN, INDENT_SIZE_MAX, INDENT_SIZE_STEP));
((JSpinner.DefaultEditor) myIndentSize.getEditor()).getTextField().setHorizontalAlignment(JTextField.LEFT);
fontPropertiesPanel.add(myIndentSize, getEditorConstraint(4));
panel.add(fontPropertiesPanel,
new GridConstraints(1, 0, 1, 1, GridConstraints.ANCHOR_NORTHWEST, GridConstraints.FILL_HORIZONTAL, GridConstraints.SIZEPOLICY_CAN_GROW,
GridConstraints.SIZEPOLICY_FIXED, null, null, null));
JPanel checkboxes = new JPanel(new GridLayout(3, 1));
myUseBraces = new JCheckBox(EditorSettingsBundle.message("checkbox.use.braces"));
checkboxes.add(myUseBraces);
myAntialiasingCheckBox = new JCheckBox(EditorSettingsBundle.message("checkbox.use.antialiasing"));
checkboxes.add(myAntialiasingCheckBox);
myPowerSaveModeCheckBox = new JCheckBox(EditorSettingsBundle.message("checkbox.power.save.mode"));
checkboxes.add(myPowerSaveModeCheckBox);
myAutoQuickFixCheckBox = new JCheckBox(EditorSettingsBundle.message("checkbox.auto.resolve.refs"));
checkboxes.add(myAutoQuickFixCheckBox);
myShowContextAssistant = new JCheckBox(EditorSettingsBundle.message("checkbox.context.assistant"));
checkboxes.add(myShowContextAssistant);
panel.add(checkboxes,
new GridConstraints(2, 0, 1, 1, GridConstraints.ANCHOR_NORTHWEST, GridConstraints.FILL_HORIZONTAL, GridConstraints.SIZEPOLICY_CAN_GROW,
GridConstraints.SIZEPOLICY_FIXED, null, null, null));
JPanel caretBlinkingPanel = new JPanel(new HorizontalLayout(gap));
caretBlinkingPanel.add(new JLabel(EditorSettingsBundle.message("label.caret.blinking")));
myCaretBlinkPeriod =
new JSpinner(
new SpinnerNumberModel(mySettings.getCaretBlinkPeriod(), EditorSettings.MIN_CARET_BLINK_PERIOD, EditorSettings.MAX_CARET_BLINK_PERIOD, 100));
caretBlinkingPanel.add(myCaretBlinkPeriod);
panel.add(caretBlinkingPanel,
new GridConstraints(3, 0, 1, 1, GridConstraints.ANCHOR_NORTHWEST, GridConstraints.FILL_HORIZONTAL, GridConstraints.SIZEPOLICY_CAN_GROW,
GridConstraints.SIZEPOLICY_FIXED, null, null, null));
myEditorSettingsPanel = new JPanel(new BorderLayout());
myEditorSettingsPanel.add(panel, BorderLayout.NORTH);
}
private GridConstraints getLabelConstraint(int row) {
return new GridConstraints(row, 0, 1, 1, GridConstraints.ANCHOR_NORTHWEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_FIXED,
GridConstraints.SIZEPOLICY_FIXED, null, null, null);
}
private GridConstraints getEditorConstraint(int row) {
return new GridConstraints(row, 1, 1, 1, GridConstraints.ANCHOR_NORTHWEST, GridConstraints.FILL_HORIZONTAL,
GridConstraints.SIZEPOLICY_CAN_GROW | GridConstraints.SIZEPOLICY_CAN_SHRINK, GridConstraints.SIZEPOLICY_FIXED, null, null, null);
}
public JComponent getComponent() {
return myEditorSettingsPanel;
}
public void commit() {
String fontName = myFontsComboBox.getFontName();
int fontSize = mySettings.getSpecifiedFontSize();
try {
fontSize = Integer.parseInt(myFontSizesComboBox.getSelectedItem().toString());
} catch (NumberFormatException e) {
// ignore wrong formatted value and reset combo box
myFontSizesComboBox.setSelectedItem(Integer.toString(fontSize));
}
Font newFont = new Font(fontName, Font.PLAIN, fontSize);
mySettings.setDefaultEditorFont(newFont);
mySettings.setVerticalBound((Integer) myRightMargin.getModel().getValue());
mySettings.setIndentSize((Integer) myIndentSize.getModel().getValue());
mySettings.setCaretBlinkPeriod((Integer) myCaretBlinkPeriod.getModel().getValue());
mySettings.setUseAntialiasing(myAntialiasingCheckBox.isSelected());
mySettings.setUseBraces(myUseBraces.isSelected());
mySettings.setShowContextAssistant(myShowContextAssistant.isSelected());
mySettings.setPowerSaveMode(myPowerSaveModeCheckBox.isSelected());
mySettings.setAutoQuickFix(myAutoQuickFixCheckBox.isSelected());
mySettings.setLineSpacing((Double) myLineSpacing.getModel().getValue());
mySettings.setShow(myTabPerAspect.isSelected() || myTabPerNode.isSelected() || myAllTabs.isSelected());
mySettings.setShowPlain(myTabPerNode.isSelected() || myAllTabs.isSelected());
mySettings.setShowGrayed(myAllTabs.isSelected());
applyState();
mySettings.updateCachedValue();
mySettings.updateGlobalScheme();
mySettings.fireEditorSettingsChanged();
}
private void applyState() {
if (!mySettings.isShow()) {
myFirstSelection = myDontShow;
} else if (!mySettings.isShowPlain()) {
myFirstSelection = myTabPerAspect;
} else if (!mySettings.isShowGrayed()) {
myFirstSelection = myTabPerNode;
} else {
myFirstSelection = myAllTabs;
}
}
public boolean isModified() {
boolean sameTextWidth = myRightMargin.getModel().getValue().equals(mySettings.getVerticalBound());
boolean sameIndentSize = myIndentSize.getModel().getValue().equals(mySettings.getIndentSize());
boolean sameAntialiasing = myAntialiasingCheckBox.isSelected() == mySettings.isUseAntialiasing();
boolean sameUseBraces = myUseBraces.isSelected() == mySettings.useBraces();
boolean samePowerSaveMode = myPowerSaveModeCheckBox.isSelected() == mySettings.isPowerSaveMode();
boolean sameAutoQuickFix = myAutoQuickFixCheckBox.isSelected() == mySettings.isAutoQuickFix();
boolean sameFontSize = myFontSizesComboBox.getSelectedItem().equals(Integer.toString(mySettings.getSpecifiedFontSize()));
boolean sameFontFamily = myFontsComboBox.getFontName().equals(mySettings.getFontFamily());
boolean sameLineSpacing = myLineSpacing.getModel().getValue().equals(mySettings.getLineSpacing());
boolean sameBlinkingRate = myCaretBlinkPeriod.getModel().getValue().equals(mySettings.getCaretBlinkPeriod());
boolean sameTabs = myFirstSelection.isSelected();
boolean sameUseContextAssistant = myShowContextAssistant.isSelected() == mySettings.isShowContextAssistant();
return !(sameTextWidth && sameIndentSize && sameAntialiasing && sameUseBraces && samePowerSaveMode
&& sameAutoQuickFix && sameFontSize && sameFontFamily && sameLineSpacing && sameBlinkingRate && sameTabs && sameUseContextAssistant);
}
public void reset() {
myRightMargin.setValue(mySettings.getVerticalBound());
myIndentSize.setValue(mySettings.getIndentSize());
myAntialiasingCheckBox.setSelected(mySettings.isUseAntialiasing());
myUseBraces.setSelected(mySettings.useBraces());
myPowerSaveModeCheckBox.setSelected(mySettings.isPowerSaveMode());
myAutoQuickFixCheckBox.setSelected(mySettings.isAutoQuickFix());
myShowContextAssistant.setSelected(mySettings.isShowContextAssistant());
myFontSizesComboBox.setSelectedItem(Integer.toString(mySettings.getSpecifiedFontSize()));
myFontsComboBox.setFontName(mySettings.getFontFamily());
myLineSpacing.setValue(mySettings.getLineSpacing());
myCaretBlinkPeriod.setValue(mySettings.getCaretBlinkPeriod());
applyState();
myFirstSelection.setSelected(true);
}
@Override
public void dispose() {
myEditorSettingsPanel = null;
}
}