Merge branch 'develop' into releases/Release_2_11_2_Branch
[jalview.git] / src / jalview / jbgui / GPreferences.java
1 /*
2  * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
3  * Copyright (C) $$Year-Rel$$ The Jalview Authors
4  * 
5  * This file is part of Jalview.
6  * 
7  * Jalview is free software: you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License 
9  * as published by the Free Software Foundation, either version 3
10  * of the License, or (at your option) any later version.
11  *  
12  * Jalview is distributed in the hope that it will be useful, but 
13  * WITHOUT ANY WARRANTY; without even the implied warranty 
14  * of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
15  * PURPOSE.  See the GNU General Public License for more details.
16  * 
17  * You should have received a copy of the GNU General Public License
18  * along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
19  * The Jalview Authors are detailed in the 'AUTHORS' file.
20  */
21 package jalview.jbgui;
22
23 import java.awt.BorderLayout;
24 import java.awt.Color;
25 import java.awt.Component;
26 import java.awt.Dimension;
27 import java.awt.FlowLayout;
28 import java.awt.Font;
29 import java.awt.GridBagConstraints;
30 import java.awt.GridBagLayout;
31 import java.awt.GridLayout;
32 import java.awt.Insets;
33 import java.awt.Rectangle;
34 import java.awt.event.ActionEvent;
35 import java.awt.event.ActionListener;
36 import java.awt.event.FocusEvent;
37 import java.awt.event.KeyEvent;
38 import java.awt.event.KeyListener;
39 import java.awt.event.MouseAdapter;
40 import java.awt.event.MouseEvent;
41 import java.util.Arrays;
42 import java.util.List;
43
44 import javax.swing.AbstractCellEditor;
45 import javax.swing.BorderFactory;
46 import javax.swing.ButtonGroup;
47 import javax.swing.DefaultListCellRenderer;
48 import javax.swing.JButton;
49 import javax.swing.JCheckBox;
50 import javax.swing.JComboBox;
51 import javax.swing.JFileChooser;
52 import javax.swing.JLabel;
53 import javax.swing.JPanel;
54 import javax.swing.JPasswordField;
55 import javax.swing.JRadioButton;
56 import javax.swing.JScrollPane;
57 import javax.swing.JSpinner;
58 import javax.swing.JTabbedPane;
59 import javax.swing.JTable;
60 import javax.swing.JTextArea;
61 import javax.swing.JTextField;
62 import javax.swing.ListSelectionModel;
63 import javax.swing.SpinnerModel;
64 import javax.swing.SpinnerNumberModel;
65 import javax.swing.SwingConstants;
66 import javax.swing.border.Border;
67 import javax.swing.border.EmptyBorder;
68 import javax.swing.border.EtchedBorder;
69 import javax.swing.border.TitledBorder;
70 import javax.swing.event.ChangeEvent;
71 import javax.swing.event.ChangeListener;
72 import javax.swing.event.DocumentEvent;
73 import javax.swing.event.DocumentListener;
74 import javax.swing.table.TableCellEditor;
75 import javax.swing.table.TableCellRenderer;
76
77 import jalview.bin.Cache;
78 import jalview.fts.core.FTSDataColumnPreferences;
79 import jalview.fts.core.FTSDataColumnPreferences.PreferenceSource;
80 import jalview.fts.service.pdb.PDBFTSRestClient;
81 import jalview.gui.Desktop;
82 import jalview.gui.JalviewBooleanRadioButtons;
83 import jalview.gui.JvOptionPane;
84 import jalview.gui.JvSwingUtils;
85 import jalview.gui.StructureViewer.ViewerType;
86 import jalview.io.BackupFilenameParts;
87 import jalview.io.BackupFiles;
88 import jalview.io.BackupFilesPresetEntry;
89 import jalview.io.IntKeyStringValueEntry;
90 import jalview.util.MessageManager;
91 import jalview.util.Platform;
92
93 /**
94  * Base class for the Preferences panel.
95  * 
96  * @author $author$
97  * @version $Revision$
98  */
99 public class GPreferences extends JPanel
100 {
101   private static final Font LABEL_FONT = JvSwingUtils.getLabelFont();
102
103   private static final Font LABEL_FONT_ITALIC = JvSwingUtils
104           .getLabelFont(false, true);
105
106   private static final Font LABEL_FONT_BOLD = JvSwingUtils
107           .getLabelFont(true, false);
108
109   /*
110    * Visual tab components
111    */
112   protected JCheckBox fullScreen = new JCheckBox();
113
114   protected JCheckBox openoverv = new JCheckBox();
115
116   protected JCheckBox seqLimit = new JCheckBox();
117
118   protected JCheckBox rightAlign = new JCheckBox();
119
120   protected JComboBox<String> fontSizeCB = new JComboBox<>();
121
122   protected JComboBox<String> fontStyleCB = new JComboBox<>();
123
124   protected JComboBox<String> fontNameCB = new JComboBox<>();
125
126   protected JCheckBox showOccupancy = new JCheckBox();
127
128   protected JCheckBox showUnconserved = new JCheckBox();
129
130   protected JCheckBox idItalics = new JCheckBox();
131
132   protected JCheckBox smoothFont = new JCheckBox();
133
134   protected JCheckBox scaleProteinToCdna = new JCheckBox();
135
136   protected JComboBox<String> gapSymbolCB = new JComboBox<>();
137
138   protected JCheckBox wrap = new JCheckBox();
139
140   protected JComboBox<String> sortby = new JComboBox<>();
141
142   protected JComboBox<String> sortAnnBy = new JComboBox<>();
143
144   protected JComboBox<String> sortAutocalc = new JComboBox<>();
145
146   protected JCheckBox startupCheckbox = new JCheckBox();
147
148   protected JTextField startupFileTextfield = new JTextField();
149
150   // below are in the 'second column'
151   protected JCheckBox annotations = new JCheckBox();
152
153   protected JCheckBox quality = new JCheckBox();
154
155   protected JCheckBox conservation = new JCheckBox();
156
157   protected JCheckBox identity = new JCheckBox();
158
159   protected JCheckBox showGroupConsensus = new JCheckBox();
160
161   protected JCheckBox showGroupConservation = new JCheckBox();
162
163   protected JCheckBox showConsensHistogram = new JCheckBox();
164
165   protected JCheckBox showConsensLogo = new JCheckBox();
166
167   protected JCheckBox showDbRefTooltip = new JCheckBox();
168
169   protected JCheckBox showNpTooltip = new JCheckBox();
170
171   /*
172    * Structure tab and components
173    */
174   protected JPanel structureTab;
175
176   protected JCheckBox structFromPdb = new JCheckBox();
177
178   protected JCheckBox addSecondaryStructure = new JCheckBox();
179
180   protected JCheckBox addTempFactor = new JCheckBox();
181
182   protected JComboBox<String> structViewer = new JComboBox<>();
183
184   protected JLabel structureViewerPathLabel;
185
186   protected JTextField structureViewerPath = new JTextField();
187
188   protected ButtonGroup mappingMethod = new ButtonGroup();
189
190   protected JRadioButton siftsMapping = new JRadioButton();
191
192   protected JRadioButton nwMapping = new JRadioButton();
193
194   /*
195    * Colours tab components
196    */
197   protected JPanel minColour = new JPanel();
198
199   protected JPanel maxColour = new JPanel();
200
201   protected JComboBox<String> protColour = new JComboBox<>();
202
203   protected JComboBox<String> nucColour = new JComboBox<>();
204
205   /*
206    * Overview tab components
207    */
208   protected JPanel gapColour = new JPanel();
209
210   protected JPanel hiddenColour = new JPanel();
211
212   protected JCheckBox useLegacyGap;
213
214   protected JCheckBox showHiddenAtStart;
215
216   protected JLabel gapLabel;
217
218   /*
219    * Connections tab components
220    */
221   protected JPanel connectTab;
222
223   protected JTable linkUrlTable = new JTable();
224
225   protected JButton editLink = new JButton();
226
227   protected JButton deleteLink = new JButton();
228
229   protected JTextField filterTB = new JTextField();
230
231   protected JButton doReset = new JButton();
232
233   protected JButton userOnly = new JButton();
234
235   protected JLabel httpLabel = new JLabel();
236
237   protected JLabel httpsLabel = new JLabel();
238
239   protected JLabel portLabel = new JLabel();
240
241   protected JLabel serverLabel = new JLabel();
242
243   protected JLabel portLabel2 = new JLabel();
244
245   protected JLabel serverLabel2 = new JLabel();
246
247   protected JLabel proxyAuthUsernameLabel = new JLabel();
248
249   protected JLabel proxyAuthPasswordLabel = new JLabel();
250
251   protected JLabel passwordNotStoredLabel = new JLabel();
252
253   protected JTextField proxyServerHttpTB = new JTextField();
254
255   protected JTextField proxyPortHttpTB = new JTextField();
256
257   protected JTextField proxyServerHttpsTB = new JTextField();
258
259   protected JTextField proxyPortHttpsTB = new JTextField();
260
261   protected JCheckBox proxyAuth = new JCheckBox();
262
263   protected JTextField proxyAuthUsernameTB = new JTextField();
264
265   protected JPasswordField proxyAuthPasswordPB = new JPasswordField();
266
267   protected JTextField defaultBrowser = new JTextField();
268
269   protected ButtonGroup proxyType = new ButtonGroup();
270
271   protected JRadioButton noProxy = new JRadioButton();
272
273   protected JRadioButton systemProxy = new JRadioButton();
274
275   protected JRadioButton customProxy = new JRadioButton();
276
277   protected JButton applyProxyButton = new JButton();
278
279   protected JCheckBox usagestats = new JCheckBox();
280
281   protected JCheckBox questionnaire = new JCheckBox();
282
283   protected JCheckBox versioncheck = new JCheckBox();
284
285   /*
286    * Output tab components
287    */
288   protected JComboBox<Object> epsRendering = new JComboBox<>();
289
290   protected JComboBox<Object> htmlRendering = new JComboBox<>();
291
292   protected JComboBox<Object> svgRendering = new JComboBox<>();
293
294   protected JLabel userIdWidthlabel = new JLabel();
295
296   protected JCheckBox autoIdWidth = new JCheckBox();
297
298   protected JTextField userIdWidth = new JTextField();
299
300   protected JCheckBox blcjv = new JCheckBox();
301
302   protected JCheckBox pileupjv = new JCheckBox();
303
304   protected JCheckBox clustaljv = new JCheckBox();
305
306   protected JCheckBox msfjv = new JCheckBox();
307
308   protected JCheckBox fastajv = new JCheckBox();
309
310   protected JCheckBox pfamjv = new JCheckBox();
311
312   protected JCheckBox pirjv = new JCheckBox();
313
314   protected JCheckBox modellerOutput = new JCheckBox();
315
316   protected JCheckBox embbedBioJSON = new JCheckBox();
317
318   /*
319    * Editing tab components
320    */
321   protected JCheckBox autoCalculateConsCheck = new JCheckBox();
322
323   protected JCheckBox padGaps = new JCheckBox();
324
325   protected JCheckBox sortByTree = new JCheckBox();
326
327   /*
328    * Web Services tab
329    */
330   protected JPanel wsTab = new JPanel();
331
332   /*
333    * Backups tab components
334    * a lot of these are member variables instead of local variables only so that they
335    * can be enabled/disabled easily in one go
336    */
337
338   protected JCheckBox enableBackupFiles = new JCheckBox();
339
340   protected JPanel presetsPanel = new JPanel();
341
342   protected JLabel presetsComboLabel = new JLabel();
343
344   protected JCheckBox customiseCheckbox = new JCheckBox();
345
346   protected JButton revertButton = new JButton();
347
348   protected JComboBox<Object> backupfilesPresetsCombo = new JComboBox<>();
349
350   private int backupfilesPresetsComboLastSelected = 0;
351
352   protected JPanel suffixPanel = new JPanel();
353
354   protected JPanel keepfilesPanel = new JPanel();
355
356   protected JPanel exampleFilesPanel = new JPanel();
357
358   protected JTextField suffixTemplate = new JTextField(null, 8);
359
360   protected JLabel suffixTemplateLabel = new JLabel();
361
362   protected JLabel suffixDigitsLabel = new JLabel();
363
364   protected JSpinner suffixDigitsSpinner = new JSpinner();
365
366   protected JalviewBooleanRadioButtons suffixReverse = new JalviewBooleanRadioButtons();
367
368   protected JalviewBooleanRadioButtons backupfilesKeepAll = new JalviewBooleanRadioButtons();
369
370   public JSpinner backupfilesRollMaxSpinner = new JSpinner();
371
372   protected JLabel oldBackupFilesLabel = new JLabel();
373
374   protected JalviewBooleanRadioButtons backupfilesConfirmDelete = new JalviewBooleanRadioButtons();
375
376   protected JTextArea backupfilesExampleLabel = new JTextArea();
377
378   private final JTabbedPane tabbedPane = new JTabbedPane();
379
380   private JLabel messageLabel = new JLabel("", JLabel.CENTER);
381
382   /**
383    * Creates a new GPreferences object.
384    */
385   public GPreferences()
386   {
387     try
388     {
389       jbInit();
390     } catch (Exception ex)
391     {
392       ex.printStackTrace();
393     }
394   }
395
396   /**
397    * Construct the panel and its tabbed sub-panels.
398    * 
399    * @throws Exception
400    */
401   private void jbInit() throws Exception
402   {
403     // final JTabbedPane tabbedPane = new JTabbedPane();
404     this.setLayout(new BorderLayout());
405
406     // message label at top
407     this.add(messageLabel, BorderLayout.NORTH);
408
409     JPanel okCancelPanel = initOkCancelPanel();
410     this.add(tabbedPane, BorderLayout.CENTER);
411     this.add(okCancelPanel, BorderLayout.SOUTH);
412
413     tabbedPane.add(initVisualTab(),
414             MessageManager.getString("label.visual"));
415
416     tabbedPane.add(initColoursTab(),
417             MessageManager.getString("label.colours"));
418
419     tabbedPane.add(initOverviewTab(),
420             MessageManager.getString("label.overview"));
421
422     tabbedPane.add(initStructureTab(),
423             MessageManager.getString("label.structure"));
424
425     tabbedPane.add(initConnectionsTab(),
426             MessageManager.getString("label.connections"));
427
428     if (!Platform.isJS())
429     {
430       tabbedPane.add(initBackupsTab(),
431               MessageManager.getString("label.backups"));
432     }
433
434     tabbedPane.add(initLinksTab(),
435             MessageManager.getString("label.urllinks"));
436
437     tabbedPane.add(initOutputTab(),
438             MessageManager.getString("label.output"));
439
440     tabbedPane.add(initEditingTab(),
441             MessageManager.getString("label.editing"));
442
443     /*
444      * See WsPreferences for the real work of configuring this tab.
445      */
446     if (!Platform.isJS())
447     {
448       wsTab.setLayout(new BorderLayout());
449       tabbedPane.add(wsTab, MessageManager.getString("label.web_services"));
450     }
451
452     /*
453      * Handler to validate a tab before leaving it - currently only for
454      * Structure.
455      * Adding a clearMessage() so messages are cleared when changing tabs.
456      */
457     tabbedPane.addChangeListener(new ChangeListener()
458     {
459       private Component lastTab;
460
461       @Override
462       public void stateChanged(ChangeEvent e)
463       {
464         if (lastTab == structureTab
465                 && tabbedPane.getSelectedComponent() != structureTab)
466         {
467           if (!validateStructure())
468           {
469             tabbedPane.setSelectedComponent(structureTab);
470             return;
471           }
472         }
473         lastTab = tabbedPane.getSelectedComponent();
474
475         clearMessage();
476       }
477
478     });
479   }
480
481   public void setMessage(String message)
482   {
483     if (message != null)
484     {
485       messageLabel.setText(message);
486       messageLabel.setFont(LABEL_FONT_BOLD);
487       messageLabel.setForeground(Color.RED.darker());
488       messageLabel.revalidate();
489       messageLabel.repaint();
490     }
491     // note message not cleared if message is null. call clearMessage()
492     // directly.
493     this.revalidate();
494     this.repaint();
495   }
496
497   public void clearMessage()
498   {
499     // only repaint if message exists
500     if (messageLabel.getText() != null
501             && messageLabel.getText().length() > 0)
502     {
503       messageLabel.setText("");
504       messageLabel.revalidate();
505       messageLabel.repaint();
506       this.revalidate();
507       this.repaint();
508     }
509   }
510
511   public static enum TabRef
512   {
513     CONNECTIONS_TAB, STRUCTURE_TAB
514   };
515
516   public void selectTab(TabRef selectTab)
517   {
518     // select a given tab - currently only for Connections
519     switch (selectTab)
520     {
521     case CONNECTIONS_TAB:
522       tabbedPane.setSelectedComponent(connectTab);
523       break;
524     case STRUCTURE_TAB:
525       tabbedPane.setSelectedComponent(structureTab);
526       break;
527     default:
528     }
529   }
530
531   /**
532    * Initialises the Editing tabbed panel.
533    * 
534    * @return
535    */
536   private JPanel initEditingTab()
537   {
538     JPanel editingTab = new JPanel();
539     editingTab.setLayout(null);
540     autoCalculateConsCheck.setFont(LABEL_FONT);
541     autoCalculateConsCheck.setText(
542             MessageManager.getString("label.autocalculate_consensus"));
543     autoCalculateConsCheck.setBounds(new Rectangle(21, 52, 209, 23));
544     padGaps.setFont(LABEL_FONT);
545     padGaps.setText(
546             MessageManager.getString("label.pad_gaps_when_editing"));
547     padGaps.setBounds(new Rectangle(22, 94, 168, 23));
548     sortByTree.setFont(LABEL_FONT);
549     sortByTree
550             .setText(MessageManager.getString("label.sort_with_new_tree"));
551     sortByTree.setToolTipText(MessageManager.getString(
552             "label.any_trees_calculated_or_loaded_alignment_automatically_sort"));
553     sortByTree.setBounds(new Rectangle(22, 136, 168, 23));
554     editingTab.add(autoCalculateConsCheck);
555     editingTab.add(padGaps);
556     editingTab.add(sortByTree);
557     return editingTab;
558   }
559
560   /**
561    * Initialises the Output tab
562    * 
563    * @return
564    */
565   private JPanel initOutputTab()
566   {
567     JPanel outputTab = new JPanel();
568     outputTab.setLayout(null);
569
570     JLabel epsLabel = new JLabel(
571             MessageManager.formatMessage("label.rendering_style", "EPS"));
572     epsLabel.setFont(LABEL_FONT);
573     epsLabel.setHorizontalAlignment(SwingConstants.RIGHT);
574     epsLabel.setBounds(new Rectangle(9, 31, 160, 24));
575     epsRendering.setFont(LABEL_FONT);
576     epsRendering.setBounds(new Rectangle(174, 34, 187, 21));
577     JLabel htmlLabel = new JLabel(
578             MessageManager.formatMessage("label.rendering_style", "HTML"));
579     htmlLabel.setFont(LABEL_FONT);
580     htmlLabel.setHorizontalAlignment(SwingConstants.RIGHT);
581     htmlLabel.setBounds(new Rectangle(9, 55, 160, 24));
582     htmlRendering.setFont(LABEL_FONT);
583     htmlRendering.setBounds(new Rectangle(174, 58, 187, 21));
584     JLabel svgLabel = new JLabel(
585             MessageManager.formatMessage("label.rendering_style", "SVG"));
586     svgLabel.setFont(LABEL_FONT);
587     svgLabel.setHorizontalAlignment(SwingConstants.RIGHT);
588     svgLabel.setBounds(new Rectangle(9, 79, 160, 24));
589     svgRendering.setFont(LABEL_FONT);
590     svgRendering.setBounds(new Rectangle(174, 82, 187, 21));
591
592     JLabel jLabel1 = new JLabel();
593     jLabel1.setFont(LABEL_FONT);
594     jLabel1.setHorizontalAlignment(SwingConstants.CENTER);
595     jLabel1.setText(MessageManager.getString("label.append_start_end"));
596     jLabel1.setFont(LABEL_FONT);
597
598     fastajv.setFont(LABEL_FONT);
599     fastajv.setHorizontalAlignment(SwingConstants.LEFT);
600     clustaljv.setText(MessageManager.getString("label.clustal") + "     ");
601     blcjv.setText(MessageManager.getString("label.blc") + "     ");
602     fastajv.setText(MessageManager.getString("label.fasta") + "     ");
603     msfjv.setText(MessageManager.getString("label.msf") + "     ");
604     pfamjv.setText(MessageManager.getString("label.pfam") + "     ");
605     pileupjv.setText(MessageManager.getString("label.pileup") + "     ");
606     msfjv.setFont(LABEL_FONT);
607     msfjv.setHorizontalAlignment(SwingConstants.LEFT);
608     pirjv.setText(MessageManager.getString("label.pir") + "     ");
609     JPanel jPanel11 = new JPanel();
610     jPanel11.setFont(LABEL_FONT);
611     TitledBorder titledBorder2 = new TitledBorder(
612             MessageManager.getString("label.file_output"));
613     jPanel11.setBorder(titledBorder2);
614     jPanel11.setBounds(new Rectangle(30, 120, 196, 182));
615     GridLayout gridLayout3 = new GridLayout();
616     jPanel11.setLayout(gridLayout3);
617     gridLayout3.setRows(8);
618     blcjv.setFont(LABEL_FONT);
619     blcjv.setHorizontalAlignment(SwingConstants.LEFT);
620     clustaljv.setFont(LABEL_FONT);
621     clustaljv.setHorizontalAlignment(SwingConstants.LEFT);
622     pfamjv.setFont(LABEL_FONT);
623     pfamjv.setHorizontalAlignment(SwingConstants.LEFT);
624     pileupjv.setFont(LABEL_FONT);
625     pileupjv.setHorizontalAlignment(SwingConstants.LEFT);
626     pirjv.setFont(LABEL_FONT);
627     pirjv.setHorizontalAlignment(SwingConstants.LEFT);
628     autoIdWidth.setFont(LABEL_FONT);
629     autoIdWidth.setText(
630             MessageManager.getString("label.automatically_set_id_width"));
631     autoIdWidth.setToolTipText(JvSwingUtils.wrapTooltip(true, MessageManager
632             .getString("label.adjusts_width_generated_eps_png")));
633     autoIdWidth.setBounds(new Rectangle(228, 144, 320, 23));
634     autoIdWidth.addActionListener(new ActionListener()
635     {
636
637       @Override
638       public void actionPerformed(ActionEvent e)
639       {
640         autoIdWidth_actionPerformed();
641       }
642     });
643     userIdWidthlabel.setFont(LABEL_FONT);
644     userIdWidthlabel.setText(
645             MessageManager.getString("label.figure_id_column_width"));
646     userIdWidth.setToolTipText(JvSwingUtils.wrapTooltip(true, MessageManager
647             .getString("label.manually_specify_width_left_column")));
648     userIdWidthlabel.setToolTipText(
649             JvSwingUtils.wrapTooltip(true, MessageManager.getString(
650                     "label.manually_specify_width_left_column")));
651     userIdWidthlabel.setBounds(new Rectangle(236, 168, 320, 23));
652     userIdWidth.setFont(JvSwingUtils.getTextAreaFont());
653     userIdWidth.setText("");
654     userIdWidth.setBounds(new Rectangle(232, 192, 84, 23));
655     userIdWidth.addActionListener(new ActionListener()
656     {
657
658       @Override
659       public void actionPerformed(ActionEvent e)
660       {
661         userIdWidth_actionPerformed();
662       }
663     });
664     modellerOutput.setFont(LABEL_FONT);
665     modellerOutput
666             .setText(MessageManager.getString("label.use_modeller_output"));
667     modellerOutput.setBounds(new Rectangle(228, 274, 320, 23));
668     embbedBioJSON.setFont(LABEL_FONT);
669     embbedBioJSON.setText(MessageManager.getString("label.embbed_biojson"));
670     embbedBioJSON.setBounds(new Rectangle(228, 248, 250, 23));
671
672     jPanel11.add(jLabel1);
673     jPanel11.add(blcjv);
674     jPanel11.add(clustaljv);
675     jPanel11.add(fastajv);
676     jPanel11.add(msfjv);
677     jPanel11.add(pfamjv);
678     jPanel11.add(pileupjv);
679     jPanel11.add(pirjv);
680     outputTab.add(autoIdWidth);
681     outputTab.add(userIdWidth);
682     outputTab.add(userIdWidthlabel);
683     outputTab.add(modellerOutput);
684     if (!Platform.isJS())
685     {
686       /*
687        * JalviewJS doesn't support Lineart option or SVG output
688        */
689       outputTab.add(embbedBioJSON);
690       outputTab.add(epsLabel);
691       outputTab.add(epsRendering);
692       outputTab.add(htmlLabel);
693       outputTab.add(htmlRendering);
694       outputTab.add(svgLabel);
695       outputTab.add(svgRendering);
696     }
697     outputTab.add(jPanel11);
698     return outputTab;
699   }
700
701   /**
702    * Initialises the Connections tabbed panel.
703    * 
704    * @return
705    */
706   private JPanel initConnectionsTab()
707   {
708     connectTab = new JPanel();
709     connectTab.setLayout(new GridBagLayout());
710
711     // Label for browser text box
712     JLabel browserLabel = new JLabel();
713     browserLabel.setFont(LABEL_FONT);
714     browserLabel.setHorizontalAlignment(SwingConstants.TRAILING);
715     browserLabel.setText(
716             MessageManager.getString("label.default_browser_unix"));
717     defaultBrowser.setFont(LABEL_FONT);
718     defaultBrowser.setText("");
719     final String tooltip = JvSwingUtils.wrapTooltip(true,
720             MessageManager.getString("label.double_click_to_browse"));
721     defaultBrowser.setToolTipText(tooltip);
722     defaultBrowser.addMouseListener(new MouseAdapter()
723     {
724       @Override
725       public void mouseClicked(MouseEvent e)
726       {
727         if (e.getClickCount() > 1)
728         {
729           defaultBrowser_mouseClicked(e);
730         }
731       }
732     });
733
734     JPanel proxyPanel = initConnTabProxyPanel();
735     initConnTabCheckboxes();
736
737     // Add default Browser text box
738     connectTab.add(browserLabel,
739             new GridBagConstraints(0, 0, 1, 1, 0.0, 0.0,
740                     GridBagConstraints.WEST, GridBagConstraints.NONE,
741                     new Insets(10, 0, 5, 5), 5, 1));
742     defaultBrowser.setFont(LABEL_FONT);
743     defaultBrowser.setText("");
744
745     connectTab.add(defaultBrowser, new GridBagConstraints(1, 0, 1, 1, 1.0,
746             0.0, GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL,
747             new Insets(10, 0, 5, 10), 30, 1));
748
749     // Add proxy server panel
750     connectTab.add(proxyPanel, new GridBagConstraints(0, 1, 2, 1, 1.0, 0.0,
751             GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL,
752             new Insets(10, 0, 5, 12), 4, 10));
753
754     // Add usage stats, version check and questionnaire checkboxes
755     connectTab.add(usagestats,
756             new GridBagConstraints(0, 2, 1, 1, 1.0, 0.0,
757                     GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL,
758                     new Insets(0, 2, 5, 5), 70, 1));
759     connectTab.add(questionnaire,
760             new GridBagConstraints(1, 2, 1, 1, 1.0, 0.0,
761                     GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL,
762                     new Insets(0, 2, 5, 10), 70, 1));
763     connectTab.add(versioncheck,
764             new GridBagConstraints(0, 3, 1, 1, 1.0, 0.0,
765                     GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL,
766                     new Insets(0, 2, 5, 5), 70, 1));
767
768     versioncheck.setVisible(false);
769
770     // Add padding so the panel doesn't look ridiculous
771     JPanel spacePanel = new JPanel();
772     connectTab.add(spacePanel,
773             new GridBagConstraints(0, 4, 1, 1, 1.0, 1.0,
774                     GridBagConstraints.WEST, GridBagConstraints.BOTH,
775                     new Insets(0, 0, 0, 5), 70, 1));
776
777     return connectTab;
778   }
779
780   /**
781    * Initialises the Links tabbed panel.
782    * 
783    * @return
784    */
785   private JPanel initLinksTab()
786   {
787     JPanel linkTab = new JPanel();
788     linkTab.setLayout(new GridBagLayout());
789
790     // Set up table for Url links
791     linkUrlTable.getTableHeader().setReorderingAllowed(false);
792     linkUrlTable.setFillsViewportHeight(true);
793     linkUrlTable.setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS);
794     linkUrlTable.setAutoCreateRowSorter(true);
795     linkUrlTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
796
797     // adjust row height so radio buttons actually fit
798     // don't do this in the renderer, it causes the awt thread to activate
799     // constantly
800     JRadioButton temp = new JRadioButton();
801     linkUrlTable.setRowHeight(temp.getMinimumSize().height);
802
803     // Table in scrollpane so that the table is given a scrollbar
804     JScrollPane linkScrollPane = new JScrollPane(linkUrlTable);
805     linkScrollPane.setBorder(null);
806
807     // Panel for links functionality
808     JPanel linkPanel = new JPanel(new GridBagLayout());
809     linkPanel.setBorder(new TitledBorder(
810             MessageManager.getString("label.url_linkfrom_sequence_id")));
811
812     // Put the Url links panel together
813
814     // Buttons go at top right, resizing only resizes the blank space vertically
815     JPanel buttonPanel = initLinkTabUrlButtons();
816     GridBagConstraints linkConstraints1 = new GridBagConstraints();
817     linkConstraints1.insets = new Insets(0, 0, 5, 0);
818     linkConstraints1.gridx = 0;
819     linkConstraints1.gridy = 0;
820     linkConstraints1.weightx = 1.0;
821     linkConstraints1.fill = GridBagConstraints.HORIZONTAL;
822     linkTab.add(buttonPanel, linkConstraints1);
823
824     // Links table goes at top left, resizing resizes the table
825     GridBagConstraints linkConstraints2 = new GridBagConstraints();
826     linkConstraints2.insets = new Insets(0, 0, 5, 5);
827     linkConstraints2.gridx = 0;
828     linkConstraints2.gridy = 1;
829     linkConstraints2.weightx = 1.0;
830     linkConstraints2.weighty = 1.0;
831     linkConstraints2.fill = GridBagConstraints.BOTH;
832     linkTab.add(linkScrollPane, linkConstraints2);
833
834     // Filter box and buttons goes at bottom left, resizing resizes the text box
835     JPanel filterPanel = initLinkTabFilterPanel();
836     GridBagConstraints linkConstraints3 = new GridBagConstraints();
837     linkConstraints3.insets = new Insets(0, 0, 0, 5);
838     linkConstraints3.gridx = 0;
839     linkConstraints3.gridy = 2;
840     linkConstraints3.weightx = 1.0;
841     linkConstraints3.fill = GridBagConstraints.HORIZONTAL;
842     linkTab.add(filterPanel, linkConstraints3);
843
844     return linkTab;
845   }
846
847   private JPanel initLinkTabFilterPanel()
848   {
849     // Filter textbox and reset button
850     JLabel filterLabel = new JLabel(
851             MessageManager.getString("label.filter"));
852     filterLabel.setFont(LABEL_FONT);
853     filterLabel.setHorizontalAlignment(SwingConstants.RIGHT);
854     filterLabel.setHorizontalTextPosition(SwingConstants.LEADING);
855
856     filterTB.setFont(LABEL_FONT);
857     filterTB.setText("");
858
859     doReset.setText(MessageManager.getString("action.showall"));
860     userOnly.setText(MessageManager.getString("action.customfilter"));
861
862     // Panel for filter functionality
863     JPanel filterPanel = new JPanel(new GridBagLayout());
864     filterPanel.setBorder(new TitledBorder("Filter"));
865     GridBagConstraints gbc = new GridBagConstraints();
866     gbc.gridx = 0;
867     gbc.gridy = 0;
868     gbc.fill = GridBagConstraints.NONE;
869     gbc.anchor = GridBagConstraints.WEST;
870
871     filterPanel.add(filterLabel, gbc);
872
873     GridBagConstraints gbc1 = new GridBagConstraints();
874     gbc1.gridx = 1;
875     gbc1.gridwidth = 2;
876     gbc1.fill = GridBagConstraints.HORIZONTAL;
877     gbc1.anchor = GridBagConstraints.WEST;
878     gbc1.weightx = 1.0;
879     filterPanel.add(filterTB, gbc1);
880
881     GridBagConstraints gbc2 = new GridBagConstraints();
882     gbc2.gridx = 3;
883     gbc2.fill = GridBagConstraints.NONE;
884     gbc2.anchor = GridBagConstraints.WEST;
885     filterPanel.add(doReset, gbc2);
886
887     GridBagConstraints gbc3 = new GridBagConstraints();
888     gbc3.gridx = 4;
889     gbc3.fill = GridBagConstraints.NONE;
890     gbc3.anchor = GridBagConstraints.WEST;
891     filterPanel.add(userOnly, gbc3);
892
893     return filterPanel;
894   }
895
896   private JPanel initLinkTabUrlButtons()
897   {
898     // Buttons for new / edit / delete Url links
899     JButton newLink = new JButton();
900     newLink.setText(MessageManager.getString("action.new"));
901
902     editLink.setText(MessageManager.getString("action.edit"));
903
904     deleteLink.setText(MessageManager.getString("action.delete"));
905
906     // no current selection, so initially disable delete/edit buttons
907     editLink.setEnabled(false);
908     deleteLink.setEnabled(false);
909
910     newLink.addActionListener(new java.awt.event.ActionListener()
911     {
912       @Override
913       public void actionPerformed(ActionEvent e)
914       {
915         newLink_actionPerformed(e);
916       }
917     });
918
919     editLink.setText(MessageManager.getString("action.edit"));
920     editLink.addActionListener(new java.awt.event.ActionListener()
921     {
922       @Override
923       public void actionPerformed(ActionEvent e)
924       {
925         editLink_actionPerformed(e);
926       }
927     });
928
929     deleteLink.setText(MessageManager.getString("action.delete"));
930     deleteLink.addActionListener(new java.awt.event.ActionListener()
931     {
932       @Override
933       public void actionPerformed(ActionEvent e)
934       {
935         deleteLink_actionPerformed(e);
936       }
937     });
938
939     JPanel buttonPanel = new JPanel(new GridBagLayout());
940     buttonPanel.setBorder(new TitledBorder("Edit links"));
941     GridBagConstraints gbc = new GridBagConstraints();
942     gbc.gridx = 0;
943     gbc.gridy = 0;
944     gbc.fill = GridBagConstraints.NONE;
945     buttonPanel.add(newLink, gbc);
946
947     GridBagConstraints gbc1 = new GridBagConstraints();
948     gbc1.gridx = 1;
949     gbc1.gridy = 0;
950     gbc1.fill = GridBagConstraints.NONE;
951     buttonPanel.add(editLink, gbc1);
952
953     GridBagConstraints gbc2 = new GridBagConstraints();
954     gbc2.gridx = 2;
955     gbc2.gridy = 0;
956     gbc2.fill = GridBagConstraints.NONE;
957     buttonPanel.add(deleteLink, gbc2);
958
959     GridBagConstraints gbc3 = new GridBagConstraints();
960     gbc3.gridx = 3;
961     gbc3.gridy = 0;
962     gbc3.fill = GridBagConstraints.HORIZONTAL;
963     gbc3.weightx = 1.0;
964     JPanel spacePanel = new JPanel();
965     spacePanel.setBorder(null);
966     buttonPanel.add(spacePanel, gbc3);
967
968     return buttonPanel;
969   }
970
971   /**
972    * Initialises the proxy server panel in the Connections tab
973    * 
974    * @return the proxy server panel
975    */
976   private JPanel initConnTabProxyPanel()
977   {
978     // Label for server text box
979     serverLabel.setText(MessageManager.getString("label.host") + ": ");
980     serverLabel.setHorizontalAlignment(SwingConstants.RIGHT);
981     serverLabel.setFont(LABEL_FONT);
982     serverLabel2.setText(MessageManager.getString("label.host") + ": ");
983     serverLabel2.setHorizontalAlignment(SwingConstants.RIGHT);
984     serverLabel2.setFont(LABEL_FONT);
985
986     // Proxy server and port text boxes
987     proxyServerHttpTB.setFont(LABEL_FONT);
988     proxyServerHttpTB.setColumns(40);
989     proxyPortHttpTB.setFont(LABEL_FONT);
990     proxyPortHttpTB.setColumns(4);
991     proxyServerHttpsTB.setFont(LABEL_FONT);
992     proxyServerHttpsTB.setColumns(40);
993     proxyPortHttpsTB.setFont(LABEL_FONT);
994     proxyPortHttpsTB.setColumns(4);
995     proxyAuthUsernameTB.setFont(LABEL_FONT);
996     proxyAuthUsernameTB.setColumns(30);
997
998     // check for any change to enable applyProxyButton
999     DocumentListener d = new DocumentListener()
1000     {
1001       @Override
1002       public void changedUpdate(DocumentEvent e)
1003       {
1004         applyProxyButtonEnabled(true);
1005       }
1006
1007       @Override
1008       public void insertUpdate(DocumentEvent e)
1009       {
1010         applyProxyButtonEnabled(true);
1011       }
1012
1013       @Override
1014       public void removeUpdate(DocumentEvent e)
1015       {
1016         applyProxyButtonEnabled(true);
1017       }
1018     };
1019     proxyServerHttpTB.getDocument().addDocumentListener(d);
1020     proxyPortHttpTB.getDocument().addDocumentListener(d);
1021     proxyServerHttpsTB.getDocument().addDocumentListener(d);
1022     proxyPortHttpsTB.getDocument().addDocumentListener(d);
1023     proxyAuthUsernameTB.getDocument().addDocumentListener(d);
1024     proxyAuthPasswordPB.setFont(LABEL_FONT);
1025     proxyAuthPasswordPB.setColumns(30);
1026     proxyAuthPasswordPB.getDocument()
1027             .addDocumentListener(new DocumentListener()
1028             {
1029               @Override
1030               public void changedUpdate(DocumentEvent e)
1031               {
1032                 proxyAuthPasswordCheckHighlight(true);
1033                 applyProxyButtonEnabled(true);
1034               }
1035
1036               @Override
1037               public void insertUpdate(DocumentEvent e)
1038               {
1039                 proxyAuthPasswordCheckHighlight(true);
1040                 applyProxyButtonEnabled(true);
1041               }
1042
1043               @Override
1044               public void removeUpdate(DocumentEvent e)
1045               {
1046                 proxyAuthPasswordCheckHighlight(true);
1047                 applyProxyButtonEnabled(true);
1048               }
1049
1050             });
1051
1052     // Label for Port text box
1053     portLabel.setFont(LABEL_FONT);
1054     portLabel.setHorizontalAlignment(SwingConstants.RIGHT);
1055     portLabel.setText(MessageManager.getString("label.port") + ": ");
1056     portLabel2.setFont(LABEL_FONT);
1057     portLabel2.setHorizontalAlignment(SwingConstants.RIGHT);
1058     portLabel2.setText(MessageManager.getString("label.port") + ": ");
1059
1060     httpLabel.setText("HTTP");
1061     httpLabel.setFont(LABEL_FONT_BOLD);
1062     httpLabel.setHorizontalAlignment(SwingConstants.LEFT);
1063     httpsLabel.setText("HTTPS");
1064     httpsLabel.setFont(LABEL_FONT_BOLD);
1065     httpsLabel.setHorizontalAlignment(SwingConstants.LEFT);
1066
1067     proxyAuthUsernameLabel
1068             .setText(MessageManager.getString("label.username") + ": ");
1069     proxyAuthUsernameLabel.setFont(LABEL_FONT);
1070     proxyAuthUsernameLabel.setHorizontalAlignment(SwingConstants.RIGHT);
1071     proxyAuthPasswordLabel
1072             .setText(MessageManager.getString("label.password") + ": ");
1073     proxyAuthPasswordLabel.setFont(LABEL_FONT);
1074     proxyAuthPasswordLabel.setHorizontalAlignment(SwingConstants.RIGHT);
1075     passwordNotStoredLabel.setText(
1076             "(" + MessageManager.getString("label.not_stored") + ")");
1077     passwordNotStoredLabel.setFont(LABEL_FONT_ITALIC);
1078     passwordNotStoredLabel.setHorizontalAlignment(SwingConstants.LEFT);
1079
1080     // Proxy type radio buttons
1081     noProxy.setFont(LABEL_FONT);
1082     noProxy.setHorizontalAlignment(SwingConstants.LEFT);
1083     noProxy.setText(MessageManager.getString("label.no_proxy"));
1084     systemProxy.setFont(LABEL_FONT);
1085     systemProxy.setHorizontalAlignment(SwingConstants.LEFT);
1086     systemProxy.setText(MessageManager.formatMessage("label.system_proxy",
1087             displayUserHostPort(Cache.startupProxyProperties[4],
1088                     Cache.startupProxyProperties[0],
1089                     Cache.startupProxyProperties[1]),
1090             displayUserHostPort(Cache.startupProxyProperties[6],
1091                     Cache.startupProxyProperties[2],
1092                     Cache.startupProxyProperties[3])));
1093     customProxy.setFont(LABEL_FONT);
1094     customProxy.setHorizontalAlignment(SwingConstants.LEFT);
1095     customProxy.setText(
1096             MessageManager.getString("label.use_proxy_server") + ":");
1097     ActionListener al = new ActionListener()
1098     {
1099       @Override
1100       public void actionPerformed(ActionEvent e)
1101       {
1102         proxyType_actionPerformed();
1103       }
1104     };
1105     noProxy.addActionListener(al);
1106     systemProxy.addActionListener(al);
1107     customProxy.addActionListener(al);
1108     proxyType.add(noProxy);
1109     proxyType.add(systemProxy);
1110     proxyType.add(customProxy);
1111
1112     proxyAuth.setFont(LABEL_FONT);
1113     proxyAuth.setHorizontalAlignment(SwingConstants.LEFT);
1114     proxyAuth.setText(MessageManager.getString("label.auth_required"));
1115     proxyAuth.addActionListener(new ActionListener()
1116     {
1117       @Override
1118       public void actionPerformed(ActionEvent e)
1119       {
1120         proxyAuth_actionPerformed();
1121       }
1122     });
1123
1124     setCustomProxyEnabled();
1125
1126     // Make proxy server panel
1127     JPanel proxyPanel = new JPanel();
1128     TitledBorder titledBorder1 = new TitledBorder(
1129             MessageManager.getString("label.proxy_servers"));
1130     proxyPanel.setBorder(titledBorder1);
1131     proxyPanel.setLayout(new GridBagLayout());
1132     GridBagConstraints gbc = new GridBagConstraints();
1133     gbc.fill = GridBagConstraints.HORIZONTAL;
1134     gbc.weightx = 1.0;
1135
1136     GridBagConstraints c = new GridBagConstraints();
1137     // Proxy type radio buttons (3)
1138     JPanel ptPanel = new JPanel();
1139     ptPanel.setLayout(new GridBagLayout());
1140     c.weightx = 1.0;
1141     c.gridy = 0;
1142     c.gridx = 0;
1143     c.gridwidth = 1;
1144     c.fill = GridBagConstraints.HORIZONTAL;
1145     ptPanel.add(noProxy, c);
1146     c.gridy++;
1147     ptPanel.add(systemProxy, c);
1148     c.gridy++;
1149     ptPanel.add(customProxy, c);
1150
1151     gbc.gridy = 0;
1152     proxyPanel.add(ptPanel, gbc);
1153
1154     // host and port text boxes
1155     JPanel hpPanel = new JPanel();
1156     hpPanel.setLayout(new GridBagLayout());
1157     // HTTP host port row
1158     c.gridy = 0;
1159     c.gridx = 0;
1160
1161     c.weightx = 0.1;
1162     c.anchor = GridBagConstraints.LINE_START;
1163     hpPanel.add(httpLabel, c);
1164
1165     c.gridx++;
1166     c.weightx = 0.1;
1167     c.anchor = GridBagConstraints.LINE_END;
1168     hpPanel.add(serverLabel, c);
1169
1170     c.gridx++;
1171     c.weightx = 1.0;
1172     c.anchor = GridBagConstraints.LINE_START;
1173     hpPanel.add(proxyServerHttpTB, c);
1174
1175     c.gridx++;
1176     c.weightx = 0.1;
1177     c.anchor = GridBagConstraints.LINE_END;
1178     hpPanel.add(portLabel, c);
1179
1180     c.gridx++;
1181     c.weightx = 0.2;
1182     c.anchor = GridBagConstraints.LINE_START;
1183     hpPanel.add(proxyPortHttpTB, c);
1184
1185     // HTTPS host port row
1186     c.gridy++;
1187     c.gridx = 0;
1188     c.gridwidth = 1;
1189
1190     c.anchor = GridBagConstraints.LINE_START;
1191     hpPanel.add(httpsLabel, c);
1192
1193     c.gridx++;
1194     c.anchor = GridBagConstraints.LINE_END;
1195     hpPanel.add(serverLabel2, c);
1196
1197     c.gridx++;
1198     c.anchor = GridBagConstraints.LINE_START;
1199     hpPanel.add(proxyServerHttpsTB, c);
1200
1201     c.gridx++;
1202     c.anchor = GridBagConstraints.LINE_END;
1203     hpPanel.add(portLabel2, c);
1204
1205     c.gridx++;
1206     c.anchor = GridBagConstraints.LINE_START;
1207     hpPanel.add(proxyPortHttpsTB, c);
1208
1209     gbc.gridy++;
1210     proxyPanel.add(hpPanel, gbc);
1211
1212     if (!Platform.isJS())
1213     /**
1214      * java.net.Authenticator is not implemented in SwingJS. Not displaying the
1215      * Authentication options in Preferences.
1216      * 
1217      * @j2sIgnore
1218      * 
1219      */
1220     {
1221       // Require authentication checkbox
1222       gbc.gridy++;
1223       proxyPanel.add(proxyAuth, gbc);
1224
1225       // username and password
1226       JPanel upPanel = new JPanel();
1227       upPanel.setLayout(new GridBagLayout());
1228       // username row
1229       c.gridy = 0;
1230       c.gridx = 0;
1231       c.gridwidth = 1;
1232       c.weightx = 0.4;
1233       c.anchor = GridBagConstraints.LINE_END;
1234       upPanel.add(proxyAuthUsernameLabel, c);
1235
1236       c.gridx++;
1237       c.weightx = 1.0;
1238       c.anchor = GridBagConstraints.LINE_START;
1239       upPanel.add(proxyAuthUsernameTB, c);
1240
1241       // password row
1242       c.gridy++;
1243       c.gridx = 0;
1244       c.weightx = 0.4;
1245       c.anchor = GridBagConstraints.LINE_END;
1246       upPanel.add(proxyAuthPasswordLabel, c);
1247
1248       c.gridx++;
1249       c.weightx = 1.0;
1250       c.anchor = GridBagConstraints.LINE_START;
1251       upPanel.add(proxyAuthPasswordPB, c);
1252
1253       c.gridx++;
1254       c.weightx = 0.4;
1255       c.anchor = GridBagConstraints.LINE_START;
1256       upPanel.add(passwordNotStoredLabel, c);
1257
1258       gbc.gridy++;
1259       proxyPanel.add(upPanel, gbc);
1260
1261     } // end j2sIgnore
1262
1263     applyProxyButton.setText(MessageManager.getString("action.apply"));
1264     applyProxyButton.addActionListener(new ActionListener()
1265     {
1266       @Override
1267       public void actionPerformed(ActionEvent e)
1268       {
1269         saveProxySettings();
1270         applyProxyButton.setEnabled(false);
1271       }
1272     });
1273     gbc.gridy++;
1274     gbc.fill = GridBagConstraints.NONE;
1275     gbc.anchor = GridBagConstraints.LINE_END;
1276     proxyPanel.add(applyProxyButton, gbc);
1277
1278     return proxyPanel;
1279   }
1280
1281   public void proxyAuthPasswordCheckHighlight(boolean enabled)
1282   {
1283     proxyAuthPasswordCheckHighlight(enabled, false);
1284   }
1285
1286   public void proxyAuthPasswordCheckHighlight(boolean enabled,
1287           boolean grabFocus)
1288   {
1289     if (enabled && proxyType.isSelected(customProxy.getModel())
1290             && proxyAuth.isSelected()
1291             && !proxyAuthUsernameTB.getText().isEmpty()
1292             && proxyAuthPasswordPB.getDocument().getLength() == 0)
1293     {
1294       if (grabFocus)
1295         proxyAuthPasswordPB.grabFocus();
1296       proxyAuthPasswordPB.setBackground(Color.PINK);
1297     }
1298     else
1299     {
1300       proxyAuthPasswordPB.setBackground(Color.WHITE);
1301     }
1302   }
1303
1304   public void applyProxyButtonEnabled(boolean enabled)
1305   {
1306     applyProxyButton.setEnabled(enabled);
1307   }
1308
1309   public void saveProxySettings()
1310   {
1311     // overridden in Preferences
1312   }
1313
1314   private String displayUserHostPort(String user, String host, String port)
1315   {
1316     boolean hostBlank = (host == null || host.isEmpty());
1317     boolean portBlank = (port == null || port.isEmpty());
1318     if (hostBlank && portBlank)
1319     {
1320       return MessageManager.getString("label.none");
1321     }
1322
1323     StringBuilder sb = new StringBuilder();
1324     if (user != null)
1325     {
1326       sb.append(user.isEmpty() || user.indexOf(" ") > -1 ? '"' + user + '"'
1327               : user);
1328       sb.append("@");
1329     }
1330     sb.append(hostBlank ? "" : host);
1331     if (!portBlank)
1332     {
1333       sb.append(":");
1334       sb.append(port);
1335     }
1336     return sb.toString();
1337   }
1338
1339   /**
1340    * Initialises the checkboxes in the Connections tab
1341    */
1342   private void initConnTabCheckboxes()
1343   {
1344     // Usage stats checkbox label
1345     usagestats.setText(
1346             MessageManager.getString("label.send_usage_statistics"));
1347     usagestats.setFont(LABEL_FONT);
1348     usagestats.setHorizontalAlignment(SwingConstants.RIGHT);
1349     usagestats.setHorizontalTextPosition(SwingConstants.LEADING);
1350
1351     // Questionnaire checkbox label
1352     questionnaire.setText(
1353             MessageManager.getString("label.check_for_questionnaires"));
1354     questionnaire.setFont(LABEL_FONT);
1355     questionnaire.setHorizontalAlignment(SwingConstants.RIGHT);
1356     questionnaire.setHorizontalTextPosition(SwingConstants.LEADING);
1357
1358     // Check for latest version checkbox label
1359     versioncheck.setText(
1360             MessageManager.getString("label.check_for_latest_version"));
1361     versioncheck.setFont(LABEL_FONT);
1362     versioncheck.setHorizontalAlignment(SwingConstants.RIGHT);
1363     versioncheck.setHorizontalTextPosition(SwingConstants.LEADING);
1364   }
1365
1366   /**
1367    * Initialises the parent panel which contains the tabbed sections.
1368    * 
1369    * @return
1370    */
1371   private JPanel initOkCancelPanel()
1372   {
1373     JButton ok = new JButton();
1374     ok.setText(MessageManager.getString("action.ok"));
1375     ok.addActionListener(new ActionListener()
1376     {
1377       @Override
1378       public void actionPerformed(ActionEvent e)
1379       {
1380         ok_actionPerformed(e);
1381       }
1382     });
1383     JButton cancel = new JButton();
1384     cancel.setText(MessageManager.getString("action.cancel"));
1385     cancel.addActionListener(new ActionListener()
1386     {
1387       @Override
1388       public void actionPerformed(ActionEvent e)
1389       {
1390         cancel_actionPerformed(e);
1391       }
1392     });
1393     JPanel okCancelPanel = new JPanel();
1394     okCancelPanel.add(ok);
1395     okCancelPanel.add(cancel);
1396     return okCancelPanel;
1397   }
1398
1399   /**
1400    * Initialises the Colours tabbed panel.
1401    * 
1402    * @return
1403    */
1404   private JPanel initColoursTab()
1405   {
1406     JPanel coloursTab = new JPanel();
1407     coloursTab.setBorder(new TitledBorder(
1408             MessageManager.getString("action.open_new_alignment")));
1409     coloursTab.setLayout(new FlowLayout());
1410     JLabel mincolourLabel = new JLabel();
1411     mincolourLabel.setFont(LABEL_FONT);
1412     mincolourLabel.setHorizontalAlignment(SwingConstants.RIGHT);
1413     mincolourLabel.setText(MessageManager.getString("label.min_colour"));
1414     minColour.setFont(LABEL_FONT);
1415     minColour.setBorder(BorderFactory.createEtchedBorder());
1416     minColour.setPreferredSize(new Dimension(40, 20));
1417     minColour.addMouseListener(new MouseAdapter()
1418     {
1419       @Override
1420       public void mousePressed(MouseEvent e)
1421       {
1422         minColour_actionPerformed(minColour);
1423       }
1424     });
1425     JLabel maxcolourLabel = new JLabel();
1426     maxcolourLabel.setFont(LABEL_FONT);
1427     maxcolourLabel.setHorizontalAlignment(SwingConstants.RIGHT);
1428     maxcolourLabel.setText(MessageManager.getString("label.max_colour"));
1429     maxColour.setFont(LABEL_FONT);
1430     maxColour.setBorder(BorderFactory.createEtchedBorder());
1431     maxColour.setPreferredSize(new Dimension(40, 20));
1432     maxColour.addMouseListener(new MouseAdapter()
1433     {
1434       @Override
1435       public void mousePressed(MouseEvent e)
1436       {
1437         maxColour_actionPerformed(maxColour);
1438       }
1439     });
1440
1441     protColour.setFont(LABEL_FONT);
1442     protColour.setBounds(new Rectangle(172, 225, 155, 21));
1443     JLabel protColourLabel = new JLabel();
1444     protColourLabel.setFont(LABEL_FONT);
1445     protColourLabel.setHorizontalAlignment(SwingConstants.LEFT);
1446     protColourLabel.setText(
1447             MessageManager.getString("label.prot_alignment_colour") + " ");
1448     JvSwingUtils.addtoLayout(coloursTab,
1449             MessageManager
1450                     .getString("label.default_colour_scheme_for_alignment"),
1451             protColourLabel, protColour);
1452
1453     nucColour.setFont(LABEL_FONT);
1454     nucColour.setBounds(new Rectangle(172, 240, 155, 21));
1455     JLabel nucColourLabel = new JLabel();
1456     nucColourLabel.setFont(LABEL_FONT);
1457     nucColourLabel.setHorizontalAlignment(SwingConstants.LEFT);
1458     nucColourLabel.setText(
1459             MessageManager.getString("label.nuc_alignment_colour") + " ");
1460     JvSwingUtils.addtoLayout(coloursTab,
1461             MessageManager
1462                     .getString("label.default_colour_scheme_for_alignment"),
1463             nucColourLabel, nucColour);
1464
1465     JPanel annotationShding = new JPanel();
1466     annotationShding.setBorder(new TitledBorder(
1467             MessageManager.getString("label.annotation_shading_default")));
1468     annotationShding.setLayout(new GridLayout(1, 2));
1469     JvSwingUtils.addtoLayout(annotationShding,
1470             MessageManager.getString(
1471                     "label.default_minimum_colour_annotation_shading"),
1472             mincolourLabel, minColour);
1473     JvSwingUtils.addtoLayout(annotationShding,
1474             MessageManager.getString(
1475                     "label.default_maximum_colour_annotation_shading"),
1476             maxcolourLabel, maxColour);
1477     coloursTab.add(annotationShding); // , FlowLayout.LEFT);
1478     return coloursTab;
1479   }
1480
1481   /**
1482    * Initialises the Overview tabbed panel.
1483    * 
1484    * @return
1485    */
1486   private JPanel initOverviewTab()
1487   {
1488     JPanel overviewPanel = new JPanel();
1489     overviewPanel.setBorder(new TitledBorder(
1490             MessageManager.getString("label.overview_settings")));
1491
1492     gapColour.setFont(LABEL_FONT);
1493     // fixing the border colours stops apparent colour bleed from the panel
1494     gapColour.setBorder(
1495             BorderFactory.createEtchedBorder(Color.white, Color.lightGray));
1496     gapColour.setPreferredSize(new Dimension(40, 20));
1497     gapColour.addMouseListener(new MouseAdapter()
1498     {
1499       @Override
1500       public void mousePressed(MouseEvent e)
1501       {
1502         gapColour_actionPerformed(gapColour);
1503       }
1504     });
1505
1506     hiddenColour.setFont(LABEL_FONT);
1507     // fixing the border colours stops apparent colour bleed from the panel
1508     hiddenColour.setBorder(
1509             BorderFactory.createEtchedBorder(Color.white, Color.lightGray));
1510     hiddenColour.setPreferredSize(new Dimension(40, 20));
1511     hiddenColour.addMouseListener(new MouseAdapter()
1512     {
1513       @Override
1514       public void mousePressed(MouseEvent e)
1515       {
1516         hiddenColour_actionPerformed(hiddenColour);
1517       }
1518     });
1519
1520     useLegacyGap = new JCheckBox(
1521             MessageManager.getString("label.ov_legacy_gap"));
1522     useLegacyGap.setFont(LABEL_FONT);
1523     useLegacyGap.setHorizontalAlignment(SwingConstants.LEFT);
1524     useLegacyGap.setVerticalTextPosition(SwingConstants.TOP);
1525     gapLabel = new JLabel(MessageManager.getString("label.gap_colour"));
1526     gapLabel.setFont(LABEL_FONT);
1527     gapLabel.setHorizontalAlignment(SwingConstants.LEFT);
1528     gapLabel.setVerticalTextPosition(SwingConstants.TOP);
1529     showHiddenAtStart = new JCheckBox(
1530             MessageManager.getString("label.ov_show_hide_default"));
1531     showHiddenAtStart.setFont(LABEL_FONT);
1532     showHiddenAtStart.setHorizontalAlignment(SwingConstants.LEFT);
1533     showHiddenAtStart.setVerticalTextPosition(SwingConstants.TOP);
1534     JLabel hiddenLabel = new JLabel(
1535             MessageManager.getString("label.hidden_colour"));
1536     hiddenLabel.setFont(LABEL_FONT);
1537     hiddenLabel.setHorizontalAlignment(SwingConstants.LEFT);
1538     hiddenLabel.setVerticalTextPosition(SwingConstants.TOP);
1539
1540     useLegacyGap.addActionListener(new ActionListener()
1541     {
1542       @Override
1543       public void actionPerformed(ActionEvent e)
1544       {
1545         useLegacyGaps_actionPerformed(e);
1546       }
1547     });
1548
1549     overviewPanel.setLayout(new GridBagLayout());
1550     GridBagConstraints c1 = new GridBagConstraints();
1551
1552     c1.fill = GridBagConstraints.HORIZONTAL;
1553     c1.gridx = 0;
1554     c1.gridy = 0;
1555     c1.weightx = 1;
1556     c1.ipady = 20;
1557     c1.anchor = GridBagConstraints.FIRST_LINE_START;
1558     overviewPanel.add(useLegacyGap, c1);
1559
1560     GridBagConstraints c2 = new GridBagConstraints();
1561     c2.fill = GridBagConstraints.HORIZONTAL;
1562     c2.gridx = 1;
1563     c2.gridy = 0;
1564     c2.insets = new Insets(0, 15, 0, 10);
1565     overviewPanel.add(gapLabel, c2);
1566
1567     GridBagConstraints c3 = new GridBagConstraints();
1568     c3.fill = GridBagConstraints.HORIZONTAL;
1569     c3.gridx = 2;
1570     c3.gridy = 0;
1571     c3.insets = new Insets(0, 0, 0, 15);
1572     overviewPanel.add(gapColour, c3);
1573
1574     GridBagConstraints c4 = new GridBagConstraints();
1575     c4.fill = GridBagConstraints.HORIZONTAL;
1576     c4.gridx = 0;
1577     c4.gridy = 1;
1578     c4.weightx = 1;
1579     overviewPanel.add(showHiddenAtStart, c4);
1580
1581     GridBagConstraints c5 = new GridBagConstraints();
1582     c5.fill = GridBagConstraints.HORIZONTAL;
1583     c5.gridx = 1;
1584     c5.gridy = 1;
1585     c5.insets = new Insets(0, 15, 0, 10);
1586     overviewPanel.add(hiddenLabel, c5);
1587
1588     GridBagConstraints c6 = new GridBagConstraints();
1589     c6.fill = GridBagConstraints.HORIZONTAL;
1590     c6.gridx = 2;
1591     c6.gridy = 1;
1592     c6.insets = new Insets(0, 0, 0, 15);
1593     overviewPanel.add(hiddenColour, c6);
1594
1595     JButton resetButton = new JButton(
1596             MessageManager.getString("label.reset_to_defaults"));
1597
1598     resetButton.addActionListener(new ActionListener()
1599     {
1600       @Override
1601       public void actionPerformed(ActionEvent e)
1602       {
1603         resetOvDefaults_actionPerformed(e);
1604       }
1605     });
1606
1607     GridBagConstraints c7 = new GridBagConstraints();
1608     c7.fill = GridBagConstraints.NONE;
1609     c7.gridx = 0;
1610     c7.gridy = 2;
1611     c7.insets = new Insets(10, 0, 0, 0);
1612     c7.anchor = GridBagConstraints.WEST;
1613     overviewPanel.add(resetButton, c7);
1614
1615     // Add padding so the panel doesn't look ridiculous
1616     JPanel spacePanel = new JPanel();
1617     overviewPanel.add(spacePanel,
1618             new GridBagConstraints(0, 3, 1, 1, 1.0, 1.0,
1619                     GridBagConstraints.WEST, GridBagConstraints.BOTH,
1620                     new Insets(0, 0, 0, 5), 0, 0));
1621
1622     return overviewPanel;
1623   }
1624
1625   /**
1626    * Initialises the Structure tabbed panel.
1627    * 
1628    * @return
1629    */
1630   private JPanel initStructureTab()
1631   {
1632     structureTab = new JPanel();
1633
1634     structureTab.setBorder(new TitledBorder(
1635             MessageManager.getString("label.structure_options")));
1636     structureTab.setLayout(null);
1637     final int width = 420;
1638     final int height = 22;
1639     final int lineSpacing = 25;
1640     int ypos = 15;
1641
1642     structFromPdb.setFont(LABEL_FONT);
1643     structFromPdb
1644             .setText(MessageManager.getString("label.struct_from_pdb"));
1645     structFromPdb.setBounds(new Rectangle(5, ypos, width, height));
1646     structFromPdb.addActionListener(new ActionListener()
1647     {
1648       @Override
1649       public void actionPerformed(ActionEvent e)
1650       {
1651         boolean selected = structFromPdb.isSelected();
1652         // enable other options only when the first is checked
1653         addSecondaryStructure.setEnabled(selected);
1654         addTempFactor.setEnabled(selected);
1655       }
1656     });
1657     structureTab.add(structFromPdb);
1658
1659     // indent checkboxes that are conditional on the first one
1660     ypos += lineSpacing;
1661     addSecondaryStructure.setFont(LABEL_FONT);
1662     addSecondaryStructure
1663             .setText(MessageManager.getString("label.autoadd_secstr"));
1664     addSecondaryStructure.setBounds(new Rectangle(25, ypos, width, height));
1665     structureTab.add(addSecondaryStructure);
1666
1667     ypos += lineSpacing;
1668     addTempFactor.setFont(LABEL_FONT);
1669     addTempFactor.setText(MessageManager.getString("label.autoadd_temp"));
1670     addTempFactor.setBounds(new Rectangle(25, ypos, width, height));
1671     structureTab.add(addTempFactor);
1672
1673     ypos += lineSpacing;
1674     JLabel viewerLabel = new JLabel();
1675     viewerLabel.setFont(LABEL_FONT);
1676     viewerLabel.setHorizontalAlignment(SwingConstants.LEFT);
1677     viewerLabel.setText(MessageManager.getString("label.structure_viewer"));
1678     viewerLabel.setBounds(new Rectangle(10, ypos, 220, height));
1679     structureTab.add(viewerLabel);
1680
1681     /*
1682      * add all external viewers as options here - check 
1683      * when selected whether the program is installed
1684      */
1685     structViewer.setFont(LABEL_FONT);
1686     structViewer.setBounds(new Rectangle(190, ypos, 120, height));
1687     structViewer.addItem(ViewerType.JMOL.name());
1688     structViewer.addItem(ViewerType.CHIMERA.name());
1689     structViewer.addItem(ViewerType.CHIMERAX.name());
1690     structViewer.addItem(ViewerType.PYMOL.name());
1691     structViewer.addActionListener(new ActionListener()
1692     {
1693       @Override
1694       public void actionPerformed(ActionEvent e)
1695       {
1696         structureViewer_actionPerformed(
1697                 (String) structViewer.getSelectedItem());
1698       }
1699     });
1700     structureTab.add(structViewer);
1701
1702     ypos += lineSpacing;
1703     structureViewerPathLabel = new JLabel();
1704     structureViewerPathLabel.setFont(LABEL_FONT);// new Font("SansSerif", 0,
1705                                                  // 11));
1706     structureViewerPathLabel.setHorizontalAlignment(SwingConstants.LEFT);
1707     structureViewerPathLabel.setText(MessageManager
1708             .formatMessage("label.viewer_path", "Chimera(X)"));
1709     structureViewerPathLabel
1710             .setBounds(new Rectangle(10, ypos, 170, height));
1711     structureViewerPathLabel.setEnabled(false);
1712     structureTab.add(structureViewerPathLabel);
1713
1714     structureViewerPath.setFont(LABEL_FONT);
1715     structureViewerPath.setText("");
1716     structureViewerPath.setEnabled(false);
1717     final String tooltip = JvSwingUtils.wrapTooltip(true,
1718             MessageManager.getString("label.viewer_path_tip"));
1719     structureViewerPath.setToolTipText(tooltip);
1720     structureViewerPath.setBounds(new Rectangle(190, ypos, 290, height));
1721     structureViewerPath.addMouseListener(new MouseAdapter()
1722     {
1723       @Override
1724       public void mouseClicked(MouseEvent e)
1725       {
1726         if (structureViewerPath.isEnabled() && e.getClickCount() == 2)
1727         {
1728           String chosen = openFileChooser();
1729           if (chosen != null)
1730           {
1731             structureViewerPath.setText(chosen);
1732           }
1733         }
1734       }
1735     });
1736     structureTab.add(structureViewerPath);
1737
1738     ypos += lineSpacing;
1739     nwMapping.setFont(LABEL_FONT);
1740     nwMapping.setText(MessageManager.getString("label.nw_mapping"));
1741     siftsMapping.setFont(LABEL_FONT);
1742     siftsMapping.setText(MessageManager.getString("label.sifts_mapping"));
1743     mappingMethod.add(nwMapping);
1744     mappingMethod.add(siftsMapping);
1745     JPanel mappingPanel = new JPanel();
1746     mappingPanel.setFont(LABEL_FONT);
1747     TitledBorder mmTitledBorder = new TitledBorder(
1748             MessageManager.getString("label.mapping_method"));
1749     mmTitledBorder.setTitleFont(LABEL_FONT);
1750     mappingPanel.setBorder(mmTitledBorder);
1751     mappingPanel.setBounds(new Rectangle(10, ypos, 472, 45));
1752     // GridLayout mappingLayout = new GridLayout();
1753     mappingPanel.setLayout(new GridLayout());
1754     mappingPanel.add(nwMapping);
1755     mappingPanel.add(siftsMapping);
1756     structureTab.add(mappingPanel);
1757
1758     ypos += lineSpacing;
1759     ypos += lineSpacing;
1760     FTSDataColumnPreferences docFieldPref = new FTSDataColumnPreferences(
1761             PreferenceSource.PREFERENCES, PDBFTSRestClient.getInstance());
1762     docFieldPref.setBounds(new Rectangle(10, ypos, 470, 120));
1763     structureTab.add(docFieldPref);
1764
1765     /*
1766      * hide Chimera options in JalviewJS
1767      */
1768     if (Platform.isJS())
1769     {
1770       structureViewerPathLabel.setVisible(false);
1771       structureViewerPath.setVisible(false);
1772       viewerLabel.setVisible(false);
1773       structViewer.setVisible(false);
1774     }
1775
1776     return structureTab;
1777   }
1778
1779   /**
1780    * Action on choosing a structure viewer from combobox options.
1781    * 
1782    * @param selectedItem
1783    */
1784   protected void structureViewer_actionPerformed(String selectedItem)
1785   {
1786   }
1787
1788   /**
1789    * Show a dialog for the user to choose a file. Returns the chosen path, or null
1790    * on Cancel.
1791    * 
1792    * @return
1793    */
1794   protected String openFileChooser()
1795   {
1796     String choice = null;
1797     JFileChooser chooser = new JFileChooser();
1798
1799     // Enable appBundleIsTraversable in macOS FileChooser to allow selecting
1800     // hidden executables within .app dirs
1801     if (Platform.isMac())
1802     {
1803       chooser.putClientProperty("JFileChooser.appBundleIsTraversable",
1804               true);
1805     }
1806
1807     // chooser.setFileView(new JalviewFileView());
1808     chooser.setDialogTitle(
1809             MessageManager.getString("label.open_local_file"));
1810     chooser.setToolTipText(MessageManager.getString("action.open"));
1811
1812     int value = chooser.showOpenDialog(this);
1813
1814     if (value == JFileChooser.APPROVE_OPTION)
1815     {
1816       choice = chooser.getSelectedFile().getPath();
1817     }
1818     return choice;
1819   }
1820
1821   /**
1822    * Validate the structure tab preferences; if invalid, set focus on this tab.
1823    * 
1824    * @param e
1825    */
1826   protected boolean validateStructure(FocusEvent e)
1827   {
1828     if (!validateStructure())
1829     {
1830       e.getComponent().requestFocusInWindow();
1831       return false;
1832     }
1833     return true;
1834   }
1835
1836   protected boolean validateStructure()
1837   {
1838     return false;
1839   }
1840
1841   /**
1842    * Initialises the Visual tabbed panel.
1843    * 
1844    * @return
1845    */
1846   private JPanel initVisualTab()
1847   {
1848     JPanel visualTab = new JPanel();
1849     visualTab.setBorder(new TitledBorder(
1850             MessageManager.getString("action.open_new_alignment")));
1851     visualTab.setLayout(null);
1852     fullScreen.setFont(LABEL_FONT);
1853     fullScreen.setHorizontalAlignment(SwingConstants.RIGHT);
1854     fullScreen.setHorizontalTextPosition(SwingConstants.LEFT);
1855     fullScreen.setText(MessageManager.getString("label.maximize_window"));
1856     quality.setEnabled(false);
1857     quality.setFont(LABEL_FONT);
1858     quality.setHorizontalAlignment(SwingConstants.RIGHT);
1859     quality.setHorizontalTextPosition(SwingConstants.LEFT);
1860     quality.setSelected(true);
1861     quality.setText(MessageManager.getString("label.quality"));
1862     conservation.setEnabled(false);
1863     conservation.setFont(LABEL_FONT);
1864     conservation.setHorizontalAlignment(SwingConstants.RIGHT);
1865     conservation.setHorizontalTextPosition(SwingConstants.LEFT);
1866     conservation.setSelected(true);
1867     conservation.setText(MessageManager.getString("label.conservation"));
1868     identity.setEnabled(false);
1869     identity.setFont(LABEL_FONT);
1870     identity.setHorizontalAlignment(SwingConstants.RIGHT);
1871     identity.setHorizontalTextPosition(SwingConstants.LEFT);
1872     identity.setSelected(true);
1873     identity.setText(MessageManager.getString("label.consensus"));
1874     showOccupancy.setFont(LABEL_FONT);
1875     showOccupancy.setEnabled(false);
1876     showOccupancy.setHorizontalAlignment(SwingConstants.RIGHT);
1877     showOccupancy.setHorizontalTextPosition(SwingConstants.LEFT);
1878     showOccupancy.setSelected(true);
1879     showOccupancy.setText(MessageManager.getString("label.occupancy"));
1880
1881     JLabel showGroupbits = new JLabel();
1882     showGroupbits.setFont(LABEL_FONT);
1883     showGroupbits.setHorizontalAlignment(SwingConstants.RIGHT);
1884     showGroupbits.setHorizontalTextPosition(SwingConstants.LEFT);
1885     showGroupbits
1886             .setText(MessageManager.getString("action.show_group") + ":");
1887     JLabel showConsensbits = new JLabel();
1888     showConsensbits.setFont(LABEL_FONT);
1889     showConsensbits.setHorizontalAlignment(SwingConstants.RIGHT);
1890     showConsensbits.setHorizontalTextPosition(SwingConstants.LEFT);
1891     showConsensbits
1892             .setText(MessageManager.getString("label.consensus") + ":");
1893     showConsensHistogram.setEnabled(false);
1894     showConsensHistogram.setFont(LABEL_FONT);
1895     showConsensHistogram.setHorizontalAlignment(SwingConstants.RIGHT);
1896     showConsensHistogram.setHorizontalTextPosition(SwingConstants.LEFT);
1897     showConsensHistogram.setSelected(true);
1898     showConsensHistogram
1899             .setText(MessageManager.getString("label.histogram"));
1900     showConsensLogo.setEnabled(false);
1901     showConsensLogo.setFont(LABEL_FONT);
1902     showConsensLogo.setHorizontalAlignment(SwingConstants.RIGHT);
1903     showConsensLogo.setHorizontalTextPosition(SwingConstants.LEFT);
1904     showConsensLogo.setSelected(true);
1905     showConsensLogo.setText(MessageManager.getString("label.logo"));
1906     showGroupConsensus.setEnabled(false);
1907     showGroupConsensus.setFont(LABEL_FONT);
1908     showGroupConsensus.setHorizontalAlignment(SwingConstants.RIGHT);
1909     showGroupConsensus.setHorizontalTextPosition(SwingConstants.LEFT);
1910     showGroupConsensus.setSelected(true);
1911     showGroupConsensus.setText(MessageManager.getString("label.consensus"));
1912     showGroupConservation.setEnabled(false);
1913     showGroupConservation.setFont(LABEL_FONT);
1914     showGroupConservation.setHorizontalAlignment(SwingConstants.RIGHT);
1915     showGroupConservation.setHorizontalTextPosition(SwingConstants.LEFT);
1916     showGroupConservation.setSelected(true);
1917     showGroupConservation
1918             .setText(MessageManager.getString("label.conservation"));
1919     showNpTooltip.setEnabled(true);
1920     showNpTooltip.setFont(LABEL_FONT);
1921     showNpTooltip.setHorizontalAlignment(SwingConstants.RIGHT);
1922     showNpTooltip.setHorizontalTextPosition(SwingConstants.LEFT);
1923     showNpTooltip.setSelected(true);
1924     showNpTooltip.setText(
1925             MessageManager.getString("label.non_positional_features"));
1926     showDbRefTooltip.setEnabled(true);
1927     showDbRefTooltip.setFont(LABEL_FONT);
1928     showDbRefTooltip.setHorizontalAlignment(SwingConstants.RIGHT);
1929     showDbRefTooltip.setHorizontalTextPosition(SwingConstants.LEFT);
1930     showDbRefTooltip.setSelected(true);
1931     showDbRefTooltip
1932             .setText(MessageManager.getString("label.database_references"));
1933     annotations.setFont(LABEL_FONT);
1934     annotations.setHorizontalAlignment(SwingConstants.RIGHT);
1935     annotations.setHorizontalTextPosition(SwingConstants.LEFT);
1936     annotations.setSelected(true);
1937     annotations.setText(MessageManager.getString("label.show_annotations"));
1938     // annotations.setBounds(new Rectangle(169, 12, 200, 23));
1939     annotations.addActionListener(new ActionListener()
1940     {
1941       @Override
1942       public void actionPerformed(ActionEvent e)
1943       {
1944         annotations_actionPerformed(e);
1945       }
1946     });
1947     identity.addActionListener(new ActionListener()
1948     {
1949       @Override
1950       public void actionPerformed(ActionEvent e)
1951       {
1952         annotations_actionPerformed(e);
1953       }
1954     });
1955     showGroupConsensus.addActionListener(new ActionListener()
1956     {
1957       @Override
1958       public void actionPerformed(ActionEvent e)
1959       {
1960         annotations_actionPerformed(e);
1961       }
1962     });
1963     showUnconserved.setFont(LABEL_FONT);
1964     showUnconserved.setHorizontalAlignment(SwingConstants.RIGHT);
1965     showUnconserved.setHorizontalTextPosition(SwingConstants.LEFT);
1966     showUnconserved.setSelected(true);
1967     showUnconserved
1968             .setText(MessageManager.getString("action.show_unconserved"));
1969     showUnconserved.addActionListener(new ActionListener()
1970     {
1971       @Override
1972       public void actionPerformed(ActionEvent e)
1973       {
1974         showunconserved_actionPerformed(e);
1975       }
1976     });
1977
1978     // TODO these are not yet added to / action from Preferences
1979     // JCheckBox shareSelections = new JCheckBox();
1980     // shareSelections.setFont(verdana11);
1981     // shareSelections.setHorizontalAlignment(SwingConstants.RIGHT);
1982     // shareSelections.setHorizontalTextPosition(SwingConstants.LEFT);
1983     // shareSelections.setSelected(true);
1984     // shareSelections.setText(MessageManager
1985     // .getString("label.share_selection_across_views"));
1986     // JCheckBox followHighlight = new JCheckBox();
1987     // followHighlight.setFont(verdana11);
1988     // followHighlight.setHorizontalAlignment(SwingConstants.RIGHT);
1989     // followHighlight.setHorizontalTextPosition(SwingConstants.LEFT);
1990     // // showUnconserved.setBounds(new Rectangle(169, 40, 200, 23));
1991     // followHighlight.setSelected(true);
1992     // followHighlight.setText(MessageManager
1993     // .getString("label.scroll_highlighted_regions"));
1994
1995     seqLimit.setFont(LABEL_FONT);
1996     seqLimit.setHorizontalAlignment(SwingConstants.RIGHT);
1997     seqLimit.setHorizontalTextPosition(SwingConstants.LEFT);
1998     seqLimit.setText(MessageManager.getString("label.full_sequence_id"));
1999     smoothFont.setFont(LABEL_FONT);
2000     smoothFont.setHorizontalAlignment(SwingConstants.RIGHT);
2001     smoothFont.setHorizontalTextPosition(SwingConstants.LEADING);
2002     smoothFont.setText(MessageManager.getString("label.smooth_font"));
2003     scaleProteinToCdna.setFont(LABEL_FONT);
2004     scaleProteinToCdna.setHorizontalAlignment(SwingConstants.RIGHT);
2005     scaleProteinToCdna.setHorizontalTextPosition(SwingConstants.LEADING);
2006     scaleProteinToCdna.setText(
2007             MessageManager.getString("label.scale_protein_to_cdna"));
2008     scaleProteinToCdna.setToolTipText(
2009             MessageManager.getString("label.scale_protein_to_cdna_tip"));
2010     JLabel gapLabel = new JLabel();
2011     gapLabel.setFont(LABEL_FONT);
2012     gapLabel.setHorizontalAlignment(SwingConstants.RIGHT);
2013     gapLabel.setText(MessageManager.getString("label.gap_symbol") + " ");
2014     JLabel fontLabel = new JLabel();
2015     fontLabel.setFont(LABEL_FONT);
2016     fontLabel.setHorizontalAlignment(SwingConstants.RIGHT);
2017     fontLabel.setText(MessageManager.getString("label.font"));
2018     fontSizeCB.setFont(LABEL_FONT);
2019     fontSizeCB.setBounds(new Rectangle(320, 112, 65, 23));
2020     fontStyleCB.setFont(LABEL_FONT);
2021     fontStyleCB.setBounds(new Rectangle(382, 112, 80, 23));
2022     fontNameCB.setFont(LABEL_FONT);
2023     fontNameCB.setBounds(new Rectangle(172, 112, 147, 23));
2024     gapSymbolCB.setFont(LABEL_FONT);
2025     gapSymbolCB.setBounds(new Rectangle(172, 215, 69, 23));
2026     DefaultListCellRenderer dlcr = new DefaultListCellRenderer();
2027     dlcr.setHorizontalAlignment(DefaultListCellRenderer.CENTER);
2028     gapSymbolCB.setRenderer(dlcr);
2029
2030     startupCheckbox.setText(MessageManager.getString("action.open_file"));
2031     startupCheckbox.setFont(LABEL_FONT);
2032     startupCheckbox.setHorizontalAlignment(SwingConstants.RIGHT);
2033     startupCheckbox.setHorizontalTextPosition(SwingConstants.LEFT);
2034     startupCheckbox.setSelected(true);
2035     startupFileTextfield.setFont(LABEL_FONT);
2036     startupFileTextfield.setBounds(new Rectangle(172, 310, 330, 20));
2037     final String tooltip = JvSwingUtils.wrapTooltip(true,
2038             MessageManager.getString("label.double_click_to_browse"));
2039     startupFileTextfield.setToolTipText(tooltip);
2040     startupFileTextfield.addMouseListener(new MouseAdapter()
2041     {
2042       @Override
2043       public void mouseClicked(MouseEvent e)
2044       {
2045         if (e.getClickCount() > 1)
2046         {
2047           startupFileTextfield_mouseClicked();
2048         }
2049       }
2050     });
2051
2052     sortby.setFont(LABEL_FONT);
2053     sortby.setBounds(new Rectangle(172, 260, 155, 21));
2054     JLabel sortLabel = new JLabel();
2055     sortLabel.setFont(LABEL_FONT);
2056     sortLabel.setHorizontalAlignment(SwingConstants.RIGHT);
2057     sortLabel.setText(MessageManager.getString("label.sort_by"));
2058     sortAnnBy.setFont(LABEL_FONT);
2059     sortAnnBy.setBounds(new Rectangle(172, 285, 110, 21));
2060     JLabel sortAnnLabel = new JLabel();
2061     sortAnnLabel.setFont(LABEL_FONT);
2062     sortAnnLabel.setHorizontalAlignment(SwingConstants.RIGHT);
2063     sortAnnLabel.setText(MessageManager.getString("label.sort_ann_by"));
2064     sortAutocalc.setFont(LABEL_FONT);
2065     sortAutocalc.setBounds(new Rectangle(290, 285, 165, 21));
2066
2067     JPanel annsettingsPanel = new JPanel();
2068     annsettingsPanel.setBounds(new Rectangle(173, 13, 320, 96));
2069     annsettingsPanel.setLayout(new FlowLayout(FlowLayout.LEFT, 0, 0));
2070     annsettingsPanel.setBorder(new EtchedBorder());
2071     visualTab.add(annsettingsPanel);
2072     Border jb = new EmptyBorder(1, 1, 4, 5);
2073     annotations.setBorder(jb);
2074     showOccupancy.setBorder(jb);
2075     quality.setBorder(jb);
2076     conservation.setBorder(jb);
2077     identity.setBorder(jb);
2078     showConsensbits.setBorder(jb);
2079     showGroupbits.setBorder(jb);
2080     showGroupConsensus.setBorder(jb);
2081     showGroupConservation.setBorder(jb);
2082     showConsensHistogram.setBorder(jb);
2083     showConsensLogo.setBorder(jb);
2084
2085     JPanel autoAnnotSettings = new JPanel();
2086     annsettingsPanel.add(autoAnnotSettings);
2087     autoAnnotSettings.setLayout(new GridLayout(0, 2));
2088     autoAnnotSettings.add(annotations);
2089     autoAnnotSettings.add(quality);
2090     // second row of autoannotation box
2091     autoAnnotSettings = new JPanel();
2092     annsettingsPanel.add(autoAnnotSettings);
2093
2094     autoAnnotSettings.setLayout(new GridLayout(0, 3));
2095     autoAnnotSettings.add(conservation);
2096     autoAnnotSettings.add(identity);
2097     autoAnnotSettings.add(showOccupancy);
2098     autoAnnotSettings.add(showGroupbits);
2099     autoAnnotSettings.add(showGroupConservation);
2100     autoAnnotSettings.add(showGroupConsensus);
2101     autoAnnotSettings.add(showConsensbits);
2102     autoAnnotSettings.add(showConsensHistogram);
2103     autoAnnotSettings.add(showConsensLogo);
2104
2105     JPanel tooltipSettings = new JPanel();
2106     tooltipSettings.setBorder(new TitledBorder(
2107             MessageManager.getString("label.sequence_id_tooltip")));
2108     tooltipSettings.setBounds(173, 140, 220, 62);
2109     tooltipSettings.setLayout(new GridLayout(2, 1));
2110     tooltipSettings.add(showDbRefTooltip);
2111     tooltipSettings.add(showNpTooltip);
2112     visualTab.add(tooltipSettings);
2113
2114     wrap.setFont(LABEL_FONT);
2115     wrap.setHorizontalAlignment(SwingConstants.TRAILING);
2116     wrap.setHorizontalTextPosition(SwingConstants.LEADING);
2117     wrap.setText(MessageManager.getString("label.wrap_alignment"));
2118     rightAlign.setFont(LABEL_FONT);
2119     rightAlign.setForeground(Color.black);
2120     rightAlign.setHorizontalAlignment(SwingConstants.RIGHT);
2121     rightAlign.setHorizontalTextPosition(SwingConstants.LEFT);
2122     rightAlign.setText(MessageManager.getString("label.right_align_ids"));
2123     idItalics.setFont(LABEL_FONT_ITALIC);
2124     idItalics.setHorizontalAlignment(SwingConstants.RIGHT);
2125     idItalics.setHorizontalTextPosition(SwingConstants.LEADING);
2126     idItalics.setText(
2127             MessageManager.getString("label.sequence_name_italics"));
2128     openoverv.setFont(LABEL_FONT);
2129     openoverv.setActionCommand(
2130             MessageManager.getString("label.open_overview"));
2131     openoverv.setHorizontalAlignment(SwingConstants.RIGHT);
2132     openoverv.setHorizontalTextPosition(SwingConstants.LEFT);
2133     openoverv.setText(MessageManager.getString("label.open_overview"));
2134     JPanel jPanel2 = new JPanel();
2135     jPanel2.setBounds(new Rectangle(7, 17, 158, 310));
2136     jPanel2.setLayout(new GridLayout(14, 1));
2137     jPanel2.add(fullScreen);
2138     jPanel2.add(openoverv);
2139     jPanel2.add(seqLimit);
2140     jPanel2.add(rightAlign);
2141     jPanel2.add(fontLabel);
2142     jPanel2.add(showUnconserved);
2143     jPanel2.add(idItalics);
2144     jPanel2.add(smoothFont);
2145     jPanel2.add(scaleProteinToCdna);
2146     jPanel2.add(gapLabel);
2147     jPanel2.add(wrap);
2148     jPanel2.add(sortLabel);
2149     jPanel2.add(sortAnnLabel);
2150     jPanel2.add(startupCheckbox);
2151     visualTab.add(jPanel2);
2152     visualTab.add(startupFileTextfield);
2153     visualTab.add(sortby);
2154     visualTab.add(sortAnnBy);
2155     visualTab.add(sortAutocalc);
2156     visualTab.add(gapSymbolCB);
2157     visualTab.add(fontNameCB);
2158     visualTab.add(fontSizeCB);
2159     visualTab.add(fontStyleCB);
2160
2161     if (Platform.isJS())
2162     {
2163       startupCheckbox.setVisible(false);
2164       startupFileTextfield.setVisible(false);
2165     }
2166
2167     return visualTab;
2168   }
2169
2170   /**
2171    * Load the saved Backups options EXCEPT "Enabled" and "Scheme"
2172    */
2173
2174   protected void loadLastSavedBackupsOptions()
2175   {
2176     BackupFilesPresetEntry savedPreset = BackupFilesPresetEntry
2177             .getSavedBackupEntry();
2178     enableBackupFiles.setSelected(
2179             Cache.getDefault(BackupFiles.ENABLED, !Platform.isJS()));
2180
2181     BackupFilesPresetEntry backupfilesCustomEntry = BackupFilesPresetEntry
2182             .createBackupFilesPresetEntry(Cache
2183                     .getDefault(BackupFilesPresetEntry.CUSTOMCONFIG, null));
2184     if (backupfilesCustomEntry == null)
2185     {
2186       backupfilesCustomEntry = BackupFilesPresetEntry.backupfilesPresetEntriesValues
2187               .get(BackupFilesPresetEntry.BACKUPFILESSCHEMEDEFAULT);
2188     }
2189     BackupFilesPresetEntry.backupfilesPresetEntriesValues.put(
2190             BackupFilesPresetEntry.BACKUPFILESSCHEMECUSTOM,
2191             backupfilesCustomEntry);
2192
2193     setComboIntStringKey(backupfilesPresetsCombo,
2194             Cache.getDefault(BackupFiles.NS + "_PRESET",
2195                     BackupFilesPresetEntry.BACKUPFILESSCHEMEDEFAULT));
2196
2197     backupsSetOptions(savedPreset);
2198
2199     backupsOptionsSetEnabled();
2200     updateBackupFilesExampleLabel();
2201   }
2202
2203   private boolean warnAboutSuffixReverseChange()
2204   {
2205     BackupFilesPresetEntry bfpe = BackupFilesPresetEntry
2206             .getSavedBackupEntry();
2207     boolean savedSuffixReverse = bfpe.reverse;
2208     int savedSuffixDigits = bfpe.digits;
2209     String savedSuffixTemplate = bfpe.suffix;
2210
2211     boolean nowSuffixReverse = suffixReverse.isSelected();
2212     int nowSuffixDigits = getSpinnerInt(suffixDigitsSpinner, 3);
2213     String nowSuffixTemplate = suffixTemplate.getText();
2214     return nowSuffixReverse != savedSuffixReverse
2215             && nowSuffixDigits == savedSuffixDigits
2216             && nowSuffixTemplate != null
2217             && nowSuffixTemplate.equals(savedSuffixTemplate);
2218   }
2219
2220   /**
2221    * Initialises the Backups tabbed panel.
2222    * 
2223    * @return
2224    */
2225   private JPanel initBackupsTab()
2226   {
2227     JPanel backupsTab = new JPanel();
2228     backupsTab.setBorder(new TitledBorder(
2229             MessageManager.getString("label.backup_files")));
2230     backupsTab.setLayout(new GridBagLayout());
2231
2232     GridBagConstraints gbc = new GridBagConstraints();
2233     gbc.weightx = 0.0;
2234     gbc.weighty = 0.0;
2235     gbc.anchor = GridBagConstraints.FIRST_LINE_START;
2236     gbc.fill = GridBagConstraints.NONE;
2237
2238     initBackupsTabPresetsPanel();
2239     initBackupsTabSuffixPanel();
2240     initBackupsTabKeepFilesPanel();
2241     initBackupsTabFilenameExamplesPanel();
2242
2243     enableBackupFiles.setFont(LABEL_FONT_BOLD);
2244     enableBackupFiles
2245             .setText(MessageManager.getString("label.enable_backupfiles"));
2246     enableBackupFiles.addActionListener(new ActionListener()
2247     {
2248       @Override
2249       public void actionPerformed(ActionEvent e)
2250       {
2251         // enable other options only when the first is checked
2252         backupsOptionsSetEnabled();
2253       }
2254     });
2255
2256     // enable checkbox 1 col
2257     gbc.gridwidth = 1;
2258     gbc.gridheight = 1;
2259     gbc.gridx = 0;
2260     gbc.gridy = 0; // row 0
2261     backupsTab.add(enableBackupFiles, gbc);
2262
2263     // summary of scheme box (over two rows)
2264     gbc.gridx = 1;
2265     gbc.weightx = 0.0;
2266     gbc.gridheight = 2;
2267     gbc.anchor = GridBagConstraints.FIRST_LINE_END;
2268     gbc.fill = GridBagConstraints.BOTH;
2269     backupsTab.add(exampleFilesPanel, gbc);
2270     gbc.gridheight = 1;
2271     gbc.anchor = GridBagConstraints.FIRST_LINE_START;
2272     gbc.fill = GridBagConstraints.NONE;
2273
2274     // fill empty space on right
2275     gbc.gridx++;
2276     gbc.weightx = 1.0;
2277     backupsTab.add(new JPanel(), gbc);
2278
2279     // schemes box
2280     gbc.weightx = 0.0;
2281     gbc.gridx = 0;
2282     gbc.gridy++; // row 1
2283     backupsTab.add(presetsPanel, gbc);
2284
2285     // now using whole row
2286     gbc.gridwidth = 2;
2287     gbc.gridheight = 1;
2288     // keep files box
2289     gbc.gridx = 0;
2290     gbc.gridy++; // row 2
2291     backupsTab.add(keepfilesPanel, gbc);
2292
2293     // filename strategy box
2294     gbc.gridy++; // row 3
2295     backupsTab.add(suffixPanel, gbc);
2296
2297     // fill empty space
2298     gbc.gridy++; // row 4
2299     gbc.weighty = 1.0;
2300     backupsTab.add(new JPanel(), gbc);
2301
2302     backupsOptionsSetEnabled();
2303     return backupsTab;
2304   }
2305
2306   private JPanel initBackupsTabPresetsPanel()
2307   {
2308
2309     String title = MessageManager.getString("label.schemes");
2310
2311     presetsPanel.setLayout(new GridBagLayout());
2312
2313     GridBagConstraints gbc = new GridBagConstraints();
2314     gbc.weightx = 0.0;
2315     gbc.weighty = 0.0;
2316     gbc.anchor = GridBagConstraints.BASELINE_LEADING;
2317     gbc.fill = GridBagConstraints.NONE;
2318     gbc.gridwidth = 1;
2319     gbc.gridheight = 1;
2320
2321     // "Scheme: "
2322     gbc.gridx = 0;
2323     gbc.gridy = 0;
2324
2325     presetsComboLabel = new JLabel(title + ":");
2326     presetsPanel.add(presetsComboLabel, gbc);
2327
2328     List<Object> entries = Arrays.asList(
2329             (Object[]) BackupFilesPresetEntry.backupfilesPresetEntries);
2330     List<String> tooltips = Arrays.asList(
2331             BackupFilesPresetEntry.backupfilesPresetEntryDescriptions);
2332     backupfilesPresetsCombo = JvSwingUtils.buildComboWithTooltips(entries,
2333             tooltips);
2334     /*
2335     for (int i = 0; i < BackupFilesPresetEntry.backupfilesPresetEntries.length; i++)
2336     {
2337       backupfilesPresetsCombo
2338               .addItem(BackupFilesPresetEntry.backupfilesPresetEntries[i]);
2339     }
2340     */
2341
2342     backupfilesPresetsCombo.addActionListener(new ActionListener()
2343     {
2344       @Override
2345       public void actionPerformed(ActionEvent e)
2346       {
2347         int key = getComboIntStringKey(backupfilesPresetsCombo);
2348         if (!customiseCheckbox.isSelected())
2349         {
2350           backupfilesPresetsComboLastSelected = key;
2351         }
2352         if (key == BackupFilesPresetEntry.BACKUPFILESSCHEMECUSTOM)
2353         {
2354           if (customiseCheckbox.isSelected())
2355           {
2356             // got here by clicking on customiseCheckbox so don't change the
2357             // values
2358             backupfilesCustomOptionsSetEnabled();
2359           }
2360           else
2361           {
2362             backupsTabUpdatePresets();
2363             backupfilesCustomOptionsSetEnabled();
2364           }
2365         }
2366         else
2367         {
2368           customiseCheckbox.setSelected(false);
2369           backupsTabUpdatePresets();
2370           backupfilesCustomOptionsSetEnabled();
2371         }
2372       }
2373     });
2374
2375     // dropdown list of preset schemes
2376     gbc.gridx = 1;
2377     presetsPanel.add(backupfilesPresetsCombo, gbc);
2378
2379     revertButton.setText(MessageManager.getString("label.cancel_changes"));
2380     revertButton.setToolTipText(
2381             MessageManager.getString("label.cancel_changes_description"));
2382     revertButton.addActionListener(new ActionListener()
2383     {
2384       @Override
2385       public void actionPerformed(ActionEvent e)
2386       {
2387         backupsSetOptions(
2388                 BackupFilesPresetEntry.backupfilesPresetEntriesValues.get(
2389                         BackupFilesPresetEntry.BACKUPFILESSCHEMECUSTOM));
2390         backupfilesCustomOptionsSetEnabled();
2391       }
2392
2393     });
2394     revertButton.setFont(LABEL_FONT);
2395
2396     customiseCheckbox.setFont(LABEL_FONT);
2397     customiseCheckbox.setText(MessageManager.getString("label.customise"));
2398     customiseCheckbox.addActionListener(new ActionListener()
2399     {
2400       @Override
2401       public void actionPerformed(ActionEvent e)
2402       {
2403         int currently = getComboIntStringKey(backupfilesPresetsCombo);
2404         if (customiseCheckbox.isSelected())
2405         {
2406           backupfilesPresetsComboLastSelected = currently;
2407           setComboIntStringKey(backupfilesPresetsCombo,
2408                   BackupFilesPresetEntry.BACKUPFILESSCHEMECUSTOM);
2409         }
2410         else
2411         {
2412           setComboIntStringKey(backupfilesPresetsCombo,
2413                   backupfilesPresetsComboLastSelected);
2414
2415         }
2416         backupfilesCustomOptionsSetEnabled();
2417       }
2418     });
2419     customiseCheckbox.setToolTipText(
2420             MessageManager.getString("label.customise_description"));
2421
2422     // customise checkbox
2423     gbc.gridx = 0;
2424     gbc.gridy++;
2425     presetsPanel.add(customiseCheckbox, gbc);
2426
2427     // "Cancel changes" button (aligned with combo box above)
2428     gbc.gridx = 1;
2429     presetsPanel.add(revertButton, gbc);
2430
2431     return presetsPanel;
2432   }
2433
2434   private JPanel initBackupsTabFilenameExamplesPanel()
2435   {
2436     String title = MessageManager.getString("label.scheme_examples");
2437     TitledBorder tb = new TitledBorder(title);
2438     exampleFilesPanel.setBorder(tb);
2439     exampleFilesPanel.setLayout(new GridBagLayout());
2440
2441     backupfilesExampleLabel.setEditable(false);
2442     backupfilesExampleLabel
2443             .setBackground(exampleFilesPanel.getBackground());
2444
2445     updateBackupFilesExampleLabel();
2446
2447     GridBagConstraints gbc = new GridBagConstraints();
2448     gbc.weightx = 1.0;
2449     gbc.weighty = 1.0;
2450     gbc.fill = GridBagConstraints.NONE;
2451     gbc.anchor = GridBagConstraints.FIRST_LINE_START;
2452
2453     exampleFilesPanel.add(backupfilesExampleLabel, gbc);
2454     return exampleFilesPanel;
2455   }
2456
2457   private void backupsTabUpdatePresets()
2458   {
2459     IntKeyStringValueEntry entry = (IntKeyStringValueEntry) backupfilesPresetsCombo
2460             .getSelectedItem();
2461     int key = entry.k;
2462     String value = entry.v;
2463
2464     if (BackupFilesPresetEntry.backupfilesPresetEntriesValues
2465             .containsKey(key))
2466     {
2467       backupsSetOptions(
2468               BackupFilesPresetEntry.backupfilesPresetEntriesValues
2469                       .get(key));
2470     }
2471     else
2472     {
2473       Cache.log.error(
2474               "Preset '" + value + "' [key:" + key + "] not implemented");
2475     }
2476
2477     // Custom options will now be enabled when the customiseCheckbox is checked
2478     // (performed above)
2479     // backupfilesCustomOptionsSetEnabled();
2480     updateBackupFilesExampleLabel();
2481   }
2482
2483   protected int getComboIntStringKey(
2484           JComboBox<Object> backupfilesPresetsCombo2)
2485   {
2486     IntKeyStringValueEntry e;
2487     try
2488     {
2489       e = (IntKeyStringValueEntry) backupfilesPresetsCombo2
2490               .getSelectedItem();
2491     } catch (Exception ex)
2492     {
2493       Cache.log.error(
2494               "Problem casting Combo entry to IntKeyStringValueEntry.");
2495       e = null;
2496     }
2497     return e != null ? e.k : 0;
2498   }
2499
2500   protected void setComboIntStringKey(
2501           JComboBox<Object> backupfilesPresetsCombo2, int key)
2502   {
2503     for (int i = 0; i < backupfilesPresetsCombo2.getItemCount(); i++)
2504     {
2505       IntKeyStringValueEntry e;
2506       try
2507       {
2508         e = (IntKeyStringValueEntry) backupfilesPresetsCombo2.getItemAt(i);
2509       } catch (Exception ex)
2510       {
2511         Cache.log.error(
2512                 "Problem casting Combo entry to IntKeyStringValueEntry. Skipping item. ");
2513         continue;
2514       }
2515       if (e.k == key)
2516       {
2517         backupfilesPresetsCombo2.setSelectedIndex(i);
2518         break;
2519       }
2520     }
2521     // backupsTabUpdatePresets();
2522   }
2523
2524   private JPanel initBackupsTabSuffixPanel()
2525   {
2526     suffixPanel.setBorder(new TitledBorder(
2527             MessageManager.getString("label.backup_filename_strategy")));
2528     suffixPanel.setLayout(new GridBagLayout());
2529
2530     suffixTemplateLabel
2531             .setText(MessageManager.getString("label.append_to_filename"));
2532     suffixTemplateLabel.setHorizontalAlignment(SwingConstants.LEFT);
2533     suffixTemplateLabel.setFont(LABEL_FONT);
2534
2535     final String tooltip = JvSwingUtils.wrapTooltip(true,
2536             MessageManager.getString("label.append_to_filename_tooltip"));
2537     suffixTemplate.setToolTipText(tooltip);
2538     suffixTemplate.addActionListener(new ActionListener()
2539     {
2540       @Override
2541       public void actionPerformed(ActionEvent e)
2542       {
2543         updateBackupFilesExampleLabel();
2544         backupfilesCustomOptionsSetEnabled();
2545         backupfilesRevertButtonSetEnabled(true);
2546       }
2547
2548     });
2549     suffixTemplate.addKeyListener(new KeyListener()
2550     {
2551       @Override
2552       public void keyReleased(KeyEvent e)
2553       {
2554         updateBackupFilesExampleLabel();
2555         backupfilesCustomOptionsSetEnabled();
2556         backupfilesRevertButtonSetEnabled(true);
2557       }
2558
2559       @Override
2560       public void keyPressed(KeyEvent e)
2561       {
2562       }
2563
2564       // disable use of ':' or '/' or '\'
2565       @Override
2566       public void keyTyped(KeyEvent e)
2567       {
2568         char c = e.getKeyChar();
2569         if (c == ':' || c == '/' || c == '\\')
2570         {
2571           // don't process ':' or '/' or '\'
2572           e.consume();
2573         }
2574       }
2575
2576     });
2577
2578     // digits spinner
2579     suffixDigitsLabel
2580             .setText(MessageManager.getString("label.index_digits"));
2581     suffixDigitsLabel.setHorizontalAlignment(SwingConstants.LEFT);
2582     suffixDigitsLabel.setFont(LABEL_FONT);
2583     ChangeListener c = new ChangeListener()
2584     {
2585       @Override
2586       public void stateChanged(ChangeEvent e)
2587       {
2588         backupfilesRevertButtonSetEnabled(true);
2589         updateBackupFilesExampleLabel();
2590       }
2591
2592     };
2593     setIntegerSpinner(suffixDigitsSpinner, BackupFilesPresetEntry.DIGITSMIN,
2594             BackupFilesPresetEntry.DIGITSMAX, 3, c);
2595
2596     suffixReverse.setLabels(MessageManager.getString("label.reverse_roll"),
2597             MessageManager.getString("label.increment_index"));
2598     suffixReverse.addActionListener(new ActionListener()
2599     {
2600       @Override
2601       public void actionPerformed(ActionEvent e)
2602       {
2603         boolean okay = true;
2604         if (warnAboutSuffixReverseChange())
2605         {
2606           // Warning popup
2607           okay = confirmSuffixReverseChange();
2608         }
2609         if (okay)
2610         {
2611           backupfilesRevertButtonSetEnabled(true);
2612           updateBackupFilesExampleLabel();
2613         }
2614         else
2615         {
2616           boolean savedSuffixReverse = BackupFilesPresetEntry
2617                   .getSavedBackupEntry().reverse;
2618           suffixReverse.setSelected(savedSuffixReverse);
2619         }
2620       }
2621     });
2622
2623     GridBagConstraints sgbc = new GridBagConstraints();
2624
2625     // first row (template text box)
2626     sgbc.anchor = GridBagConstraints.WEST;
2627     sgbc.gridx = 0;
2628     sgbc.gridy = 0;
2629     sgbc.gridwidth = 1;
2630     sgbc.gridheight = 1;
2631     sgbc.weightx = 1.0;
2632     sgbc.weighty = 0.0;
2633     sgbc.fill = GridBagConstraints.NONE;
2634     suffixPanel.add(suffixTemplateLabel, sgbc);
2635
2636     sgbc.gridx = 1;
2637     sgbc.fill = GridBagConstraints.HORIZONTAL;
2638     suffixPanel.add(suffixTemplate, sgbc);
2639
2640     // second row (number of digits spinner)
2641     sgbc.gridy = 1;
2642
2643     sgbc.gridx = 0;
2644     sgbc.fill = GridBagConstraints.NONE;
2645     suffixPanel.add(suffixDigitsLabel, sgbc);
2646
2647     sgbc.gridx = 1;
2648     sgbc.fill = GridBagConstraints.HORIZONTAL;
2649     suffixPanel.add(suffixDigitsSpinner, sgbc);
2650
2651     // third row (forward order radio selection)
2652     sgbc.gridx = 0;
2653     sgbc.gridy = 2;
2654     sgbc.gridwidth = GridBagConstraints.REMAINDER;
2655     sgbc.fill = GridBagConstraints.HORIZONTAL;
2656     suffixPanel.add(suffixReverse.getFalseButton(), sgbc);
2657
2658     // fourth row (reverse order radio selection)
2659     sgbc.gridy = 3;
2660     suffixPanel.add(suffixReverse.getTrueButton(), sgbc);
2661     return suffixPanel;
2662   }
2663
2664   private boolean confirmSuffixReverseChange()
2665   {
2666     boolean ret = false;
2667     String warningMessage = MessageManager
2668             .getString("label.warning_confirm_change_reverse");
2669     int confirm = JvOptionPane.showConfirmDialog(Desktop.desktop,
2670             warningMessage,
2671             MessageManager.getString("label.change_increment_decrement"),
2672             JvOptionPane.YES_NO_OPTION, JvOptionPane.WARNING_MESSAGE);
2673
2674     ret = (confirm == JvOptionPane.YES_OPTION);
2675     return ret;
2676   }
2677
2678   private JPanel initBackupsTabKeepFilesPanel()
2679   {
2680     keepfilesPanel.setBorder(
2681             new TitledBorder(MessageManager.getString("label.keep_files")));
2682     keepfilesPanel.setLayout(new GridBagLayout());
2683
2684     backupfilesKeepAll.setLabels(
2685             MessageManager.getString("label.keep_all_backup_files"),
2686             MessageManager.getString(
2687                     "label.keep_only_this_number_of_backup_files"));
2688     backupfilesKeepAll.addTrueActionListener(new ActionListener()
2689     {
2690       @Override
2691       public void actionPerformed(ActionEvent e)
2692       {
2693         backupfilesRevertButtonSetEnabled(true);
2694         updateBackupFilesExampleLabel();
2695       }
2696     });
2697     backupfilesKeepAll.addActionListener(new ActionListener()
2698     {
2699       @Override
2700       public void actionPerformed(ActionEvent e)
2701       {
2702         backupfilesRevertButtonSetEnabled(true);
2703         keepRollMaxOptionsEnabled();
2704         updateBackupFilesExampleLabel();
2705       }
2706     });
2707
2708     ChangeListener c = new ChangeListener()
2709     {
2710       @Override
2711       public void stateChanged(ChangeEvent e)
2712       {
2713         backupfilesRevertButtonSetEnabled(true);
2714         updateBackupFilesExampleLabel();
2715       }
2716
2717     };
2718     setIntegerSpinner(backupfilesRollMaxSpinner,
2719             BackupFilesPresetEntry.ROLLMAXMIN,
2720             BackupFilesPresetEntry.ROLLMAXMAX, 4, true, c);
2721
2722     backupfilesConfirmDelete.setLabels(
2723             MessageManager.getString("label.always_ask"),
2724             MessageManager.getString("label.auto_delete"));
2725     backupfilesConfirmDelete.addActionListener(new ActionListener()
2726     {
2727       @Override
2728       public void actionPerformed(ActionEvent e)
2729       {
2730         backupfilesRevertButtonSetEnabled(true);
2731       }
2732     });
2733     // update the enabled section
2734     keepRollMaxOptionsEnabled();
2735
2736     GridBagConstraints kgbc = new GridBagConstraints();
2737
2738     // first row (template text box)
2739     kgbc.anchor = GridBagConstraints.WEST;
2740     kgbc.gridx = 0;
2741     kgbc.gridy = 0;
2742     kgbc.gridwidth = GridBagConstraints.REMAINDER;
2743     kgbc.gridheight = 1;
2744     kgbc.weightx = 1.0;
2745     kgbc.weighty = 0.0;
2746     kgbc.fill = GridBagConstraints.HORIZONTAL;
2747     keepfilesPanel.add(backupfilesKeepAll.getTrueButton(), kgbc);
2748
2749     // second row
2750     kgbc.gridy = 1;
2751
2752     kgbc.gridx = 0;
2753     kgbc.gridwidth = GridBagConstraints.RELATIVE;
2754     keepfilesPanel.add(backupfilesKeepAll.getFalseButton(), kgbc);
2755
2756     kgbc.gridx = 1;
2757     kgbc.gridwidth = GridBagConstraints.REMAINDER;
2758     keepfilesPanel.add(backupfilesRollMaxSpinner, kgbc);
2759
2760     // third row (indented)
2761     kgbc.gridy = 2;
2762     kgbc.insets = new Insets(0, 20, 0, 0);
2763
2764     kgbc.gridx = 0;
2765     kgbc.gridwidth = GridBagConstraints.REMAINDER;
2766     kgbc.fill = GridBagConstraints.HORIZONTAL;
2767     kgbc.weightx = 1.0;
2768
2769     JPanel jp = new JPanel();
2770     jp.setLayout(new FlowLayout());
2771     oldBackupFilesLabel.setText(
2772             MessageManager.getString("label.autodelete_old_backup_files"));
2773     oldBackupFilesLabel.setFont(LABEL_FONT);
2774     oldBackupFilesLabel.setHorizontalAlignment(SwingConstants.LEFT);
2775     jp.add(oldBackupFilesLabel);
2776     jp.add(backupfilesConfirmDelete.getTrueButton());
2777     jp.add(backupfilesConfirmDelete.getFalseButton());
2778     keepfilesPanel.add(jp, kgbc);
2779
2780     return keepfilesPanel;
2781   }
2782
2783   protected void updateBackupFilesExampleLabel()
2784   {
2785     int exampleindex = 12;
2786     String base = MessageManager.getString("label.filename") + ".fa";
2787     if (base == null || base.length() == 0)
2788     {
2789       base = "file_name.fa";
2790     }
2791
2792     boolean reverse = suffixReverse.isSelected();
2793     boolean keepAll = backupfilesKeepAll.isSelected();
2794     int rollMax = 4;
2795     String suffix = suffixTemplate.getText();
2796     int digits = 3;
2797
2798     backupfilesExampleLabel.setFont(LABEL_FONT_ITALIC);
2799     if (suffix == null || suffix.length() == 0)
2800     {
2801       backupfilesExampleLabel
2802               .setText(MessageManager.getString("label.no_backup_files"));
2803       backupfilesExampleLabel.setFont(LABEL_FONT_BOLD);
2804       return;
2805     }
2806
2807     rollMax = getSpinnerInt(backupfilesRollMaxSpinner, 4);
2808     rollMax = rollMax < 1 ? 1 : rollMax;
2809
2810     if (suffix.indexOf(BackupFiles.NUM_PLACEHOLDER) == -1)
2811     {
2812       rollMax = 1;
2813     }
2814
2815     digits = getSpinnerInt(suffixDigitsSpinner, 3);
2816     digits = digits < 1 ? 1 : digits;
2817
2818     int lowersurround = 2;
2819     int uppersurround = 0;
2820     StringBuilder exampleSB = new StringBuilder();
2821     boolean firstLine = true;
2822     int lineNumber = 0;
2823     if (reverse)
2824     {
2825
2826       int min = 1;
2827       int max = keepAll ? exampleindex : rollMax;
2828       for (int index = min; index <= max; index++)
2829       {
2830         if (index == min + lowersurround && index < max - uppersurround - 1)
2831         {
2832           exampleSB.append("\n...");
2833           lineNumber++;
2834         }
2835         else if (index > min + lowersurround && index < max - uppersurround)
2836         {
2837           // nothing
2838         }
2839         else
2840         {
2841           if (firstLine)
2842           {
2843             firstLine = false;
2844           }
2845           else
2846           {
2847             exampleSB.append("\n");
2848             lineNumber++;
2849           }
2850           exampleSB.append(BackupFilenameParts.getBackupFilename(index,
2851                   base, suffix, digits));
2852           if (min == max)
2853           {
2854             // no extra text needed
2855           }
2856           else if (index == min)
2857           {
2858             String newest = MessageManager.getString("label.braced_newest");
2859             if (newest != null && newest.length() > 0)
2860             {
2861               exampleSB.append(" " + newest);
2862             }
2863           }
2864           else if (index == max)
2865           {
2866             String oldest = MessageManager.getString("label.braced_oldest");
2867             if (oldest != null && oldest.length() > 0)
2868             {
2869               exampleSB.append(" " + oldest);
2870             }
2871           }
2872         }
2873       }
2874     }
2875     else
2876     {
2877
2878       int min = (keepAll || exampleindex - rollMax < 0) ? 1
2879               : exampleindex - rollMax + 1;
2880       int max = exampleindex;
2881
2882       for (int index = min; index <= max; index++)
2883       {
2884
2885         if (index == min + lowersurround && index < max - uppersurround - 1)
2886         {
2887           exampleSB.append("\n...");
2888           lineNumber++;
2889         }
2890         else if (index > min + lowersurround && index < max - uppersurround)
2891         {
2892           // nothing
2893         }
2894         else
2895         {
2896           if (firstLine)
2897           {
2898             firstLine = false;
2899           }
2900           else
2901           {
2902             exampleSB.append("\n");
2903             lineNumber++;
2904           }
2905           exampleSB.append(BackupFilenameParts.getBackupFilename(index,
2906                   base, suffix, digits));
2907           if (min == max)
2908           {
2909             // no extra text needed
2910           }
2911           else if (index == min)
2912           {
2913             String oldest = MessageManager.getString("label.braced_oldest");
2914             if (oldest != null && oldest.length() > 0)
2915             {
2916               exampleSB.append(" " + oldest);
2917             }
2918           }
2919           else if (index == max)
2920           {
2921             String newest = MessageManager.getString("label.braced_newest");
2922             if (newest != null && newest.length() > 0)
2923             {
2924               exampleSB.append(" " + newest);
2925             }
2926           }
2927         }
2928       }
2929
2930     }
2931
2932     // add some extra empty lines to pad out the example files box. ugh, please
2933     // tell
2934     // me how to do this better
2935     int remainingLines = lowersurround + uppersurround + 1 - lineNumber;
2936     if (remainingLines > 0)
2937     {
2938       for (int i = 0; i < remainingLines; i++)
2939       {
2940         exampleSB.append("\n ");
2941         lineNumber++;
2942       }
2943     }
2944
2945     backupfilesExampleLabel.setText(exampleSB.toString());
2946   }
2947
2948   protected void setIntegerSpinner(JSpinner s, int min, int max, int def,
2949           boolean useExistingVal, ChangeListener c)
2950   {
2951     int i = def;
2952     if (useExistingVal)
2953     {
2954       try
2955       {
2956         i = ((Integer) s.getValue()).intValue();
2957       } catch (Exception e)
2958       {
2959         Cache.log.error(
2960                 "Exception casting the initial value of s.getValue()");
2961       }
2962     }
2963
2964     setIntegerSpinner(s, min, max, i, c);
2965   }
2966
2967   protected void setIntegerSpinner(JSpinner s, int min, int max, int def,
2968           ChangeListener c)
2969   {
2970     // integer spinner for number of digits
2971     if (def > max)
2972     {
2973       max = def;
2974     }
2975     if (def < min)
2976     {
2977       def = min;
2978     }
2979     SpinnerModel sModel = new SpinnerNumberModel(def, min, max, 1);
2980     s.setModel(sModel);
2981
2982     s.addChangeListener(c);
2983
2984   }
2985
2986   protected static int getSpinnerInt(JSpinner s, int def)
2987   {
2988     int i = def;
2989     try
2990     {
2991       s.commitEdit();
2992       i = (Integer) s.getValue();
2993     } catch (Exception e)
2994     {
2995       Cache.log.error("Failed casting (Integer) JSpinner s.getValue()");
2996     }
2997     return i;
2998   }
2999
3000   private void keepRollMaxOptionsEnabled()
3001   {
3002     boolean enabled = backupfilesKeepAll.isEnabled()
3003             && !backupfilesKeepAll.isSelected();
3004     oldBackupFilesLabel.setEnabled(enabled);
3005     backupfilesRollMaxSpinner.setEnabled(enabled);
3006     backupfilesConfirmDelete.setEnabled(enabled);
3007   }
3008
3009   private void backupfilesKeepAllSetEnabled(boolean tryEnabled)
3010   {
3011     boolean enabled = tryEnabled && enableBackupFiles.isSelected()
3012             && customiseCheckbox.isSelected() && suffixTemplate.getText()
3013                     .indexOf(BackupFiles.NUM_PLACEHOLDER) > -1;
3014     keepfilesPanel.setEnabled(enabled);
3015     backupfilesKeepAll.setEnabled(enabled);
3016     oldBackupFilesLabel.setEnabled(enabled);
3017     keepRollMaxOptionsEnabled();
3018   }
3019
3020   private void backupfilesSuffixTemplateDigitsSetEnabled()
3021   {
3022     boolean enabled = suffixTemplate.isEnabled() && suffixTemplate.getText()
3023             .indexOf(BackupFiles.NUM_PLACEHOLDER) > -1;
3024     suffixDigitsLabel.setEnabled(enabled);
3025     suffixDigitsSpinner.setEnabled(enabled);
3026     suffixReverse.setEnabled(enabled);
3027   }
3028
3029   private void backupfilesSuffixTemplateSetEnabled(boolean tryEnabled)
3030   {
3031     boolean enabled = tryEnabled && enableBackupFiles.isSelected()
3032             && customiseCheckbox.isSelected();
3033     suffixPanel.setEnabled(enabled);
3034     suffixTemplateLabel.setEnabled(enabled);
3035     suffixTemplate.setEnabled(enabled);
3036     backupfilesSuffixTemplateDigitsSetEnabled();
3037   }
3038
3039   private void backupfilesRevertButtonSetEnabled(boolean tryEnabled)
3040   {
3041     boolean enabled = tryEnabled && enableBackupFiles.isSelected()
3042             && customiseCheckbox.isSelected() && backupfilesCustomChanged();
3043     revertButton.setEnabled(enabled);
3044   }
3045
3046   private boolean backupfilesCustomChanged()
3047   {
3048     BackupFilesPresetEntry custom = BackupFilesPresetEntry.backupfilesPresetEntriesValues
3049             .get(BackupFilesPresetEntry.BACKUPFILESSCHEMECUSTOM);
3050     BackupFilesPresetEntry current = getBackupfilesCurrentEntry();
3051     return !custom.equals(current);
3052   }
3053
3054   protected BackupFilesPresetEntry getBackupfilesCurrentEntry()
3055   {
3056     String suffix = suffixTemplate.getText();
3057     int digits = getSpinnerInt(suffixDigitsSpinner, 3);
3058     boolean reverse = suffixReverse.isSelected();
3059     boolean keepAll = backupfilesKeepAll.isSelected();
3060     int rollMax = getSpinnerInt(backupfilesRollMaxSpinner, 3);
3061     boolean confirmDelete = backupfilesConfirmDelete.isSelected();
3062
3063     BackupFilesPresetEntry bfpe = new BackupFilesPresetEntry(suffix, digits,
3064             reverse, keepAll, rollMax, confirmDelete);
3065
3066     return bfpe;
3067   }
3068
3069   protected void backupfilesCustomOptionsSetEnabled()
3070   {
3071     boolean enabled = customiseCheckbox.isSelected();
3072
3073     backupfilesRevertButtonSetEnabled(enabled);
3074     backupfilesSuffixTemplateSetEnabled(enabled);
3075     backupfilesKeepAllSetEnabled(enabled);
3076   }
3077
3078   private void backupfilesSummarySetEnabled()
3079   {
3080     boolean enabled = enableBackupFiles.isSelected();
3081     backupfilesExampleLabel.setEnabled(enabled);
3082     exampleFilesPanel.setEnabled(enabled);
3083   }
3084
3085   private void backupfilesPresetsSetEnabled()
3086   {
3087     boolean enabled = enableBackupFiles.isSelected();
3088     presetsPanel.setEnabled(enabled);
3089     presetsComboLabel.setEnabled(enabled);
3090     backupfilesPresetsCombo.setEnabled(enabled);
3091     customiseCheckbox.setEnabled(enabled);
3092     revertButton.setEnabled(enabled);
3093   }
3094
3095   protected void backupsOptionsSetEnabled()
3096   {
3097     backupfilesPresetsSetEnabled();
3098     backupfilesSummarySetEnabled();
3099     backupfilesCustomOptionsSetEnabled();
3100   }
3101
3102   protected void backupsSetOptions(String suffix, int digits,
3103           boolean reverse, boolean keepAll, int rollMax,
3104           boolean confirmDelete)
3105   {
3106     suffixTemplate.setText(suffix);
3107     suffixDigitsSpinner.setValue(digits);
3108     suffixReverse.setSelected(reverse);
3109     backupfilesKeepAll.setSelected(keepAll);
3110     backupfilesRollMaxSpinner.setValue(rollMax);
3111     backupfilesConfirmDelete.setSelected(confirmDelete);
3112   }
3113
3114   protected void backupsSetOptions(BackupFilesPresetEntry p)
3115   {
3116     backupsSetOptions(p.suffix, p.digits, p.reverse, p.keepAll, p.rollMax,
3117             p.confirmDelete);
3118   }
3119
3120   protected void autoIdWidth_actionPerformed()
3121   {
3122     // TODO Auto-generated method stub
3123
3124   }
3125
3126   protected void userIdWidth_actionPerformed()
3127   {
3128     // TODO Auto-generated method stub
3129
3130   }
3131
3132   protected void maxColour_actionPerformed(JPanel panel)
3133   {
3134   }
3135
3136   protected void minColour_actionPerformed(JPanel panel)
3137   {
3138   }
3139
3140   protected void gapColour_actionPerformed(JPanel panel)
3141   {
3142   }
3143
3144   protected void hiddenColour_actionPerformed(JPanel panel)
3145   {
3146   }
3147
3148   protected void showunconserved_actionPerformed(ActionEvent e)
3149   {
3150     // TODO Auto-generated method stub
3151
3152   }
3153
3154   protected void useLegacyGaps_actionPerformed(ActionEvent e)
3155   {
3156   }
3157
3158   protected void resetOvDefaults_actionPerformed(ActionEvent e)
3159   {
3160   }
3161
3162   /**
3163    * DOCUMENT ME!
3164    * 
3165    * @param e
3166    *            DOCUMENT ME!
3167    */
3168   public void ok_actionPerformed(ActionEvent e)
3169   {
3170   }
3171
3172   /**
3173    * DOCUMENT ME!
3174    * 
3175    * @param e
3176    *            DOCUMENT ME!
3177    */
3178   public void cancel_actionPerformed(ActionEvent e)
3179   {
3180   }
3181
3182   /**
3183    * DOCUMENT ME!
3184    * 
3185    * @param e
3186    *            DOCUMENT ME!
3187    */
3188   public void annotations_actionPerformed(ActionEvent e)
3189   {
3190   }
3191
3192   /**
3193    * DOCUMENT ME!
3194    */
3195   public void startupFileTextfield_mouseClicked()
3196   {
3197   }
3198
3199   public void newLink_actionPerformed(ActionEvent e)
3200   {
3201
3202   }
3203
3204   public void editLink_actionPerformed(ActionEvent e)
3205   {
3206
3207   }
3208
3209   public void deleteLink_actionPerformed(ActionEvent e)
3210   {
3211
3212   }
3213
3214   public void defaultBrowser_mouseClicked(MouseEvent e)
3215   {
3216
3217   }
3218
3219   public void linkURLList_keyTyped(KeyEvent e)
3220   {
3221
3222   }
3223
3224   public void setProxyAuthEnabled()
3225   {
3226     boolean enabled = proxyAuth.isSelected() && proxyAuth.isEnabled();
3227     proxyAuthUsernameLabel.setEnabled(enabled);
3228     proxyAuthPasswordLabel.setEnabled(enabled);
3229     passwordNotStoredLabel.setEnabled(enabled);
3230     proxyAuthUsernameTB.setEnabled(enabled);
3231     proxyAuthPasswordPB.setEnabled(enabled);
3232   }
3233
3234   public void setCustomProxyEnabled()
3235   {
3236     boolean enabled = customProxy.isSelected();
3237     portLabel.setEnabled(enabled);
3238     serverLabel.setEnabled(enabled);
3239     portLabel2.setEnabled(enabled);
3240     serverLabel2.setEnabled(enabled);
3241     httpLabel.setEnabled(enabled);
3242     httpsLabel.setEnabled(enabled);
3243     proxyServerHttpTB.setEnabled(enabled);
3244     proxyPortHttpTB.setEnabled(enabled);
3245     proxyServerHttpsTB.setEnabled(enabled);
3246     proxyPortHttpsTB.setEnabled(enabled);
3247     proxyAuth.setEnabled(enabled);
3248     setProxyAuthEnabled();
3249   }
3250
3251   public void proxyType_actionPerformed()
3252   {
3253     setCustomProxyEnabled();
3254     proxyAuthPasswordCheckHighlight(true);
3255     applyProxyButtonEnabled(true);
3256   }
3257
3258   public void proxyAuth_actionPerformed()
3259   {
3260     setProxyAuthEnabled();
3261     proxyAuthPasswordCheckHighlight(true);
3262     applyProxyButtonEnabled(true);
3263   }
3264
3265   /**
3266    * Customer renderer for JTable: supports column of radio buttons
3267    */
3268   public class RadioButtonRenderer extends JRadioButton
3269           implements TableCellRenderer
3270   {
3271     public RadioButtonRenderer()
3272     {
3273       setHorizontalAlignment(CENTER);
3274       setToolTipText(MessageManager.getString("label.urltooltip"));
3275     }
3276
3277     @Override
3278     public Component getTableCellRendererComponent(JTable table,
3279             Object value, boolean isSelected, boolean hasFocus, int row,
3280             int column)
3281     {
3282       setSelected((boolean) value);
3283
3284       // set colours to match rest of table
3285       if (isSelected)
3286       {
3287         setBackground(table.getSelectionBackground());
3288         setForeground(table.getSelectionForeground());
3289       }
3290       else
3291       {
3292         setBackground(table.getBackground());
3293         setForeground(table.getForeground());
3294       }
3295       return this;
3296     }
3297   }
3298
3299   /**
3300    * Customer cell editor for JTable: supports column of radio buttons in
3301    * conjunction with renderer
3302    */
3303   public class RadioButtonEditor extends AbstractCellEditor
3304           implements TableCellEditor
3305   {
3306     private JRadioButton button = new JRadioButton();
3307
3308     public RadioButtonEditor()
3309     {
3310       button.setHorizontalAlignment(SwingConstants.CENTER);
3311       this.button.addActionListener(new ActionListener()
3312       {
3313         @Override
3314         public void actionPerformed(ActionEvent e)
3315         {
3316           fireEditingStopped();
3317         }
3318       });
3319     }
3320
3321     @Override
3322     public Component getTableCellEditorComponent(JTable table, Object value,
3323             boolean isSelected, int row, int column)
3324     {
3325       button.setSelected((boolean) value);
3326       return button;
3327     }
3328
3329     @Override
3330     public Object getCellEditorValue()
3331     {
3332       return button.isSelected();
3333     }
3334
3335   }
3336 }