EditorConfig documentation test
[idea/community.git] / images / src / org / intellij / images / options / impl / ImagesOptionsComponent.java
1 /*
2  * Copyright 2004-2005 Alexey Efimov
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package org.intellij.images.options.impl;
17
18 import com.intellij.openapi.application.Application;
19 import com.intellij.openapi.application.ApplicationManager;
20 import com.intellij.openapi.fileChooser.FileChooser;
21 import com.intellij.openapi.fileChooser.FileChooserDescriptor;
22 import com.intellij.openapi.ui.TextFieldWithBrowseButton;
23 import com.intellij.openapi.util.NullableComputable;
24 import com.intellij.openapi.util.SystemInfoRt;
25 import com.intellij.openapi.util.io.FileUtil;
26 import com.intellij.openapi.vfs.LocalFileSystem;
27 import com.intellij.openapi.vfs.VirtualFile;
28 import com.intellij.ui.ColorPanel;
29 import com.intellij.ui.DocumentAdapter;
30 import org.intellij.images.ImagesBundle;
31 import org.intellij.images.options.*;
32 import org.jetbrains.annotations.NotNull;
33
34 import javax.swing.*;
35 import javax.swing.event.ChangeEvent;
36 import javax.swing.event.ChangeListener;
37 import javax.swing.event.DocumentEvent;
38 import javax.swing.text.BadLocationException;
39 import javax.swing.text.Document;
40 import javax.swing.text.Position;
41 import java.awt.*;
42 import java.awt.event.ActionEvent;
43 import java.awt.event.ActionListener;
44 import java.awt.event.ItemEvent;
45 import java.awt.event.ItemListener;
46
47 /**
48  * Options UI form bean.
49  *
50  * @author <a href="mailto:aefimov.box@gmail.com">Alexey Efimov</a>
51  */
52 final class ImagesOptionsComponent {
53   private JPanel contentPane;
54   private JCheckBox showGrid;
55   private JLabel gridLineZoomFactorLabel;
56   private JSpinner gridLineZoomFactor;
57   private JLabel gridLineSpanLabel;
58   private JSpinner gridLineSpan;
59   private JCheckBox showChessboard;
60   private JSpinner chessboardSize;
61   private JLabel chessboardSizeLabel;
62   private JCheckBox wheelZooming;
63   private JCheckBox smartZooming;
64   private JSpinner smartZoomingWidth;
65   private JLabel smartZoomingWidthLabel;
66   private JSpinner smartZoomingHeight;
67   private JLabel smartZoomingHeightLabel;
68   private JLabel gridLineColorLabel;
69   private ColorPanel gridLineColor;
70   private JLabel chessboardWhiteColorLabel;
71   private JLabel chessboardBlackColorLabel;
72   private ColorPanel chessboardBlackColor;
73   private ColorPanel chessboardWhiteColor;
74   private JLabel externalEditorLabel;
75   private TextFieldWithBrowseButton externalEditorPath;
76
77   // Options
78   private final Options options = new OptionsImpl();
79
80   ImagesOptionsComponent() {
81
82     wheelZooming.setText(ImagesBundle.message("enable.mousewheel.zooming", SystemInfoRt.isMac ? "Cmd" : "Ctrl"));
83
84     // Setup labels
85     gridLineZoomFactorLabel.setLabelFor(gridLineZoomFactor);
86     gridLineSpanLabel.setLabelFor(gridLineSpan);
87     chessboardSizeLabel.setLabelFor(chessboardSize);
88     smartZoomingWidthLabel.setLabelFor(smartZoomingWidth);
89     smartZoomingHeightLabel.setLabelFor(smartZoomingHeight);
90     gridLineColorLabel.setLabelFor(gridLineColor);
91     chessboardWhiteColorLabel.setLabelFor(chessboardWhiteColor);
92     chessboardBlackColorLabel.setLabelFor(chessboardBlackColor);
93     externalEditorLabel.setLabelFor(externalEditorPath);
94
95     // Setup listeners for enabling and disabling linked checkbox groups
96     smartZooming.addItemListener(new LinkEnabledListener(new JComponent[]{
97       smartZoomingHeightLabel,
98       smartZoomingHeight,
99       smartZoomingWidthLabel,
100       smartZoomingWidth,
101     }));
102     // Setup spinners models
103     gridLineZoomFactor.setModel(new SpinnerNumberModel(GridOptions.DEFAULT_LINE_ZOOM_FACTOR, 2, 8, 1));
104     gridLineSpan.setModel(new SpinnerNumberModel(GridOptions.DEFAULT_LINE_SPAN, 1, 100, 1));
105     chessboardSize.setModel(new SpinnerNumberModel(TransparencyChessboardOptions.DEFAULT_CELL_SIZE, 1, 100, 1));
106     smartZoomingWidth.setModel(new SpinnerNumberModel(ZoomOptions.DEFAULT_PREFFERED_SIZE.width, 1, 9999, 1));
107     smartZoomingHeight.setModel(new SpinnerNumberModel(ZoomOptions.DEFAULT_PREFFERED_SIZE.height, 1, 9999, 1));
108
109     // Setup listeners for chnages
110     showGrid.addItemListener(new CheckboxOptionsListener(GridOptions.ATTR_SHOW_DEFAULT));
111     gridLineZoomFactor.addChangeListener(new SpinnerOptionsListener(GridOptions.ATTR_LINE_ZOOM_FACTOR));
112     gridLineSpan.addChangeListener(new SpinnerOptionsListener(GridOptions.ATTR_LINE_SPAN));
113     showChessboard.addItemListener(new CheckboxOptionsListener(TransparencyChessboardOptions.ATTR_SHOW_DEFAULT));
114     chessboardSize.addChangeListener(new SpinnerOptionsListener(TransparencyChessboardOptions.ATTR_CELL_SIZE));
115     wheelZooming.addItemListener(new CheckboxOptionsListener(ZoomOptions.ATTR_WHEEL_ZOOMING));
116     smartZooming.addItemListener(new CheckboxOptionsListener(ZoomOptions.ATTR_SMART_ZOOMING));
117     smartZoomingWidth.addChangeListener(new SpinnerOptionsListener(ZoomOptions.ATTR_PREFFERED_WIDTH));
118     smartZoomingHeight.addChangeListener(new SpinnerOptionsListener(ZoomOptions.ATTR_PREFFERED_HEIGHT));
119     gridLineColor.addActionListener(new ColorOptionsListener(GridOptions.ATTR_LINE_COLOR));
120     chessboardWhiteColor.addActionListener(new ColorOptionsListener(TransparencyChessboardOptions.ATTR_WHITE_COLOR));
121     chessboardBlackColor.addActionListener(new ColorOptionsListener(TransparencyChessboardOptions.ATTR_BLACK_COLOR));
122     externalEditorPath.getTextField().getDocument()
123       .addDocumentListener(new TextDocumentOptionsListener(ExternalEditorOptions.ATTR_EXECUTABLE_PATH));
124
125     externalEditorPath.addActionListener(new ExternalEditorPathActionListener());
126
127     updateUI();
128   }
129
130   public JPanel getContentPane() {
131     return contentPane;
132   }
133
134   private static class LinkEnabledListener implements ItemListener {
135     private final JComponent[] children;
136
137     LinkEnabledListener(JComponent[] children) {
138       this.children = children.clone();
139     }
140
141     @Override
142     public void itemStateChanged(ItemEvent e) {
143       setSelected(e.getStateChange() == ItemEvent.SELECTED);
144     }
145
146     private void setSelected(boolean selected) {
147       for (JComponent component : children) {
148         component.setEnabled(selected);
149       }
150     }
151   }
152
153   @NotNull
154   public Options getOptions() {
155     return options;
156   }
157
158   public void updateUI() {
159     // Grid options
160     EditorOptions editorOptions = options.getEditorOptions();
161     ExternalEditorOptions externalEditorOptions = options.getExternalEditorOptions();
162
163     GridOptions gridOptions = editorOptions.getGridOptions();
164     showGrid.setSelected(gridOptions.isShowDefault());
165     gridLineZoomFactor.setValue(gridOptions.getLineZoomFactor());
166     gridLineSpan.setValue(gridOptions.getLineSpan());
167     gridLineColor.setSelectedColor(gridOptions.getLineColor());
168     TransparencyChessboardOptions transparencyChessboardOptions = editorOptions.getTransparencyChessboardOptions();
169     showChessboard.setSelected(transparencyChessboardOptions.isShowDefault());
170     chessboardSize.setValue(transparencyChessboardOptions.getCellSize());
171     chessboardWhiteColor.setSelectedColor(transparencyChessboardOptions.getWhiteColor());
172     chessboardBlackColor.setSelectedColor(transparencyChessboardOptions.getBlackColor());
173     ZoomOptions zoomOptions = editorOptions.getZoomOptions();
174     wheelZooming.setSelected(zoomOptions.isWheelZooming());
175     smartZooming.setSelected(zoomOptions.isSmartZooming());
176     Dimension prefferedSize = zoomOptions.getPrefferedSize();
177     smartZoomingWidth.setValue(prefferedSize.width);
178     smartZoomingHeight.setValue(prefferedSize.height);
179     externalEditorPath.setText(externalEditorOptions.getExecutablePath());
180   }
181
182   private final class CheckboxOptionsListener implements ItemListener {
183     @NotNull
184     private final String name;
185
186     private CheckboxOptionsListener(@NotNull String name) {
187       this.name = name;
188     }
189
190     @Override
191     @SuppressWarnings({"UnnecessaryBoxing"})
192     public void itemStateChanged(ItemEvent e) {
193       options.setOption(name, Boolean.valueOf(ItemEvent.SELECTED == e.getStateChange()));
194     }
195   }
196
197   private final class SpinnerOptionsListener implements ChangeListener {
198     private final String name;
199
200     private SpinnerOptionsListener(String name) {
201       this.name = name;
202     }
203
204     @Override
205     public void stateChanged(ChangeEvent e) {
206       JSpinner source = (JSpinner)e.getSource();
207       options.setOption(name, source.getValue());
208     }
209   }
210
211   private final class ColorOptionsListener implements ActionListener {
212     private final String name;
213
214     private ColorOptionsListener(String name) {
215       this.name = name;
216     }
217
218     @Override
219     public void actionPerformed(ActionEvent e) {
220       ColorPanel source = (ColorPanel)e.getSource();
221       options.setOption(name, source.getSelectedColor());
222     }
223   }
224
225   private final class TextDocumentOptionsListener extends DocumentAdapter {
226     private final String name;
227
228     TextDocumentOptionsListener(String name) {
229       this.name = name;
230     }
231
232     @Override
233     protected void textChanged(@NotNull DocumentEvent documentEvent) {
234       Document document = documentEvent.getDocument();
235       Position startPosition = document.getStartPosition();
236       try {
237         options.setOption(name, document.getText(startPosition.getOffset(), document.getLength()));
238       }
239       catch (BadLocationException e) {
240         // Ignore
241       }
242     }
243   }
244
245   private final class ExternalEditorPathActionListener implements ActionListener {
246     @Override
247     public void actionPerformed(ActionEvent e) {
248       Application application = ApplicationManager.getApplication();
249       VirtualFile previous = application.runWriteAction((NullableComputable<VirtualFile>)() -> {
250         final String path = FileUtil.toSystemIndependentName(externalEditorPath.getText());
251         return LocalFileSystem.getInstance().refreshAndFindFileByPath(path);
252       });
253       FileChooserDescriptor fileDescriptor = new FileChooserDescriptor(true, SystemInfoRt.isMac, false, false, false, false);
254       fileDescriptor.setShowFileSystemRoots(true);
255       fileDescriptor.setTitle(ImagesBundle.message("select.external.executable.title"));
256       fileDescriptor.setDescription(ImagesBundle.message("select.external.executable.message"));
257       FileChooser.chooseFiles(fileDescriptor, null, previous, files -> {
258         String path = files.get(0).getPath();
259         externalEditorPath.setText(path);
260       });
261     }
262   }
263 }