blob: 5d52a464fdcf4a1759575f1eb249fc12d65a68a4 [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.gradle.IdeaAndroidProject;
import com.android.tools.idea.ui.ComboBoxItemWithApiTag;
import com.android.tools.idea.ui.FileTreeCellRenderer;
import com.android.tools.idea.ui.FileTreeModel;
import com.android.tools.idea.wizard.template.TemplateWizardState;
import com.android.tools.idea.wizard.template.TemplateWizardStep;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.ui.treeStructure.Tree;
import org.jetbrains.android.facet.AndroidFacet;
import org.jetbrains.android.facet.AndroidRootUtil;
import org.jetbrains.android.facet.IdeaSourceProvider;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreeModel;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.util.Iterator;
import java.util.Map;
/**
* This step allows the user to select a build variant and provides a preview
* of the assets that are about to be created.
*/
public class ChooseOutputResDirStep extends TemplateWizardStep {
public static final String ATTR_TARGET_MODULE = "targetModule";
public static final String ATTR_TARGET_VARIANT = "targetVariant";
public static final String ATTR_OUTPUT_FOLDER = "outputFolder";
private final VirtualFile myTargetFile;
private JComboBox myModuleComboBox;
private JLabel myDescription;
private JPanel myPanel;
private JComboBox myVariantComboBox;
private Tree myOutputPreviewTree;
private JLabel myResDirLabel;
private Module mySelectedModule;
private Module[] myModuleArray;
private boolean myComputeNewSourceSet;
private static final TreeModel EMPTY_MODEL = new DefaultTreeModel(null);
private final FileTreeCellRenderer myFileTreeRenderer = new FileTreeCellRenderer();
private FileTreeModel myTreeModel;
private AssetStudioAssetGenerator myAssetGenerator;
public ChooseOutputResDirStep(@NotNull TemplateWizardState state,
@NotNull Project project,
@Nullable Icon sidePanelIcon,
UpdateListener updateListener,
@Nullable Module module,
@Nullable VirtualFile invocationTarget) {
super(state, project, module, sidePanelIcon, updateListener);
myAssetGenerator = new AssetStudioAssetGenerator(state);
myTargetFile = invocationTarget;
init();
}
public void init() {
if (myTargetFile != null) {
AndroidFacet facet = AndroidFacet.getInstance(myModule);
if (facet != null) {
Iterator<SourceProvider> sourceProvidersIter = IdeaSourceProvider.getSourceProvidersForFile(facet, myTargetFile, null).iterator();
if (sourceProvidersIter.hasNext()) {
SourceProvider provider = sourceProvidersIter.next();
File resDir = NewTemplateObjectWizard.findResDirectory(provider);
String path;
if (resDir == null) {
// No res dir exists, infer one
path = provider.getManifestFile().getParent() + facet.getProperties().RES_FOLDER_RELATIVE_PATH;
} else {
path = resDir.getPath();
}
myTemplateState.put(ATTR_OUTPUT_FOLDER, FileUtil.toSystemIndependentName(path));
}
}
}
setUpUiComponents();
}
@NotNull
@Override
protected JLabel getDescription() {
return myDescription;
}
@NotNull
@Override
protected JLabel getError() {
return myDescription;
}
@Override
public JComponent getComponent() {
return myPanel;
}
@Override
public void updateStep() {
super.updateStep();
myComputeNewSourceSet = true;
update();
}
private void setUpUiComponents() {
// Populate the Module chooser list
myModuleArray = ModuleManager.getInstance(myProject).getModules();
populateComboBox(myModuleComboBox, myModuleArray);
register(ATTR_TARGET_MODULE, myModuleComboBox);
register(ATTR_TARGET_VARIANT, myVariantComboBox);
if (myModule != null) {
int index = -1;
for (int i = 0; i < myModuleArray.length; ++i) {
if (myModuleArray[i].equals(myModule)) {
index = i;
break;
}
}
if (index != -1) {
myModuleComboBox.setSelectedIndex(index);
}
}
myOutputPreviewTree.setBorder(BorderFactory.createLoweredBevelBorder());
// Tell the tree to ask the TreeCellRenderer for an individual height for each cell.
myOutputPreviewTree.setRowHeight(-1);
}
@Override
public void update() {
if (myVisible) {
super.update();
}
}
@Override
public void updateParams() {
super.updateParams();
mySelectedModule = myModuleArray[myModuleComboBox.getSelectedIndex()];
}
@Override
public void deriveValues() {
if (myIdsWithNewValues.contains(ATTR_TARGET_MODULE)) {
// Populate the Build Flavor and Build Type lists
AndroidFacet facet = AndroidFacet.getInstance(mySelectedModule);
if (facet == null) {
// Clear variant list
myVariantComboBox.setModel(new DefaultComboBoxModel());
// Remove entries from the file tree preview
myOutputPreviewTree.setModel(EMPTY_MODEL);
return;
}
IdeaAndroidProject androidModel = facet.getAndroidModel();
if (androidModel != null) {
show(myVariantComboBox, myResDirLabel);
DefaultComboBoxModel comboBoxModel = new DefaultComboBoxModel();
String moduleRoot = FileUtil.toSystemIndependentName(AndroidRootUtil.getModuleDirPath(facet.getModule()));
File resDir = new File(FileUtil.toSystemDependentName(myTemplateState.getString(ATTR_OUTPUT_FOLDER)));
int index = 0;
int selectedIndex = 0;
// Offer all source sets
for (SourceProvider sourceProvider : IdeaSourceProvider.getAllSourceProviders(facet)) {
for (File f : sourceProvider.getResDirectories()) {
String resPath = FileUtil.getRelativePath(moduleRoot,
FileUtil.toSystemIndependentName(f.getPath()), '/');
comboBoxModel.addElement(new ComboBoxItemWithApiTag(f, resPath, 1, 1));
if (resDir != null && resDir.equals(f)) {
selectedIndex = index;
}
index++;
}
}
myVariantComboBox.setModel(comboBoxModel);
myVariantComboBox.setSelectedIndex(selectedIndex);
} else {
hide(myVariantComboBox, myResDirLabel);
Object path = myTemplateState.get(ATTR_OUTPUT_FOLDER);
if (path != null) {
myTemplateState.put(ATTR_TARGET_VARIANT, new File((String)path));
} else {
// Remove entries from the file tree preview
myOutputPreviewTree.setModel(EMPTY_MODEL);
myOutputPreviewTree.getEmptyText().setText("No Res Folder defined in project");
return;
}
}
myIdsWithNewValues.add(ATTR_TARGET_VARIANT);
}
if (myIdsWithNewValues.contains(ATTR_TARGET_VARIANT) || myComputeNewSourceSet) {
File resDir = (File)myTemplateState.get(ATTR_TARGET_VARIANT);
if (resDir == null) {
Object selectedVariant = myVariantComboBox.getSelectedItem();
if (selectedVariant instanceof ComboBoxItemWithApiTag) {
resDir = (File)((ComboBoxItemWithApiTag)selectedVariant).id;
}
}
if (resDir != null) {
// Populate the output file tree
myTreeModel = new FileTreeModel(resDir, true);
myTemplateState.put(ATTR_OUTPUT_FOLDER, resDir);
try {
Map<String, Map<String, BufferedImage>> images = myAssetGenerator.generateImages(false);
for (String density : images.keySet()) {
Map<String, BufferedImage> filenameMap = images.get(density);
for (String filename : filenameMap.keySet()) {
Image image = filenameMap.get(filename);
Icon ic = null;
if (image != null) {
while (image.getHeight(null) > 200) {
image = image.getScaledInstance(image.getWidth(null)/2, image.getHeight(null)/2,Image.SCALE_SMOOTH);
}
ic = new ImageIcon(image);
}
myTreeModel.forceAddFile(new File(resDir, filename), ic);
}
}
} catch (Exception e) {
// pass
}
myOutputPreviewTree.setModel(myTreeModel);
myOutputPreviewTree.setCellRenderer(myFileTreeRenderer);
expandTree();
}
}
myComputeNewSourceSet = false;
}
private void expandTree() {
for (int i = 0; i < myOutputPreviewTree.getRowCount(); ++i) {
myOutputPreviewTree.expandRow(i);
}
}
@Override
public boolean validate() {
if (!super.validate()) {
return false;
}
AndroidFacet facet = AndroidFacet.getInstance(mySelectedModule);
if (facet == null) {
setErrorHtml("The selected module does not have an Android Facet. Please choose an Android module");
return false;
}
if (myTreeModel != null && myTreeModel.hasConflicts()) {
setErrorHtml("Some existing files will be overwritten by this operation. Files which replace existing files are marked" +
" red in the preview above.");
}
return true;
}
}