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