| /* |
| * Copyright 2000-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. |
| */ |
| |
| /** |
| * @author cdr |
| */ |
| package com.intellij.codeInspection.i18n; |
| |
| import com.intellij.codeInsight.CodeInsightBundle; |
| import com.intellij.codeInsight.intention.IntentionAction; |
| import com.intellij.ide.fileTemplates.FileTemplate; |
| import com.intellij.ide.fileTemplates.FileTemplateManager; |
| import com.intellij.ide.fileTemplates.impl.FileTemplateConfigurable; |
| import com.intellij.lang.properties.psi.I18nizedTextGenerator; |
| import com.intellij.lang.properties.psi.PropertiesFile; |
| import com.intellij.lang.properties.psi.PropertyCreationHandler; |
| import com.intellij.lang.properties.psi.ResourceBundleManager; |
| import com.intellij.lang.properties.references.I18nizeQuickFixDialog; |
| import com.intellij.openapi.editor.Document; |
| import com.intellij.openapi.editor.event.DocumentAdapter; |
| import com.intellij.openapi.fileTypes.StdFileTypes; |
| import com.intellij.openapi.options.ShowSettingsUtil; |
| import com.intellij.openapi.project.Project; |
| import com.intellij.openapi.ui.Messages; |
| import com.intellij.openapi.ui.ex.MultiLineLabel; |
| import com.intellij.openapi.util.text.StringUtil; |
| import com.intellij.psi.*; |
| import com.intellij.ui.EditorComboBox; |
| import com.intellij.ui.HyperlinkLabel; |
| import com.intellij.util.ArrayUtil; |
| import com.intellij.util.IncorrectOperationException; |
| import gnu.trove.THashMap; |
| import org.jetbrains.annotations.NonNls; |
| import org.jetbrains.annotations.NotNull; |
| import org.jetbrains.annotations.Nullable; |
| |
| import javax.swing.*; |
| import javax.swing.event.HyperlinkEvent; |
| import javax.swing.event.HyperlinkListener; |
| import java.awt.*; |
| import java.io.IOException; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.Set; |
| |
| public class JavaI18nizeQuickFixDialog extends I18nizeQuickFixDialog { |
| private final PsiLiteralExpression myLiteralExpression; |
| |
| private final JLabel myPreviewLabel; |
| private final JPanel myHyperLinkPanel; |
| private final JPanel myResourceBundleSuggester; |
| private EditorComboBox myRBEditorTextField; |
| private final JPanel myJavaCodeInfoPanel; |
| private final JPanel myPreviewPanel; |
| private PsiClassType myResourceBundleType; |
| protected final ResourceBundleManager myResourceBundleManager; |
| |
| private final boolean myShowJavaCodeInfo; |
| private final boolean myShowPreview; |
| |
| @NonNls public static final String PROPERTY_KEY_OPTION_KEY = "PROPERTY_KEY"; |
| @NonNls private static final String RESOURCE_BUNDLE_OPTION_KEY = "RESOURCE_BUNDLE"; |
| @NonNls public static final String PROPERTY_VALUE_ATTR = "PROPERTY_VALUE"; |
| |
| public JavaI18nizeQuickFixDialog(@NotNull Project project, |
| @NotNull final PsiFile context, |
| @Nullable final PsiLiteralExpression literalExpression, |
| String defaultPropertyValue, |
| DialogCustomization customization, |
| final boolean showJavaCodeInfo, |
| final boolean showPreview) { |
| super(project, context, defaultPropertyValue, customization, true); |
| |
| ResourceBundleManager resourceBundleManager = null; |
| try { |
| resourceBundleManager = ResourceBundleManager.getManager(context); |
| LOG.assertTrue(resourceBundleManager != null); |
| } |
| catch (ResourceBundleManager.ResourceBundleNotFoundException e) { |
| LOG.error(e); |
| } |
| myResourceBundleManager = resourceBundleManager; |
| |
| JavaExtensibilityData data = new JavaExtensibilityData(); |
| myExtensibilityPanel.setLayout(new BorderLayout()); |
| myExtensibilityPanel.add(data.myPanel, BorderLayout.CENTER); |
| myJavaCodeInfoPanel = data.myJavaCodeInfoPanel; |
| myPreviewPanel = data.myPreviewPanel; |
| myHyperLinkPanel = data.myHyperLinkPanel; |
| myResourceBundleSuggester = data.myResourceBundleSuggester; |
| myPreviewLabel = data.myPreviewLabel; |
| |
| myLiteralExpression = literalExpression; |
| myShowPreview = showPreview; |
| |
| myResourceBundleSuggester.setLayout(new BorderLayout()); |
| PsiElementFactory factory = JavaPsiFacade.getInstance(myProject).getElementFactory(); |
| PsiClass resourceBundle = myResourceBundleManager.getResourceBundle(); |
| |
| myShowJavaCodeInfo = showJavaCodeInfo && myResourceBundleManager.canShowJavaCodeInfo(); |
| |
| if (myShowJavaCodeInfo) { |
| LOG.assertTrue(resourceBundle != null); |
| myResourceBundleType = factory.createType(resourceBundle); |
| @NonNls String defaultVarName = "resourceBundle"; |
| final JavaCodeFragmentFactory codeFragmentFactory = JavaCodeFragmentFactory.getInstance(project); |
| PsiExpressionCodeFragment expressionCodeFragment = |
| codeFragmentFactory.createExpressionCodeFragment(defaultVarName, myLiteralExpression, myResourceBundleType, true); |
| Document document = PsiDocumentManager.getInstance(myProject).getDocument(expressionCodeFragment); |
| myRBEditorTextField = new EditorComboBox(document, myProject, StdFileTypes.JAVA); |
| myResourceBundleSuggester.add(myRBEditorTextField, BorderLayout.CENTER); |
| suggestAvailableResourceBundleExpressions(); |
| myRBEditorTextField.addDocumentListener(new DocumentAdapter() { |
| @Override |
| public void documentChanged(com.intellij.openapi.editor.event.DocumentEvent e) { |
| somethingChanged(); |
| } |
| }); |
| } |
| |
| myHyperLinkPanel.setLayout(new BorderLayout()); |
| final String templateName = getTemplateName(); |
| |
| if (templateName != null) { |
| HyperlinkLabel link = new HyperlinkLabel(CodeInsightBundle.message("i18nize.dialog.template.link.label")); |
| link.addHyperlinkListener(new HyperlinkListener() { |
| @Override |
| public void hyperlinkUpdate(HyperlinkEvent e) { |
| final FileTemplateConfigurable configurable = new FileTemplateConfigurable(); |
| final FileTemplate template = FileTemplateManager.getInstance().getCodeTemplate(templateName); |
| SwingUtilities.invokeLater(new Runnable() { |
| @Override |
| public void run() { |
| configurable.setTemplate(template, null); |
| } |
| }); |
| boolean ok = ShowSettingsUtil.getInstance().editConfigurable(myPanel, configurable); |
| if (ok) { |
| somethingChanged(); |
| if (myShowJavaCodeInfo) { |
| suggestAvailableResourceBundleExpressions(); |
| } |
| } |
| } |
| }); |
| myHyperLinkPanel.add(link, BorderLayout.CENTER); |
| } |
| |
| if (!myShowJavaCodeInfo) { |
| myJavaCodeInfoPanel.setVisible(false); |
| } |
| if (!myShowPreview) { |
| myPreviewPanel.setVisible(false); |
| } |
| |
| init(); |
| } |
| |
| public static boolean isAvailable(PsiFile file) { |
| final Project project = file.getProject(); |
| final String title = CodeInsightBundle.message("i18nize.dialog.error.jdk.title"); |
| try { |
| return ResourceBundleManager.getManager(file) != null; |
| } |
| catch (ResourceBundleManager.ResourceBundleNotFoundException e) { |
| final IntentionAction fix = e.getFix(); |
| if (fix != null) { |
| if (Messages.showOkCancelDialog(project, e.getMessage(), title, Messages.getErrorIcon()) == Messages.OK) { |
| try { |
| fix.invoke(project, null, file); |
| return false; |
| } |
| catch (IncorrectOperationException e1) { |
| LOG.error(e1); |
| } |
| } |
| } |
| Messages.showErrorDialog(project, e.getMessage(), title); |
| return false; |
| } |
| } |
| |
| public PropertyCreationHandler getPropertyCreationHandler() { |
| PropertyCreationHandler handler = myResourceBundleManager.getPropertyCreationHandler(); |
| return handler != null ? handler : JavaI18nUtil.DEFAULT_PROPERTY_CREATION_HANDLER; |
| } |
| |
| private void suggestAvailableResourceBundleExpressions() { |
| String templateName = getTemplateName(); |
| if (templateName == null) return; |
| |
| if (myShowJavaCodeInfo) { |
| FileTemplate template = FileTemplateManager.getInstance().getCodeTemplate(templateName); |
| boolean showResourceBundleSuggester = template.getText().contains("${" + RESOURCE_BUNDLE_OPTION_KEY + "}"); |
| myJavaCodeInfoPanel.setVisible(showResourceBundleSuggester); |
| } |
| Set<String> result = JavaI18nUtil.suggestExpressionOfType(myResourceBundleType, myLiteralExpression); |
| if (result.isEmpty()) { |
| result.add(getResourceBundleText()); |
| } |
| |
| myRBEditorTextField.setHistory(ArrayUtil.toStringArray(result)); |
| SwingUtilities.invokeLater(new Runnable() { |
| @Override |
| public void run() { |
| myRBEditorTextField.setSelectedIndex(0); |
| } |
| }); |
| } |
| |
| @Override |
| protected void somethingChanged() { |
| if (myShowPreview) { |
| myPreviewLabel.setText(getI18nizedText()); |
| } |
| super.somethingChanged(); |
| } |
| |
| @Nullable |
| protected String getTemplateName() { |
| return myResourceBundleManager.getTemplateName(); |
| } |
| |
| @Override |
| protected String defaultSuggestPropertyKey(String value) { |
| return myResourceBundleManager.suggestPropertyKey(value); |
| } |
| |
| @Override |
| protected List<String> defaultSuggestPropertiesFiles() { |
| return myResourceBundleManager.suggestPropertiesFiles(); |
| } |
| |
| public String getI18nizedText() { |
| String propertyKey = StringUtil.escapeStringCharacters(getKey()); |
| I18nizedTextGenerator textGenerator = myResourceBundleManager.getI18nizedTextGenerator(); |
| if (textGenerator != null) { |
| return generateText(textGenerator, propertyKey, getPropertiesFile(), myLiteralExpression); |
| } |
| |
| String templateName = getTemplateName(); |
| LOG.assertTrue(templateName != null); |
| FileTemplate template = FileTemplateManager.getInstance().getCodeTemplate(templateName); |
| Map<String, String> attributes = new THashMap<String, String>(); |
| attributes.put(PROPERTY_KEY_OPTION_KEY, propertyKey); |
| attributes.put(RESOURCE_BUNDLE_OPTION_KEY, getResourceBundleText()); |
| attributes.put(PROPERTY_VALUE_ATTR, StringUtil.escapeStringCharacters(myDefaultPropertyValue)); |
| addAdditionalAttributes(attributes); |
| String text = null; |
| try { |
| text = template.getText(attributes); |
| } |
| catch (IOException e) { |
| LOG.error(e); |
| } |
| return text; |
| } |
| |
| protected String generateText(final I18nizedTextGenerator textGenerator, |
| final String propertyKey, |
| final PropertiesFile propertiesFile, |
| final PsiLiteralExpression literalExpression) { |
| return textGenerator.getI18nizedText(propertyKey, propertiesFile, literalExpression); |
| } |
| |
| protected void addAdditionalAttributes(final Map<String, String> attributes) { |
| } |
| |
| private String getResourceBundleText() { |
| return myShowJavaCodeInfo ? myRBEditorTextField.getText() : null; |
| } |
| |
| public PsiLiteralExpression getLiteralExpression() { |
| return myLiteralExpression; |
| } |
| |
| public PsiExpression[] getParameters() { |
| return PsiExpression.EMPTY_ARRAY; |
| } |
| |
| static class JavaExtensibilityData { |
| private JPanel myPreviewPanel; |
| private JPanel myJavaCodeInfoPanel; |
| private JPanel myPanel; |
| private JPanel myHyperLinkPanel; |
| private MultiLineLabel myPreviewLabel; |
| private JPanel myResourceBundleSuggester; |
| } |
| } |