blob: a834aa11715fd461f80dbbb2f1f548231ab13af6 [file] [log] [blame]
/*
* Copyright 2000-2012 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.facet;
import com.android.SdkConstants;
import com.intellij.facet.ui.FacetEditorContext;
import com.intellij.facet.ui.FacetEditorTab;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.fileChooser.FileChooser;
import com.intellij.openapi.fileChooser.FileChooserDescriptor;
import com.intellij.openapi.fileChooser.FileChooserDescriptorFactory;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.options.ConfigurationException;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.ModuleRootManager;
import com.intellij.openapi.ui.ComboBox;
import com.intellij.openapi.ui.TextFieldWithBrowseButton;
import com.intellij.openapi.util.Condition;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VfsUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.ui.CheckBoxList;
import com.intellij.ui.ComboboxWithBrowseButton;
import com.intellij.ui.ListCellRendererWrapper;
import com.intellij.ui.RawCommandLineEditor;
import com.intellij.ui.components.JBCheckBox;
import com.intellij.ui.components.JBLabel;
import com.intellij.ui.components.JBTabbedPane;
import com.intellij.util.ArrayUtil;
import com.intellij.util.Function;
import com.intellij.util.PathUtil;
import com.intellij.util.ui.UIUtil;
import org.jetbrains.android.compiler.AndroidAutogeneratorMode;
import org.jetbrains.android.compiler.AndroidCompileUtil;
import org.jetbrains.android.compiler.artifact.ProGuardConfigFilesPanel;
import org.jetbrains.android.maven.AndroidMavenProvider;
import org.jetbrains.android.maven.AndroidMavenUtil;
import org.jetbrains.android.util.AndroidBundle;
import org.jetbrains.android.util.AndroidUtils;
import org.jetbrains.annotations.Nls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jps.android.model.impl.AndroidImportableProperty;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.util.*;
import java.util.List;
/**
* @author yole
*/
public class AndroidFacetEditorTab extends FacetEditorTab {
private static final Logger LOG = Logger.getInstance("#org.jetbrains.android.facet.AndroidFacetEditorTab");
private final AndroidFacetConfiguration myConfiguration;
private final FacetEditorContext myContext;
private JPanel myContentPanel;
private TextFieldWithBrowseButton myRGenPathField;
private TextFieldWithBrowseButton myAidlGenPathField;
private JButton myResetPathsButton;
private TextFieldWithBrowseButton myResFolderField;
private TextFieldWithBrowseButton myAssetsFolderField;
private TextFieldWithBrowseButton myNativeLibsFolder;
private TextFieldWithBrowseButton myManifestFileField;
private JRadioButton myUseAptResDirectoryFromPathRadio;
private JRadioButton myUseCustomSourceDirectoryRadio;
private TextFieldWithBrowseButton myCustomAptSourceDirField;
private JCheckBox myIsLibraryProjectCheckbox;
private JPanel myAaptCompilerPanel;
private ComboboxWithBrowseButton myApkPathCombo;
private JLabel myApkPathLabel;
private JRadioButton myRunProcessResourcesRadio;
private JRadioButton myCompileResourcesByIdeRadio;
private JLabel myManifestFileLabel;
private JLabel myResFolderLabel;
private JLabel myAssetsFolderLabel;
private JLabel myNativeLibsFolderLabel;
private JLabel myAidlGenPathLabel;
private JLabel myRGenPathLabel;
private TextFieldWithBrowseButton myCustomDebugKeystoreField;
private JBLabel myCustomKeystoreLabel;
private JCheckBox myIncludeTestCodeAndCheckBox;
private JBCheckBox myRunProguardCheckBox;
private JBCheckBox myIncludeAssetsFromLibraries;
private JBCheckBox myUseCustomManifestPackage;
private JTextField myCustomManifestPackageField;
private ComboBox myUpdateProjectPropertiesCombo;
private CheckBoxList<AndroidImportableProperty> myImportedOptionsList;
private JBTabbedPane myTabbedPane;
private JBCheckBox myEnableManifestMerging;
private JBCheckBox myPreDexEnabledCheckBox;
private ProGuardConfigFilesPanel myProGuardConfigFilesPanel;
private JBCheckBox myEnableSourcesAutogenerationCheckBox;
private JPanel myAptAutogenerationOptionsPanel;
private JPanel myAidlAutogenerationOptionsPanel;
private RawCommandLineEditor myAdditionalPackagingCommandLineParametersField;
private TextFieldWithBrowseButton myProguardLogsDirectoryField;
private JBLabel myProGuardLogsDirectoryLabel;
private static final String MAVEN_TAB_TITLE = "Maven";
private final Component myMavenTabComponent;
public AndroidFacetEditorTab(FacetEditorContext context, AndroidFacetConfiguration androidFacetConfiguration) {
final Project project = context.getProject();
myConfiguration = androidFacetConfiguration;
myContext = context;
myManifestFileLabel.setLabelFor(myManifestFileField);
myResFolderLabel.setLabelFor(myResFolderField);
myAssetsFolderLabel.setLabelFor(myAssetsFolderField);
myNativeLibsFolderLabel.setLabelFor(myNativeLibsFolder);
myAidlGenPathLabel.setLabelFor(myAidlGenPathField);
myRGenPathLabel.setLabelFor(myRGenPathField);
myCustomKeystoreLabel.setLabelFor(myCustomDebugKeystoreField);
final AndroidFacet facet = (AndroidFacet)myContext.getFacet();
myRGenPathField.getButton()
.addActionListener(new MyGenSourceFieldListener(myRGenPathField, AndroidRootUtil.getAptGenSourceRootPath(facet)));
myAidlGenPathField.getButton()
.addActionListener(new MyGenSourceFieldListener(myAidlGenPathField, AndroidRootUtil.getAidlGenSourceRootPath(facet)));
Module module = myContext.getModule();
myManifestFileField.getButton().addActionListener(
new MyFolderFieldListener(myManifestFileField, AndroidRootUtil.getManifestFile(facet), true, new MyManifestFilter()));
myResFolderField.getButton().addActionListener(new MyFolderFieldListener(myResFolderField,
AndroidRootUtil.getResourceDir(facet), false, null));
myAssetsFolderField.getButton().addActionListener(new MyFolderFieldListener(myAssetsFolderField,
AndroidRootUtil.getAssetsDir(facet), false, null));
myNativeLibsFolder.getButton().addActionListener(new MyFolderFieldListener(myNativeLibsFolder,
AndroidRootUtil.getLibsDir(facet), false, null));
myCustomAptSourceDirField.getButton().addActionListener(new MyFolderFieldListener(myCustomAptSourceDirField, getCustomResourceDirForApt(facet), false, null));
myRunProguardCheckBox.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
myProGuardConfigFilesPanel.setEnabled(myRunProguardCheckBox.isSelected());
}
});
myCustomDebugKeystoreField.getButton().addActionListener(new MyFolderFieldListener(myCustomDebugKeystoreField, null, true, null));
myResetPathsButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
AndroidFacetConfiguration configuration = new AndroidFacetConfiguration();
configuration.setFacet((AndroidFacet)myContext.getFacet());
Module module = myContext.getModule();
VirtualFile[] contentRoots = ModuleRootManager.getInstance(module).getContentRoots();
if (contentRoots.length == 1) {
configuration.init(module, contentRoots[0]);
}
if (AndroidMavenUtil.isMavenizedModule(module)) {
AndroidMavenProvider mavenProvider = AndroidMavenUtil.getMavenProvider();
if (mavenProvider != null) {
mavenProvider.setPathsToDefault(module, configuration);
}
}
resetOptions(configuration);
}
});
myEnableSourcesAutogenerationCheckBox.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
updateAutogenerationPanels();
}
});
ActionListener listener = new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
myCustomAptSourceDirField.setEnabled(myUseCustomSourceDirectoryRadio.isSelected());
}
};
myUseCustomSourceDirectoryRadio.addActionListener(listener);
myUseAptResDirectoryFromPathRadio.addActionListener(listener);
myIsLibraryProjectCheckbox.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
updateLibAndAppSpecificFields();
}
});
listener = new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
updateAptPanel();
}
};
myRunProcessResourcesRadio.addActionListener(listener);
myCompileResourcesByIdeRadio.addActionListener(listener);
myApkPathLabel.setLabelFor(myApkPathCombo);
final JComboBox apkPathComboBoxComponent = myApkPathCombo.getComboBox();
apkPathComboBoxComponent.setEditable(true);
apkPathComboBoxComponent.setModel(new DefaultComboBoxModel(getDefaultApks(module)));
apkPathComboBoxComponent.setMinimumSize(new Dimension(10, apkPathComboBoxComponent.getMinimumSize().height));
apkPathComboBoxComponent.setPreferredSize(new Dimension(10, apkPathComboBoxComponent.getPreferredSize().height));
myApkPathCombo.addBrowseFolderListener(project, new FileChooserDescriptor(true, false, false, false, false, false) {
@Override
public boolean isFileVisible(VirtualFile file, boolean showHiddenFiles) {
if (!super.isFileVisible(file, showHiddenFiles)) {
return false;
}
return file.isDirectory() || "apk".equals(file.getExtension());
}
});
myUseCustomManifestPackage.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
myCustomManifestPackageField.setEnabled(myUseCustomManifestPackage.isSelected());
}
});
myUpdateProjectPropertiesCombo.setModel(new DefaultComboBoxModel(new Object[]{"", Boolean.TRUE.toString(), Boolean.FALSE.toString()}));
myUpdateProjectPropertiesCombo.setRenderer(new ListCellRendererWrapper<String>() {
@Override
public void customize(JList list, String value, int index, boolean selected, boolean hasFocus) {
if (value != null && value.isEmpty()) {
setText("Ask");
}
else if (Boolean.parseBoolean(value)) {
setText("Yes");
}
else {
setText("No");
}
}
});
buildImportedOptionsList();
final int mavenTabIndex = myTabbedPane.indexOfTab(MAVEN_TAB_TITLE);
assert mavenTabIndex >= 0;
myMavenTabComponent = myTabbedPane.getComponentAt(mavenTabIndex);
myProguardLogsDirectoryField.getButton().addActionListener(new MyFolderFieldListener(myProguardLogsDirectoryField, null, false, null));
}
@Nullable
public static VirtualFile getCustomResourceDirForApt(@NotNull AndroidFacet facet) {
return AndroidRootUtil.getFileByRelativeModulePath(facet.getModule(), facet.getProperties().CUSTOM_APK_RESOURCE_FOLDER, false);
}
private void updateLibAndAppSpecificFields() {
boolean lib = myIsLibraryProjectCheckbox.isSelected();
myAssetsFolderField.setEnabled(!lib);
myEnableManifestMerging.setEnabled(!lib);
myIncludeAssetsFromLibraries.setEnabled(!lib);
myUseCustomManifestPackage.setEnabled(!lib);
myCustomManifestPackageField.setEnabled(!lib && myUseCustomManifestPackage.isSelected());
myAdditionalPackagingCommandLineParametersField.setEnabled(!lib);
myRunProguardCheckBox.setEnabled(!lib);
myProGuardConfigFilesPanel.setEnabled(!lib && myRunProguardCheckBox.isSelected());
myApkPathLabel.setEnabled(!lib);
myApkPathCombo.setEnabled(!lib);
myCustomKeystoreLabel.setEnabled(!lib);
myCustomDebugKeystoreField.setEnabled(!lib);
myPreDexEnabledCheckBox.setEnabled(!lib);
myProGuardLogsDirectoryLabel.setEnabled(!lib);
myProguardLogsDirectoryField.setEnabled(!lib);
}
private void updateAutogenerationPanels() {
UIUtil.setEnabled(myAidlAutogenerationOptionsPanel, myEnableSourcesAutogenerationCheckBox.isSelected(), true);
updateAptPanel();
}
private void buildImportedOptionsList() {
myImportedOptionsList.setItems(Arrays.asList(AndroidImportableProperty.values()), new Function<AndroidImportableProperty, String>() {
@Override
public String fun(AndroidImportableProperty property) {
return property.getDisplayName();
}
});
}
private void updateAptPanel() {
if (!myEnableSourcesAutogenerationCheckBox.isSelected()) {
UIUtil.setEnabled(myAptAutogenerationOptionsPanel, false, true);
}
else {
UIUtil.setEnabled(myAptAutogenerationOptionsPanel, true, true);
boolean enabled = !myRunProcessResourcesRadio.isVisible() || !myRunProcessResourcesRadio.isSelected();
UIUtil.setEnabled(myAaptCompilerPanel, enabled, true);
}
}
private static String[] getDefaultApks(@NotNull Module module) {
List<String> result = new ArrayList<String>();
String path = AndroidCompileUtil.getOutputPackage(module);
if (path != null) {
result.add(path);
}
AndroidMavenProvider mavenProvider = AndroidMavenUtil.getMavenProvider();
if (mavenProvider != null && mavenProvider.isMavenizedModule(module)) {
String buildDirectory = mavenProvider.getBuildDirectory(module);
if (buildDirectory != null) {
result.add(FileUtil.toSystemDependentName(buildDirectory + '/' + AndroidCompileUtil.getApkName(module)));
}
}
return ArrayUtil.toStringArray(result);
}
@Override
@Nls
public String getDisplayName() {
return "Android SDK Settings";
}
@NotNull
@Override
public JComponent createComponent() {
return myContentPanel;
}
@Override
public boolean isModified() {
//if (myAddAndroidLibrary.isSelected() != myConfiguration.ADD_ANDROID_LIBRARY) return true;
if (myIsLibraryProjectCheckbox.isSelected() != myConfiguration.getState().LIBRARY_PROJECT) return true;
if (checkRelativePath(myConfiguration.getState().GEN_FOLDER_RELATIVE_PATH_APT, myRGenPathField.getText())) {
return true;
}
if (checkRelativePath(myConfiguration.getState().GEN_FOLDER_RELATIVE_PATH_AIDL, myAidlGenPathField.getText())) {
return true;
}
if (checkRelativePath(myConfiguration.getState().MANIFEST_FILE_RELATIVE_PATH, myManifestFileField.getText())) {
return true;
}
if (checkRelativePath(myConfiguration.getState().RES_FOLDER_RELATIVE_PATH, myResFolderField.getText())) {
return true;
}
if (checkRelativePath(myConfiguration.getState().ASSETS_FOLDER_RELATIVE_PATH, myAssetsFolderField.getText())) {
return true;
}
if (checkRelativePath(myConfiguration.getState().LIBS_FOLDER_RELATIVE_PATH, myNativeLibsFolder.getText())) {
return true;
}
if (checkRelativePath(myConfiguration.getState().APK_PATH, (String)myApkPathCombo.getComboBox().getEditor().getItem())) {
return true;
}
if (myUseCustomSourceDirectoryRadio.isSelected() != myConfiguration.getState().USE_CUSTOM_APK_RESOURCE_FOLDER) {
return true;
}
if (checkRelativePath(myConfiguration.getState().CUSTOM_APK_RESOURCE_FOLDER, myCustomAptSourceDirField.getText())) {
return true;
}
if (myRunProcessResourcesRadio.isSelected() != myConfiguration.getState().RUN_PROCESS_RESOURCES_MAVEN_TASK) {
return true;
}
if (!myConfiguration.getState().CUSTOM_DEBUG_KEYSTORE_PATH.equals(getSelectedCustomKeystorePath())) {
return true;
}
if (myConfiguration.getState().ENABLE_MANIFEST_MERGING != myEnableManifestMerging.isSelected()) {
return true;
}
if (myConfiguration.getState().ENABLE_PRE_DEXING != myPreDexEnabledCheckBox.isSelected()) {
return true;
}
if (myConfiguration.getState().PACK_TEST_CODE != myIncludeTestCodeAndCheckBox.isSelected()) {
return true;
}
if (myConfiguration.getState().ENABLE_SOURCES_AUTOGENERATION != myEnableSourcesAutogenerationCheckBox.isSelected()) {
return true;
}
if (myConfiguration.isIncludeAssetsFromLibraries() != myIncludeAssetsFromLibraries.isSelected()) {
return true;
}
if (myConfiguration.getState().RUN_PROGUARD != myRunProguardCheckBox.isSelected()) {
return true;
}
if (!myProGuardConfigFilesPanel.getUrls().equals(myConfiguration.getState().myProGuardCfgFiles)) {
return true;
}
if (myConfiguration.getState().USE_CUSTOM_MANIFEST_PACKAGE != myUseCustomManifestPackage.isSelected()) {
return true;
}
if (!myCustomManifestPackageField.getText().trim().equals(myConfiguration.getState().CUSTOM_MANIFEST_PACKAGE)) {
return true;
}
if (!myAdditionalPackagingCommandLineParametersField.getText().trim().equals(
myConfiguration.getState().ADDITIONAL_PACKAGING_COMMAND_LINE_PARAMETERS)) {
return true;
}
if (!myUpdateProjectPropertiesCombo.getSelectedItem().equals(myConfiguration.getState().UPDATE_PROPERTY_FILES)) {
return true;
}
if (checkRelativePath(myConfiguration.getState().PROGUARD_LOGS_FOLDER_RELATIVE_PATH, myProguardLogsDirectoryField.getText())) {
return true;
}
if (AndroidMavenUtil.isMavenizedModule(myContext.getModule())) {
final Set<AndroidImportableProperty> newNotImportedProperties = EnumSet.noneOf(AndroidImportableProperty.class);
for (int i = 0; i < myImportedOptionsList.getItemsCount(); i++) {
final AndroidImportableProperty property = (AndroidImportableProperty)myImportedOptionsList.getItemAt(i);
if (!myImportedOptionsList.isItemSelected(i)) {
newNotImportedProperties.add(property);
}
}
if (!myConfiguration.getState().myNotImportedProperties.equals(newNotImportedProperties)) {
return true;
}
}
return false;
}
@NotNull
private String getSelectedCustomKeystorePath() {
final String path = myCustomDebugKeystoreField.getText().trim();
return path.length() > 0 ? VfsUtil.pathToUrl(FileUtil.toSystemIndependentName(path)) : "";
}
private boolean checkRelativePath(String relativePathFromConfig, String absPathFromTextField) {
String pathFromConfig = relativePathFromConfig;
if (pathFromConfig != null && pathFromConfig.length() > 0) {
pathFromConfig = toAbsolutePath(pathFromConfig);
}
String pathFromTextField = absPathFromTextField.trim();
return !FileUtil.pathsEqual(pathFromConfig, pathFromTextField);
}
@Nullable
private String toRelativePath(String absPath) {
absPath = FileUtil.toSystemIndependentName(absPath);
String moduleDirPath = AndroidRootUtil.getModuleDirPath(myContext.getModule());
if (moduleDirPath != null) {
moduleDirPath = FileUtil.toSystemIndependentName(moduleDirPath);
return FileUtil.getRelativePath(moduleDirPath, absPath, '/');
}
return null;
}
@Override
public String getHelpTopic() {
return "reference.settings.project.modules.android.facet";
}
@Override
public void apply() throws ConfigurationException {
if (!isModified()) return;
String absGenPathR = myRGenPathField.getText().trim();
String absGenPathAidl = myAidlGenPathField.getText().trim();
boolean runApt = false;
boolean runIdl = false;
if (absGenPathR == null || absGenPathR.length() == 0 || absGenPathAidl == null || absGenPathAidl.length() == 0) {
throw new ConfigurationException("Please specify source root for autogenerated files");
}
else {
String relativeGenPathR = getAndCheckRelativePath(absGenPathR, false);
String newAptDestDir = '/' + relativeGenPathR;
if (!newAptDestDir.equals(myConfiguration.getState().GEN_FOLDER_RELATIVE_PATH_APT)) {
runApt = true;
}
myConfiguration.getState().GEN_FOLDER_RELATIVE_PATH_APT = newAptDestDir;
String relativeGenPathAidl = getAndCheckRelativePath(absGenPathAidl, false);
String newIdlDestDir = '/' + relativeGenPathAidl;
if (!newIdlDestDir.equals(myConfiguration.getState().GEN_FOLDER_RELATIVE_PATH_AIDL)) {
runIdl = true;
}
myConfiguration.getState().GEN_FOLDER_RELATIVE_PATH_AIDL = newIdlDestDir;
}
String absManifestPath = myManifestFileField.getText().trim();
if (absManifestPath.length() == 0) {
throw new ConfigurationException("Manifest file not specified");
}
String manifestRelPath = getAndCheckRelativePath(absManifestPath, true);
if (!SdkConstants.FN_ANDROID_MANIFEST_XML.equals(AndroidUtils.getSimpleNameByRelativePath(manifestRelPath))) {
throw new ConfigurationException("Manifest file must have name AndroidManifest.xml");
}
myConfiguration.getState().MANIFEST_FILE_RELATIVE_PATH = '/' + manifestRelPath;
String absResPath = myResFolderField.getText().trim();
if (absResPath.length() == 0) {
throw new ConfigurationException("Resources folder not specified");
}
myConfiguration.getState().RES_FOLDER_RELATIVE_PATH = '/' + getAndCheckRelativePath(absResPath, false);
String absAssetsPath = myAssetsFolderField.getText().trim();
myConfiguration.getState().ASSETS_FOLDER_RELATIVE_PATH = absAssetsPath.length() > 0 ? '/' + getAndCheckRelativePath(absAssetsPath, false) : "";
String absApkPath = (String)myApkPathCombo.getComboBox().getEditor().getItem();
if (absApkPath.length() == 0) {
myConfiguration.getState().APK_PATH = "";
}
else {
myConfiguration.getState().APK_PATH = '/' + getAndCheckRelativePath(absApkPath, false);
}
String absLibsPath = myNativeLibsFolder.getText().trim();
myConfiguration.getState().LIBS_FOLDER_RELATIVE_PATH = absLibsPath.length() > 0 ? '/' + getAndCheckRelativePath(absLibsPath, false) : "";
myConfiguration.getState().CUSTOM_DEBUG_KEYSTORE_PATH = getSelectedCustomKeystorePath();
myConfiguration.getState().LIBRARY_PROJECT = myIsLibraryProjectCheckbox.isSelected();
myConfiguration.getState().RUN_PROCESS_RESOURCES_MAVEN_TASK = myRunProcessResourcesRadio.isSelected();
myConfiguration.getState().ENABLE_MANIFEST_MERGING = myEnableManifestMerging.isSelected();
myConfiguration.getState().ENABLE_PRE_DEXING = myPreDexEnabledCheckBox.isSelected();
myConfiguration.getState().PACK_TEST_CODE = myIncludeTestCodeAndCheckBox.isSelected();
myConfiguration.getState().ENABLE_SOURCES_AUTOGENERATION = myEnableSourcesAutogenerationCheckBox.isSelected();
myConfiguration.setIncludeAssetsFromLibraries(myIncludeAssetsFromLibraries.isSelected());
if (AndroidMavenUtil.isMavenizedModule(myContext.getModule())) {
final Set<AndroidImportableProperty> notImportedProperties = myConfiguration.getState().myNotImportedProperties;
notImportedProperties.clear();
for (int i = 0; i < myImportedOptionsList.getItemsCount(); i++) {
final AndroidImportableProperty property = (AndroidImportableProperty)myImportedOptionsList.getItemAt(i);
if (!myImportedOptionsList.isItemSelected(i)) {
notImportedProperties.add(property);
}
}
}
myConfiguration.getState().RUN_PROGUARD = myRunProguardCheckBox.isSelected();
myConfiguration.getState().myProGuardCfgFiles = myProGuardConfigFilesPanel.getUrls();
boolean useCustomAptSrc = myUseCustomSourceDirectoryRadio.isSelected();
myConfiguration.getState().USE_CUSTOM_APK_RESOURCE_FOLDER = useCustomAptSrc;
myConfiguration.getState().USE_CUSTOM_MANIFEST_PACKAGE = myUseCustomManifestPackage.isSelected();
myConfiguration.getState().CUSTOM_MANIFEST_PACKAGE = myCustomManifestPackageField.getText().trim();
myConfiguration.getState().ADDITIONAL_PACKAGING_COMMAND_LINE_PARAMETERS = myAdditionalPackagingCommandLineParametersField.getText().trim();
String absAptSourcePath = myCustomAptSourceDirField.getText().trim();
if (useCustomAptSrc) {
if (absAptSourcePath.length() == 0) {
throw new ConfigurationException("Resources folder not specified");
}
myConfiguration.getState().CUSTOM_APK_RESOURCE_FOLDER = '/' + getAndCheckRelativePath(absAptSourcePath, false);
}
else {
String relPath = toRelativePath(absAptSourcePath);
myConfiguration.getState().CUSTOM_APK_RESOURCE_FOLDER = relPath != null ? '/' + relPath : "";
}
myConfiguration.getState().UPDATE_PROPERTY_FILES = (String)myUpdateProjectPropertiesCombo.getSelectedItem();
String absProguardLogsPath = myProguardLogsDirectoryField.getText().trim();
myConfiguration.getState().PROGUARD_LOGS_FOLDER_RELATIVE_PATH =
absProguardLogsPath.length() > 0 ? '/' + getAndCheckRelativePath(absProguardLogsPath, false) : "";
if (runApt || runIdl) {
final Module module = myContext.getModule();
if (runApt) {
AndroidCompileUtil.generate(module, AndroidAutogeneratorMode.AAPT);
}
if (runIdl) {
AndroidCompileUtil.generate(module, AndroidAutogeneratorMode.AIDL);
}
}
}
private String getAndCheckRelativePath(String absPath, boolean checkExists) throws ConfigurationException {
if (absPath.indexOf('/') < 0 && absPath.indexOf(File.separatorChar) < 0) {
throw new ConfigurationException(AndroidBundle.message("file.must.be.under.module.error", FileUtil.toSystemDependentName(absPath)));
}
String relativeGenPathR = toRelativePath(absPath);
if (relativeGenPathR == null || relativeGenPathR.length() == 0) {
throw new ConfigurationException(AndroidBundle.message("file.must.be.under.module.error", FileUtil.toSystemDependentName(absPath)));
}
if (checkExists && LocalFileSystem.getInstance().findFileByPath(FileUtil.toSystemIndependentName(absPath)) == null) {
throw new ConfigurationException(AndroidBundle.message("android.file.not.exist.error", FileUtil.toSystemDependentName(absPath)));
}
return relativeGenPathR;
}
@Override
public void reset() {
myIsLibraryProjectCheckbox.setSelected(myConfiguration.getState().LIBRARY_PROJECT);
resetOptions(myConfiguration);
}
private void resetOptions(AndroidFacetConfiguration configuration) {
String aptGenPath = configuration.getState().GEN_FOLDER_RELATIVE_PATH_APT;
String aptAbspath = aptGenPath.length() > 0 ? toAbsolutePath(aptGenPath) : "";
myRGenPathField.setText(aptAbspath != null ? aptAbspath : "");
String aidlGenPath = configuration.getState().GEN_FOLDER_RELATIVE_PATH_AIDL;
String aidlAbsPath = aidlGenPath.length() > 0 ? toAbsolutePath(aidlGenPath) : "";
myAidlGenPathField.setText(aidlAbsPath != null ? aidlAbsPath : "");
String manifestPath = configuration.getState().MANIFEST_FILE_RELATIVE_PATH;
String manifestAbsPath = manifestPath.length() > 0 ? toAbsolutePath(manifestPath) : "";
myManifestFileField.setText(manifestAbsPath != null ? manifestAbsPath : "");
String resPath = configuration.getState().RES_FOLDER_RELATIVE_PATH;
String resAbsPath = resPath.length() > 0 ? toAbsolutePath(resPath) : "";
myResFolderField.setText(resAbsPath != null ? resAbsPath : "");
String assetsPath = configuration.getState().ASSETS_FOLDER_RELATIVE_PATH;
String assetsAbsPath = assetsPath.length() > 0 ? toAbsolutePath(assetsPath) : "";
myAssetsFolderField.setText(assetsAbsPath != null ? assetsAbsPath : "");
String libsPath = configuration.getState().LIBS_FOLDER_RELATIVE_PATH;
String libsAbsPath = libsPath.length() > 0 ? toAbsolutePath(libsPath) : "";
myNativeLibsFolder.setText(libsAbsPath != null ? libsAbsPath : "");
myCustomDebugKeystoreField.setText(FileUtil.toSystemDependentName(
VfsUtil.urlToPath(configuration.getState().CUSTOM_DEBUG_KEYSTORE_PATH)));
final boolean runProguard = configuration.getState().RUN_PROGUARD;
myRunProguardCheckBox.setSelected(runProguard);
myProGuardConfigFilesPanel.setUrls(configuration.getState().myProGuardCfgFiles);
myUseCustomSourceDirectoryRadio.setSelected(configuration.getState().USE_CUSTOM_APK_RESOURCE_FOLDER);
myUseAptResDirectoryFromPathRadio.setSelected(!configuration.getState().USE_CUSTOM_APK_RESOURCE_FOLDER);
String aptSourcePath = configuration.getState().CUSTOM_APK_RESOURCE_FOLDER;
String aptSourceAbsPath = aptSourcePath.length() > 0 ? toAbsolutePath(aptSourcePath) : "";
myCustomAptSourceDirField.setText(aptSourceAbsPath != null ? aptSourceAbsPath : "");
myCustomAptSourceDirField.setEnabled(configuration.getState().USE_CUSTOM_APK_RESOURCE_FOLDER);
String apkPath = configuration.getState().APK_PATH;
String apkAbsPath = apkPath.length() > 0 ? toAbsolutePath(apkPath) : "";
myApkPathCombo.getComboBox().getEditor().setItem(apkAbsPath != null ? apkAbsPath : "");
boolean mavenizedModule = AndroidMavenUtil.isMavenizedModule(myContext.getModule());
myRunProcessResourcesRadio.setVisible(mavenizedModule);
myRunProcessResourcesRadio.setSelected(myConfiguration.getState().RUN_PROCESS_RESOURCES_MAVEN_TASK);
myCompileResourcesByIdeRadio.setVisible(mavenizedModule);
myCompileResourcesByIdeRadio.setSelected(!myConfiguration.getState().RUN_PROCESS_RESOURCES_MAVEN_TASK);
myEnableManifestMerging.setSelected(myConfiguration.getState().ENABLE_MANIFEST_MERGING);
myPreDexEnabledCheckBox.setSelected(myConfiguration.getState().ENABLE_PRE_DEXING);
myIncludeTestCodeAndCheckBox.setSelected(myConfiguration.getState().PACK_TEST_CODE);
myIncludeAssetsFromLibraries.setSelected(myConfiguration.isIncludeAssetsFromLibraries());
myUseCustomManifestPackage.setSelected(myConfiguration.getState().USE_CUSTOM_MANIFEST_PACKAGE);
myCustomManifestPackageField.setEnabled(myConfiguration.getState().USE_CUSTOM_MANIFEST_PACKAGE);
myCustomManifestPackageField.setText(myConfiguration.getState().CUSTOM_MANIFEST_PACKAGE);
myAdditionalPackagingCommandLineParametersField.setText(myConfiguration.getState().ADDITIONAL_PACKAGING_COMMAND_LINE_PARAMETERS);
String proguardLogsPath = configuration.getState().PROGUARD_LOGS_FOLDER_RELATIVE_PATH;
String proguardLogsAbsPath = proguardLogsPath.length() > 0 ? toAbsolutePath(proguardLogsPath) : "";
myProguardLogsDirectoryField.setText(proguardLogsAbsPath != null ? proguardLogsAbsPath : "");
myUpdateProjectPropertiesCombo.setSelectedItem(myConfiguration.getState().UPDATE_PROPERTY_FILES);
myEnableSourcesAutogenerationCheckBox.setSelected(myConfiguration.getState().ENABLE_SOURCES_AUTOGENERATION);
updateAutogenerationPanels();
final int mavenTabIndex = myTabbedPane.indexOfTab(MAVEN_TAB_TITLE);
if (mavenTabIndex >= 0) {
myTabbedPane.removeTabAt(mavenTabIndex);
}
if (mavenizedModule) {
myTabbedPane.insertTab(MAVEN_TAB_TITLE, null, myMavenTabComponent, null, 2);
for (int i = 0; i < myImportedOptionsList.getItemsCount(); i++) {
final AndroidImportableProperty property = (AndroidImportableProperty)myImportedOptionsList.getItemAt(i);
myImportedOptionsList.setItemSelected(property, configuration.isImportedProperty(property));
}
}
updateLibAndAppSpecificFields();
}
@Nullable
private String toAbsolutePath(String genRelativePath) {
if (genRelativePath == null) {
return null;
}
if (genRelativePath.length() == 0) {
return "";
}
String moduleDirPath = AndroidRootUtil.getModuleDirPath(myContext.getModule());
if (moduleDirPath == null) return null;
final String path = PathUtil.getCanonicalPath(new File(moduleDirPath, genRelativePath).getPath());
return path != null ? PathUtil.getLocalPath(path) : null;
}
@Override
public void disposeUIResources() {
}
private void createUIComponents() {
myProGuardConfigFilesPanel = new ProGuardConfigFilesPanel() {
@Nullable
@Override
protected AndroidFacet getFacet() {
return (AndroidFacet)myContext.getFacet();
}
};
}
private class MyGenSourceFieldListener implements ActionListener {
private final TextFieldWithBrowseButton myTextField;
private final String myDefaultPath;
private MyGenSourceFieldListener(TextFieldWithBrowseButton textField, String defaultPath) {
myTextField = textField;
myDefaultPath = defaultPath;
}
@Override
public void actionPerformed(ActionEvent e) {
Module module = myContext.getModule();
final VirtualFile[] contentRoots = ModuleRootManager.getInstance(module).getContentRoots();
if (contentRoots.length == 0) {
return;
}
VirtualFile initialFile = null;
String path = myTextField.getText().trim();
if (path.length() == 0) {
path = myDefaultPath;
}
if (path != null) {
initialFile = LocalFileSystem.getInstance().findFileByPath(path);
}
if (initialFile == null) {
ModuleRootManager manager = ModuleRootManager.getInstance(module);
VirtualFile[] sourceRoots = manager.getSourceRoots();
if (sourceRoots.length > 0) {
initialFile = sourceRoots[0];
}
else {
initialFile = module.getModuleFile();
if (initialFile == null) {
String p = AndroidRootUtil.getModuleDirPath(myContext.getModule());
if (p != null) {
initialFile = LocalFileSystem.getInstance().findFileByPath(p);
}
}
}
}
final FileChooserDescriptor descriptor = FileChooserDescriptorFactory.createSingleFolderDescriptor();
descriptor.setRoots(contentRoots);
VirtualFile file = FileChooser.chooseFile(descriptor, myContentPanel, myContext.getProject(), initialFile);
if (file != null) {
myTextField.setText(FileUtil.toSystemDependentName(file.getPath()));
}
}
}
private class MyFolderFieldListener implements ActionListener {
private final TextFieldWithBrowseButton myTextField;
private final VirtualFile myDefaultDir;
private final boolean myChooseFile;
private final Condition<VirtualFile> myFilter;
public MyFolderFieldListener(TextFieldWithBrowseButton textField,
VirtualFile defaultDir,
boolean chooseFile,
@Nullable Condition<VirtualFile> filter) {
myTextField = textField;
myDefaultDir = defaultDir;
myChooseFile = chooseFile;
myFilter = filter;
}
@Override
public void actionPerformed(ActionEvent e) {
VirtualFile initialFile = null;
String path = myTextField.getText().trim();
if (path.length() == 0) {
VirtualFile dir = myDefaultDir;
path = dir != null ? dir.getPath() : null;
}
if (path != null) {
initialFile = LocalFileSystem.getInstance().findFileByPath(path);
}
VirtualFile[] files = chooserDirsUnderModule(initialFile, myChooseFile, false, myFilter);
if (files.length > 0) {
assert files.length == 1;
myTextField.setText(FileUtil.toSystemDependentName(files[0].getPath()));
}
}
}
private VirtualFile[] chooserDirsUnderModule(@Nullable VirtualFile initialFile,
final boolean chooseFile,
boolean chooseMultiple,
@Nullable final Condition<VirtualFile> filter) {
if (initialFile == null) {
initialFile = myContext.getModule().getModuleFile();
}
if (initialFile == null) {
String p = AndroidRootUtil.getModuleDirPath(myContext.getModule());
if (p != null) {
initialFile = LocalFileSystem.getInstance().findFileByPath(p);
}
}
final FileChooserDescriptor descriptor = new FileChooserDescriptor(chooseFile, !chooseFile, false, false, false, chooseMultiple) {
@Override
public boolean isFileVisible(VirtualFile file, boolean showHiddenFiles) {
if (!super.isFileVisible(file, showHiddenFiles)) {
return false;
}
if (!file.isDirectory() && !chooseFile) {
return false;
}
return filter == null || filter.value(file);
}
};
return FileChooser.chooseFiles(descriptor, myContentPanel, myContext.getProject(), initialFile);
}
private static class MyManifestFilter implements Condition<VirtualFile> {
@Override
public boolean value(VirtualFile file) {
return file.isDirectory() || file.getName().equals(SdkConstants.FN_ANDROID_MANIFEST_XML);
}
}
}