package com.intellij.lang.javascript.flex.projectStructure.ui; import com.intellij.lang.javascript.flex.FlexUtils; import com.intellij.lang.javascript.flex.projectStructure.model.AirSigningOptions; import com.intellij.openapi.fileChooser.FileChooserDescriptor; import com.intellij.openapi.fileChooser.FileChooserDescriptorFactory; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.TextFieldWithBrowseButton; import com.intellij.openapi.util.ActionCallback; import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.wm.IdeFocusManager; import com.intellij.ui.HoverHyperlinkLabel; import com.intellij.ui.RawCommandLineEditor; import com.intellij.ui.components.JBRadioButton; import com.intellij.util.ui.PlatformColors; import com.intellij.util.ui.UIUtil; import org.jetbrains.annotations.NotNull; import javax.swing.*; import javax.swing.event.HyperlinkEvent; import javax.swing.event.HyperlinkListener; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; public class SigningOptionsForm { private static final String MORE_OPTIONS = "More options"; private static final String LESS_OPTIONS = "Less options"; private final Mode myMode; private JPanel myMainPanel; private JLabel myTargetArchitectureLabel; private JBRadioButton myArchArmv7RadioButton; private JBRadioButton myArchX86RadioButton; private JCheckBox myUseTempCertificateCheckBox; private JLabel myProvisioningProfileLabel; private TextFieldWithBrowseButton myProvisioningProfileTextWithBrowse; private JLabel myKeystoreFileLabel; private TextFieldWithBrowseButton myKeystoreFileTextWithBrowse; private JLabel myIosSdkLabel; private TextFieldWithBrowseButton myIosSdkTextWithBrowse; private HoverHyperlinkLabel myMoreOptionsHyperlinkLabel; private JLabel myKeystoreTypeLabel; private JTextField myKeystoreTypeTextField; private JLabel myKeyAliasLabel; private JTextField myKeyAliasTextField; private JLabel myProviderClassNameLabel; private JTextField myProviderClassNameTextField; private JLabel myTsaUrlLabel; private JTextField myTsaUrlTextField; private JLabel myAdtOptionsLabel; private RawCommandLineEditor myAdtOptionsComponent; enum Mode {Desktop, Android, iOS} public SigningOptionsForm(final Project project, final Mode mode) { myMode = mode; myUseTempCertificateCheckBox.addActionListener(new ActionListener() { public void actionPerformed(final ActionEvent e) { updateControls(); } }); myProvisioningProfileTextWithBrowse .addBrowseFolderListener(null, null, project, FlexUtils.createFileChooserDescriptor("mobileprovision")); myIosSdkTextWithBrowse .addBrowseFolderListener(null, null, project, FileChooserDescriptorFactory.createSingleFolderDescriptor()); final FileChooserDescriptor d = mode == Mode.iOS ? FlexUtils.createFileChooserDescriptor("p12") : FileChooserDescriptorFactory.createSingleFileNoJarsDescriptor(); myKeystoreFileTextWithBrowse.addBrowseFolderListener(null, null, project, d); myAdtOptionsComponent.setDialogCaption("Additional ADT Options"); myMoreOptionsHyperlinkLabel.setText(MORE_OPTIONS); myMoreOptionsHyperlinkLabel.addHyperlinkListener(new HyperlinkListener() { public void hyperlinkUpdate(HyperlinkEvent e) { if (e.getEventType() == HyperlinkEvent.EventType.ACTIVATED) { showMoreOptions(!isShowingMoreOptions()); } } }); updateMoreOptions(); switch (mode) { case Desktop: myTargetArchitectureLabel.setVisible(false); myArchArmv7RadioButton.setVisible(false); myArchX86RadioButton.setVisible(false); // no break here case Android: myProvisioningProfileLabel.setVisible(false); myProvisioningProfileTextWithBrowse.setVisible(false); myIosSdkLabel.setVisible(false); myIosSdkTextWithBrowse.setVisible(false); myAdtOptionsLabel.setVisible(false); myAdtOptionsComponent.setVisible(false); break; case iOS: myTargetArchitectureLabel.setVisible(false); myArchArmv7RadioButton.setVisible(false); myArchX86RadioButton.setVisible(false); myUseTempCertificateCheckBox.setVisible(false); showMoreOptions(false); myMoreOptionsHyperlinkLabel.setVisible(false); break; } } private void createUIComponents() { myMoreOptionsHyperlinkLabel = new HoverHyperlinkLabel(MORE_OPTIONS); } private void showMoreOptions(final boolean show) { myMoreOptionsHyperlinkLabel.setText(show ? LESS_OPTIONS : MORE_OPTIONS); updateMoreOptions(); } private boolean isShowingMoreOptions() { return myMoreOptionsHyperlinkLabel.getText().contains(LESS_OPTIONS); } private void updateMoreOptions() { final boolean showingMoreOption = isShowingMoreOptions(); myKeystoreTypeLabel.setVisible(showingMoreOption); myKeystoreTypeTextField.setVisible(showingMoreOption); myKeyAliasLabel.setVisible(showingMoreOption); myKeyAliasTextField.setVisible(showingMoreOption); myProviderClassNameLabel.setVisible(showingMoreOption); myProviderClassNameTextField.setVisible(showingMoreOption); myTsaUrlLabel.setVisible(showingMoreOption && myMode != Mode.Android); myTsaUrlTextField.setVisible(showingMoreOption && myMode != Mode.Android); } private void updateControls() { final boolean enabled = !myUseTempCertificateCheckBox.isVisible() || !myUseTempCertificateCheckBox.isSelected(); myProvisioningProfileLabel.setEnabled(enabled); myProviderClassNameTextField.setEnabled(enabled); myKeystoreFileLabel.setEnabled(enabled); myKeystoreFileTextWithBrowse.setEnabled(enabled); myIosSdkLabel.setEnabled(enabled); myIosSdkTextWithBrowse.setEnabled(enabled); myMoreOptionsHyperlinkLabel.setEnabled(enabled); if (myMoreOptionsHyperlinkLabel.isEnabled()) { myMoreOptionsHyperlinkLabel.setForeground(PlatformColors.BLUE); // workaround of JLabel-related workaround at UIUtil.setEnabled(..) } myKeystoreTypeLabel.setEnabled(enabled); myKeystoreTypeTextField.setEnabled(enabled); myKeyAliasLabel.setEnabled(enabled); myKeyAliasTextField.setEnabled(enabled); myProviderClassNameLabel.setEnabled(enabled); myProviderClassNameTextField.setEnabled(enabled); myTsaUrlLabel.setEnabled(enabled); myTsaUrlTextField.setEnabled(enabled); } public void setEnabled(final boolean enabled) { UIUtil.setEnabled(myMainPanel, enabled, true); if (enabled) { updateControls(); } } @NotNull private String getArch() { return myArchX86RadioButton.isSelected() ? AirSigningOptions.ARCH_X86 : AirSigningOptions.ARCH_ARMV7; } public void resetFrom(final AirSigningOptions signingOptions) { if (signingOptions.getArch().equals(AirSigningOptions.ARCH_X86)) { myArchX86RadioButton.setSelected(true); } else { myArchArmv7RadioButton.setSelected(true); } myUseTempCertificateCheckBox.setSelected(signingOptions.isUseTempCertificate()); myProvisioningProfileTextWithBrowse.setText(FileUtil.toSystemDependentName(signingOptions.getProvisioningProfilePath())); myKeystoreFileTextWithBrowse.setText(FileUtil.toSystemDependentName(signingOptions.getKeystorePath())); myIosSdkTextWithBrowse.setText(FileUtil.toSystemDependentName(signingOptions.getIOSSdkPath())); myAdtOptionsComponent.setText(signingOptions.getADTOptions()); myKeystoreTypeTextField.setText(signingOptions.getKeystoreType()); myKeyAliasTextField.setText(signingOptions.getKeyAlias()); myProviderClassNameTextField.setText(signingOptions.getProvider()); myTsaUrlTextField.setText(signingOptions.getTsa()); } public boolean isModified(final AirSigningOptions signingOptions) { if (myTargetArchitectureLabel.isVisible() && !getArch().equals(signingOptions.getArch())) return true; if (myUseTempCertificateCheckBox.isVisible() && myUseTempCertificateCheckBox.isSelected() != signingOptions.isUseTempCertificate()) { return true; } final String profilePath = FileUtil.toSystemIndependentName(myProvisioningProfileTextWithBrowse.getText().trim()); if (myProvisioningProfileTextWithBrowse.isVisible() && !profilePath.equals(signingOptions.getProvisioningProfilePath())) return true; final String keystorePath = FileUtil.toSystemIndependentName(myKeystoreFileTextWithBrowse.getText().trim()); if (!keystorePath.equals(signingOptions.getKeystorePath())) return true; final String iosSdkPath = FileUtil.toSystemIndependentName(myIosSdkTextWithBrowse.getText().trim()); if (myIosSdkTextWithBrowse.isVisible() && !iosSdkPath.equals(signingOptions.getIOSSdkPath())) return true; if (myAdtOptionsComponent.isVisible() && !myAdtOptionsComponent.getText().equals(signingOptions.getADTOptions())) return false; if (!myKeystoreTypeTextField.getText().trim().equals(signingOptions.getKeystoreType())) return true; if (!myKeyAliasTextField.getText().equals(signingOptions.getKeyAlias())) return true; if (!myProviderClassNameTextField.getText().equals(signingOptions.getProvider())) return true; if (!myTsaUrlTextField.getText().equals(signingOptions.getTsa())) return true; return false; } public void applyTo(final AirSigningOptions signingOptions) { signingOptions.setArch(getArch()); signingOptions.setUseTempCertificate(myUseTempCertificateCheckBox.isSelected()); signingOptions.setProvisioningProfilePath(FileUtil.toSystemIndependentName(myProvisioningProfileTextWithBrowse.getText().trim())); signingOptions.setKeystorePath(FileUtil.toSystemIndependentName(myKeystoreFileTextWithBrowse.getText().trim())); signingOptions.setIOSSdkPath(FileUtil.toSystemIndependentName(myIosSdkTextWithBrowse.getText().trim())); signingOptions.setADTOptions(myAdtOptionsComponent.getText().trim()); signingOptions.setKeystoreType(myKeystoreTypeTextField.getText().trim()); signingOptions.setKeyAlias(myKeyAliasTextField.getText()); signingOptions.setProvider(myProviderClassNameTextField.getText()); signingOptions.setTsa(myTsaUrlTextField.getText()); } public ActionCallback navigateTo(final AirPackagingConfigurableBase.Location location) { switch (location) { case ProvisioningProfile: return IdeFocusManager.findInstance().requestFocus(myProvisioningProfileTextWithBrowse.getChildComponent(), true); case Keystore: return IdeFocusManager.findInstance().requestFocus(myKeystoreFileTextWithBrowse.getChildComponent(), true); case IosSdkPath: return IdeFocusManager.findInstance().requestFocus(myIosSdkTextWithBrowse.getTextField(), true); default: return ActionCallback.DONE; } } }