blob: 6e26a860193a189b188381a47195f7c1a5d456ed [file] [log] [blame]
/*
* 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.npw;
import com.android.builder.model.SourceProvider;
import com.android.tools.idea.templates.Parameter;
import com.android.tools.idea.templates.TemplateMetadata;
import com.android.tools.idea.ui.TextFieldWithLaunchBrowserButton;
import com.android.tools.idea.wizard.template.TemplateWizardState;
import com.android.tools.idea.wizard.template.TemplateWizardStep;
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;
}
}