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