4d9a541ea6ef2f41442e9cc9605f629871420ab0
[idea/community.git] / plugins / ui-designer / src / com / intellij / uiDesigner / GuiDesignerConfigurable.java
1 /*
2  * Copyright 2000-2011 JetBrains s.r.o.
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 com.intellij.uiDesigner;
17
18 import com.intellij.codeInsight.CodeInsightUtil;
19 import com.intellij.ide.ui.ListCellRendererWrapper;
20 import com.intellij.openapi.application.ApplicationManager;
21 import com.intellij.openapi.command.CommandProcessor;
22 import com.intellij.openapi.diagnostic.Logger;
23 import com.intellij.openapi.options.Configurable;
24 import com.intellij.openapi.options.SearchableConfigurable;
25 import com.intellij.openapi.progress.ProgressManager;
26 import com.intellij.openapi.progress.util.DispatchThreadProgressWindow;
27 import com.intellij.openapi.project.Project;
28 import com.intellij.openapi.util.Comparing;
29 import com.intellij.openapi.util.IconLoader;
30 import com.intellij.openapi.vfs.VirtualFile;
31 import com.intellij.psi.*;
32 import com.intellij.psi.search.GlobalSearchScope;
33 import com.intellij.psi.search.PsiShortNamesCache;
34 import com.intellij.uiDesigner.compiler.AsmCodeGenerator;
35 import com.intellij.uiDesigner.make.FormSourceCodeGenerator;
36 import com.intellij.uiDesigner.radComponents.LayoutManagerRegistry;
37 import com.intellij.util.IncorrectOperationException;
38 import org.jetbrains.annotations.NotNull;
39 import org.jetbrains.annotations.Nullable;
40
41 import javax.swing.*;
42
43 /**
44  * @author Anton Katilin
45  * @author Vladimir Kondratyev
46  */
47 public final class GuiDesignerConfigurable implements SearchableConfigurable, Configurable.NoScroll {
48   private static final Logger LOG = Logger.getInstance("#com.intellij.uiDesigner.GuiDesignerConfigurable");
49   private final Project myProject;
50   private MyGeneralUI myGeneralUI;
51
52   /**
53    * Invoked by reflection
54    */
55   public GuiDesignerConfigurable(final Project project) {
56     myProject = project;
57   }
58
59   public String getDisplayName() {
60     return UIDesignerBundle.message("title.gui.designer");
61   }
62
63   public Icon getIcon() {
64     return IconLoader.getIcon("/general/uiDesigner.png");
65   }
66
67   @NotNull
68   public String getHelpTopic() {
69     return "project.propGUI";
70   }
71
72   public JComponent createComponent() {
73     if (myGeneralUI == null) {
74       myGeneralUI = new MyGeneralUI();
75     }
76
77     return myGeneralUI.myPanel;
78   }
79
80   public boolean isModified() {
81     final GuiDesignerConfiguration configuration = GuiDesignerConfiguration.getInstance(myProject);
82
83     if (myGeneralUI == null) {
84       return false;
85     }
86
87     if (myGeneralUI.myChkCopyFormsRuntime.isSelected() != configuration.COPY_FORMS_RUNTIME_TO_OUTPUT) {
88       return true;
89     }
90
91     if (!Comparing.equal(configuration.DEFAULT_LAYOUT_MANAGER, myGeneralUI.myLayoutManagerCombo.getSelectedItem())) {
92       return true;
93     }
94
95     if (!Comparing.equal(configuration.DEFAULT_FIELD_ACCESSIBILITY, myGeneralUI.myDefaultFieldAccessibilityCombo.getSelectedItem())) {
96       return true;
97     }
98
99     if (configuration.INSTRUMENT_CLASSES != myGeneralUI.myRbInstrumentClasses.isSelected()) {
100       return true;
101     }
102
103     return false;
104   }
105
106   public void apply() {
107     final GuiDesignerConfiguration configuration = GuiDesignerConfiguration.getInstance(myProject);
108     configuration.COPY_FORMS_RUNTIME_TO_OUTPUT = myGeneralUI.myChkCopyFormsRuntime.isSelected();
109     configuration.DEFAULT_LAYOUT_MANAGER = (String)myGeneralUI.myLayoutManagerCombo.getSelectedItem();
110     configuration.INSTRUMENT_CLASSES = myGeneralUI.myRbInstrumentClasses.isSelected();
111     configuration.DEFAULT_FIELD_ACCESSIBILITY = (String)myGeneralUI .myDefaultFieldAccessibilityCombo.getSelectedItem();
112
113     if (configuration.INSTRUMENT_CLASSES && !myProject.isDefault()) {
114       final DispatchThreadProgressWindow progressWindow = new DispatchThreadProgressWindow(false, myProject);
115       progressWindow.setRunnable(new MyApplyRunnable(progressWindow));
116       progressWindow.setTitle(UIDesignerBundle.message("title.converting.project"));
117       progressWindow.start();
118     }
119   }
120
121   public void reset() {
122     final GuiDesignerConfiguration configuration = GuiDesignerConfiguration.getInstance(myProject);
123
124     /*general*/
125     if (configuration.INSTRUMENT_CLASSES) {
126       myGeneralUI.myRbInstrumentClasses.setSelected(true);
127     }
128     else {
129       myGeneralUI.myRbInstrumentSources.setSelected(true);
130     }
131     myGeneralUI.myChkCopyFormsRuntime.setSelected(configuration.COPY_FORMS_RUNTIME_TO_OUTPUT);
132
133     myGeneralUI.myLayoutManagerCombo.setModel(new DefaultComboBoxModel(LayoutManagerRegistry.getNonDeprecatedLayoutManagerNames()));
134     myGeneralUI.myLayoutManagerCombo.setRenderer(new ListCellRendererWrapper<String>(myGeneralUI.myLayoutManagerCombo.getRenderer()) {
135       @Override
136       public void customize(JList list, String value, int index, boolean selected, boolean hasFocus) {
137         setText(LayoutManagerRegistry.getLayoutManagerDisplayName(value));
138       }
139     });
140     myGeneralUI.myLayoutManagerCombo.setSelectedItem(configuration.DEFAULT_LAYOUT_MANAGER);
141
142     myGeneralUI.myDefaultFieldAccessibilityCombo.setSelectedItem(configuration.DEFAULT_FIELD_ACCESSIBILITY);
143   }
144
145   public void disposeUIResources() {
146     myGeneralUI = null;
147   } /*UI for "General" tab*/
148
149   private static final class MyGeneralUI {
150     public JPanel myPanel;
151     public JRadioButton myRbInstrumentClasses;
152     public JRadioButton myRbInstrumentSources;
153     public JCheckBox myChkCopyFormsRuntime;
154     private JComboBox myLayoutManagerCombo;
155     private JComboBox myDefaultFieldAccessibilityCombo;
156   }
157
158   private final class MyApplyRunnable implements Runnable {
159     private final DispatchThreadProgressWindow myProgressWindow;
160
161     public MyApplyRunnable(final DispatchThreadProgressWindow progressWindow) {
162       myProgressWindow = progressWindow;
163     }
164
165     /**
166      * Removes all generated sources
167      */
168     private void vanishGeneratedSources() {
169       final PsiShortNamesCache cache = PsiShortNamesCache.getInstance(myProject);
170       final PsiMethod[] methods = cache.getMethodsByName(AsmCodeGenerator.SETUP_METHOD_NAME, GlobalSearchScope.projectScope(myProject));
171
172       CodeInsightUtil.preparePsiElementsForWrite(methods);
173
174       for (int i = 0; i < methods.length; i++) {
175         final PsiMethod method = methods[i];
176         final PsiClass aClass = method.getContainingClass();
177         if (aClass != null) {
178           try {
179             final PsiFile psiFile = aClass.getContainingFile();
180             LOG.assertTrue(psiFile != null);
181             final VirtualFile vFile = psiFile.getVirtualFile();
182             LOG.assertTrue(vFile != null);
183             myProgressWindow.setText(UIDesignerBundle.message("progress.converting", vFile.getPresentableUrl()));
184             myProgressWindow.setFraction(((double)i) / ((double)methods.length));
185             if (vFile.isWritable()) {
186               FormSourceCodeGenerator.cleanup(aClass);
187             }
188           }
189           catch (IncorrectOperationException e) {
190             LOG.error(e);
191           }
192         }
193       }
194     }
195
196     /**
197      * Launches vanish/generate sources processes
198      */
199     private void applyImpl() {
200       CommandProcessor.getInstance().executeCommand(myProject, new Runnable() {
201         public void run() {
202           ApplicationManager.getApplication().runWriteAction(new Runnable() {
203             public void run() {
204               PsiDocumentManager.getInstance(myProject).commitAllDocuments();
205               vanishGeneratedSources();
206             }
207           });
208         }
209       }, "", null);
210     }
211
212     public void run() {
213       ProgressManager.getInstance().runProcess(new Runnable() {
214         public void run() {
215           applyImpl();
216         }
217       }, myProgressWindow);
218     }
219   }
220
221   @NotNull
222   public String getId() {
223     return getHelpTopic();
224   }
225
226   @Nullable
227   public Runnable enableSearch(String option) {
228     return null;
229   }
230 }