update copyrights
[fedora-idea.git] / platform / lang-impl / src / com / intellij / application / options / CodeStyleAbstractPanel.java
blob1dbe3e8a438e343c6df13966b0c628b445c6f9cb
1 /*
2 * Copyright 2000-2009 JetBrains s.r.o.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
16 package com.intellij.application.options;
18 import com.intellij.application.options.codeStyle.CodeStyleSchemesModel;
19 import com.intellij.ide.DataManager;
20 import com.intellij.openapi.Disposable;
21 import com.intellij.openapi.actionSystem.PlatformDataKeys;
22 import com.intellij.openapi.application.ApplicationBundle;
23 import com.intellij.openapi.application.ApplicationManager;
24 import com.intellij.openapi.command.CommandProcessor;
25 import com.intellij.openapi.diagnostic.Logger;
26 import com.intellij.openapi.editor.Document;
27 import com.intellij.openapi.editor.Editor;
28 import com.intellij.openapi.editor.EditorFactory;
29 import com.intellij.openapi.editor.EditorSettings;
30 import com.intellij.openapi.editor.colors.EditorColors;
31 import com.intellij.openapi.editor.colors.EditorColorsScheme;
32 import com.intellij.openapi.editor.ex.EditorEx;
33 import com.intellij.openapi.editor.highlighter.EditorHighlighter;
34 import com.intellij.openapi.fileTypes.FileType;
35 import com.intellij.openapi.project.Project;
36 import com.intellij.openapi.project.ProjectManager;
37 import com.intellij.psi.PsiFile;
38 import com.intellij.psi.PsiFileFactory;
39 import com.intellij.psi.codeStyle.CodeStyleManager;
40 import com.intellij.psi.codeStyle.CodeStyleSettings;
41 import com.intellij.psi.codeStyle.CodeStyleSettingsManager;
42 import com.intellij.ui.UserActivityListener;
43 import com.intellij.ui.UserActivityWatcher;
44 import com.intellij.util.Alarm;
45 import com.intellij.util.IncorrectOperationException;
46 import com.intellij.util.LocalTimeCounter;
47 import com.intellij.util.ui.update.UiNotifyConnector;
48 import org.jetbrains.annotations.NonNls;
49 import org.jetbrains.annotations.NotNull;
51 import javax.swing.*;
52 import java.awt.*;
53 import java.io.IOException;
54 import java.io.InputStream;
55 import java.io.InputStreamReader;
56 import java.io.LineNumberReader;
58 public abstract class CodeStyleAbstractPanel implements Disposable {
59 private static final Logger LOG = Logger.getInstance("#com.intellij.application.options.CodeStyleXmlPanel");
60 private final Editor myEditor;
61 private final CodeStyleSettings mySettings;
62 private boolean myShouldUpdatePreview;
63 protected static final int[] ourWrappings =
64 {CodeStyleSettings.DO_NOT_WRAP, CodeStyleSettings.WRAP_AS_NEEDED, CodeStyleSettings.WRAP_ON_EVERY_ITEM, CodeStyleSettings.WRAP_ALWAYS};
65 private long myLastDocumentModificationStamp;
66 private String myTextToReformat = null;
67 private final UserActivityWatcher myUserActivityWatcher = new UserActivityWatcher();
69 private final Alarm myUpdateAlarm = new Alarm(Alarm.ThreadToUse.SWING_THREAD);
71 private CodeStyleSchemesModel myModel;
72 private boolean mySomethingChanged = false;
74 private synchronized void setSomethingChanged(final boolean b) {
75 mySomethingChanged = b;
78 private synchronized boolean isSomethingChanged() {
79 return mySomethingChanged;
82 protected CodeStyleAbstractPanel(CodeStyleSettings settings) {
83 mySettings = settings;
84 myEditor = createEditor();
86 myUpdateAlarm.setActivationComponent(myEditor.getComponent());
87 myUserActivityWatcher.addUserActivityListener(new UserActivityListener() {
88 public void stateChanged() {
89 somethingChanged();
91 });
94 public void setModel(final CodeStyleSchemesModel model) {
95 myModel = model;
98 protected void somethingChanged() {
99 if (myModel != null) {
100 myModel.fireCurrentSettingsChanged();
104 protected void addPanelToWatch(Component component) {
105 myUserActivityWatcher.register(component);
108 private Editor createEditor() {
109 EditorFactory editorFactory = EditorFactory.getInstance();
110 myTextToReformat = getPreviewText();
111 Document editorDocument = editorFactory.createDocument(myTextToReformat);
112 EditorEx editor = (EditorEx)editorFactory.createViewer(editorDocument);
114 myLastDocumentModificationStamp = editor.getDocument().getModificationStamp();
116 EditorSettings editorSettings = editor.getSettings();
117 fillEditorSettings(editorSettings);
119 updatePreviewHighlighter(editor);
121 return editor;
124 private void updatePreviewHighlighter(final EditorEx editor) {
125 EditorColorsScheme scheme = editor.getColorsScheme();
126 scheme.setColor(EditorColors.CARET_ROW_COLOR, null);
128 editor.setHighlighter(createHighlighter(scheme));
131 protected void updatePreviewEditor() {
132 myTextToReformat = getPreviewText();
133 updatePreview();
134 updatePreviewHighlighter((EditorEx)myEditor);
137 protected abstract EditorHighlighter createHighlighter(final EditorColorsScheme scheme);
139 private void fillEditorSettings(final EditorSettings editorSettings) {
140 editorSettings.setWhitespacesShown(true);
141 editorSettings.setLineMarkerAreaShown(false);
142 editorSettings.setLineNumbersShown(false);
143 editorSettings.setFoldingOutlineShown(false);
144 editorSettings.setAdditionalColumnsCount(0);
145 editorSettings.setAdditionalLinesCount(1);
146 final int rightMargin = getRightMargin();
147 if (rightMargin > 0) {
148 editorSettings.setRightMargin(rightMargin);
152 protected abstract int getRightMargin();
154 public final void updatePreview() {
155 if (!myShouldUpdatePreview || !myEditor.getComponent().isShowing()) {
156 return;
159 if (myLastDocumentModificationStamp != myEditor.getDocument().getModificationStamp()) {
160 myTextToReformat = myEditor.getDocument().getText();
163 Project project = PlatformDataKeys.PROJECT.getData(DataManager.getInstance().getDataContext());
164 if (project == null) {
165 project = ProjectManager.getInstance().getDefaultProject();
167 final Project finalProject = project;
168 CommandProcessor.getInstance().executeCommand(finalProject, new Runnable() {
169 public void run() {
170 replaceText(finalProject);
172 }, null, null);
173 myEditor.getSettings().setRightMargin(getRightMargin());
174 myLastDocumentModificationStamp = myEditor.getDocument().getModificationStamp();
177 private void replaceText(final Project project) {
178 ApplicationManager.getApplication().runWriteAction(new Runnable() {
179 public void run() {
180 try {
181 //important not mark as generated not to get the classes before setting language level
182 PsiFile psiFile = PsiFileFactory.getInstance(project)
183 .createFileFromText("a." + getFileTypeExtension(getFileType()), getFileType(), myTextToReformat, LocalTimeCounter.currentTime(),
184 false, false);
186 prepareForReformat(psiFile);
187 apply(mySettings);
188 CodeStyleSettings clone = mySettings.clone();
189 if (getRightMargin() > 0) {
190 clone.RIGHT_MARGIN = getRightMargin();
194 CodeStyleSettingsManager.getInstance(project).setTemporarySettings(clone);
195 CodeStyleManager.getInstance(project).reformat(psiFile);
196 CodeStyleSettingsManager.getInstance(project).dropTemporarySettings();
198 myEditor.getSettings().setTabSize(clone.getTabSize(getFileType()));
199 Document document = myEditor.getDocument();
200 document.replaceString(0, document.getTextLength(), psiFile.getText());
202 catch (IncorrectOperationException e) {
203 LOG.error(e);
209 protected abstract void prepareForReformat(PsiFile psiFile);
211 @NotNull
212 protected abstract FileType getFileType();
214 @NonNls
215 protected abstract String getPreviewText();
217 public abstract void apply(CodeStyleSettings settings);
219 public final void reset(final CodeStyleSettings settings) {
220 myShouldUpdatePreview = false;
221 try {
222 resetImpl(settings);
224 finally {
225 myShouldUpdatePreview = true;
229 protected static int getIndexForWrapping(int value) {
230 for (int i = 0; i < ourWrappings.length; i++) {
231 int ourWrapping = ourWrappings[i];
232 if (ourWrapping == value) return i;
234 LOG.assertTrue(false);
235 return 0;
238 public abstract boolean isModified(CodeStyleSettings settings);
240 public abstract JComponent getPanel();
242 public final void dispose() {
243 myUpdateAlarm.cancelAllRequests();
244 EditorFactory.getInstance().releaseEditor(myEditor);
247 protected abstract void resetImpl(final CodeStyleSettings settings);
249 protected static void fillWrappingCombo(final JComboBox wrapCombo) {
250 wrapCombo.addItem(ApplicationBundle.message("combobox.codestyle.do.not.wrap"));
251 wrapCombo.addItem(ApplicationBundle.message("combobox.codestyle.wrap.if.long"));
252 wrapCombo.addItem(ApplicationBundle.message("combobox.codestyle.chop.down.if.long"));
253 wrapCombo.addItem(ApplicationBundle.message("combobox.codestyle.wrap.always"));
256 public static String readFromFile(final Class resourceContainerClass, @NonNls final String fileName) {
257 try {
258 final InputStream stream = resourceContainerClass.getClassLoader().getResourceAsStream("codeStyle/preview/" + fileName);
259 final InputStreamReader reader = new InputStreamReader(stream);
260 final LineNumberReader lineNumberReader = new LineNumberReader(reader);
261 final StringBuffer result;
262 try {
263 result = new StringBuffer();
264 String line;
265 while ((line = lineNumberReader.readLine()) != null) {
266 result.append(line);
267 result.append("\n");
270 finally {
271 lineNumberReader.close();
274 return result.toString();
276 catch (IOException e) {
277 return "";
281 protected void installPreviewPanel(final JPanel previewPanel) {
282 previewPanel.setLayout(new BorderLayout());
283 previewPanel.add(myEditor.getComponent(), BorderLayout.CENTER);
286 @NonNls
287 protected
288 String getFileTypeExtension(FileType fileType) {
289 return fileType.getDefaultExtension();
292 public void onSomethingChanged() {
293 setSomethingChanged(true);
294 UiNotifyConnector.doWhenFirstShown(myEditor.getComponent(), new Runnable(){
295 public void run() {
296 addUpdatePreviewRequest();
301 private void addUpdatePreviewRequest() {
302 myUpdateAlarm.addComponentRequest(new Runnable() {
303 public void run() {
304 try {
305 myUpdateAlarm.cancelAllRequests();
306 if (isSomethingChanged()) {
307 updatePreview();
310 finally {
311 setSomethingChanged(false);
314 }, 300);