View Javadoc
1   /*
2    * DavMail POP/IMAP/SMTP/CalDav/LDAP Exchange Gateway
3    * Copyright (C) 2009  Mickael Guessant
4    *
5    * This program is free software; you can redistribute it and/or
6    * modify it under the terms of the GNU General Public License
7    * as published by the Free Software Foundation; either version 2
8    * of the License, or (at your option) any later version.
9    *
10   * This program is distributed in the hope that it will be useful,
11   * but WITHOUT ANY WARRANTY; without even the implied warranty of
12   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13   * GNU General Public License for more details.
14   *
15   * You should have received a copy of the GNU General Public License
16   * along with this program; if not, write to the Free Software
17   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
18   */
19  package davmail.ui;
20  
21  import davmail.BundleMessage;
22  import davmail.DavGateway;
23  import davmail.Settings;
24  import davmail.ui.browser.DesktopBrowser;
25  import davmail.ui.tray.DavGatewayTray;
26  import org.apache.log4j.Level;
27  
28  import javax.swing.*;
29  import java.awt.*;
30  import java.awt.event.ActionEvent;
31  import java.awt.event.ActionListener;
32  
33  /**
34   * DavMail settings frame
35   */
36  public class SettingsFrame extends JFrame {
37      static final Level[] LOG_LEVELS = {Level.OFF, Level.FATAL, Level.ERROR, Level.WARN, Level.INFO, Level.DEBUG, Level.ALL};
38  
39      protected JTextField urlField;
40      protected JTextField popPortField;
41      protected JCheckBox popPortCheckBox;
42      protected JCheckBox popNoSSLCheckBox;
43      protected JTextField imapPortField;
44      protected JCheckBox imapPortCheckBox;
45      protected JCheckBox imapNoSSLCheckBox;
46      protected JTextField smtpPortField;
47      protected JCheckBox smtpPortCheckBox;
48      protected JCheckBox smtpNoSSLCheckBox;
49      protected JTextField caldavPortField;
50      protected JCheckBox caldavPortCheckBox;
51      protected JCheckBox caldavNoSSLCheckBox;
52      protected JTextField ldapPortField;
53      protected JCheckBox ldapPortCheckBox;
54      protected JCheckBox ldapNoSSLCheckBox;
55      protected JTextField keepDelayField;
56      protected JTextField sentKeepDelayField;
57      protected JTextField caldavPastDelayField;
58      protected JCheckBox caldavAutoScheduleCheckBox;
59      protected JTextField imapIdleDelayField;
60  
61      protected JCheckBox useSystemProxiesField;
62      protected JCheckBox enableProxyField;
63      protected JTextField httpProxyField;
64      protected JTextField httpProxyPortField;
65      protected JTextField httpProxyUserField;
66      protected JTextField httpProxyPasswordField;
67      protected JTextField noProxyForField;
68  
69      protected JCheckBox allowRemoteField;
70      protected JTextField bindAddressField;
71      protected JTextField clientSoTimeoutField;
72      protected JTextField certHashField;
73      protected JCheckBox disableUpdateCheck;
74  
75      protected JComboBox<String> keystoreTypeCombo;
76      protected JTextField keystoreFileField;
77      protected JPasswordField keystorePassField;
78      protected JPasswordField keyPassField;
79  
80      protected JComboBox<String> clientKeystoreTypeCombo;
81      protected JTextField clientKeystoreFileField;
82      protected JPasswordField clientKeystorePassField;
83      protected JTextField pkcs11LibraryField;
84      protected JTextArea pkcs11ConfigField;
85  
86      protected JComboBox<Level> rootLoggingLevelField;
87      protected JComboBox<Level> davmailLoggingLevelField;
88      protected JComboBox<Level> httpclientLoggingLevelField;
89      protected JComboBox<Level> wireLoggingLevelField;
90      protected JTextField logFilePathField;
91      protected JTextField logFileSizeField;
92  
93      protected JCheckBox caldavEditNotificationsField;
94      protected JTextField caldavAlarmSoundField;
95      protected JCheckBox forceActiveSyncUpdateCheckBox;
96      protected JTextField defaultDomainField;
97      protected JCheckBox showStartupBannerCheckBox;
98      protected JCheckBox disableGuiNotificationsCheckBox;
99      protected JCheckBox disableTrayActivitySwitchCheckBox;
100 
101     protected JCheckBox imapAutoExpungeCheckBox;
102     protected JCheckBox enableKeepAliveCheckBox;
103     protected JCheckBox popMarkReadOnRetrCheckBox;
104     protected JComboBox<String> modeComboBox;
105     protected JCheckBox enableKerberosCheckBox;
106     protected JTextField folderSizeLimitField;
107     protected JCheckBox smtpSaveInSentCheckBox;
108     protected JCheckBox imapAlwaysApproxMsgSizeCheckBox;
109 
110     protected JTextField oauthTenantIdField;
111     protected JTextField oauthClientIdField;
112     protected JTextField oauthRedirectUriField;
113     protected JTextField oauthTldField;
114 
115     JCheckBox osxHideFromDockCheckBox;
116 
117     protected void addSettingComponent(JPanel panel, String label, JComponent component) {
118         addSettingComponent(panel, label, component, null);
119     }
120 
121     protected JLabel buildFieldLabel(String label, String toolTipText) {
122         JLabel fieldLabel = new JLabel(label);
123         fieldLabel.setHorizontalAlignment(SwingConstants.RIGHT);
124         fieldLabel.setVerticalAlignment(SwingConstants.CENTER);
125         if (toolTipText != null) {
126             fieldLabel.setToolTipText(toolTipText);
127         }
128         return fieldLabel;
129     }
130 
131     protected void addSettingComponent(JPanel panel, String label, JComponent component, String toolTipText) {
132         panel.add(buildFieldLabel(label, toolTipText));
133 
134         component.setMaximumSize(component.getPreferredSize());
135         JPanel innerPanel = new JPanel();
136         innerPanel.setBorder(BorderFactory.createEmptyBorder(1,0,0,0));
137         innerPanel.setLayout(new BoxLayout(innerPanel, BoxLayout.X_AXIS));
138         innerPanel.add(component);
139         panel.add(innerPanel);
140         if (toolTipText != null) {
141             component.setToolTipText(toolTipText);
142         }
143     }
144 
145     protected void addPortSettingComponent(JPanel panel, String label, JComponent component, JComponent checkboxComponent, JComponent checkboxSSLComponent, String toolTipText) {
146         panel.add(buildFieldLabel(label, toolTipText));
147         component.setMaximumSize(component.getPreferredSize());
148         JPanel innerPanel = new JPanel();
149         innerPanel.setLayout(new BoxLayout(innerPanel, BoxLayout.X_AXIS));
150         innerPanel.add(checkboxComponent);
151         innerPanel.add(component);
152         innerPanel.add(checkboxSSLComponent);
153         panel.add(innerPanel);
154         if (toolTipText != null) {
155             component.setToolTipText(toolTipText);
156         }
157     }
158 
159     protected JPanel getSettingsPanel() {
160         JPanel settingsPanel = new JPanel(new GridLayout(7, 2));
161         settingsPanel.setBorder(BorderFactory.createTitledBorder(BundleMessage.format("UI_GATEWAY")));
162 
163         modeComboBox = new JComboBox<>();
164         modeComboBox.addItem(Settings.EWS);
165         modeComboBox.addItem(Settings.O365);
166         modeComboBox.addItem(Settings.O365_MODERN);
167         modeComboBox.addItem(Settings.O365_INTERACTIVE);
168         modeComboBox.addItem(Settings.O365_MANUAL);
169         modeComboBox.addItem(Settings.WEBDAV);
170         modeComboBox.addItem(Settings.AUTO);
171         modeComboBox.setSelectedItem(Settings.getProperty("davmail.mode", Settings.EWS));
172         modeComboBox.addActionListener(evt -> {
173             String selectedItem = (String)modeComboBox.getSelectedItem();
174             modeComboBox.setToolTipText(BundleMessage.format("UI_"+selectedItem+"_HELP"));
175             if (selectedItem != null && selectedItem.startsWith("O365")) {
176                 urlField.setEnabled(false);
177                 urlField.setText(Settings.getO365Url());
178             } else {
179                 urlField.setEnabled(true);
180             }
181         });
182         urlField = new JTextField(Settings.getProperty("davmail.url", Settings.getO365Url()), 20);
183         popPortField = new JTextField(Settings.getProperty("davmail.popPort"), 4);
184         popPortCheckBox = new JCheckBox();
185         popNoSSLCheckBox = new JCheckBox(BundleMessage.format("UI_NO_SSL"), Settings.getBooleanProperty("davmail.ssl.nosecurepop"));
186         popPortCheckBox.setSelected(Settings.getProperty("davmail.popPort") != null && !Settings.getProperty("davmail.popPort").isEmpty());
187         popPortField.setEnabled(popPortCheckBox.isSelected());
188         popNoSSLCheckBox.setEnabled(popPortCheckBox.isSelected() && isSslEnabled());
189         popPortCheckBox.addActionListener(evt -> {
190             popPortField.setEnabled(popPortCheckBox.isSelected());
191             popNoSSLCheckBox.setEnabled(popPortCheckBox.isSelected() && isSslEnabled());
192         });
193 
194         imapPortField = new JTextField(Settings.getProperty("davmail.imapPort"), 4);
195         imapPortCheckBox = new JCheckBox();
196         imapNoSSLCheckBox = new JCheckBox(BundleMessage.format("UI_NO_SSL"), Settings.getBooleanProperty("davmail.ssl.nosecureimap"));
197         imapPortCheckBox.setSelected(Settings.getProperty("davmail.imapPort") != null && !Settings.getProperty("davmail.imapPort").isEmpty());
198         imapPortField.setEnabled(imapPortCheckBox.isSelected());
199         imapNoSSLCheckBox.setEnabled(imapPortCheckBox.isSelected() && isSslEnabled());
200         imapPortCheckBox.addActionListener(evt -> {
201             imapPortField.setEnabled(imapPortCheckBox.isSelected());
202             imapNoSSLCheckBox.setEnabled(imapPortCheckBox.isSelected() && isSslEnabled());
203         });
204 
205         smtpPortField = new JTextField(Settings.getProperty("davmail.smtpPort"), 4);
206         smtpPortCheckBox = new JCheckBox();
207         smtpNoSSLCheckBox = new JCheckBox(BundleMessage.format("UI_NO_SSL"), Settings.getBooleanProperty("davmail.ssl.nosecuresmtp"));
208         smtpPortCheckBox.setSelected(Settings.getProperty("davmail.smtpPort") != null && !Settings.getProperty("davmail.smtpPort").isEmpty());
209         smtpPortField.setEnabled(smtpPortCheckBox.isSelected());
210         smtpNoSSLCheckBox.setEnabled(smtpPortCheckBox.isSelected() && isSslEnabled());
211         smtpPortCheckBox.addActionListener(evt -> {
212             smtpPortField.setEnabled(smtpPortCheckBox.isSelected());
213             smtpNoSSLCheckBox.setEnabled(smtpPortCheckBox.isSelected() && isSslEnabled());
214         });
215 
216         caldavPortField = new JTextField(Settings.getProperty("davmail.caldavPort"), 4);
217         caldavPortCheckBox = new JCheckBox();
218         caldavNoSSLCheckBox = new JCheckBox(BundleMessage.format("UI_NO_SSL"), Settings.getBooleanProperty("davmail.ssl.nosecurecaldav"));
219         caldavPortCheckBox.setSelected(Settings.getProperty("davmail.caldavPort") != null && !Settings.getProperty("davmail.caldavPort").isEmpty());
220         caldavPortField.setEnabled(caldavPortCheckBox.isSelected());
221         caldavNoSSLCheckBox.setEnabled(caldavPortCheckBox.isSelected() && isSslEnabled());
222         caldavPortCheckBox.addActionListener(evt -> {
223             caldavPortField.setEnabled(caldavPortCheckBox.isSelected());
224             caldavNoSSLCheckBox.setEnabled(caldavPortCheckBox.isSelected() && isSslEnabled());
225         });
226 
227         ldapPortField = new JTextField(Settings.getProperty("davmail.ldapPort"), 4);
228         ldapPortCheckBox = new JCheckBox();
229         ldapNoSSLCheckBox = new JCheckBox(BundleMessage.format("UI_NO_SSL"), Settings.getBooleanProperty("davmail.ssl.nosecureldap"));
230         ldapPortCheckBox.setSelected(Settings.getProperty("davmail.ldapPort") != null && !Settings.getProperty("davmail.ldapPort").isEmpty());
231         ldapPortField.setEnabled(ldapPortCheckBox.isSelected());
232         ldapNoSSLCheckBox.setEnabled(ldapPortCheckBox.isSelected() && isSslEnabled());
233         ldapPortCheckBox.addActionListener(evt -> {
234             ldapPortField.setEnabled(ldapPortCheckBox.isSelected());
235             ldapNoSSLCheckBox.setEnabled(ldapPortCheckBox.isSelected() && isSslEnabled());
236         });
237 
238         addSettingComponent(settingsPanel, BundleMessage.format("UI_ENABLE_EWS"), modeComboBox,
239                 BundleMessage.format("UI_ENABLE_EWS_HELP"));
240         addSettingComponent(settingsPanel, BundleMessage.format("UI_OWA_URL"), urlField, BundleMessage.format("UI_OWA_URL_HELP"));
241         addPortSettingComponent(settingsPanel, BundleMessage.format("UI_POP_PORT"), popPortField, popPortCheckBox,
242                 popNoSSLCheckBox, BundleMessage.format("UI_POP_PORT_HELP"));
243         addPortSettingComponent(settingsPanel, BundleMessage.format("UI_IMAP_PORT"), imapPortField, imapPortCheckBox,
244                 imapNoSSLCheckBox, BundleMessage.format("UI_IMAP_PORT_HELP"));
245         addPortSettingComponent(settingsPanel, BundleMessage.format("UI_SMTP_PORT"), smtpPortField, smtpPortCheckBox,
246                 smtpNoSSLCheckBox, BundleMessage.format("UI_SMTP_PORT_HELP"));
247         addPortSettingComponent(settingsPanel, BundleMessage.format("UI_CALDAV_PORT"), caldavPortField, caldavPortCheckBox,
248                 caldavNoSSLCheckBox, BundleMessage.format("UI_CALDAV_PORT_HELP"));
249         addPortSettingComponent(settingsPanel, BundleMessage.format("UI_LDAP_PORT"), ldapPortField, ldapPortCheckBox,
250                 ldapNoSSLCheckBox, BundleMessage.format("UI_LDAP_PORT_HELP"));
251         return settingsPanel;
252     }
253 
254     protected JPanel getDelaysPanel() {
255         JPanel delaysPanel = new JPanel(new GridLayout(4, 2));
256         delaysPanel.setBorder(BorderFactory.createTitledBorder(BundleMessage.format("UI_DELAYS")));
257 
258         keepDelayField = new JTextField(Settings.getProperty("davmail.keepDelay"), 4);
259         sentKeepDelayField = new JTextField(Settings.getProperty("davmail.sentKeepDelay"), 4);
260         caldavPastDelayField = new JTextField(Settings.getProperty("davmail.caldavPastDelay"), 4);
261         imapIdleDelayField = new JTextField(Settings.getProperty("davmail.imapIdleDelay"), 4);
262 
263         addSettingComponent(delaysPanel, BundleMessage.format("UI_KEEP_DELAY"), keepDelayField,
264                 BundleMessage.format("UI_KEEP_DELAY_HELP"));
265         addSettingComponent(delaysPanel, BundleMessage.format("UI_SENT_KEEP_DELAY"), sentKeepDelayField,
266                 BundleMessage.format("UI_SENT_KEEP_DELAY_HELP"));
267         addSettingComponent(delaysPanel, BundleMessage.format("UI_CALENDAR_PAST_EVENTS"), caldavPastDelayField,
268                 BundleMessage.format("UI_CALENDAR_PAST_EVENTS_HELP"));
269         addSettingComponent(delaysPanel, BundleMessage.format("UI_IMAP_IDLE_DELAY"), imapIdleDelayField,
270                 BundleMessage.format("UI_IMAP_IDLE_DELAY_HELP"));
271         return delaysPanel;
272     }
273 
274     protected JPanel getProxyPanel() {
275         JPanel proxyPanel = new JPanel(new GridLayout(7, 2));
276         proxyPanel.setBorder(BorderFactory.createTitledBorder(BundleMessage.format("UI_PROXY")));
277 
278         boolean useSystemProxies = Settings.getBooleanProperty("davmail.useSystemProxies", Boolean.FALSE);
279         boolean enableProxy = Settings.getBooleanProperty("davmail.enableProxy");
280         useSystemProxiesField = new JCheckBox();
281         useSystemProxiesField.setSelected(useSystemProxies);
282         enableProxyField = new JCheckBox();
283         enableProxyField.setSelected(enableProxy);
284         httpProxyField = new JTextField(Settings.getProperty("davmail.proxyHost"), 15);
285         httpProxyPortField = new JTextField(Settings.getProperty("davmail.proxyPort"), 4);
286         httpProxyUserField = new JTextField(Settings.getProperty("davmail.proxyUser"), 10);
287         httpProxyPasswordField = new JPasswordField(Settings.getProperty("davmail.proxyPassword"), 10);
288         noProxyForField = new JTextField(Settings.getProperty("davmail.noProxyFor"), 15);
289 
290         enableProxyField.setEnabled(!useSystemProxies);
291         httpProxyField.setEnabled(enableProxy);
292         httpProxyPortField.setEnabled(enableProxy);
293         httpProxyUserField.setEnabled(enableProxy || useSystemProxies);
294         httpProxyPasswordField.setEnabled(enableProxy || useSystemProxies);
295         noProxyForField.setEnabled(enableProxy);
296 
297         useSystemProxiesField.addActionListener(evt -> {
298             boolean newUseSystemProxies = useSystemProxiesField.isSelected();
299             if (newUseSystemProxies) {
300                 enableProxyField.setSelected(false);
301                 enableProxyField.setEnabled(false);
302                 httpProxyField.setEnabled(false);
303                 httpProxyPortField.setEnabled(false);
304                 httpProxyUserField.setEnabled(true);
305                 httpProxyPasswordField.setEnabled(true);
306                 noProxyForField.setEnabled(false);
307             } else {
308                 enableProxyField.setEnabled(true);
309                 httpProxyUserField.setEnabled(false);
310                 httpProxyPasswordField.setEnabled(false);
311             }
312         });
313         enableProxyField.addActionListener(evt -> {
314             boolean newEnableProxy = enableProxyField.isSelected();
315             httpProxyField.setEnabled(newEnableProxy);
316             httpProxyPortField.setEnabled(newEnableProxy);
317             httpProxyUserField.setEnabled(newEnableProxy);
318             httpProxyPasswordField.setEnabled(newEnableProxy);
319             noProxyForField.setEnabled(newEnableProxy);
320         });
321 
322         addSettingComponent(proxyPanel, BundleMessage.format("UI_USE_SYSTEM_PROXIES"), useSystemProxiesField);
323         addSettingComponent(proxyPanel, BundleMessage.format("UI_ENABLE_PROXY"), enableProxyField);
324         addSettingComponent(proxyPanel, BundleMessage.format("UI_PROXY_SERVER"), httpProxyField);
325         addSettingComponent(proxyPanel, BundleMessage.format("UI_PROXY_PORT"), httpProxyPortField);
326         addSettingComponent(proxyPanel, BundleMessage.format("UI_PROXY_USER"), httpProxyUserField);
327         addSettingComponent(proxyPanel, BundleMessage.format("UI_PROXY_PASSWORD"), httpProxyPasswordField);
328         addSettingComponent(proxyPanel, BundleMessage.format("UI_NO_PROXY"), noProxyForField);
329         updateMaximumSize(proxyPanel);
330         return proxyPanel;
331     }
332 
333     protected JPanel getKeystorePanel() {
334         JPanel keyStorePanel = new JPanel(new GridLayout(4, 2));
335         keyStorePanel.setBorder(BorderFactory.createTitledBorder(BundleMessage.format("UI_DAVMAIL_SERVER_CERTIFICATE")));
336 
337         keystoreTypeCombo = new JComboBox<>(new String[]{"JKS", "PKCS12"});
338         keystoreTypeCombo.setSelectedItem(Settings.getProperty("davmail.ssl.keystoreType"));
339         keystoreFileField = new JTextField(Settings.getProperty("davmail.ssl.keystoreFile"), 20);
340         keystorePassField = new JPasswordField(Settings.getProperty("davmail.ssl.keystorePass"), 20);
341         keyPassField = new JPasswordField(Settings.getProperty("davmail.ssl.keyPass"), 20);
342 
343         addSettingComponent(keyStorePanel, BundleMessage.format("UI_KEY_STORE_TYPE"), keystoreTypeCombo,
344                 BundleMessage.format("UI_KEY_STORE_TYPE_HELP"));
345         addSettingComponent(keyStorePanel, BundleMessage.format("UI_KEY_STORE"), keystoreFileField,
346                 BundleMessage.format("UI_KEY_STORE_HELP"));
347         addSettingComponent(keyStorePanel, BundleMessage.format("UI_KEY_STORE_PASSWORD"), keystorePassField,
348                 BundleMessage.format("UI_KEY_STORE_PASSWORD_HELP"));
349         addSettingComponent(keyStorePanel, BundleMessage.format("UI_KEY_PASSWORD"), keyPassField,
350                 BundleMessage.format("UI_KEY_PASSWORD_HELP"));
351         updateMaximumSize(keyStorePanel);
352         return keyStorePanel;
353     }
354 
355     protected JPanel getSmartCardPanel() {
356         JPanel clientKeystorePanel = new JPanel(new GridLayout(2, 1));
357         clientKeystorePanel.setLayout(new BoxLayout(clientKeystorePanel, BoxLayout.Y_AXIS));
358         clientKeystorePanel.setBorder(BorderFactory.createTitledBorder(BundleMessage.format("UI_CLIENT_CERTIFICATE")));
359 
360         if (System.getProperty("os.name").toLowerCase().startsWith("windows")) {
361             clientKeystoreTypeCombo = new JComboBox<>(new String[]{"MSCAPI", "PKCS11", "JKS", "PKCS12"});
362         } else {
363             clientKeystoreTypeCombo = new JComboBox<>(new String[]{"PKCS11", "JKS", "PKCS12"});
364         }
365         clientKeystoreTypeCombo.setSelectedItem(Settings.getProperty("davmail.ssl.clientKeystoreType"));
366         clientKeystoreFileField = new JTextField(Settings.getProperty("davmail.ssl.clientKeystoreFile"), 20);
367         clientKeystorePassField = new JPasswordField(Settings.getProperty("davmail.ssl.clientKeystorePass"), 20);
368 
369         pkcs11LibraryField = new JTextField(Settings.getProperty("davmail.ssl.pkcs11Library"), 20);
370         pkcs11ConfigField = new JTextArea(2, 20);
371         pkcs11ConfigField.setText(Settings.getProperty("davmail.ssl.pkcs11Config"));
372         pkcs11ConfigField.setBorder(pkcs11LibraryField.getBorder());
373         pkcs11ConfigField.setFont(pkcs11LibraryField.getFont());
374 
375         JPanel clientKeystoreTypePanel = new JPanel(new GridLayout(1, 2));
376         addSettingComponent(clientKeystoreTypePanel, BundleMessage.format("UI_CLIENT_KEY_STORE_TYPE"), clientKeystoreTypeCombo,
377                 BundleMessage.format("UI_CLIENT_KEY_STORE_TYPE_HELP"));
378         clientKeystorePanel.add(clientKeystoreTypePanel);
379 
380         final JPanel cardPanel = new JPanel(new CardLayout());
381         clientKeystorePanel.add(cardPanel);
382 
383         JPanel clientKeystoreFilePanel = new JPanel(new GridLayout(2, 2));
384         addSettingComponent(clientKeystoreFilePanel, BundleMessage.format("UI_CLIENT_KEY_STORE"), clientKeystoreFileField,
385                 BundleMessage.format("UI_CLIENT_KEY_STORE_HELP"));
386         addSettingComponent(clientKeystoreFilePanel, BundleMessage.format("UI_CLIENT_KEY_STORE_PASSWORD"), clientKeystorePassField,
387                 BundleMessage.format("UI_CLIENT_KEY_STORE_PASSWORD_HELP"));
388         JPanel wrapperPanel = new JPanel();
389         wrapperPanel.add(clientKeystoreFilePanel);
390         cardPanel.add(wrapperPanel, "FILE");
391 
392         JPanel pkcs11Panel = new JPanel(new GridLayout(2, 2));
393         addSettingComponent(pkcs11Panel, BundleMessage.format("UI_PKCS11_LIBRARY"), pkcs11LibraryField,
394                 BundleMessage.format("UI_PKCS11_LIBRARY_HELP"));
395         addSettingComponent(pkcs11Panel, BundleMessage.format("UI_PKCS11_CONFIG"), pkcs11ConfigField,
396                 BundleMessage.format("UI_PKCS11_CONFIG_HELP"));
397         cardPanel.add(pkcs11Panel, "PKCS11");
398 
399         ((CardLayout) cardPanel.getLayout()).show(cardPanel, (String) clientKeystoreTypeCombo.getSelectedItem());
400 
401         clientKeystoreTypeCombo.addItemListener(event -> {
402             CardLayout cardLayout = (CardLayout) (cardPanel.getLayout());
403             if ("PKCS11".equals(event.getItem())) {
404                 cardLayout.show(cardPanel, "PKCS11");
405             } else {
406                 cardLayout.show(cardPanel, "FILE");
407             }
408         });
409         updateMaximumSize(clientKeystorePanel);
410         return clientKeystorePanel;
411     }
412 
413     protected JPanel getOauthPanel() {
414         JPanel oAuthPanel = new JPanel(new GridLayout(4, 2));
415         oAuthPanel.setBorder(BorderFactory.createTitledBorder(BundleMessage.format("UI_OAUTH")));
416 
417         oauthTenantIdField = new JTextField(Settings.getProperty("davmail.oauth.tenantId"), 20);
418         oauthClientIdField = new JTextField(Settings.getProperty("davmail.oauth.clientId"), 20);
419         oauthRedirectUriField = new JTextField(Settings.getProperty("davmail.oauth.redirectUri"), 20);
420         oauthTldField = new JTextField(Settings.getProperty("davmail.tld"), 20);
421 
422         addSettingComponent(oAuthPanel, BundleMessage.format("UI_OAUTH_TENANTID"), oauthTenantIdField,
423                 BundleMessage.format("UI_OAUTH_TENANTID_HELP"));
424         addSettingComponent(oAuthPanel, BundleMessage.format("UI_OAUTH_CLIENTID"), oauthClientIdField,
425                 BundleMessage.format("UI_OAUTH_CLIENTID_HELP"));
426         addSettingComponent(oAuthPanel, BundleMessage.format("UI_OAUTH_REDIRECTURI"), oauthRedirectUriField,
427                 BundleMessage.format("UI_OAUTH_REDIRECTURI_HELP"));
428         addSettingComponent(oAuthPanel, BundleMessage.format("UI_OAUTH_TLD"), oauthTldField,
429                 BundleMessage.format("UI_OAUTH_TLD_HELP"));
430         updateMaximumSize(oAuthPanel);
431         return oAuthPanel;
432     }
433 
434     protected JPanel getNetworkSettingsPanel() {
435         JPanel networkSettingsPanel = new JPanel(new GridLayout(4, 2));
436         networkSettingsPanel.setBorder(BorderFactory.createTitledBorder(BundleMessage.format("UI_NETWORK")));
437 
438         allowRemoteField = new JCheckBox();
439         allowRemoteField.setSelected(Settings.getBooleanProperty("davmail.allowRemote"));
440 
441         bindAddressField = new JTextField(Settings.getProperty("davmail.bindAddress"), 15);
442         clientSoTimeoutField = new JTextField(Settings.getProperty("davmail.clientSoTimeout"), 15);
443 
444         certHashField = new JTextField(Settings.getProperty("davmail.server.certificate.hash"), 15);
445 
446         addSettingComponent(networkSettingsPanel, BundleMessage.format("UI_BIND_ADDRESS"), bindAddressField,
447                 BundleMessage.format("UI_BIND_ADDRESS_HELP"));
448         addSettingComponent(networkSettingsPanel, BundleMessage.format("UI_CLIENT_SO_TIMEOUT"), clientSoTimeoutField,
449                 BundleMessage.format("UI_CLIENT_SO_TIMEOUT_HELP"));
450         addSettingComponent(networkSettingsPanel, BundleMessage.format("UI_ALLOW_REMOTE_CONNECTION"), allowRemoteField,
451                 BundleMessage.format("UI_ALLOW_REMOTE_CONNECTION_HELP"));
452         addSettingComponent(networkSettingsPanel, BundleMessage.format("UI_SERVER_CERTIFICATE_HASH"), certHashField,
453                 BundleMessage.format("UI_SERVER_CERTIFICATE_HASH_HELP"));
454         updateMaximumSize(networkSettingsPanel);
455         return networkSettingsPanel;
456     }
457 
458     protected JPanel getOtherSettingsPanel() {
459         JPanel otherSettingsPanel = new JPanel(new GridLayout(16, 2));
460         otherSettingsPanel.setBorder(BorderFactory.createTitledBorder(BundleMessage.format("UI_OTHER")));
461 
462         folderSizeLimitField = new JTextField(Settings.getProperty("davmail.folderSizeLimit"), 6);
463         enableKerberosCheckBox = new JCheckBox();
464         enableKerberosCheckBox.setSelected(Settings.getBooleanProperty("davmail.enableKerberos"));
465         caldavEditNotificationsField = new JCheckBox();
466         caldavEditNotificationsField.setSelected(Settings.getBooleanProperty("davmail.caldavEditNotifications"));
467         caldavAlarmSoundField = new JTextField(Settings.getProperty("davmail.caldavAlarmSound"), 15);
468         forceActiveSyncUpdateCheckBox = new JCheckBox();
469         forceActiveSyncUpdateCheckBox.setSelected(Settings.getBooleanProperty("davmail.forceActiveSyncUpdate"));
470         defaultDomainField = new JTextField(Settings.getProperty("davmail.defaultDomain"), 15);
471         showStartupBannerCheckBox = new JCheckBox();
472         showStartupBannerCheckBox.setSelected(Settings.getBooleanProperty("davmail.showStartupBanner", true));
473         disableGuiNotificationsCheckBox = new JCheckBox();
474         disableGuiNotificationsCheckBox.setSelected(Settings.getBooleanProperty("davmail.disableGuiNotifications", false));
475         disableTrayActivitySwitchCheckBox =  new JCheckBox();
476         disableTrayActivitySwitchCheckBox.setSelected(Settings.getBooleanProperty("davmail.disableTrayActivitySwitch", false));
477         imapAutoExpungeCheckBox = new JCheckBox();
478         imapAutoExpungeCheckBox.setSelected(Settings.getBooleanProperty("davmail.imapAutoExpunge", true));
479         imapAlwaysApproxMsgSizeCheckBox = new JCheckBox();
480         imapAlwaysApproxMsgSizeCheckBox.setSelected(Settings.getBooleanProperty("davmail.imapAlwaysApproxMsgSize", false));
481         enableKeepAliveCheckBox = new JCheckBox();
482         enableKeepAliveCheckBox.setSelected(Settings.getBooleanProperty("davmail.enableKeepAlive", false));
483         popMarkReadOnRetrCheckBox = new JCheckBox();
484         popMarkReadOnRetrCheckBox.setSelected(Settings.getBooleanProperty("davmail.popMarkReadOnRetr", false));
485         smtpSaveInSentCheckBox = new JCheckBox();
486         smtpSaveInSentCheckBox.setSelected(Settings.getBooleanProperty("davmail.smtpSaveInSent", true));
487         disableUpdateCheck = new JCheckBox();
488         disableUpdateCheck.setSelected(Settings.getBooleanProperty("davmail.disableUpdateCheck"));
489         caldavAutoScheduleCheckBox = new JCheckBox();
490         caldavAutoScheduleCheckBox.setSelected(Settings.getBooleanProperty("davmail.caldavAutoSchedule"));
491 
492         addSettingComponent(otherSettingsPanel, BundleMessage.format("UI_FOLDER_SIZE_LIMIT"), folderSizeLimitField,
493                 BundleMessage.format("UI_FOLDER_SIZE_LIMIT_HELP"));
494         addSettingComponent(otherSettingsPanel, BundleMessage.format("UI_ENABLE_KERBEROS"), enableKerberosCheckBox,
495                 BundleMessage.format("UI_ENABLE_KERBEROS_HELP"));
496         addSettingComponent(otherSettingsPanel, BundleMessage.format("UI_CALDAV_EDIT_NOTIFICATIONS"), caldavEditNotificationsField,
497                 BundleMessage.format("UI_CALDAV_EDIT_NOTIFICATIONS_HELP"));
498         addSettingComponent(otherSettingsPanel, BundleMessage.format("UI_CALDAV_ALARM_SOUND"), caldavAlarmSoundField,
499                 BundleMessage.format("UI_CALDAV_ALARM_SOUND_HELP"));
500         addSettingComponent(otherSettingsPanel, BundleMessage.format("UI_FORCE_ACTIVESYNC_UPDATE"), forceActiveSyncUpdateCheckBox,
501                 BundleMessage.format("UI_FORCE_ACTIVESYNC_UPDATE_HELP"));
502         addSettingComponent(otherSettingsPanel, BundleMessage.format("UI_DEFAULT_DOMAIN"), defaultDomainField,
503                 BundleMessage.format("UI_DEFAULT_DOMAIN_HELP"));
504         addSettingComponent(otherSettingsPanel, BundleMessage.format("UI_SHOW_STARTUP_BANNER"), showStartupBannerCheckBox,
505                 BundleMessage.format("UI_SHOW_STARTUP_BANNER_HELP"));
506         addSettingComponent(otherSettingsPanel, BundleMessage.format("UI_DISABLE_GUI_NOTIFICATIONS"), disableGuiNotificationsCheckBox,
507                 BundleMessage.format("UI_DISABLE_GUI_NOTIFICATIONS_HELP"));
508         addSettingComponent(otherSettingsPanel, BundleMessage.format("UI_DISABLE_TRAY_ACTIVITY_SWITCH"), disableTrayActivitySwitchCheckBox,
509                 BundleMessage.format("UI_DISABLE_TRAY_ACTIVITY_SWITCH_HELP"));
510         addSettingComponent(otherSettingsPanel, BundleMessage.format("UI_IMAP_AUTO_EXPUNGE"), imapAutoExpungeCheckBox,
511                 BundleMessage.format("UI_IMAP_AUTO_EXPUNGE_HELP"));
512         addSettingComponent(otherSettingsPanel, BundleMessage.format("UI_ALWAYS_APPROXIMATE_MSG_SIZE"), imapAlwaysApproxMsgSizeCheckBox,
513                 BundleMessage.format("UI_ALWAYS_APPROXIMATE_MSG_SIZE_HELP"));
514         addSettingComponent(otherSettingsPanel, BundleMessage.format("UI_ENABLE_KEEPALIVE"), enableKeepAliveCheckBox,
515                 BundleMessage.format("UI_ENABLE_KEEPALIVE_HELP"));
516         addSettingComponent(otherSettingsPanel, BundleMessage.format("UI_POP_MARK_READ"), popMarkReadOnRetrCheckBox,
517                 BundleMessage.format("UI_POP_MARK_READ_HELP"));
518         addSettingComponent(otherSettingsPanel, BundleMessage.format("UI_SAVE_IN_SENT"), smtpSaveInSentCheckBox,
519                 BundleMessage.format("UI_SAVE_IN_SENT_HELP"));
520         addSettingComponent(otherSettingsPanel, BundleMessage.format("UI_DISABLE_UPDATE_CHECK"), disableUpdateCheck,
521                 BundleMessage.format("UI_DISABLE_UPDATE_CHECK_HELP"));
522 
523         addSettingComponent(otherSettingsPanel, BundleMessage.format("UI_CALDAV_AUTO_SCHEDULE"), caldavAutoScheduleCheckBox,
524                 BundleMessage.format("UI_CALDAV_AUTO_SCHEDULE_HELP"));
525 
526         updateMaximumSize(otherSettingsPanel);
527         return otherSettingsPanel;
528     }
529 
530     protected JPanel getOSXPanel() {
531         JPanel osxSettingsPanel = new JPanel(new GridLayout(1, 2));
532         osxSettingsPanel.setBorder(BorderFactory.createTitledBorder(BundleMessage.format("UI_OSX")));
533 
534         osxHideFromDockCheckBox = new JCheckBox();
535         osxHideFromDockCheckBox.setSelected(OSXInfoPlist.isHideFromDock());
536 
537         addSettingComponent(osxSettingsPanel, BundleMessage.format("UI_OSX_HIDE_FROM_DOCK"), osxHideFromDockCheckBox,
538                 BundleMessage.format("UI_OSX_HIDE_FROM_DOCK_HELP"));
539 
540         updateMaximumSize(osxSettingsPanel);
541         return osxSettingsPanel;
542     }
543 
544     protected JPanel getLoggingSettingsPanel() {
545         JPanel loggingLevelPanel = new JPanel();
546         JPanel leftLoggingPanel = new JPanel(new GridLayout(2, 2));
547         JPanel rightLoggingPanel = new JPanel(new GridLayout(2, 2));
548         loggingLevelPanel.add(leftLoggingPanel);
549         loggingLevelPanel.add(rightLoggingPanel);
550 
551         rootLoggingLevelField = new JComboBox<>(LOG_LEVELS);
552         davmailLoggingLevelField = new JComboBox<>(LOG_LEVELS);
553         httpclientLoggingLevelField = new JComboBox<>(LOG_LEVELS);
554         wireLoggingLevelField = new JComboBox<>(LOG_LEVELS);
555         logFilePathField = new JTextField(Settings.getProperty("davmail.logFilePath"), 15);
556         logFileSizeField = new JTextField(Settings.getProperty("davmail.logFileSize"), 15);
557 
558         rootLoggingLevelField.setSelectedItem(Settings.getLoggingLevel("rootLogger"));
559         davmailLoggingLevelField.setSelectedItem(Settings.getLoggingLevel("davmail"));
560         httpclientLoggingLevelField.setSelectedItem(Settings.getLoggingLevel("httpclient"));
561         wireLoggingLevelField.setSelectedItem(Settings.getLoggingLevel("httpclient.wire"));
562 
563         addSettingComponent(leftLoggingPanel, BundleMessage.format("UI_LOG_DEFAULT"), rootLoggingLevelField);
564         addSettingComponent(leftLoggingPanel, BundleMessage.format("UI_LOG_DAVMAIL"), davmailLoggingLevelField);
565         addSettingComponent(rightLoggingPanel, BundleMessage.format("UI_LOG_HTTPCLIENT"), httpclientLoggingLevelField);
566         addSettingComponent(rightLoggingPanel, BundleMessage.format("UI_LOG_WIRE"), wireLoggingLevelField);
567 
568         JPanel logFilePathPanel = new JPanel(new GridLayout(2, 2));
569         addSettingComponent(logFilePathPanel, BundleMessage.format("UI_LOG_FILE_PATH"), logFilePathField);
570         addSettingComponent(logFilePathPanel, BundleMessage.format("UI_LOG_FILE_SIZE"), logFileSizeField, BundleMessage.format("UI_LOG_FILE_SIZE_HELP"));
571 
572         JButton defaultButton = new JButton(BundleMessage.format("UI_BUTTON_DEFAULT"));
573         defaultButton.setToolTipText(BundleMessage.format("UI_BUTTON_DEFAULT_HELP"));
574         defaultButton.addActionListener(e -> {
575             rootLoggingLevelField.setSelectedItem(Level.WARN);
576             davmailLoggingLevelField.setSelectedItem(Level.DEBUG);
577             httpclientLoggingLevelField.setSelectedItem(Level.WARN);
578             wireLoggingLevelField.setSelectedItem(Level.WARN);
579         });
580 
581         JPanel loggingPanel = new JPanel();
582         loggingPanel.setLayout(new BoxLayout(loggingPanel, BoxLayout.Y_AXIS));
583         loggingPanel.setBorder(BorderFactory.createTitledBorder(BundleMessage.format("UI_LOGGING_LEVELS")));
584         loggingPanel.add(logFilePathPanel);
585         loggingPanel.add(loggingLevelPanel);
586         loggingPanel.add(defaultButton);
587 
588         updateMaximumSize(loggingPanel);
589         return loggingPanel;
590     }
591 
592     protected void updateMaximumSize(JPanel panel) {
593         Dimension preferredSize = panel.getPreferredSize();
594         preferredSize.width = Integer.MAX_VALUE;
595         panel.setMaximumSize(preferredSize);
596     }
597 
598     /**
599      * Reload settings from properties.
600      */
601     public void reload() {
602         // reload settings in form
603         urlField.setText(Settings.getProperty("davmail.url", Settings.getO365Url()));
604         popPortField.setText(Settings.getProperty("davmail.popPort"));
605         popPortCheckBox.setSelected(Settings.getProperty("davmail.popPort") != null && !Settings.getProperty("davmail.popPort").isEmpty());
606         popNoSSLCheckBox.setSelected(Settings.getBooleanProperty("davmail.ssl.nosecurepop"));
607         imapPortField.setText(Settings.getProperty("davmail.imapPort"));
608         imapPortCheckBox.setSelected(Settings.getProperty("davmail.imapPort") != null && !Settings.getProperty("davmail.imapPort").isEmpty());
609         imapNoSSLCheckBox.setSelected(Settings.getBooleanProperty("davmail.ssl.nosecureimap"));
610         smtpPortField.setText(Settings.getProperty("davmail.smtpPort"));
611         smtpPortCheckBox.setSelected(Settings.getProperty("davmail.smtpPort") != null && !Settings.getProperty("davmail.smtpPort").isEmpty());
612         smtpNoSSLCheckBox.setSelected(Settings.getBooleanProperty("davmail.ssl.nosecuresmtp"));
613         caldavPortField.setText(Settings.getProperty("davmail.caldavPort"));
614         caldavPortCheckBox.setSelected(Settings.getProperty("davmail.caldavPort") != null && !Settings.getProperty("davmail.caldavPort").isEmpty());
615         caldavNoSSLCheckBox.setSelected(Settings.getBooleanProperty("davmail.ssl.nosecurecaldav"));
616         ldapPortField.setText(Settings.getProperty("davmail.ldapPort"));
617         ldapPortCheckBox.setSelected(Settings.getProperty("davmail.ldapPort") != null && !Settings.getProperty("davmail.ldapPort").isEmpty());
618         ldapNoSSLCheckBox.setSelected(Settings.getBooleanProperty("davmail.ssl.nosecureldap"));
619         keepDelayField.setText(Settings.getProperty("davmail.keepDelay"));
620         sentKeepDelayField.setText(Settings.getProperty("davmail.sentKeepDelay"));
621         caldavPastDelayField.setText(Settings.getProperty("davmail.caldavPastDelay"));
622         imapIdleDelayField.setText(Settings.getProperty("davmail.imapIdleDelay"));
623         boolean useSystemProxies = Settings.getBooleanProperty("davmail.useSystemProxies", Boolean.FALSE);
624         useSystemProxiesField.setSelected(useSystemProxies);
625         boolean enableProxy = Settings.getBooleanProperty("davmail.enableProxy");
626         enableProxyField.setSelected(enableProxy);
627         enableProxyField.setEnabled(!useSystemProxies);
628         httpProxyField.setEnabled(enableProxy);
629         httpProxyPortField.setEnabled(enableProxy);
630         httpProxyUserField.setEnabled(useSystemProxies || enableProxy);
631         httpProxyPasswordField.setEnabled(useSystemProxies || enableProxy);
632         noProxyForField.setEnabled(enableProxy);
633         httpProxyField.setText(Settings.getProperty("davmail.proxyHost"));
634         httpProxyPortField.setText(Settings.getProperty("davmail.proxyPort"));
635         httpProxyUserField.setText(Settings.getProperty("davmail.proxyUser"));
636         httpProxyPasswordField.setText(Settings.getProperty("davmail.proxyPassword"));
637         noProxyForField.setText(Settings.getProperty("davmail.noProxyFor"));
638 
639         bindAddressField.setText(Settings.getProperty("davmail.bindAddress"));
640         allowRemoteField.setSelected(Settings.getBooleanProperty(("davmail.allowRemote")));
641         certHashField.setText(Settings.getProperty("davmail.server.certificate.hash"));
642         disableUpdateCheck.setSelected(Settings.getBooleanProperty(("davmail.disableUpdateCheck")));
643 
644         caldavEditNotificationsField.setSelected(Settings.getBooleanProperty("davmail.caldavEditNotifications"));
645         clientSoTimeoutField.setText(Settings.getProperty("davmail.clientSoTimeout"));
646         caldavAlarmSoundField.setText(Settings.getProperty("davmail.caldavAlarmSound"));
647         forceActiveSyncUpdateCheckBox.setSelected(Settings.getBooleanProperty("davmail.forceActiveSyncUpdate"));
648         defaultDomainField.setText(Settings.getProperty("davmail.defaultDomain"));
649         showStartupBannerCheckBox.setSelected(Settings.getBooleanProperty("davmail.showStartupBanner", true));
650         disableGuiNotificationsCheckBox.setSelected(Settings.getBooleanProperty("davmail.disableGuiNotifications", false));
651         disableTrayActivitySwitchCheckBox.setSelected(Settings.getBooleanProperty("davmail.disableTrayActivitySwitch", false));
652         imapAutoExpungeCheckBox.setSelected(Settings.getBooleanProperty("davmail.imapAutoExpunge", true));
653         imapAlwaysApproxMsgSizeCheckBox.setSelected(Settings.getBooleanProperty("davmail.imapAlwaysApproxMsgSize", false));
654         enableKeepAliveCheckBox.setSelected(Settings.getBooleanProperty("davmail.enableKeepAlive", false));
655         popMarkReadOnRetrCheckBox.setSelected(Settings.getBooleanProperty("davmail.popMarkReadOnRetr", false));
656         modeComboBox.setSelectedItem(Settings.getProperty("davmail.mode", Settings.EWS));
657         smtpSaveInSentCheckBox.setSelected(Settings.getBooleanProperty("davmail.smtpSaveInSent", true));
658         enableKerberosCheckBox.setSelected(Settings.getBooleanProperty("davmail.enableKerberos", false));
659         folderSizeLimitField.setText(Settings.getProperty("davmail.folderSizeLimit"));
660 
661         keystoreTypeCombo.setSelectedItem(Settings.getProperty("davmail.ssl.keystoreType"));
662         keystoreFileField.setText(Settings.getProperty("davmail.ssl.keystoreFile"));
663         keystorePassField.setText(Settings.getProperty("davmail.ssl.keystorePass"));
664         keyPassField.setText(Settings.getProperty("davmail.ssl.keyPass"));
665 
666         clientKeystoreTypeCombo.setSelectedItem(Settings.getProperty("davmail.ssl.clientKeystoreType"));
667         pkcs11LibraryField.setText(Settings.getProperty("davmail.ssl.pkcs11Library"));
668         pkcs11ConfigField.setText(Settings.getProperty("davmail.ssl.pkcs11Config"));
669 
670         oauthTenantIdField.setText(Settings.getProperty("davmail.oauth.tenantId"));
671         oauthClientIdField.setText(Settings.getProperty("davmail.oauth.clientId"));
672         oauthRedirectUriField.setText(Settings.getProperty("davmail.oauth.redirectUri"));
673         oauthTldField.setText(Settings.getProperty("davmail.tld"));
674 
675         rootLoggingLevelField.setSelectedItem(Settings.getLoggingLevel("rootLogger"));
676         davmailLoggingLevelField.setSelectedItem(Settings.getLoggingLevel("davmail"));
677         httpclientLoggingLevelField.setSelectedItem(Settings.getLoggingLevel("httpclient"));
678         wireLoggingLevelField.setSelectedItem(Settings.getLoggingLevel("httpclient.wire"));
679         logFilePathField.setText(Settings.getProperty("davmail.logFilePath"));
680         logFileSizeField.setText(Settings.getProperty("davmail.logFileSize"));
681 
682         if (osxHideFromDockCheckBox != null) {
683             osxHideFromDockCheckBox.setSelected(OSXInfoPlist.isHideFromDock());
684         }
685     }
686 
687     protected boolean isSslEnabled() {
688         if (keystoreFileField != null) {
689             return !keystoreFileField.getText().isEmpty();
690         } else {
691             return Settings.getProperty("davmail.ssl.keystoreFile") != null &&
692                     (!Settings.getProperty("davmail.ssl.keystoreFile").isEmpty());
693         }
694     }
695 
696     /**
697      * DavMail settings frame.
698      */
699     public SettingsFrame() {
700         setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE);
701         setTitle(BundleMessage.format("UI_DAVMAIL_SETTINGS"));
702         try {
703             setIconImages(DavGatewayTray.getFrameIcons());
704         } catch (NoSuchMethodError error) {
705             DavGatewayTray.debug(new BundleMessage("LOG_UNABLE_TO_SET_ICON_IMAGE"));
706         }
707 
708         JTabbedPane tabbedPane = new JTabbedPane();
709         // add help (F1 handler)
710         tabbedPane.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(KeyStroke.getKeyStroke("F1"),
711                 "help");
712         tabbedPane.getActionMap().put("help", new AbstractAction() {
713             public void actionPerformed(ActionEvent e) {
714                 DesktopBrowser.browse("https://davmail.sourceforge.net");
715             }
716         });
717         tabbedPane.addChangeListener(e -> {
718             boolean isSslEnabled = isSslEnabled();
719             popNoSSLCheckBox.setEnabled(Settings.getProperty("davmail.popPort") != null && isSslEnabled);
720             imapNoSSLCheckBox.setEnabled(imapPortCheckBox.isSelected() && isSslEnabled);
721             smtpNoSSLCheckBox.setEnabled(smtpPortCheckBox.isSelected() && isSslEnabled);
722             caldavNoSSLCheckBox.setEnabled(caldavPortCheckBox.isSelected() && isSslEnabled);
723             ldapNoSSLCheckBox.setEnabled(ldapPortCheckBox.isSelected() && isSslEnabled);
724         });
725 
726         JPanel mainPanel = new JPanel();
727         mainPanel.setLayout(new BoxLayout(mainPanel, BoxLayout.Y_AXIS));
728         mainPanel.add(getSettingsPanel());
729         mainPanel.add(getDelaysPanel());
730         mainPanel.add(Box.createVerticalGlue());
731 
732         tabbedPane.add(BundleMessage.format("UI_TAB_MAIN"), mainPanel);
733 
734         JPanel proxyPanel = new JPanel();
735         proxyPanel.setLayout(new BoxLayout(proxyPanel, BoxLayout.Y_AXIS));
736         proxyPanel.add(getProxyPanel());
737         proxyPanel.add(getNetworkSettingsPanel());
738         tabbedPane.add(BundleMessage.format("UI_TAB_NETWORK"), proxyPanel);
739 
740         JPanel encryptionPanel = new JPanel();
741         encryptionPanel.setLayout(new BoxLayout(encryptionPanel, BoxLayout.Y_AXIS));
742         encryptionPanel.add(getKeystorePanel());
743         encryptionPanel.add(getSmartCardPanel());
744         encryptionPanel.add(getOauthPanel());
745         // empty panel
746         encryptionPanel.add(new JPanel());
747         tabbedPane.add(BundleMessage.format("UI_TAB_ENCRYPTION"), encryptionPanel);
748 
749         JPanel loggingPanel = new JPanel();
750         loggingPanel.setLayout(new BoxLayout(loggingPanel, BoxLayout.Y_AXIS));
751         loggingPanel.add(getLoggingSettingsPanel());
752         // empty panel
753         loggingPanel.add(new JPanel());
754 
755         tabbedPane.add(BundleMessage.format("UI_TAB_LOGGING"), loggingPanel);
756 
757         JPanel advancedPanel = new JPanel();
758         advancedPanel.setLayout(new BoxLayout(advancedPanel, BoxLayout.Y_AXIS));
759 
760         advancedPanel.add(getOtherSettingsPanel());
761         // empty panel
762         advancedPanel.add(new JPanel());
763 
764         tabbedPane.add(BundleMessage.format("UI_TAB_ADVANCED"), advancedPanel);
765 
766         if (OSXInfoPlist.isOSX()) {
767             JPanel osxPanel = new JPanel();
768             osxPanel.setLayout(new BoxLayout(osxPanel, BoxLayout.Y_AXIS));
769             osxPanel.add(getOSXPanel());
770             // empty panel
771             osxPanel.add(new JPanel());
772 
773             tabbedPane.add(BundleMessage.format("UI_TAB_OSX"), osxPanel);
774         }
775 
776         add(BorderLayout.CENTER, tabbedPane);
777 
778         JPanel buttonPanel = new JPanel();
779         JButton cancel = new JButton(BundleMessage.format("UI_BUTTON_CANCEL"));
780         JButton ok = new JButton(BundleMessage.format("UI_BUTTON_SAVE"));
781         JButton help = new JButton(BundleMessage.format("UI_BUTTON_HELP"));
782         ActionListener save = evt -> {
783             // save options
784             Settings.setProperty("davmail.url", urlField.getText().trim());
785             Settings.setProperty("davmail.popPort", popPortCheckBox.isSelected() ? popPortField.getText() : "");
786             Settings.setProperty("davmail.ssl.nosecurepop", String.valueOf(popNoSSLCheckBox.isSelected()));
787             Settings.setProperty("davmail.imapPort", imapPortCheckBox.isSelected() ? imapPortField.getText() : "");
788             Settings.setProperty("davmail.ssl.nosecureimap", String.valueOf(imapNoSSLCheckBox.isSelected()));
789             Settings.setProperty("davmail.smtpPort", smtpPortCheckBox.isSelected() ? smtpPortField.getText() : "");
790             Settings.setProperty("davmail.ssl.nosecuresmtp", String.valueOf(smtpNoSSLCheckBox.isSelected()));
791             Settings.setProperty("davmail.caldavPort", caldavPortCheckBox.isSelected() ? caldavPortField.getText() : "");
792             Settings.setProperty("davmail.ssl.nosecurecaldav", String.valueOf(caldavNoSSLCheckBox.isSelected()));
793             Settings.setProperty("davmail.ldapPort", ldapPortCheckBox.isSelected() ? ldapPortField.getText() : "");
794             Settings.setProperty("davmail.ssl.nosecureldap", String.valueOf(ldapNoSSLCheckBox.isSelected()));
795             Settings.setProperty("davmail.keepDelay", keepDelayField.getText());
796             Settings.setProperty("davmail.sentKeepDelay", sentKeepDelayField.getText());
797             Settings.setProperty("davmail.caldavPastDelay", caldavPastDelayField.getText());
798             Settings.setProperty("davmail.imapIdleDelay", imapIdleDelayField.getText());
799             Settings.setProperty("davmail.useSystemProxies", String.valueOf(useSystemProxiesField.isSelected()));
800             Settings.setProperty("davmail.enableProxy", String.valueOf(enableProxyField.isSelected()));
801             Settings.setProperty("davmail.proxyHost", httpProxyField.getText());
802             Settings.setProperty("davmail.proxyPort", httpProxyPortField.getText());
803             Settings.setProperty("davmail.proxyUser", httpProxyUserField.getText());
804             Settings.setProperty("davmail.proxyPassword", httpProxyPasswordField.getText());
805             Settings.setProperty("davmail.noProxyFor", noProxyForField.getText());
806 
807             Settings.setProperty("davmail.bindAddress", bindAddressField.getText());
808             Settings.setProperty("davmail.clientSoTimeout", String.valueOf(clientSoTimeoutField.getText()));
809             Settings.setProperty("davmail.allowRemote", String.valueOf(allowRemoteField.isSelected()));
810             Settings.setProperty("davmail.server.certificate.hash", certHashField.getText());
811             Settings.setProperty("davmail.disableUpdateCheck", String.valueOf(disableUpdateCheck.isSelected()));
812             Settings.setProperty("davmail.caldavAutoSchedule", String.valueOf(caldavAutoScheduleCheckBox.isSelected()));
813 
814             Settings.setProperty("davmail.caldavEditNotifications", String.valueOf(caldavEditNotificationsField.isSelected()));
815             Settings.setProperty("davmail.caldavAlarmSound", String.valueOf(caldavAlarmSoundField.getText()));
816             Settings.setProperty("davmail.forceActiveSyncUpdate", String.valueOf(forceActiveSyncUpdateCheckBox.isSelected()));
817             Settings.setProperty("davmail.defaultDomain", String.valueOf(defaultDomainField.getText()));
818             Settings.setProperty("davmail.showStartupBanner", String.valueOf(showStartupBannerCheckBox.isSelected()));
819             Settings.setProperty("davmail.disableGuiNotifications", String.valueOf(disableGuiNotificationsCheckBox.isSelected()));
820             Settings.setProperty("davmail.disableTrayActivitySwitch", String.valueOf(disableTrayActivitySwitchCheckBox.isSelected()));
821             Settings.setProperty("davmail.imapAutoExpunge", String.valueOf(imapAutoExpungeCheckBox.isSelected()));
822             Settings.setProperty("davmail.imapAlwaysApproxMsgSize", String.valueOf(imapAlwaysApproxMsgSizeCheckBox.isSelected()));
823             Settings.setProperty("davmail.enableKeepAlive", String.valueOf(enableKeepAliveCheckBox.isSelected()));
824             Settings.setProperty("davmail.popMarkReadOnRetr", String.valueOf(popMarkReadOnRetrCheckBox.isSelected()));
825 
826             Settings.setProperty("davmail.mode", (String) modeComboBox.getSelectedItem());
827             Settings.setProperty("davmail.enableKerberos", String.valueOf(enableKerberosCheckBox.isSelected()));
828             Settings.setProperty("davmail.folderSizeLimit", folderSizeLimitField.getText());
829             Settings.setProperty("davmail.smtpSaveInSent", String.valueOf(smtpSaveInSentCheckBox.isSelected()));
830 
831             Settings.setProperty("davmail.ssl.keystoreType", (String) keystoreTypeCombo.getSelectedItem());
832             Settings.setProperty("davmail.ssl.keystoreFile", keystoreFileField.getText());
833             Settings.setProperty("davmail.ssl.keystorePass", String.valueOf(keystorePassField.getPassword()));
834             Settings.setProperty("davmail.ssl.keyPass", String.valueOf(keyPassField.getPassword()));
835 
836             Settings.setProperty("davmail.ssl.clientKeystoreType", (String) clientKeystoreTypeCombo.getSelectedItem());
837             Settings.setProperty("davmail.ssl.clientKeystoreFile", clientKeystoreFileField.getText());
838             Settings.setProperty("davmail.ssl.clientKeystorePass", String.valueOf(clientKeystorePassField.getPassword()));
839             Settings.setProperty("davmail.ssl.pkcs11Library", pkcs11LibraryField.getText());
840             Settings.setProperty("davmail.ssl.pkcs11Config", pkcs11ConfigField.getText());
841 
842             Settings.setProperty("davmail.oauth.tenantId", oauthTenantIdField.getText());
843             Settings.setProperty("davmail.oauth.clientId", oauthClientIdField.getText());
844             Settings.setProperty("davmail.oauth.redirectUri", oauthRedirectUriField.getText());
845             Settings.setProperty("davmail.tld", oauthTldField.getText());
846 
847             Settings.setLoggingLevel("rootLogger", (Level) rootLoggingLevelField.getSelectedItem());
848             Settings.setLoggingLevel("davmail", (Level) davmailLoggingLevelField.getSelectedItem());
849             Settings.setLoggingLevel("httpclient", (Level) httpclientLoggingLevelField.getSelectedItem());
850             Settings.setLoggingLevel("httpclient.wire", (Level) wireLoggingLevelField.getSelectedItem());
851             Settings.setProperty("davmail.logFilePath", logFilePathField.getText());
852             Settings.setProperty("davmail.logFileSize", logFileSizeField.getText());
853 
854             setVisible(false);
855             Settings.save();
856 
857             if (osxHideFromDockCheckBox != null) {
858                 OSXInfoPlist.setOSXHideFromDock(osxHideFromDockCheckBox.isSelected());
859             }
860 
861             // restart listeners with new config
862             DavGateway.restart();
863         };
864         ok.addActionListener(save);
865 
866         cancel.addActionListener(evt -> {
867             reload();
868             setVisible(false);
869         });
870 
871         help.addActionListener(e -> DesktopBrowser.browse("https://davmail.sourceforge.net"));
872 
873         buttonPanel.add(ok);
874         buttonPanel.add(cancel);
875         buttonPanel.add(help);
876 
877         add(BorderLayout.SOUTH, buttonPanel);
878 
879         pack();
880         //setResizable(false);
881         // center frame
882         setLocationRelativeTo(null);
883         urlField.requestFocus();
884     }
885 }