package com.intellij.lang.javascript.flex.projectStructure.ui; import com.intellij.execution.ExecutionBundle; import com.intellij.flex.FlexCommonUtils; import com.intellij.flex.model.bc.BuildConfigurationNature; import com.intellij.flex.model.bc.CompilerOptionInfo; import com.intellij.flex.model.bc.OutputType; import com.intellij.flex.model.bc.TargetPlatform; import com.intellij.lang.javascript.flex.FlexBundle; import com.intellij.lang.javascript.flex.FlexUtils; import com.intellij.lang.javascript.flex.build.FlexCompilationUtils; import com.intellij.lang.javascript.flex.build.FlexCompilerConfigFileUtil; import com.intellij.lang.javascript.flex.build.InfoFromConfigFile; import com.intellij.lang.javascript.flex.projectStructure.FlexBCConfigurator; import com.intellij.lang.javascript.flex.projectStructure.FlexBuildConfigurationsExtension; import com.intellij.lang.javascript.flex.projectStructure.model.FlexBuildConfiguration; import com.intellij.lang.javascript.flex.projectStructure.model.ModifiableFlexBuildConfiguration; import com.intellij.lang.javascript.flex.projectStructure.model.impl.FlexProjectConfigurationEditor; import com.intellij.lang.javascript.flex.projectStructure.options.BCUtils; import com.intellij.lang.javascript.flex.sdk.FlexmojosSdkType; import com.intellij.lang.javascript.psi.impl.PublicInheritorFilter; import com.intellij.lang.javascript.refactoring.ui.JSReferenceEditor; import com.intellij.openapi.Disposable; import com.intellij.openapi.fileChooser.FileChooserDescriptorFactory; import com.intellij.openapi.module.Module; import com.intellij.openapi.options.ConfigurationException; import com.intellij.openapi.projectRoots.Sdk; import com.intellij.openapi.roots.libraries.Library; import com.intellij.openapi.roots.ui.configuration.ModuleEditor; import com.intellij.openapi.roots.ui.configuration.ModulesConfigurator; import com.intellij.openapi.roots.ui.configuration.projectRoot.ModuleStructureConfigurable; import com.intellij.openapi.roots.ui.configuration.projectRoot.ProjectSdksModel; import com.intellij.openapi.roots.ui.configuration.projectRoot.ProjectStructureElementConfigurable; import com.intellij.openapi.roots.ui.configuration.projectRoot.StructureConfigurableContext; import com.intellij.openapi.roots.ui.configuration.projectRoot.daemon.ProjectStructureElement; import com.intellij.openapi.ui.NamedConfigurable; import com.intellij.openapi.ui.TextFieldWithBrowseButton; import com.intellij.openapi.util.ActionCallback; import com.intellij.openapi.util.Conditions; import com.intellij.openapi.util.Disposer; import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.wm.IdeFocusManager; import com.intellij.ui.*; import com.intellij.ui.navigation.History; import com.intellij.ui.navigation.Place; import com.intellij.util.PathUtil; import com.intellij.util.PlatformIcons; import com.intellij.util.containers.ContainerUtil; import com.intellij.util.ui.UIUtil; import icons.FlexIcons; import org.jetbrains.annotations.Nls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import javax.swing.*; import javax.swing.event.DocumentEvent; import javax.swing.event.HyperlinkEvent; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.*; import static com.intellij.lang.javascript.flex.projectStructure.ui.AirPackagingConfigurableBase.AirDescriptorInfoProvider; public class FlexBCConfigurable extends ProjectStructureElementConfigurable<ModifiableFlexBuildConfiguration> implements CompositeConfigurable.Item, Place.Navigator { public static final String TAB_NAME = FlexBundle.message("bc.tab.general.display.name"); public static final String LOCATION_ON_TAB = "FlashBuildConfiguration.locationOnTab"; public enum Location { Nature("nature"), MainClass("main-class"), OutputFileName("output-file-name"), OutputFolder("output-folder"), HtmlTemplatePath("html-template-path"), RLMs("runtime-loaded-modules"), RuntimeStyleSheets("runtime-style-sheets"); public final String errorId; Location(final String errorId) { this.errorId = errorId; } } private JPanel myMainPanel; private JLabel myNatureLabel; private HoverHyperlinkLabel myChangeNatureHyperlink; private JTextField myNameField; private JPanel myOptimizeForPanel; private JComboBox myOptimizeForCombo; private JLabel myMainClassLabel; private JSReferenceEditor myMainClassComponent; private JLabel myMainClassWarning; private JTextField myOutputFileNameTextField; private JLabel myOutputFileNameWarning; private TextFieldWithBrowseButton myOutputFolderField; private JLabel myOutputFolderWarning; private JCheckBox myUseHTMLWrapperCheckBox; private JLabel myWrapperFolderLabel; private TextFieldWithBrowseButton myWrapperTemplateTextWithBrowse; private JButton myCreateHtmlWrapperTemplateButton; private JLabel myRLMLabel; private TextFieldWithBrowseButton.NoPathCompletion myRLMTextWithBrowse; private Collection<FlexBuildConfiguration.RLMInfo> myRLMs; private JLabel myCssFilesLabel; private TextFieldWithBrowseButton.NoPathCompletion myCssFilesTextWithBrowse; private Collection<String> myCssFilesToCompile; private JCheckBox mySkipCompilationCheckBox; private JLabel myWarning; private final Module myModule; private final ModifiableFlexBuildConfiguration myConfiguration; private @NotNull final FlexProjectConfigurationEditor myConfigEditor; private final ProjectSdksModel mySdksModel; private final StructureConfigurableContext myContext; private String myName; private DependenciesConfigurable myDependenciesConfigurable; private CompilerOptionsConfigurable myCompilerOptionsConfigurable; private @Nullable AirDesktopPackagingConfigurable myAirDesktopPackagingConfigurable; private @Nullable AndroidPackagingConfigurable myAndroidPackagingConfigurable; private @Nullable IOSPackagingConfigurable myIOSPackagingConfigurable; private final BuildConfigurationProjectStructureElement myStructureElement; private final Disposable myDisposable; private final UserActivityListener myUserActivityListener; private boolean myFreeze; private PublicInheritorFilter myMainClassFilter; public FlexBCConfigurable(final Module module, final ModifiableFlexBuildConfiguration bc, final Runnable bcNatureModifier, final @NotNull FlexProjectConfigurationEditor configEditor, final ProjectSdksModel sdksModel, final StructureConfigurableContext context) { super(false, null); myModule = module; myConfiguration = bc; myConfigEditor = configEditor; mySdksModel = sdksModel; myContext = context; myName = bc.getName(); myStructureElement = new BuildConfigurationProjectStructureElement(bc, module, context) { @Override protected void libraryReplaced(@NotNull final Library library, @Nullable final Library replacement) { myDependenciesConfigurable.libraryReplaced(library, replacement); } }; myRLMs = Collections.emptyList(); myCssFilesToCompile = Collections.emptyList(); myDisposable = Disposer.newDisposable(); myUserActivityListener = new UserActivityListener() { @Override public void stateChanged() { if (myFreeze) { return; } try { apply(); } catch (ConfigurationException ignored) { } myContext.getDaemonAnalyzer().queueUpdate(myStructureElement); myContext.getDaemonAnalyzer().queueUpdateForAllElementsWithErrors(); final FlexBCConfigurator configurator = FlexBuildConfigurationsExtension.getInstance().getConfigurator(); final List<ModifiableFlexBuildConfiguration> bcs = configurator.getBCsByOutputPath(myConfiguration.getActualOutputFilePath()); if (bcs != null) { for (ModifiableFlexBuildConfiguration bc : bcs) { if (bc == myConfiguration) continue; myContext.getDaemonAnalyzer().queueUpdate(configurator.getBCConfigurable(bc).myStructureElement); } } } }; final UserActivityWatcher watcher = new UserActivityWatcher(); watcher.register(myMainPanel); watcher.addUserActivityListener(myUserActivityListener, myDisposable); createChildConfigurables(); myChangeNatureHyperlink.addHyperlinkListener(new HyperlinkAdapter() { protected void hyperlinkActivated(final HyperlinkEvent e) { bcNatureModifier.run(); } }); myNameField.getDocument().addDocumentListener(new DocumentAdapter() { protected void textChanged(DocumentEvent e) { setDisplayName(myNameField.getText().trim()); } }); myOutputFolderField.addBrowseFolderListener(null, null, module.getProject(), FileChooserDescriptorFactory.createSingleFolderDescriptor()); initHtmlWrapperControls(); initRLMControls(); initCSSControls(); myOptimizeForCombo.setModel(new CollectionComboBoxModel(Arrays.asList(""), "")); myOptimizeForCombo.setRenderer(new ListCellRendererWrapper() { @Override public void customize(JList list, Object value, int index, boolean selected, boolean hasFocus) { if ("".equals(value)) { setText("<no optimization>"); } } }); myMainClassWarning.setIcon(FlexIcons.Flex.SmallWarning); myOutputFileNameWarning.setIcon(FlexIcons.Flex.SmallWarning); myOutputFolderWarning.setIcon(FlexIcons.Flex.SmallWarning); myWarning.setIcon(UIUtil.getBalloonWarningIcon()); } private void initHtmlWrapperControls() { myUseHTMLWrapperCheckBox.addActionListener(new ActionListener() { public void actionPerformed(final ActionEvent e) { updateControls(); IdeFocusManager.getInstance(myModule.getProject()).requestFocus(myWrapperTemplateTextWithBrowse.getTextField(), true); } }); final String title = "Select folder with HTML wrapper template"; final String description = "Folder must contain 'index.template.html' file which must contain '${swf}' macro."; myWrapperTemplateTextWithBrowse.addBrowseFolderListener(title, description, myModule.getProject(), FileChooserDescriptorFactory.createSingleFolderDescriptor()); myCreateHtmlWrapperTemplateButton.addActionListener(new ActionListener() { public void actionPerformed(final ActionEvent e) { final Sdk sdk = myDependenciesConfigurable.getCurrentSdk(); if (sdk == null || sdk.getSdkType() == FlexmojosSdkType.getInstance()) { final SelectFlexSdkDialog dialog = new SelectFlexSdkDialog(myModule.getProject(), CreateHtmlWrapperTemplateDialog.TITLE, FlexBundle.message("take.wrapper.template.from.sdk")); if (dialog.showAndGet()) { final Sdk dialogSdk = dialog.getSdk(); if (dialogSdk != null) { showHtmlWrapperCreationDialog(dialogSdk); } } } else { showHtmlWrapperCreationDialog(sdk); } } }); } private void initRLMControls() { myRLMTextWithBrowse.getTextField().setEditable(false); myRLMTextWithBrowse.setButtonIcon(PlatformIcons.OPEN_EDIT_DIALOG_ICON); myRLMTextWithBrowse.addActionListener(new ActionListener() { public void actionPerformed(final ActionEvent e) { final RLMsDialog dialog = new RLMsDialog(myModule, myRLMs); if (dialog.showAndGet()) { myRLMs = dialog.getRLMs(); updateRLMsText(); } } }); } private void initCSSControls() { myCssFilesTextWithBrowse.getTextField().setEditable(false); myCssFilesTextWithBrowse.setButtonIcon(PlatformIcons.OPEN_EDIT_DIALOG_ICON); myCssFilesTextWithBrowse.addActionListener(new ActionListener() { public void actionPerformed(final ActionEvent e) { final List<StringBuilder> value = new ArrayList<>(); for (String cssFilePath : myCssFilesToCompile) { value.add(new StringBuilder(cssFilePath)); } final RepeatableValueDialog dialog = new RepeatableValueDialog(myModule.getProject(), FlexBundle.message("css.files.to.compile.dialog.title"), value, CompilerOptionInfo.CSS_FILES_INFO_FOR_UI); if (dialog.showAndGet()) { final List<StringBuilder> newValue = dialog.getCurrentList(); myCssFilesToCompile = new ArrayList<>(newValue.size()); for (StringBuilder cssPath : newValue) { myCssFilesToCompile.add(cssPath.toString()); } updateCssFilesText(); } } }); } private void showHtmlWrapperCreationDialog(final @NotNull Sdk sdk) { String path = myWrapperTemplateTextWithBrowse.getText().trim(); if (path.isEmpty()) { path = FlexUtils.getContentOrModuleFolderPath(myModule) + "/" + CreateHtmlWrapperTemplateDialog.HTML_TEMPLATE_FOLDER_NAME; } final CreateHtmlWrapperTemplateDialog dialog = new CreateHtmlWrapperTemplateDialog(myModule, sdk, myOutputFolderField.getText().trim(), path); if (dialog.showAndGet()) { myWrapperTemplateTextWithBrowse.setText(FileUtil.toSystemDependentName(dialog.getWrapperFolderPath())); } } public void createChildConfigurables() { final BuildConfigurationNature nature = myConfiguration.getNature(); if (myDependenciesConfigurable != null) { myDependenciesConfigurable.removeUserActivityListeners(); myDependenciesConfigurable.disposeUIResources(); } if (myCompilerOptionsConfigurable != null) { myCompilerOptionsConfigurable.removeUserActivityListeners(); myCompilerOptionsConfigurable.disposeUIResources(); } if (myAirDesktopPackagingConfigurable != null) { myAirDesktopPackagingConfigurable.removeUserActivityListeners(); myAirDesktopPackagingConfigurable.disposeUIResources(); } if (myAndroidPackagingConfigurable != null) { myAndroidPackagingConfigurable.removeUserActivityListeners(); myAndroidPackagingConfigurable.disposeUIResources(); } if (myIOSPackagingConfigurable != null) { myIOSPackagingConfigurable.removeUserActivityListeners(); myIOSPackagingConfigurable.disposeUIResources(); } myDependenciesConfigurable = new DependenciesConfigurable(myConfiguration, myModule.getProject(), myConfigEditor, mySdksModel); myDependenciesConfigurable.addUserActivityListener(myUserActivityListener, myDisposable); myCompilerOptionsConfigurable = new CompilerOptionsConfigurable(myModule, nature, myDependenciesConfigurable, myConfiguration.getCompilerOptions()); myCompilerOptionsConfigurable.addUserActivityListener(myUserActivityListener, myDisposable); myCompilerOptionsConfigurable.addAdditionalOptionsListener(new CompilerOptionsConfigurable.OptionsListener() { public void configFileChanged(final String additionalConfigFilePath) { checkIfConfigFileOverridesOptions(additionalConfigFilePath); } public void additionalOptionsChanged(final String additionalOptions) { // may be parse additionalOptions in the same way as config file } }); final AirDescriptorInfoProvider airDescriptorInfoProvider = new AirDescriptorInfoProvider() { public String getMainClass() { return myMainClassComponent.getText().trim(); } public String getAirVersion() { final Sdk sdk = myDependenciesConfigurable.getCurrentSdk(); return sdk == null || sdk.getVersionString() == null ? "" : StringUtil.notNullize(FlexCommonUtils.getAirVersion(sdk.getHomePath(), sdk.getVersionString())); } public String[] getExtensionIDs() { return FlexCompilationUtils.getAirExtensionIDs(myConfigEditor.getModifiableRootModel(myModule), myDependenciesConfigurable.getEditableObject()); } public boolean isAndroidPackagingEnabled() { return myAndroidPackagingConfigurable != null && myAndroidPackagingConfigurable.isPackagingEnabled(); } public boolean isIOSPackagingEnabled() { return myIOSPackagingConfigurable != null && myIOSPackagingConfigurable.isPackagingEnabled(); } public void setCustomDescriptorForAndroidAndIOS(final String descriptorPath) { assert myAndroidPackagingConfigurable != null && myIOSPackagingConfigurable != null; myAndroidPackagingConfigurable.setUseCustomDescriptor(descriptorPath); myIOSPackagingConfigurable.setUseCustomDescriptor(descriptorPath); } }; myAirDesktopPackagingConfigurable = nature.isDesktopPlatform() && nature.isApp() ? new AirDesktopPackagingConfigurable(myModule, myConfiguration.getAirDesktopPackagingOptions(), airDescriptorInfoProvider) : null; if (myAirDesktopPackagingConfigurable != null) { myAirDesktopPackagingConfigurable.addUserActivityListener(myUserActivityListener, myDisposable); } myAndroidPackagingConfigurable = nature.isMobilePlatform() && nature.isApp() ? new AndroidPackagingConfigurable(myModule, myConfiguration.getAndroidPackagingOptions(), airDescriptorInfoProvider) : null; if (myAndroidPackagingConfigurable != null) { myAndroidPackagingConfigurable.addUserActivityListener(myUserActivityListener, myDisposable); } myIOSPackagingConfigurable = nature.isMobilePlatform() && nature.isApp() ? new IOSPackagingConfigurable(myModule, myConfiguration.getIosPackagingOptions(), airDescriptorInfoProvider) : null; if (myIOSPackagingConfigurable != null) { myIOSPackagingConfigurable.addUserActivityListener(myUserActivityListener, myDisposable); } } private void checkIfConfigFileOverridesOptions(final String configFilePath) { final InfoFromConfigFile info = FlexCompilerConfigFileUtil.getInfoFromConfigFile(configFilePath); overriddenValuesChanged(info.getMainClass(myModule), info.getOutputFileName(), info.getOutputFolderPath()); myDependenciesConfigurable.overriddenTargetPlayerChanged(info.getTargetPlayer()); } /** * Called when {@link CompilerOptionsConfigurable} is initialized and when path to additional config file is changed * <code>null</code> parameter value means that the value is not overridden in additional config file */ public void overriddenValuesChanged(final @Nullable String mainClass, final @Nullable String outputFileName, final @Nullable String outputFolderPath) { myMainClassWarning.setToolTipText(FlexBundle.message("actual.value.from.config.file.0", mainClass)); myMainClassWarning.setVisible(myMainClassComponent.isVisible() && mainClass != null); myOutputFileNameWarning.setToolTipText(FlexBundle.message("actual.value.from.config.file.0", outputFileName)); myOutputFileNameWarning.setVisible(outputFileName != null); myOutputFolderWarning.setToolTipText( FlexBundle.message("actual.value.from.config.file.0", FileUtil.toSystemDependentName(StringUtil.notNullize(outputFolderPath)))); myOutputFolderWarning.setVisible(outputFolderPath != null); final String warning = myMainClassWarning.isVisible() && outputFileName == null && outputFolderPath == null ? FlexBundle.message("overridden.in.config.file", "Main class", mainClass) : !myMainClassWarning.isVisible() && outputFileName != null && outputFolderPath != null ? FlexBundle.message("overridden.in.config.file", "Output path", FileUtil.toSystemDependentName(outputFolderPath + "/" + outputFileName)) : FlexBundle.message("main.class.and.output.overridden.in.config.file"); myWarning.setText(warning); myWarning.setVisible(myMainClassWarning.isVisible() || myOutputFileNameWarning.isVisible() || myOutputFolderWarning.isVisible()); } @Nls public String getDisplayName() { return myName; } @Override public void updateName() { myFreeze = true; try { myNameField.setText(getDisplayName()); } finally { myFreeze = false; } } public void setDisplayName(final String name) { myName = name; } public String getBannerSlogan() { return "Build Configuration '" + myName + "'"; } public Module getModule() { return myModule; } public String getModuleName() { final ModuleEditor moduleEditor = getModulesConfigurator().getModuleEditor(myModule); assert moduleEditor != null : myModule; return moduleEditor.getName(); } private ModulesConfigurator getModulesConfigurator() { return ModuleStructureConfigurable.getInstance(myModule.getProject()).getContext().getModulesConfigurator(); } public Icon getIcon() { return myConfiguration.getIcon(); } public ModifiableFlexBuildConfiguration getEditableObject() { return myConfiguration; } public String getHelpTopic() { return "BuildConfigurationPage.General"; } public JComponent createOptionsPanel() { return myMainPanel; } private void updateControls() { final TargetPlatform targetPlatform = myConfiguration.getTargetPlatform(); final OutputType outputType = myConfiguration.getOutputType(); myOptimizeForPanel.setVisible(false /*outputType == OutputType.RuntimeLoadedModule*/); final boolean showMainClass = outputType == OutputType.Application || outputType == OutputType.RuntimeLoadedModule; myMainClassLabel.setVisible(showMainClass); myMainClassComponent.setVisible(showMainClass); final boolean wrapperApplicable = targetPlatform == TargetPlatform.Web && outputType == OutputType.Application; myUseHTMLWrapperCheckBox.setVisible(wrapperApplicable); myWrapperFolderLabel.setVisible(wrapperApplicable); myWrapperTemplateTextWithBrowse.setVisible(wrapperApplicable); myCreateHtmlWrapperTemplateButton.setVisible(wrapperApplicable); if (wrapperApplicable) { myWrapperFolderLabel.setEnabled(myUseHTMLWrapperCheckBox.isSelected()); myWrapperTemplateTextWithBrowse.setEnabled(myUseHTMLWrapperCheckBox.isSelected()); myCreateHtmlWrapperTemplateButton.setEnabled(myUseHTMLWrapperCheckBox.isSelected()); } final boolean canHaveRLMsAndRuntimeStylesheets = FlexCommonUtils.canHaveRLMsAndRuntimeStylesheets(outputType, targetPlatform); myRLMLabel.setVisible(canHaveRLMsAndRuntimeStylesheets); myRLMTextWithBrowse.setVisible(canHaveRLMsAndRuntimeStylesheets); updateRLMsText(); myCssFilesLabel.setVisible(canHaveRLMsAndRuntimeStylesheets); myCssFilesTextWithBrowse.setVisible(canHaveRLMsAndRuntimeStylesheets); updateCssFilesText(); } private void updateRLMsText() { final String s = StringUtil.join(myRLMs, info -> info.MAIN_CLASS, ", "); myRLMTextWithBrowse.setText(s); } private void updateCssFilesText() { final String s = StringUtil.join(myCssFilesToCompile, path -> PathUtil.getFileName(path), ", "); myCssFilesTextWithBrowse.setText(s); } public String getTreeNodeText() { return myConfiguration.getShortText(); } public OutputType getOutputType() { // immutable field return myConfiguration.getOutputType(); } public boolean isModified() { if (!myConfiguration.getName().equals(myName)) return true; if (!myConfiguration.getOptimizeFor().equals(myOptimizeForCombo.getSelectedItem())) return true; if (!myConfiguration.getMainClass().equals(myMainClassComponent.getText().trim())) return true; if (!myConfiguration.getOutputFileName().equals(myOutputFileNameTextField.getText().trim())) return true; if (!myConfiguration.getOutputFolder().equals(FileUtil.toSystemIndependentName(myOutputFolderField.getText().trim()))) return true; if (myConfiguration.isUseHtmlWrapper() != myUseHTMLWrapperCheckBox.isSelected()) return true; if (!myConfiguration.getWrapperTemplatePath() .equals(FileUtil.toSystemIndependentName(myWrapperTemplateTextWithBrowse.getText().trim()))) { return true; } if (!myConfiguration.getRLMs().equals(myRLMs)) return true; if (!myConfiguration.getCssFilesToCompile().equals(myCssFilesToCompile)) return true; if (myConfiguration.isSkipCompile() != mySkipCompilationCheckBox.isSelected()) return true; if (myDependenciesConfigurable.isModified()) return true; if (myCompilerOptionsConfigurable.isModified()) return true; if (myAirDesktopPackagingConfigurable != null && myAirDesktopPackagingConfigurable.isModified()) return true; if (myAndroidPackagingConfigurable != null && myAndroidPackagingConfigurable.isModified()) return true; if (myIOSPackagingConfigurable != null && myIOSPackagingConfigurable.isModified()) return true; return false; } public void apply() throws ConfigurationException { applyOwnTo(myConfiguration, true); myDependenciesConfigurable.apply(); myCompilerOptionsConfigurable.apply(); if (myAirDesktopPackagingConfigurable != null) myAirDesktopPackagingConfigurable.apply(); if (myAndroidPackagingConfigurable != null) myAndroidPackagingConfigurable.apply(); if (myIOSPackagingConfigurable != null) myIOSPackagingConfigurable.apply(); // main class validation is based on live settings from dependencies tab rebuildMainClassFilter(); } private void rebuildMainClassFilter() { final boolean rlm = myConfiguration.getOutputType() == OutputType.RuntimeLoadedModule; myMainClassFilter = BCUtils.getMainClassFilter(myModule, myConfiguration, rlm, false, true); } private void applyOwnTo(ModifiableFlexBuildConfiguration configuration, boolean validate) throws ConfigurationException { if (validate && StringUtil.isEmptyOrSpaces(myName)) { throw new ConfigurationException("Module '" + getModuleName() + "': build configuration name is empty"); } configuration.setName(myName); configuration.setOptimizeFor((String)myOptimizeForCombo.getSelectedItem()); configuration.setMainClass(myMainClassComponent.getText().trim()); configuration.setOutputFileName(myOutputFileNameTextField.getText().trim()); configuration.setOutputFolder(FileUtil.toSystemIndependentName(myOutputFolderField.getText().trim())); configuration.setUseHtmlWrapper(myUseHTMLWrapperCheckBox.isSelected()); configuration.setWrapperTemplatePath(FileUtil.toSystemIndependentName(myWrapperTemplateTextWithBrowse.getText().trim())); configuration.setRLMs(myRLMs); configuration.setCssFilesToCompile(myCssFilesToCompile); configuration.setSkipCompile(mySkipCompilationCheckBox.isSelected()); } public void reset() { myFreeze = true; try { setDisplayName(myConfiguration.getName()); myNatureLabel.setText(myConfiguration.getNature().getPresentableText()); myOptimizeForCombo.setSelectedItem(myConfiguration.getOptimizeFor()); myMainClassComponent.setText(myConfiguration.getMainClass()); myOutputFileNameTextField.setText(myConfiguration.getOutputFileName()); myOutputFolderField.setText(FileUtil.toSystemDependentName(myConfiguration.getOutputFolder())); myUseHTMLWrapperCheckBox.setSelected(myConfiguration.isUseHtmlWrapper()); myWrapperTemplateTextWithBrowse.setText(FileUtil.toSystemDependentName(myConfiguration.getWrapperTemplatePath())); myRLMs = new ArrayList<>(myConfiguration.getRLMs()); myCssFilesToCompile = new ArrayList<>(myConfiguration.getCssFilesToCompile()); mySkipCompilationCheckBox.setSelected(myConfiguration.isSkipCompile()); updateControls(); overriddenValuesChanged(null, null, null); // no warnings initially myDependenciesConfigurable.reset(); myCompilerOptionsConfigurable.reset(); if (myAirDesktopPackagingConfigurable != null) myAirDesktopPackagingConfigurable.reset(); if (myAndroidPackagingConfigurable != null) myAndroidPackagingConfigurable.reset(); if (myIOSPackagingConfigurable != null) myIOSPackagingConfigurable.reset(); } finally { myFreeze = false; } rebuildMainClassFilter(); myContext.getDaemonAnalyzer().queueUpdate(myStructureElement); } public void disposeUIResources() { myDependenciesConfigurable.disposeUIResources(); myCompilerOptionsConfigurable.disposeUIResources(); if (myAirDesktopPackagingConfigurable != null) myAirDesktopPackagingConfigurable.disposeUIResources(); if (myAndroidPackagingConfigurable != null) myAndroidPackagingConfigurable.disposeUIResources(); if (myIOSPackagingConfigurable != null) myIOSPackagingConfigurable.disposeUIResources(); Disposer.dispose(myDisposable); } //public ModifiableFlexBuildConfiguration getCurrentConfiguration() { // final ModifiableFlexBuildConfiguration configuration = Factory.createBuildConfiguration(); // try { // applyTo(configuration, false); // } // catch (ConfigurationException ignored) { // // no validation // } // return configuration; //} private List<NamedConfigurable> getChildren() { final List<NamedConfigurable> children = new ArrayList<>(); children.add(myDependenciesConfigurable); children.add(myCompilerOptionsConfigurable); ContainerUtil.addIfNotNull(children, myAirDesktopPackagingConfigurable); ContainerUtil.addIfNotNull(children, myAndroidPackagingConfigurable); ContainerUtil.addIfNotNull(children, myIOSPackagingConfigurable); return children; } public CompositeConfigurable wrapInTabs() { return new CompositeConfigurable(this, getChildren(), null); } public void updateTabs(final CompositeConfigurable compositeConfigurable) { final List<NamedConfigurable> children = compositeConfigurable.getChildren(); assert children.get(0) == this : children.get(0).getDisplayName(); for (int i = children.size() - 1; i >= 1; i--) { compositeConfigurable.removeChildAt(i); } for (NamedConfigurable child : getChildren()) { compositeConfigurable.addChild(child); } } public DependenciesConfigurable getDependenciesConfigurable() { return myDependenciesConfigurable; } public boolean isParentFor(final DependenciesConfigurable dependenciesConfigurable) { return myDependenciesConfigurable == dependenciesConfigurable; } private void createUIComponents() { myChangeNatureHyperlink = new HoverHyperlinkLabel("Change..."); rebuildMainClassFilter(); myMainClassComponent = JSReferenceEditor.forClassName("", myModule.getProject(), null, myModule.getModuleScope(false), null, Conditions.alwaysTrue(), // no filtering until IDEA-83046 ExecutionBundle.message("choose.main.class.dialog.title")); } public void addSharedLibrary(final Library library) { myDependenciesConfigurable.addSharedLibraries(Collections.singletonList(library)); } public static FlexBCConfigurable unwrap(CompositeConfigurable c) { return c.getMainChild(); } @Override public String getTabTitle() { return TAB_NAME; } @Override public ProjectStructureElement getProjectStructureElement() { return myStructureElement; } @Override public void setHistory(final History history) { } @Override public ActionCallback navigateTo(@Nullable final Place place, final boolean requestFocus) { if (place != null) { final Object location = place.getPath(LOCATION_ON_TAB); if (location instanceof Location) { switch ((Location)location) { case Nature: return IdeFocusManager.findInstance().requestFocus(myChangeNatureHyperlink, true); case MainClass: return IdeFocusManager.findInstance().requestFocus(myMainClassComponent.getChildComponent(), true); case OutputFileName: return IdeFocusManager.findInstance().requestFocus(myOutputFileNameTextField, true); case OutputFolder: return IdeFocusManager.findInstance().requestFocus(myOutputFolderField.getChildComponent(), true); case HtmlTemplatePath: return IdeFocusManager.findInstance().requestFocus(myWrapperTemplateTextWithBrowse.getChildComponent(), true); case RuntimeStyleSheets: return IdeFocusManager.findInstance().requestFocus(myCssFilesTextWithBrowse.getChildComponent(), true); case RLMs: return IdeFocusManager.findInstance().requestFocus(myRLMTextWithBrowse.getChildComponent(), true); } } } return ActionCallback.DONE; } @Override public void queryPlace(@NotNull final Place place) { } }