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