package games.strategy.engine.framework.startup.ui.editors; import java.awt.GridBagConstraints; import java.awt.HeadlessException; import java.awt.Insets; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import javax.swing.JButton; import javax.swing.JCheckBox; import javax.swing.JLabel; import javax.swing.JOptionPane; import javax.swing.JPasswordField; import javax.swing.JTextField; import javax.swing.SwingUtilities; import games.strategy.engine.ClientFileSystemHelper; import games.strategy.engine.framework.startup.ui.MainFrame; import games.strategy.engine.framework.startup.ui.editors.validators.EmailValidator; import games.strategy.engine.framework.startup.ui.editors.validators.IntegerRangeValidator; import games.strategy.engine.pbem.GenericEmailSender; import games.strategy.engine.pbem.IEmailSender; import games.strategy.ui.ProgressWindow; /** * An editor for modifying email senders. */ public class EmailSenderEditor extends EditorPanel { private static final long serialVersionUID = -4647781117491269926L; private final GenericEmailSender m_bean; private final JTextField m_subject = new JTextField(); private final JTextField m_toAddress = new JTextField(); private final JTextField m_host = new JTextField(); private final JTextField m_port = new JTextField(); private final JTextField m_login = new JTextField(); private final JCheckBox m_useTLS = new JCheckBox("Use TLS encryption"); private final JTextField m_password = new JPasswordField(); private final JLabel m_toLabel = new JLabel("To:"); private final JLabel m_hostLabel = new JLabel("Host:"); private final JLabel m_portLabel = new JLabel("Port:"); private final JButton m_testEmail = new JButton("Test Email"); private final JCheckBox m_alsoPostAfterCombatMove = new JCheckBox("Also Post After Combat Move"); /** * creates a new instance. * * @param bean * the EmailSender to edit * @param editorConfiguration * configures which editor fields should be visible */ public EmailSenderEditor(final GenericEmailSender bean, final EditorConfiguration editorConfiguration) { super(); m_bean = bean; m_subject.setText(m_bean.getSubjectPrefix()); m_host.setText(m_bean.getHost()); m_port.setText(String.valueOf(m_bean.getPort())); m_toAddress.setText(m_bean.getToAddress()); m_login.setText(m_bean.getUserName()); m_password.setText(m_bean.getPassword()); m_useTLS.setSelected(m_bean.getEncryption() == GenericEmailSender.Encryption.TLS); final int bottomSpace = 1; final int labelSpace = 2; int row = 0; add(new JLabel("Subject:"), new GridBagConstraints(0, row, 1, 1, 0, 0, GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, new Insets(0, 0, bottomSpace, labelSpace), 0, 0)); add(m_subject, new GridBagConstraints(1, row, 2, 1, 1.0, 0, GridBagConstraints.EAST, GridBagConstraints.HORIZONTAL, new Insets(0, 0, bottomSpace, 0), 0, 0)); row++; add(m_toLabel, new GridBagConstraints(0, row, 1, 1, 0, 0, GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, new Insets(0, 0, bottomSpace, labelSpace), 0, 0)); add(m_toAddress, new GridBagConstraints(1, row, 2, 1, 1.0, 0, GridBagConstraints.EAST, GridBagConstraints.HORIZONTAL, new Insets(0, 0, bottomSpace, 0), 0, 0)); row++; final JLabel m_loginLabel = new JLabel("Login:"); add(m_loginLabel, new GridBagConstraints(0, row, 1, 1, 0, 0, GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, new Insets(0, 0, bottomSpace, labelSpace), 0, 0)); add(m_login, new GridBagConstraints(1, row, 2, 1, 1.0, 0, GridBagConstraints.EAST, GridBagConstraints.HORIZONTAL, new Insets(0, 0, bottomSpace, 0), 0, 0)); row++; final JLabel m_passwordLabel = new JLabel("Password:"); add(m_passwordLabel, new GridBagConstraints(0, row, 1, 1, 0, 0, GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, new Insets(0, 0, bottomSpace, labelSpace), 0, 0)); add(m_password, new GridBagConstraints(1, row, 2, 1, 1.0, 0, GridBagConstraints.EAST, GridBagConstraints.HORIZONTAL, new Insets(0, 0, bottomSpace, 0), 0, 0)); if (editorConfiguration.showHost) { row++; add(m_hostLabel, new GridBagConstraints(0, row, 1, 1, 0, 0, GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, new Insets(0, 0, bottomSpace, labelSpace), 0, 0)); add(m_host, new GridBagConstraints(1, row, 2, 1, 1.0, 0, GridBagConstraints.EAST, GridBagConstraints.HORIZONTAL, new Insets(0, 0, bottomSpace, 0), 0, 0)); } if (editorConfiguration.showPort) { row++; add(m_portLabel, new GridBagConstraints(0, row, 1, 1, 0, 0, GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, new Insets(0, 0, bottomSpace, labelSpace), 0, 0)); add(m_port, new GridBagConstraints(1, row, 2, 1, 0, 0, GridBagConstraints.EAST, GridBagConstraints.HORIZONTAL, new Insets(0, 0, bottomSpace, 0), 0, 0)); } if (editorConfiguration.showEncryption) { row++; add(m_useTLS, new GridBagConstraints(0, row, 2, 1, 0, 0, GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, new Insets(0, 0, bottomSpace, 0), 0, 0)); // add Test button on the same line as encryption add(m_testEmail, new GridBagConstraints(2, row, 1, 1, 0, 0, GridBagConstraints.EAST, GridBagConstraints.NONE, new Insets(0, 0, bottomSpace, 0), 0, 0)); row++; add(m_alsoPostAfterCombatMove, new GridBagConstraints(0, row, 2, 1, 0, 0, GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, new Insets(0, 0, bottomSpace, 0), 0, 0)); } else { row++; add(m_alsoPostAfterCombatMove, new GridBagConstraints(0, row, 2, 1, 0, 0, GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, new Insets(0, 0, bottomSpace, 0), 0, 0)); add(m_testEmail, new GridBagConstraints(2, row, 1, 1, 0, 0, GridBagConstraints.EAST, GridBagConstraints.NONE, new Insets(0, 0, bottomSpace, 0), 0, 0)); // or on a separate line if no encryption // add(m_testEmail, new GridBagConstraints(1, row, 3, 1, 0, 0, GridBagConstraints.EAST, GridBagConstraints.NONE, // new Insets(0, 0, // bottomSpace, 0), 0, 0)); } setupListeners(); } private void setupListeners() { final EditorChangedFiringDocumentListener listener = new EditorChangedFiringDocumentListener(); m_host.getDocument().addDocumentListener(listener); m_login.getDocument().addDocumentListener(listener); m_port.getDocument().addDocumentListener(listener); m_password.getDocument().addDocumentListener(listener); m_toAddress.getDocument().addDocumentListener(listener); m_useTLS.addActionListener(e -> fireEditorChanged()); m_testEmail.addActionListener(e -> testEmail()); } /** * Tests the email sender. This must be called from the swing event thread */ private void testEmail() { final ProgressWindow progressWindow = new ProgressWindow(MainFrame.getInstance(), "Sending test email..."); progressWindow.setVisible(true); final Runnable runnable = () -> { // initialize variables to error state, override if successful String message = "An unknown occurred, report this as a bug on the TripleA dev forum"; int messageType = JOptionPane.ERROR_MESSAGE; try { final String html = "<html><body><h1>Success</h1><p>This was a test email sent by TripleA<p></body></html>"; final File dummy = new File(ClientFileSystemHelper.getUserRootFolder(), "dummySave.txt"); dummy.deleteOnExit(); final FileOutputStream fout = new FileOutputStream(dummy); fout.write("This file would normally be a save game".getBytes()); fout.close(); ((IEmailSender) getBean()).sendEmail("TripleA Test", html, dummy, "dummy.txt"); // email was sent, or an exception would have been thrown message = "Email sent, it should arrive shortly, otherwise check your spam folder"; messageType = JOptionPane.INFORMATION_MESSAGE; } catch (final IOException ioe) { message = "Unable to send email: " + ioe.getMessage(); } finally { // now that we have a result, marshall it back unto the swing thread final String finalMessage = message; final int finalMessageType = messageType; SwingUtilities.invokeLater(() -> { try { JOptionPane.showMessageDialog(MainFrame.getInstance(), finalMessage, "Email Test", finalMessageType); } catch (final HeadlessException e) { // should never happen in a GUI app } }); progressWindow.setVisible(false); } }; // start a background thread final Thread t = new Thread(runnable); t.start(); } @Override public boolean isBeanValid() { final boolean hostValid = validateTextFieldNotEmpty(m_host, m_hostLabel); final boolean portValid = validateTextField(m_port, m_portLabel, new IntegerRangeValidator(0, 65635)); // boolean loginValid = validateTextFieldNotEmpty(m_login, m_loginLabel); // boolean passwordValid = validateTextFieldNotEmpty(m_password, m_passwordLabel); final boolean addressValid = validateTextField(m_toAddress, m_toLabel, new EmailValidator(false)); final boolean allValid = hostValid && portValid && /* loginValid && passwordValid && */addressValid; m_testEmail.setEnabled(allValid); return allValid; } @Override public IBean getBean() { m_bean .setEncryption(m_useTLS.isSelected() ? GenericEmailSender.Encryption.TLS : GenericEmailSender.Encryption.NONE); m_bean.setSubjectPrefix(m_subject.getText()); m_bean.setHost(m_host.getText()); m_bean.setUserName(m_login.getText()); m_bean.setPassword(m_password.getText()); int port = 0; try { port = Integer.parseInt(m_port.getText()); } catch (final NumberFormatException e) { // ignore } m_bean.setPort(port); m_bean.setToAddress(m_toAddress.getText()); m_bean.setAlsoPostAfterCombatMove(m_alsoPostAfterCombatMove.isSelected()); return m_bean; } /** * class for configuring the editor so some fields can be hidden. */ public static class EditorConfiguration { public boolean showHost; public boolean showPort; public boolean showEncryption; public EditorConfiguration() {} public EditorConfiguration(final boolean showHost, final boolean showPort, final boolean showEncryption) { this.showHost = showHost; this.showPort = showPort; this.showEncryption = showEncryption; } } }