/* * Copyright (C) 2013 The Android Open Source Project * * 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 com.android.tools.idea.wizard; import com.android.builder.model.SourceProvider; import com.android.tools.idea.templates.Parameter; import com.android.tools.idea.templates.TemplateMetadata; import com.google.common.annotations.VisibleForTesting; import com.google.common.collect.Sets; import com.google.common.io.Files; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.module.Module; import com.intellij.openapi.project.Project; import com.intellij.uiDesigner.core.GridConstraints; import com.intellij.uiDesigner.core.GridLayoutManager; import com.intellij.uiDesigner.core.Spacer; import icons.AndroidIcons; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import javax.swing.*; import java.awt.*; import java.io.File; import java.io.IOException; import java.util.Collection; import java.util.Set; /** * TemplateParameterStep is a step in new project or add module wizards that pulls eligible parameters from the template being run * and puts up a UI to let the user edit those parameters. * * Deprecated. Use {@link TemplateParameterStep2} instead. */ @Deprecated public class TemplateParameterStep extends TemplateWizardStep { private static final Logger LOG = Logger.getInstance(TemplateParameterStep.class); private JPanel myParamContainer; private JPanel myContainer; private JLabel myDescription; private JLabel myError; @VisibleForTesting JLabel myPreview; private JComponent myPreferredFocusComponent; @VisibleForTesting String myCurrentThumb; public TemplateParameterStep(TemplateWizardState state, @Nullable Project project, @Nullable Module module, @Nullable Icon sidePanelIcon, UpdateListener updateListener) { super(state, project, module, sidePanelIcon, updateListener); } @Override public void _init() { myParamContainer.removeAll(); myPreferredFocusComponent = null; int row = 0; Collection<Parameter> parameters = myTemplateState.getTemplateMetadata().getParameters(); myParamContainer.setLayout(new GridLayoutManager(parameters.size() + 1, 3)); String packageName = null; if (myTemplateState.hasAttr(TemplateMetadata.ATTR_PACKAGE_NAME)) { packageName = myTemplateState.getString(TemplateMetadata.ATTR_PACKAGE_NAME); } GridConstraints c = new GridConstraints(); c.setVSizePolicy(GridConstraints.SIZEPOLICY_FIXED); c.setAnchor(GridConstraints.ANCHOR_WEST); c.setFill(GridConstraints.FILL_HORIZONTAL); for (Parameter parameter : parameters) { if (myTemplateState.myHidden.contains(parameter.id)) { continue; } JLabel label = new JLabel(parameter.name); registerLabel(parameter.id, label); c.setHSizePolicy(GridConstraints.SIZEPOLICY_CAN_GROW); c.setColumn(0); c.setColSpan(1); c.setRow(row++); Object value = myTemplateState.get(parameter.id) != null ? myTemplateState.get(parameter.id) : parameter.initial; myTemplateState.put(parameter.id, value); switch(parameter.type) { case SEPARATOR: c.setColSpan(3); JSeparator separator = new JSeparator(SwingConstants.HORIZONTAL); myParamContainer.add(separator, c); break; case BOOLEAN: c.setColumn(1); JCheckBox checkBox = new JCheckBox(parameter.name); register(parameter.id, checkBox); myParamContainer.add(checkBox, c); if (myPreferredFocusComponent == null) { myPreferredFocusComponent = checkBox; } break; case ENUM: myParamContainer.add(label, c); JComboBox comboBox = new JComboBox(); c.setColumn(1); populateComboBox(comboBox, parameter); register(parameter.id, comboBox); myParamContainer.add(comboBox, c); if (myPreferredFocusComponent == null) { myPreferredFocusComponent = comboBox; } break; case CUSTOM: case STRING: myParamContainer.add(label, c); c.setHSizePolicy(GridConstraints.SIZEPOLICY_WANT_GROW); JTextField textField = new JTextField(); c.setColumn(1); c.setColSpan(2); register(parameter.id, textField); myParamContainer.add(textField, c); if (myPreferredFocusComponent == null) { myPreferredFocusComponent = textField; textField.selectAll(); } break; case EXTERNAL: final String url = parameter.sourceUrl; if (url == null) { break; } myParamContainer.add(label, c); c.setHSizePolicy(GridConstraints.SIZEPOLICY_WANT_GROW); TextFieldWithLaunchBrowserButton externalField = new TextFieldWithLaunchBrowserButton(url); c.setColumn(1); c.setColSpan(2); register(parameter.id, externalField); myParamContainer.add(externalField, c); if (myPreferredFocusComponent == null) { myPreferredFocusComponent = externalField; externalField.getTextField().selectAll(); } break; } updateVisibility(parameter); } update(); deduplicateSuggestions(packageName); c.setFill(GridConstraints.FILL_HORIZONTAL); c.setHSizePolicy(GridConstraints.SIZEPOLICY_WANT_GROW); c.setVSizePolicy(GridConstraints.SIZEPOLICY_WANT_GROW); c.setRow(row); c.setRowSpan(1); c.setColSpan(1); c.setColumn(2); Spacer spacer = new Spacer(); myParamContainer.add(spacer, c); setDescriptionHtml(myTemplateState.getTemplateMetadata().getDescription()); } private void deduplicateSuggestions(@Nullable String packageName) { if (myProject == null || myTemplateState.getTemplateMetadata() == null) { return; } SourceProvider provider = myTemplateState.getSourceProvider(); for (String paramName : myParamFields.keySet()) { Parameter parameter = myTemplateState.hasTemplate() ? myTemplateState.getTemplateMetadata().getParameter(paramName) : null; // For the moment, only string types can be checked for uniqueness if (parameter == null || parameter.type != Parameter.Type.STRING) { continue; } JComponent component = myParamFields.get(paramName); // If we have existing files, ensure uniqueness is satisfied if (parameter.constraints.contains(Parameter.Constraint.UNIQUE) && !parameter.uniquenessSatisfied(myProject, myModule, provider, packageName, myTemplateState.getString(parameter.id))) { // While uniqueness isn't satisfied, increment number and add to end int i = 2; String originalValue = myTemplateState.getString(parameter.id); while (!parameter.uniquenessSatisfied(myProject, myModule, provider, packageName, originalValue + Integer.toString(i))) { i++; } String derivedValue = String.format("%s%d", originalValue, i); myTemplateState.put(parameter.id, derivedValue); if (component instanceof JTextField) { ((JTextField)component).setText(derivedValue); } myTemplateState.myModified.remove(paramName); } } } @Override protected void deriveValues() { super.deriveValues(); String thumb = myTemplateState.getTemplateMetadata().getThumbnailPath(myTemplateState); // Only show new image if we have something to show (and skip decoding if it's the same image we already have) if (thumb == null) { myPreview.setIcon(AndroidIcons.Wizards.DefaultTemplate256); } else if (!thumb.isEmpty() && !thumb.equals(myCurrentThumb)) { File file = new File(myTemplateState.getTemplate().getRootPath(), thumb.replace('/', File.separatorChar)); try { byte[] bytes = Files.toByteArray(file); ImageIcon previewImage = new ImageIcon(bytes); myPreview.setIcon(new ImageIcon(previewImage.getImage().getScaledInstance(256, 256, Image.SCALE_SMOOTH))); myCurrentThumb = thumb; } catch (IOException e) { LOG.warn(e); } } } @Override public boolean validate() { if (!super.validate()) { return false; } Set<String> layoutNames = Sets.newHashSet(); Collection<Parameter> parameters = myTemplateState.getTemplateMetadata().getParameters(); for (Parameter parameter : parameters) { if (parameter.constraints.contains(Parameter.Constraint.UNIQUE)) { String value = myTemplateState.getString(parameter.id); if (parameter.constraints.contains(Parameter.Constraint.LAYOUT) && layoutNames.contains(value)) { setErrorHtml(String.format("Layout name %s is already in use. Please choose a unique name.", value)); return false; } else { layoutNames.add(value); } } } return true; } @Override public JComponent getComponent() { return myContainer; } @Override public JComponent getPreferredFocusedComponent() { return myPreferredFocusComponent; } @NotNull @Override protected JLabel getDescription() { return myDescription; } @NotNull @Override protected JLabel getError() { return myError; } @Override public boolean isStepVisible() { boolean hasVisibleParameter = false; if (myTemplateState.hasTemplate()) { Collection<Parameter> parameters = myTemplateState.getTemplateMetadata().getParameters(); for (Parameter parameter : parameters) { if (!myTemplateState.myHidden.contains(parameter.id)) { hasVisibleParameter = true; break; } } } return hasVisibleParameter && myVisible; } }