8ff483061ab6677e3d2b2f8a608052a691adb3f3
[idea/community.git] / platform / lang-impl / src / com / intellij / codeInsight / intention / impl / config / IntentionDescriptionPanel.java
1 /*
2  * Copyright 2000-2009 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
17 /**
18  * @author cdr
19  */
20 package com.intellij.codeInsight.intention.impl.config;
21
22 import com.intellij.codeInsight.CodeInsightBundle;
23 import com.intellij.ide.plugins.IdeaPluginDescriptor;
24 import com.intellij.ide.plugins.PluginManager;
25 import com.intellij.ide.plugins.PluginManagerConfigurable;
26 import com.intellij.ide.plugins.PluginManagerUISettings;
27 import com.intellij.ide.ui.search.SearchUtil;
28 import com.intellij.openapi.application.ApplicationNamesInfo;
29 import com.intellij.openapi.diagnostic.Logger;
30 import com.intellij.openapi.extensions.PluginId;
31 import com.intellij.openapi.fileTypes.FileType;
32 import com.intellij.openapi.fileTypes.ex.FileTypeManagerEx;
33 import com.intellij.openapi.options.ShowSettingsUtil;
34 import com.intellij.openapi.project.Project;
35 import com.intellij.openapi.project.ProjectManager;
36 import com.intellij.ui.HyperlinkLabel;
37 import com.intellij.ui.TitledSeparator;
38 import org.jetbrains.annotations.NonNls;
39 import org.jetbrains.annotations.Nullable;
40
41 import javax.swing.*;
42 import javax.swing.event.HyperlinkEvent;
43 import javax.swing.event.HyperlinkListener;
44 import java.awt.*;
45 import java.io.IOException;
46 import java.net.URL;
47 import java.util.ArrayList;
48 import java.util.List;
49
50 public class IntentionDescriptionPanel {
51   private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.intention.impl.config.IntentionDescriptionPanel");
52   private JPanel myPanel;
53
54   private JPanel myAfterPanel;
55   private JPanel myBeforePanel;
56   private JEditorPane myDescriptionBrowser;
57   private TitledSeparator myBeforeSeparator;
58   private TitledSeparator myAfterSeparator;
59   private JPanel myPoweredByPanel;
60   private final List<IntentionUsagePanel> myBeforeUsagePanels = new ArrayList<IntentionUsagePanel>();
61   private final List<IntentionUsagePanel> myAfterUsagePanels = new ArrayList<IntentionUsagePanel>();
62   @NonNls private static final String BEFORE_TEMPLATE = "before.java.template";
63   @NonNls private static final String AFTER_TEMPLATE = "after.java.template";
64
65   public void reset(IntentionActionMetaData actionMetaData, String filter)  {
66     try {
67       final TextDescriptor url = actionMetaData.getDescription();
68       final String description = url == null ?
69                                  CodeInsightBundle.message("under.construction.string") :
70                                  SearchUtil.markup(url.getText(), filter);
71       myDescriptionBrowser.setText(description);
72       setupPoweredByPanel(actionMetaData);
73
74       showUsages(myBeforePanel, myBeforeSeparator, myBeforeUsagePanels, actionMetaData.getExampleUsagesBefore());
75       showUsages(myAfterPanel, myAfterSeparator, myAfterUsagePanels, actionMetaData.getExampleUsagesAfter());
76
77       SwingUtilities.invokeLater(new Runnable() {
78         public void run() {
79           myPanel.revalidate();
80         }
81       });
82
83     }
84     catch (IOException e) {
85       LOG.error(e);
86     }
87   }
88
89   private void setupPoweredByPanel(final IntentionActionMetaData actionMetaData) {
90     PluginId pluginId = actionMetaData == null ? null : actionMetaData.getPluginId();
91     JComponent owner;
92     if (pluginId == null) {
93       @NonNls String label = "<html><body><b>" + ApplicationNamesInfo.getInstance().getFullProductName() + "</b></body></html>";
94       owner = new JLabel(label);
95     }
96     else {
97       final IdeaPluginDescriptor pluginDescriptor = PluginManager.getPlugin(pluginId);
98       HyperlinkLabel label = new HyperlinkLabel(CodeInsightBundle.message("powered.by.plugin", pluginDescriptor.getName()));
99       label.addHyperlinkListener(new HyperlinkListener() {
100         public void hyperlinkUpdate(HyperlinkEvent e) {
101           final ShowSettingsUtil util = ShowSettingsUtil.getInstance();
102           final PluginManagerConfigurable pluginConfigurable = new PluginManagerConfigurable(PluginManagerUISettings.getInstance());
103           final Project project = ProjectManager.getInstance().getDefaultProject();
104           util.editConfigurable(project, pluginConfigurable, new Runnable(){
105             public void run() {
106               pluginConfigurable.select(pluginDescriptor);
107             }
108           });
109         }
110       });
111       owner = label;
112     }
113     //myPoweredByContainer.setVisible(true);
114     myPoweredByPanel.removeAll();
115     myPoweredByPanel.add(owner, BorderLayout.CENTER);
116   }
117
118
119   public void reset(String intentionCategory)  {
120     try {
121       String text = CodeInsightBundle.message("intention.settings.category.text", intentionCategory);
122
123       myDescriptionBrowser.setText(text);
124       setupPoweredByPanel(null);
125
126       URL beforeURL = getClass().getClassLoader().getResource(getClass().getPackage().getName().replace('.','/') + "/" + BEFORE_TEMPLATE);
127       showUsages(myBeforePanel, myBeforeSeparator, myBeforeUsagePanels, new ResourceTextDescriptor[]{new ResourceTextDescriptor(beforeURL)});
128       URL afterURL = getClass().getClassLoader().getResource(getClass().getPackage().getName().replace('.','/') + "/" + AFTER_TEMPLATE);
129       showUsages(myAfterPanel, myAfterSeparator, myAfterUsagePanels, new ResourceTextDescriptor[]{new ResourceTextDescriptor(afterURL)});
130
131       SwingUtilities.invokeLater(new Runnable() {
132         public void run() {
133           myPanel.revalidate();
134         }
135       });
136     }
137     catch (IOException e) {
138       LOG.error(e);
139     }
140   }
141
142   private void createUIComponents() {
143     // TODO: place custom component creation code here
144   }
145
146   private static void showUsages(final JPanel panel,
147                                  final TitledSeparator separator,
148                                  final List<IntentionUsagePanel> usagePanels,
149                                  @Nullable final TextDescriptor[] exampleUsages) throws IOException {
150     GridBagConstraints gb = null;
151     boolean reuse = exampleUsages != null && panel.getComponents().length == exampleUsages.length;
152     if (!reuse) {
153       disposeUsagePanels(usagePanels);
154       panel.setLayout(new GridBagLayout());
155       panel.removeAll();
156       gb = new GridBagConstraints();
157       gb.anchor = GridBagConstraints.NORTHWEST;
158       gb.fill = GridBagConstraints.BOTH;
159       gb.gridheight = GridBagConstraints.REMAINDER;
160       gb.gridwidth = 1;
161       gb.gridx = 0;
162       gb.gridy = 0;
163       gb.insets = new Insets(0,0,0,0);
164       gb.ipadx = 5;
165       gb.ipady = 5;
166       gb.weightx = 1;
167       gb.weighty = 1;
168     }
169
170     if (exampleUsages != null) {
171       for (int i = 0; i < exampleUsages.length; i++) {
172         final TextDescriptor exampleUsage = exampleUsages[i];
173         final String name = exampleUsage.getFileName();
174         final FileTypeManagerEx fileTypeManager = FileTypeManagerEx.getInstanceEx();
175         final String extension = fileTypeManager.getExtension(name);
176         final FileType fileType = fileTypeManager.getFileTypeByExtension(extension);
177
178         IntentionUsagePanel usagePanel;
179         if (reuse) {
180           usagePanel = (IntentionUsagePanel)panel.getComponent(i);
181         }
182         else {
183           usagePanel = new IntentionUsagePanel();
184           usagePanels.add(usagePanel);
185         }
186         usagePanel.reset(exampleUsage.getText(), fileType);
187
188         if (!reuse) {
189           if (i == exampleUsages.length) {
190             gb.gridwidth = GridBagConstraints.REMAINDER;
191           }
192           panel.add(usagePanel, gb);
193           gb.gridx++;
194         }
195       }
196     }
197     panel.revalidate();
198     panel.repaint();
199   }
200
201   public JPanel getComponent() {
202     return myPanel;
203   }
204
205   public void dispose() {
206     disposeUsagePanels(myBeforeUsagePanels);
207     disposeUsagePanels(myAfterUsagePanels);
208   }
209
210   private static void disposeUsagePanels(List<IntentionUsagePanel> usagePanels) {
211     for (final IntentionUsagePanel usagePanel : usagePanels) {
212       usagePanel.dispose();
213     }
214     usagePanels.clear();
215   }
216
217   public void init(final int preferredWidth) {
218     //adjust vertical dimension to be equal for all three panels
219     double height = (myDescriptionBrowser.getSize().getHeight() + myBeforePanel.getSize().getHeight() + myAfterPanel.getSize().getHeight()) / 3;
220     final Dimension newd = new Dimension(preferredWidth, (int)height);
221     myDescriptionBrowser.setSize(newd);
222     myDescriptionBrowser.setPreferredSize(newd);
223     myDescriptionBrowser.setMaximumSize(newd);
224     myDescriptionBrowser.setMinimumSize(newd);
225
226     myBeforePanel.setSize(newd);
227     myBeforePanel.setPreferredSize(newd);
228     myBeforePanel.setMaximumSize(newd);
229     myBeforePanel.setMinimumSize(newd);
230
231     myAfterPanel.setSize(newd);
232     myAfterPanel.setPreferredSize(newd);
233     myAfterPanel.setMaximumSize(newd);
234     myAfterPanel.setMinimumSize(newd);
235   }
236 }