/* * Copyright 2000-2010 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. */ package org.jetbrains.android.actions; import com.android.ide.common.resources.configuration.FolderConfiguration; import com.android.resources.ResourceFolderType; import com.android.resources.ResourceType; import com.android.tools.idea.rendering.ResourceHelper; import com.android.tools.idea.rendering.ResourceNameValidator; import com.intellij.CommonBundle; import com.intellij.ide.actions.TemplateKindCombo; import com.intellij.openapi.module.Module; import com.intellij.application.options.ModulesComboBox; import com.intellij.openapi.ui.DialogWrapper; import com.intellij.openapi.ui.InputValidator; import com.intellij.openapi.ui.Messages; import com.intellij.ui.DocumentAdapter; import com.intellij.ui.TextFieldWithAutoCompletion; import com.intellij.ui.components.JBLabel; import com.intellij.util.PlatformIcons; import com.intellij.util.containers.HashMap; import com.intellij.util.containers.HashSet; import org.jetbrains.android.facet.AndroidFacet; import org.jetbrains.android.uipreview.DeviceConfiguratorPanel; import org.jetbrains.android.uipreview.InvalidOptionValueException; import org.jetbrains.android.util.AndroidBundle; import org.jetbrains.android.util.AndroidUtils; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import javax.swing.*; import javax.swing.event.DocumentEvent; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.*; import java.util.List; /** * Created by IntelliJ IDEA. * User: Eugene.Kudelevsky * Date: Aug 22, 2009 * Time: 7:47:01 PM * To change this template use File | Settings | File Templates. */ public class CreateResourceFileDialog extends DialogWrapper { private JTextField myFileNameField; private TemplateKindCombo myResourceTypeCombo; private JPanel myPanel; private JLabel myUpDownHint; private JLabel myResTypeLabel; private JPanel myDeviceConfiguratorWrapper; private JBLabel myErrorLabel; private JTextField myDirectoryNameTextField; private JPanel myRootElementFieldWrapper; private JBLabel myRootElementLabel; private JLabel myFileNameLabel; private ModulesComboBox myModuleCombo; private JBLabel myModuleLabel; private TextFieldWithAutoCompletion<String> myRootElementField; private InputValidator myValidator; private final Map<String, CreateTypedResourceFileAction> myResType2ActionMap = new HashMap<String, CreateTypedResourceFileAction>(); private final DeviceConfiguratorPanel myDeviceConfiguratorPanel; private final AndroidFacet myFacet; private final ResourceType myPredefinedResourceType; public CreateResourceFileDialog(@NotNull AndroidFacet facet, Collection<CreateTypedResourceFileAction> actions, @Nullable ResourceType predefinedResourceType, @Nullable String predefinedFileName, @Nullable String predefinedRootElement, @Nullable FolderConfiguration predefinedConfig, boolean chooseFileName, @NotNull Module module, boolean chooseModule) { super(facet.getModule().getProject()); myFacet = facet; myPredefinedResourceType = predefinedResourceType; myResTypeLabel.setLabelFor(myResourceTypeCombo); myResourceTypeCombo.registerUpDownHint(myFileNameField); myUpDownHint.setIcon(PlatformIcons.UP_DOWN_ARROWS); CreateTypedResourceFileAction[] actionArray = actions.toArray(new CreateTypedResourceFileAction[actions.size()]); Arrays.sort(actionArray, new Comparator<CreateTypedResourceFileAction>() { @Override public int compare(CreateTypedResourceFileAction a1, CreateTypedResourceFileAction a2) { return a1.toString().compareTo(a2.toString()); } }); String selectedTemplate = null; for (CreateTypedResourceFileAction action : actionArray) { String resType = action.getResourceType(); assert !myResType2ActionMap.containsKey(resType); myResType2ActionMap.put(resType, action); myResourceTypeCombo.addItem(action.toString(), null, resType); if (predefinedResourceType != null && predefinedResourceType.getName().equals(resType)) { selectedTemplate = resType; } } myDeviceConfiguratorPanel = new DeviceConfiguratorPanel() { @Override public void applyEditors() { try { doApplyEditors(); final FolderConfiguration config = myDeviceConfiguratorPanel.getConfiguration(); final CreateTypedResourceFileAction selectedAction = getSelectedAction(); myErrorLabel.setText(""); myDirectoryNameTextField.setText(""); if (selectedAction != null) { final String resTypeStr = selectedAction.getResourceType(); if (resTypeStr != null) { final ResourceFolderType resFolderType = ResourceFolderType.getTypeByName(resTypeStr); if (resFolderType != null) { myDirectoryNameTextField.setText(config.getFolderName(resFolderType)); } } } } catch (InvalidOptionValueException e) { myErrorLabel.setText("<html><body><font color=\"red\">" + e.getMessage() + "</font></body></html>"); myDirectoryNameTextField.setText(""); } updateOkAction(); } }; if (predefinedConfig != null) { myDeviceConfiguratorPanel.init(predefinedConfig); } myResourceTypeCombo.getComboBox().addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { myDeviceConfiguratorPanel.applyEditors(); updateRootElementTextField(); } }); if (predefinedResourceType != null && selectedTemplate != null) { final boolean v = predefinedResourceType == ResourceType.LAYOUT; myRootElementLabel.setVisible(v); myRootElementFieldWrapper.setVisible(v); myResTypeLabel.setVisible(false); myResourceTypeCombo.setVisible(false); myUpDownHint.setVisible(false); myResourceTypeCombo.setSelectedName(selectedTemplate); } if (chooseFileName) { predefinedFileName = ResourceHelper.prependResourcePrefix(module, predefinedFileName); } boolean validateImmediately = false; if (predefinedFileName != null && getNameError(predefinedFileName) != null) { chooseFileName = true; validateImmediately = true; } if (predefinedFileName != null) { if (!chooseFileName) { myFileNameField.setVisible(false); myFileNameLabel.setVisible(false); } myFileNameField.setText(predefinedFileName); } final Set<Module> modulesSet = new HashSet<Module>(); modulesSet.add(module); for (AndroidFacet depFacet : AndroidUtils.getAllAndroidDependencies(module, true)) { modulesSet.add(depFacet.getModule()); } myModuleCombo.setModules(modulesSet); if (!chooseModule || modulesSet.size() == 1) { myModuleLabel.setVisible(false); myModuleCombo.setVisible(false); } myModuleCombo.setSelectedModule(module); myDeviceConfiguratorPanel.updateAll(); myDeviceConfiguratorWrapper.add(myDeviceConfiguratorPanel, BorderLayout.CENTER); updateOkAction(); updateRootElementTextField(); if (predefinedRootElement != null) { myRootElementLabel.setVisible(false); myRootElementFieldWrapper.setVisible(false); myRootElementField.setText(predefinedRootElement); } init(); setTitle(AndroidBundle.message("new.resource.dialog.title")); myFileNameField.getDocument().addDocumentListener(new DocumentAdapter() { @Override public void textChanged(DocumentEvent event) { validateName(); } }); myResourceTypeCombo.getComboBox().addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent actionEvent) { validateName(); } }); if (validateImmediately) { validateName(); } } private void updateOkAction() { boolean enabled = myDirectoryNameTextField.getText().length() > 0; enabled = enabled && getNameError(myFileNameField.getText()) == null; setOKActionEnabled(enabled); } @Nullable private String getNameError(@NotNull String fileName) { String typeName = myResourceTypeCombo.getSelectedName(); if (typeName != null) { ResourceFolderType type = ResourceFolderType.getFolderType(typeName); if (type != null) { ResourceNameValidator validator = ResourceNameValidator.create(true, type); return validator.getErrorText(fileName); } } return null; } private void validateName() { setErrorText(getNameError(myFileNameField.getText())); updateOkAction(); } private void updateRootElementTextField() { final CreateTypedResourceFileAction action = getSelectedAction(); if (action != null) { final List<String> allowedTagNames = action.getSortedAllowedTagNames(myFacet); myRootElementField = new TextFieldWithAutoCompletion<String>( myFacet.getModule().getProject(), new TextFieldWithAutoCompletion.StringsCompletionProvider(allowedTagNames, null), true, null); myRootElementField.setEnabled(allowedTagNames.size() > 1); myRootElementField.setText(!action.isChooseTagName() && myPredefinedResourceType != ResourceType.LAYOUT ? action.getDefaultRootTag() : ""); myRootElementFieldWrapper.removeAll(); myRootElementFieldWrapper.add(myRootElementField, BorderLayout.CENTER); myRootElementLabel.setLabelFor(myRootElementField); } } @NotNull public String getFileName() { return myFileNameField.getText().trim(); } @Nullable protected InputValidator createValidator(@NotNull String subdirName) { return null; } @Override protected void doOKAction() { String fileName = myFileNameField.getText().trim(); final CreateTypedResourceFileAction action = getSelectedAction(); assert action != null; if (fileName.length() == 0) { Messages.showErrorDialog(myPanel, AndroidBundle.message("file.name.not.specified.error"), CommonBundle.getErrorTitle()); return; } if (!action.isChooseTagName() && getRootElement().length() == 0) { Messages.showErrorDialog(myPanel, AndroidBundle.message("root.element.not.specified.error"), CommonBundle.getErrorTitle()); return; } final String subdirName = getSubdirName(); if (subdirName.length() == 0) { Messages.showErrorDialog(myPanel, AndroidBundle.message("directory.not.specified.error"), CommonBundle.getErrorTitle()); return; } final String errorMessage = getNameError(fileName); if (errorMessage != null) { Messages.showErrorDialog(myPanel, errorMessage, CommonBundle.getErrorTitle()); return; } myValidator = createValidator(subdirName); if (myValidator == null || myValidator.checkInput(fileName) && myValidator.canClose(fileName)) { super.doOKAction(); } } @Override protected String getDimensionServiceKey() { return "AndroidCreateResourceFileDialog"; } @NotNull public Module getSelectedModule() { return myModuleCombo.getSelectedModule(); } @NotNull public String getSubdirName() { return myDirectoryNameTextField.getText().trim(); } @NotNull protected String getRootElement() { return myRootElementField.getText().trim(); } public InputValidator getValidator() { return myValidator; } @Override protected JComponent createCenterPanel() { return myPanel; } @Override public JComponent getPreferredFocusedComponent() { String name = myFileNameField.getText(); if (name.length() == 0 || name.equals(ResourceHelper.prependResourcePrefix(getSelectedModule(), null)) || getNameError(name) != null) { return myFileNameField; } else if (myResourceTypeCombo.isVisible()) { return myResourceTypeCombo; } else if (myModuleCombo.isVisible()) { return myModuleCombo; } else if (myRootElementFieldWrapper.isVisible()) { return myRootElementField; } return myDirectoryNameTextField; } public CreateTypedResourceFileAction getSelectedAction() { return myResType2ActionMap.get(myResourceTypeCombo.getSelectedName()); } }