Clover icon

Coverage Report

  1. Project Clover database Thu Jan 15 2026 16:11:02 GMT
  2. Package jalview.gui

File Preferences.java

 

Coverage histogram

../../img/srcFileCovDistChart4.png
51% of files have more coverage

Code metrics

164
648
56
3
1,982
1,463
168
0.26
11.57
18.67
3

Classes

Class Line # Actions
Preferences 94 624 155
0.3155985531.6%
Preferences.OptionsParam 1887 11 9
0.4285714342.9%
Preferences.UrlListSelectionHandler 1942 13 4
0.00%
 

Contributing tests

This file is covered by 6 tests. .

Source view

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.gui;
22   
23    import java.awt.BorderLayout;
24    import java.awt.Color;
25    import java.awt.Component;
26    import java.awt.Dimension;
27    import java.awt.Font;
28    import java.awt.event.ActionEvent;
29    import java.awt.event.ActionListener;
30    import java.awt.event.FocusAdapter;
31    import java.awt.event.FocusEvent;
32    import java.awt.event.MouseEvent;
33    import java.io.File;
34    import java.util.ArrayList;
35    import java.util.List;
36    import java.util.concurrent.CompletableFuture;
37   
38    import javax.help.HelpSetException;
39    import javax.swing.JComboBox;
40    import javax.swing.JFileChooser;
41    import javax.swing.JInternalFrame;
42    import javax.swing.JPanel;
43    import javax.swing.JTextField;
44    import javax.swing.ListSelectionModel;
45    import javax.swing.RowFilter;
46    import javax.swing.RowSorter;
47    import javax.swing.SortOrder;
48    import javax.swing.event.DocumentEvent;
49    import javax.swing.event.DocumentListener;
50    import javax.swing.event.ListSelectionEvent;
51    import javax.swing.event.ListSelectionListener;
52    import javax.swing.table.TableCellRenderer;
53    import javax.swing.table.TableColumn;
54    import javax.swing.table.TableModel;
55    import javax.swing.table.TableRowSorter;
56   
57    import jalview.hmmer.HmmerCommand;
58    import jalview.util.FileUtils;
59    import ext.edu.ucsf.rbvi.strucviz2.StructureManager;
60    import jalview.analysis.AnnotationSorter.SequenceAnnotationOrder;
61    import jalview.bin.ApplicationSingletonProvider;
62    import jalview.bin.ApplicationSingletonProvider.ApplicationSingletonI;
63    import jalview.bin.Cache;
64    import jalview.bin.Console;
65    import jalview.bin.MemorySetting;
66    import jalview.ext.pymol.PymolManager;
67    import jalview.gui.Help.HelpId;
68    import jalview.gui.StructureViewer.ViewerType;
69    import jalview.io.BackupFiles;
70    import jalview.io.BackupFilesPresetEntry;
71    import jalview.io.FileFormatI;
72    import jalview.io.JalviewFileChooser;
73    import jalview.io.JalviewFileView;
74    import jalview.jbgui.GPreferences;
75    import jalview.jbgui.GSequenceLink;
76    import jalview.schemes.ColourSchemeI;
77    import jalview.schemes.ColourSchemes;
78    import jalview.schemes.ResidueColourScheme;
79    import jalview.urls.UrlLinkTableModel;
80    import jalview.urls.api.UrlProviderFactoryI;
81    import jalview.urls.api.UrlProviderI;
82    import jalview.urls.desktop.DesktopUrlProviderFactory;
83    import jalview.util.MessageManager;
84    import jalview.util.Platform;
85    import jalview.util.UrlConstants;
86    import jalview.ws.sifts.SiftsSettings;
87   
88    /**
89    * DOCUMENT ME!
90    *
91    * @author $author$
92    * @version $Revision$
93    */
 
94    public class Preferences extends GPreferences implements ApplicationSingletonI
95    {
96    // suggested list delimiter character
97    public static final String COMMA = ",";
98   
99    public static final String HMMSEARCH_SEQCOUNT = "HMMSEARCH_SEQCOUNT";
100   
101    public static final String HMMINFO_GLOBAL_BACKGROUND = "HMMINFO_GLOBAL_BACKGROUND";
102   
103    public static final String HMMALIGN_TRIM_TERMINI = "HMMALIGN_TRIM_TERMINI";
104   
105    public static final String ADD_SS_ANN = "ADD_SS_ANN";
106   
107    public static final String ADD_TEMPFACT_ANN = "ADD_TEMPFACT_ANN";
108   
109    public static final String ALLOW_UNPUBLISHED_PDB_QUERYING = "ALLOW_UNPUBLISHED_PDB_QUERYING";
110   
111    public static final String ANNOTATIONCOLOUR_MAX = "ANNOTATIONCOLOUR_MAX";
112   
113    public static final String ANNOTATIONCOLOUR_MIN = "ANNOTATIONCOLOUR_MIN";
114   
115    public static final String ANTI_ALIAS = "ANTI_ALIAS";
116   
117    public static final String AUTO_CALC_CONSENSUS = "AUTO_CALC_CONSENSUS";
118   
119    public static final String AUTOASSOCIATE_PDBANDSEQS = "AUTOASSOCIATE_PDBANDSEQS";
120   
121    public static final String BLOSUM62_PCA_FOR_NUCLEOTIDE = "BLOSUM62_PCA_FOR_NUCLEOTIDE";
122   
123    public static final String CENTRE_COLUMN_LABELS = "CENTRE_COLUMN_LABELS";
124   
125    public static final String CHIMERA_PATH = "CHIMERA_PATH";
126   
127    public static final String CHIMERAX_PATH = "CHIMERAX_PATH";
128   
129    public static final String DBREFFETCH_USEPICR = "DBREFFETCH_USEPICR";
130   
131    public static final String DEFAULT_COLOUR = "DEFAULT_COLOUR";
132   
133    public static final String DEFAULT_COLOUR_NUC = "DEFAULT_COLOUR_NUC";
134    public static final String DEFAULT_COLOUR_PROT = "DEFAULT_COLOUR_PROT";
135   
136    public static final String ENABLE_SPLIT_FRAME = "ENABLE_SPLIT_FRAME";
137   
138    public static final String FIGURE_AUTOIDWIDTH = "FIGURE_AUTOIDWIDTH";
139   
140    public static final String FIGURE_FIXEDIDWIDTH = "FIGURE_FIXEDIDWIDTH";
141   
142    public static final String FOLLOW_SELECTIONS = "FOLLOW_SELECTIONS";
143   
144    public static final String FONT_NAME = "FONT_NAME";
145   
146    public static final String FONT_SIZE = "FONT_SIZE";
147   
148    public static final String FONT_STYLE = "FONT_STYLE";
149   
150    public static final String HMMER_PATH = "HMMER_PATH";
151   
152    public static final String CYGWIN_PATH = "CYGWIN_PATH";
153   
154    public static final String HMMSEARCH_DBS = "HMMSEARCH_DBS";
155   
156    public static final String GAP_COLOUR = "GAP_COLOUR";
157   
158    public static final String GAP_SYMBOL = "GAP_SYMBOL";
159   
160    public static final String HIDDEN_COLOUR = "HIDDEN_COLOUR";
161   
162    public static final String HIDE_INTRONS = "HIDE_INTRONS";
163   
164    public static final String ID_ITALICS = "ID_ITALICS";
165   
166    public static final String ID_ORG_HOSTURL = "ID_ORG_HOSTURL";
167   
168    public static final String MAP_WITH_SIFTS = "MAP_WITH_SIFTS";
169   
170    public static final String NOQUESTIONNAIRES = "NOQUESTIONNAIRES";
171   
172    public static final String NORMALISE_CONSENSUS_LOGO = "NORMALISE_CONSENSUS_LOGO";
173   
174    public static final String NORMALISE_LOGO = "NORMALISE_LOGO";
175   
176    public static final String PAD_GAPS = "PAD_GAPS";
177   
178    public static final String PDB_DOWNLOAD_FORMAT = "PDB_DOWNLOAD_FORMAT";
179    public static final String PYMOL_PATH = "PYMOL_PATH";
180   
181    public static final String QUESTIONNAIRE = "QUESTIONNAIRE";
182   
183    public static final String RELAXEDSEQIDMATCHING = "RELAXEDSEQIDMATCHING";
184   
185    public static final String RIGHT_ALIGN_IDS = "RIGHT_ALIGN_IDS";
186   
187    public static final String SCALE_PROTEIN_TO_CDNA = "SCALE_PROTEIN_TO_CDNA";
188   
189    public static final String SHOW_ANNOTATIONS = "SHOW_ANNOTATIONS";
190   
191    public static final String SHOW_AUTOCALC_ABOVE = "SHOW_AUTOCALC_ABOVE";
192   
193    public static final String SHOW_CONSENSUS = "SHOW_CONSENSUS";
194   
195    public static final String SHOW_CONSENSUS_HISTOGRAM = "SHOW_CONSENSUS_HISTOGRAM";
196   
197    public static final String SHOW_CONSENSUS_LOGO = "SHOW_CONSENSUS_LOGO";
198   
199    public static final String SHOW_CONSERVATION = "SHOW_CONSERVATION";
200   
201    public static final String SHOW_DBREFS_TOOLTIP = "SHOW_DBREFS_TOOLTIP";
202   
203    public static final String SHOW_GROUP_CONSENSUS = "SHOW_GROUP_CONSENSUS";
204   
205    public static final String SHOW_GROUP_CONSERVATION = "SHOW_GROUP_CONSERVATION";
206   
207    public static final String SHOW_JVSUFFIX = "SHOW_JVSUFFIX";
208   
209    public static final String SHOW_NPFEATS_TOOLTIP = "SHOW_NPFEATS_TOOLTIP";
210    public static final String SHOW_OCCUPANCY = "SHOW_OCCUPANCY";
211   
212    public static final String SHOW_OV_HIDDEN_AT_START = "SHOW_OV_HIDDEN_AT_START";
213   
214    public static final String SHOW_OVERVIEW = "SHOW_OVERVIEW";
215   
216    public static final String SHOW_QUALITY = "SHOW_QUALITY";
217   
218    public static final String SHOW_UNCONSERVED = "SHOW_UNCONSERVED";
219   
220    public static final String SORT_ALIGNMENT = "SORT_ALIGNMENT";
221   
222    public static final String SORT_ANNOTATIONS = "SORT_ANNOTATIONS";
223   
224    public static final String SORT_BY_TREE = "SORT_BY_TREE";
225   
226    public static final String STRUCT_FROM_PDB = "STRUCT_FROM_PDB";
227   
228    public static final String STRUCTURE_DISPLAY = "STRUCTURE_DISPLAY";
229   
230    public static final String STRUCTURE_DIMENSIONS = "STRUCTURE_DIMENSIONS";
231   
232    public static final String UNIPROT_DOMAIN = "UNIPROT_DOMAIN";
233   
234    public static final String USE_FULL_SO = "USE_FULL_SO";
235    public static final String USE_LEGACY_GAP = "USE_LEGACY_GAP";
236   
237    public static final String USE_RNAVIEW = "USE_RNAVIEW";
238   
239    public static final String USER_DEFINED_COLOURS = "USER_DEFINED_COLOURS";
240   
241    public static final String WRAP_ALIGNMENT = "WRAP_ALIGNMENT";
242   
243    private static final int MIN_FONT_SIZE = 1;
244   
245    private static final int MAX_FONT_SIZE = 30;
246   
247    public static final String SHOW_STRUC_PROVIDER = "SHOW_STRUCTURE_PROVIDER";
248   
249    private String previousProxyType;
250   
251    private static Preferences INSTANCE = null; // add "final"
252   
253    /**
254    * Holds name and link separated with | character. Sequence ID must be
255    * $SEQUENCE_ID$ or $SEQUENCE_ID=/.possible | chars ./=$
256    */
257    public UrlProviderI sequenceUrlLinks;
258   
259    public UrlLinkTableModel dataModel;
260   
261    /**
262    * Holds name and link separated with | character. Sequence IDS and Sequences
263    * must be $SEQUENCEIDS$ or $SEQUENCEIDS=/.possible | chars ./=$ and $SEQUENCES$
264    * or $SEQUENCES=/.possible | chars ./=$ and separation character for first and
265    * second token specified after a pipe character at end |,|. (TODO: proper
266    * escape for using | to separate ids or sequences
267    */
268   
269    public static List<String> groupURLLinks;
270   
 
271  11 toggle {
272    // don't populate with session properties
273  11 Cache.disableSessionProperties();
274   
275    // get links selected to be in the menu (SEQUENCE_LINKS)
276    // and links entered by the user but not selected (STORED_LINKS)
277  11 String inMenuString = Cache.getDefault("SEQUENCE_LINKS", "");
278  11 String notInMenuString = Cache.getDefault("STORED_LINKS", "");
279  11 String defaultUrl = Cache.getDefault("DEFAULT_URL",
280    UrlConstants.DEFAULT_LABEL);
281   
282    // if both links lists are empty, add the DEFAULT_URL link
283    // otherwise we assume the default link is in one of the lists
284  11 if (inMenuString.isEmpty() && notInMenuString.isEmpty())
285    {
286  6 inMenuString = UrlConstants.DEFAULT_STRING;
287    }
288  11 UrlProviderFactoryI factory = new DesktopUrlProviderFactory(defaultUrl,
289    inMenuString, notInMenuString);
290  11 sequenceUrlLinks = factory.createUrlProvider();
291  11 dataModel = new UrlLinkTableModel(sequenceUrlLinks);
292   
293    /**
294    * TODO: reformulate groupURL encoding so two or more can be stored in the
295    * .properties file as '|' separated strings
296    */
297   
298  11 groupURLLinks = new ArrayList<>();
299   
300    // reenable
301  11 Cache.enableSessionProperties();
302    }
303   
304    JInternalFrame frame;
305   
306    private WsPreferences wsPrefs;
307   
308    private SlivkaPreferences slivkaPrefs;
309    private OptionsParam promptEachTimeOpt = new OptionsParam(
310    MessageManager.getString("label.prompt_each_time"),
311    LineartOptions.PROMPT_EACH_TIME);
312   
313    private OptionsParam lineArtOpt = new OptionsParam(
314    MessageManager.getString("label.lineart"), "Lineart");
315   
316    private OptionsParam textOpt = new OptionsParam(
317    MessageManager.getString("action.text"), "Text");
318   
319    // get singleton Preferences instance
 
320  48 toggle public static Preferences getInstance()
321    {
322  48 Preferences INSTANCE = ApplicationSingletonProvider.getInstance(Preferences.class);
323  48 if (INSTANCE == null || INSTANCE.frame == null
324    || INSTANCE.frame.isClosed())
325    {
326  0 ApplicationSingletonProvider.removeInstance(Preferences.class);
327  0 INSTANCE = ApplicationSingletonProvider.getInstance(Preferences.class);
328    }
329  48 return INSTANCE;
330    }
331   
 
332  0 toggle public static void openPreferences()
333    {
334  0 openPreferences(null, null);
335    }
336   
 
337  0 toggle public static void openPreferences(TabRef selectTab, String message)
338    {
339  0 Preferences p = getInstance();
340  0 p.showThePreferencesFrame();
341  0 if (selectTab != null)
342  0 p.selectTab(selectTab, message);
343  0 p.frame.show();
344  0 p.frame.moveToFront();
345  0 p.frame.grabFocus();
346    }
347   
 
348  0 toggle public void selectTab(TabRef selectTab, String message)
349    {
350  0 this.selectTab(selectTab);
351  0 if (message != null)
352  0 this.setMessage(message);
353  0 this.frame.show();
354    }
355   
 
356  0 toggle private void showThePreferencesFrame()
357    {
358  0 int width = 500, height = 450;
359  0 if (Platform.isAMacAndNotJS())
360    {
361  0 width = 570;
362  0 height = 480;
363    }
364  0 if (frame.getParent() == null)
365    {
366  0 Desktop.addInternalFrame(frame,
367    MessageManager.getString("label.preferences"), width, height);
368    }
369  0 frame.setMinimumSize(new Dimension(width, height));
370    }
371    /**
372    * Creates a new Preferences object.
373    */
 
374  11 toggle private Preferences()
375    {
376  11 super();
377    // don't populate with session properties
378  11 Cache.disableSessionProperties();
379   
380  11 frame = new JInternalFrame();
381  11 frame.setFrameIcon(null);
382  11 frame.setContentPane(this);
383  11 if (!Platform.isJS())
384    /**
385    * Java only
386    *
387    * @j2sIgnore
388    */
389    {
390  11 wsPrefs = new WsPreferences();
391  11 wsTab.add(wsPrefs, BorderLayout.CENTER);
392    }
393   
394  11 slivkaPrefs = new SlivkaPreferences();
395  11 slivkaTab.add(slivkaPrefs, BorderLayout.CENTER);
396    // TODO bring together GPreferences.hmmrTab and this code so we don't have to check for not isJs again!
397  11 if (!Platform.isJS())
398    {
399    /*
400    * Set HMMER tab defaults
401    */
402  11 hmmrTrimTermini
403    .setSelected(Cache.getDefault(HMMALIGN_TRIM_TERMINI, false));
404  11 if (Cache.getDefault(HMMINFO_GLOBAL_BACKGROUND, false))
405    {
406  0 hmmerBackgroundUniprot.setSelected(true);
407    }
408    else
409    {
410  11 hmmerBackgroundAlignment.setSelected(true);
411    }
412  11 hmmerSequenceCount.setText(Cache.getProperty(HMMSEARCH_SEQCOUNT));
413  11 hmmerPath.setText(Cache.getProperty(HMMER_PATH));
414  11 hmmerPath.addActionListener(new ActionListener()
415    {
 
416  0 toggle @Override
417    public void actionPerformed(ActionEvent e)
418    {
419  0 validateHmmerPath();
420    }
421    });
422  11 hmmerPath.addFocusListener(new FocusAdapter()
423    {
 
424  0 toggle @Override
425    public void focusLost(FocusEvent e)
426    {
427  0 validateHmmerPath();
428    }
429    });
430  11 if (cygwinPath != null)
431    {
432  0 String path = Cache.getProperty(CYGWIN_PATH);
433  0 if (path == null)
434    {
435  0 path = FileUtils.getPathTo("bash");
436    }
437  0 cygwinPath.setText(path);
438  0 cygwinPath.addActionListener(new ActionListener()
439    {
 
440  0 toggle @Override
441    public void actionPerformed(ActionEvent e)
442    {
443  0 validateCygwinPath();
444    }
445    });
446  0 cygwinPath.addFocusListener(new FocusAdapter()
447    {
 
448  0 toggle @Override
449    public void focusLost(FocusEvent e)
450    {
451  0 validateCygwinPath();
452    }
453    });
454    }
455    }
456   
457    /*
458    * Set Visual tab defaults
459    */
460  11 seqLimit.setSelected(Cache.getDefault("SHOW_JVSUFFIX", true));
461  11 rightAlign.setSelected(Cache.getDefault("RIGHT_ALIGN_IDS", false));
462  11 fullScreen.setSelected(Cache.getDefault("SHOW_FULLSCREEN", false));
463  11 annotations.setSelected(Cache.getDefault("SHOW_ANNOTATIONS", true));
464   
465  11 conservation.setSelected(Cache.getDefault("SHOW_CONSERVATION", true));
466  11 quality.setSelected(Cache.getDefault("SHOW_QUALITY", true));
467  11 identity.setSelected(Cache.getDefault("SHOW_IDENTITY", true));
468  11 ssConsensus.setSelected(Cache.getDefault("SHOW_SS_CONSENSUS", false));
469  11 openoverv.setSelected(Cache.getDefault("SHOW_OVERVIEW", false));
470  11 showUnconserved
471    .setSelected(Cache.getDefault("SHOW_UNCONSERVED", false));
472  11 showOccupancy.setSelected(Cache.getDefault(SHOW_OCCUPANCY, false));
473  11 showGroupConsensus
474    .setSelected(Cache.getDefault("SHOW_GROUP_CONSENSUS", false));
475  11 showGroupConservation.setSelected(
476    Cache.getDefault("SHOW_GROUP_CONSERVATION", false));
477  11 showConsensHistogram.setSelected(
478    Cache.getDefault("SHOW_CONSENSUS_HISTOGRAM", true));
479  11 showConsensLogo
480    .setSelected(Cache.getDefault("SHOW_CONSENSUS_LOGO", false));
481  11 showInformationHistogram.setSelected(
482    Cache.getDefault("SHOW_INFORMATION_HISTOGRAM", true));
483  11 showHMMLogo.setSelected(Cache.getDefault("SHOW_HMM_LOGO", false));
484  11 showNpTooltip
485    .setSelected(Cache.getDefault("SHOW_NPFEATS_TOOLTIP", true));
486  11 showDbRefTooltip
487    .setSelected(Cache.getDefault("SHOW_DBREFS_TOOLTIP", true));
488   
489  11 String[] fonts = java.awt.GraphicsEnvironment
490    .getLocalGraphicsEnvironment().getAvailableFontFamilyNames();
491  374 for (int i = 0; i < fonts.length; i++)
492    {
493  363 fontNameCB.addItem(fonts[i]);
494    }
495   
496  341 for (int i = MIN_FONT_SIZE; i <= MAX_FONT_SIZE; i++)
497    {
498  330 fontSizeCB.addItem(i + "");
499    }
500   
501  11 fontStyleCB.addItem("plain");
502  11 fontStyleCB.addItem("bold");
503  11 fontStyleCB.addItem("italic");
504   
505  11 fontNameCB.setSelectedItem(Cache.getDefault("FONT_NAME", "SansSerif"));
506  11 fontSizeCB.setSelectedItem(Cache.getDefault("FONT_SIZE", "10"));
507  11 fontStyleCB.setSelectedItem(
508    Cache.getDefault("FONT_STYLE", Font.PLAIN + ""));
509   
510  11 smoothFont.setSelected(Cache.getDefault("ANTI_ALIAS", true));
511  11 scaleProteinToCdna
512    .setSelected(Cache.getDefault(SCALE_PROTEIN_TO_CDNA, false));
513   
514  11 idItalics.setSelected(Cache.getDefault("ID_ITALICS", true));
515   
516  11 wrap.setSelected(Cache.getDefault("WRAP_ALIGNMENT", false));
517   
518  11 gapSymbolCB.addItem("-");
519  11 gapSymbolCB.addItem(".");
520   
521  11 gapSymbolCB.setSelectedItem(Cache.getDefault("GAP_SYMBOL", "-"));
522   
523  11 sortby.addItem("No sort");
524  11 sortby.addItem("Id");
525  11 sortby.addItem("Pairwise Identity");
526  11 sortby.setSelectedItem(Cache.getDefault("SORT_ALIGNMENT", "No sort"));
527   
528  11 sortAnnBy.addItem(SequenceAnnotationOrder.NONE.toString());
529  11 sortAnnBy
530    .addItem(SequenceAnnotationOrder.SEQUENCE_AND_LABEL.toString());
531  11 sortAnnBy
532    .addItem(SequenceAnnotationOrder.LABEL_AND_SEQUENCE.toString());
533  11 SequenceAnnotationOrder savedSort = SequenceAnnotationOrder
534    .valueOf(Cache.getDefault(SORT_ANNOTATIONS,
535    SequenceAnnotationOrder.NONE.name()));
536  11 sortAnnBy.setSelectedItem(savedSort.toString());
537   
538  11 sortAutocalc.addItem("Autocalculated first");
539  11 sortAutocalc.addItem("Autocalculated last");
540  11 final boolean showAbove = Cache.getDefault(SHOW_AUTOCALC_ABOVE, true);
541  11 sortAutocalc.setSelectedItem(showAbove ? sortAutocalc.getItemAt(0)
542    : sortAutocalc.getItemAt(1));
543  11 startupCheckbox
544    .setSelected(Cache.getDefault("SHOW_STARTUP_FILE", true));
545  11 startupFileTextfield.setText(Cache.getDefault("STARTUP_FILE",
546    Cache.getDefault("www.jalview.org", "https://www.jalview.org")
547    + "/examples/exampleFile_2_7.jvp"));
548   
549    /*
550    * Set Colours tab defaults
551    */
552  11 protColour.addItem(ResidueColourScheme.NONE);
553  11 nucColour.addItem(ResidueColourScheme.NONE);
554  11 for (ColourSchemeI cs : ColourSchemes.getInstance().getColourSchemes())
555    {
556  253 String name = cs.getSchemeName();
557  253 protColour.addItem(name);
558  253 nucColour.addItem(name);
559    }
560  11 String oldProp = Cache.getDefault(DEFAULT_COLOUR,
561    ResidueColourScheme.NONE);
562  11 String newProp = Cache.getDefault(DEFAULT_COLOUR_PROT, null);
563  11 protColour.setSelectedItem(newProp != null ? newProp : oldProp);
564  11 newProp = Cache.getDefault(DEFAULT_COLOUR_NUC, null);
565  11 nucColour.setSelectedItem(newProp != null ? newProp : oldProp);
566  11 minColour.setBackground(
567    Cache.getDefaultColour("ANNOTATIONCOLOUR_MIN", Color.orange));
568  11 maxColour.setBackground(
569    Cache.getDefaultColour("ANNOTATIONCOLOUR_MAX", Color.red));
570   
571    /*
572    * Set overview panel defaults
573    */
574  11 gapColour.setBackground(Cache.getDefaultColour(GAP_COLOUR,
575    OverviewCanvas.OVERVIEW_DEFAULT_GAP));
576  11 hiddenColour.setBackground(Cache.getDefaultColour(HIDDEN_COLOUR,
577    OverviewCanvas.OVERVIEW_DEFAULT_HIDDEN));
578  11 useLegacyGap.setSelected(Cache.getDefault(USE_LEGACY_GAP, false));
579  11 gapLabel.setEnabled(!useLegacyGap.isSelected());
580  11 gapColour.setEnabled(!useLegacyGap.isSelected());
581  11 showHiddenAtStart
582    .setSelected(Cache.getDefault(SHOW_OV_HIDDEN_AT_START, false));
583   
584    /*
585    * Set Structure tab defaults
586    */
587  11 final boolean structSelected = Cache.getDefault(STRUCT_FROM_PDB, true);
588  11 structFromPdb.setSelected(structSelected);
589  11 addSecondaryStructure.setSelected(Cache.getDefault(ADD_SS_ANN, true));
590  11 addSecondaryStructure.setEnabled(structSelected);
591  11 addTempFactor.setSelected(Cache.getDefault(ADD_TEMPFACT_ANN, true));
592  11 addTempFactor.setEnabled(structSelected);
593   
594    /*
595    * set choice of structure viewer, and path if saved as a preference;
596    * default to Jmol (first choice) if an unexpected value is found
597    */
598  11 String viewerType = ViewerType.JMOL.name();
599  11 if (!Platform.isJS())
600    {
601  11 Cache.getDefault(STRUCTURE_DISPLAY,
602    ViewerType.JMOL.name());
603    }
604    // TODO - disable external viewers for JS
605  11 structViewer.setSelectedItem(viewerType);
606  11 String viewerPath = "";
607  11 ViewerType type = null;
608  11 try
609    {
610  11 type = ViewerType.valueOf(viewerType);
611  11 switch (type)
612    {
613  11 case JMOL:
614  11 break;
615  0 case CHIMERA:
616  0 viewerPath = Cache.getDefault(CHIMERA_PATH, "");
617  0 break;
618  0 case CHIMERAX:
619  0 viewerPath = Cache.getDefault(CHIMERAX_PATH, "");
620  0 break;
621  0 case PYMOL:
622  0 viewerPath = Cache.getDefault(PYMOL_PATH, "");
623  0 break;
624    }
625    } catch (IllegalArgumentException e)
626    {
627  0 Console.error("Unknown structure viewer type: " + viewerType
628    + ", defaulting to Jmol");
629  0 type = ViewerType.JMOL;
630    }
631  11 structureViewerPath.setText(viewerPath);
632   
633  11 structureViewerPath.addActionListener(new ActionListener()
634    {
 
635  0 toggle @Override
636    public void actionPerformed(ActionEvent e)
637    {
638  0 if (validateViewerPath())
639    {
640  0 String path = structureViewerPath.getText();
641  0 try
642    {
643  0 ViewerType type = ViewerType.valueOf(viewerType);
644  0 switch (type)
645    {
646  0 case JMOL:
647  0 break;
648  0 case CHIMERA:
649  0 Cache.setProperty(CHIMERA_PATH, path);
650  0 break;
651  0 case CHIMERAX:
652  0 Cache.setProperty(CHIMERAX_PATH, path);
653  0 break;
654  0 case PYMOL:
655  0 Cache.setProperty(PYMOL_PATH, path);
656  0 break;
657    }
658    } catch (IllegalArgumentException x)
659    {
660  0 Console.error("Failed to set path - unknown viewer type", x);
661    }
662    }
663    }
664    });
665   
666  11 if (Cache.getDefault("MAP_WITH_SIFTS", false))
667    {
668  0 siftsMapping.setSelected(true);
669    }
670    else
671    {
672  11 nwMapping.setSelected(true);
673    }
674   
675  11 SiftsSettings
676    .setMapWithSifts(Cache.getDefault("MAP_WITH_SIFTS", false));
677   
678    /*
679    * Set Connections tab defaults
680    */
681   
682    // set up sorting
683  11 linkUrlTable.setModel(dataModel);
684  11 final TableRowSorter<TableModel> sorter = new TableRowSorter<>(
685    linkUrlTable.getModel());
686  11 linkUrlTable.setRowSorter(sorter);
687  11 List<RowSorter.SortKey> sortKeys = new ArrayList<>();
688   
689  11 UrlLinkTableModel m = (UrlLinkTableModel) linkUrlTable.getModel();
690  11 sortKeys.add(new RowSorter.SortKey(m.getPrimaryColumn(),
691    SortOrder.DESCENDING));
692  11 sortKeys.add(new RowSorter.SortKey(m.getSelectedColumn(),
693    SortOrder.DESCENDING));
694  11 sortKeys.add(
695    new RowSorter.SortKey(m.getNameColumn(), SortOrder.ASCENDING));
696   
697  11 sorter.setSortKeys(sortKeys);
698    // BH 2018 setSortKeys will do the sort
699    // sorter.sort();
700   
701    // set up filtering
702  11 ActionListener onReset;
703  11 onReset = new ActionListener()
704    {
 
705  0 toggle @Override
706    public void actionPerformed(ActionEvent e)
707    {
708  0 filterTB.setText("");
709  0 sorter.setRowFilter(RowFilter.regexFilter(""));
710    }
711   
712    };
713  11 doReset.addActionListener(onReset);
714   
715    // filter to display only custom urls
716  11 final RowFilter<TableModel, Object> customUrlFilter = new RowFilter<TableModel, Object>()
717    {
 
718  7425 toggle @Override
719    public boolean include(
720    Entry<? extends TableModel, ? extends Object> entry)
721    {
722  7425 return ((UrlLinkTableModel) entry.getModel()).isUserEntry(entry);
723    }
724    };
725   
726  11 final TableRowSorter<TableModel> customSorter = new TableRowSorter<>(
727    linkUrlTable.getModel());
728  11 customSorter.setRowFilter(customUrlFilter);
729   
730  11 ActionListener onCustomOnly;
731  11 onCustomOnly = new ActionListener()
732    {
 
733  0 toggle @Override
734    public void actionPerformed(ActionEvent e)
735    {
736  0 filterTB.setText("");
737  0 sorter.setRowFilter(customUrlFilter);
738    }
739    };
740  11 userOnly.addActionListener(onCustomOnly);
741   
742  11 filterTB.getDocument().addDocumentListener(new DocumentListener()
743    {
744    String caseInsensitiveFlag = "(?i)";
745   
 
746  0 toggle @Override
747    public void changedUpdate(DocumentEvent e)
748    {
749  0 sorter.setRowFilter(RowFilter
750    .regexFilter(caseInsensitiveFlag + filterTB.getText()));
751    }
752   
 
753  0 toggle @Override
754    public void removeUpdate(DocumentEvent e)
755    {
756  0 sorter.setRowFilter(RowFilter
757    .regexFilter(caseInsensitiveFlag + filterTB.getText()));
758    }
759   
 
760  0 toggle @Override
761    public void insertUpdate(DocumentEvent e)
762    {
763  0 sorter.setRowFilter(RowFilter
764    .regexFilter(caseInsensitiveFlag + filterTB.getText()));
765    }
766    });
767   
768    // set up list selection functionality
769  11 linkUrlTable.getSelectionModel()
770    .addListSelectionListener(new UrlListSelectionHandler());
771   
772    // set up radio buttons
773  11 int onClickCol = ((UrlLinkTableModel) linkUrlTable.getModel())
774    .getPrimaryColumn();
775  11 String onClickName = linkUrlTable.getColumnName(onClickCol);
776  11 linkUrlTable.getColumn(onClickName)
777    .setCellRenderer(new RadioButtonRenderer());
778  11 linkUrlTable.getColumn(onClickName)
779    .setCellEditor(new RadioButtonEditor());
780   
781    // get boolean columns and resize those to min possible
782  66 for (int column = 0; column < linkUrlTable.getColumnCount(); column++)
783    {
784  55 if (linkUrlTable.getModel().getColumnClass(column)
785    .equals(Boolean.class))
786    {
787  22 TableColumn tableColumn = linkUrlTable.getColumnModel()
788    .getColumn(column);
789  22 int preferredWidth = tableColumn.getMinWidth();
790   
791  22 TableCellRenderer cellRenderer = linkUrlTable.getCellRenderer(0,
792    column);
793  22 Component c = linkUrlTable.prepareRenderer(cellRenderer, 0, column);
794  22 int cwidth = c.getPreferredSize().width
795    + linkUrlTable.getIntercellSpacing().width;
796  22 preferredWidth = Math.max(preferredWidth, cwidth);
797   
798  22 tableColumn.setPreferredWidth(preferredWidth);
799    }
800    }
801   
802  11 String proxyTypeString = Cache.getDefault("USE_PROXY", "false");
803  11 previousProxyType = proxyTypeString;
804  11 switch (proxyTypeString)
805    {
806  0 case Cache.PROXYTYPE_NONE:
807  0 proxyType.setSelected(noProxy.getModel(), true);
808  0 break;
809  11 case Cache.PROXYTYPE_SYSTEM:
810  11 proxyType.setSelected(systemProxy.getModel(), true);
811  11 break;
812  0 case Cache.PROXYTYPE_CUSTOM:
813  0 proxyType.setSelected(customProxy.getModel(), true);
814  0 break;
815  0 default:
816  0 Console.warn(
817    "Incorrect PROXY_TYPE - should be 'none' (clear proxy properties), 'false' (system settings), 'true' (custom settings): "
818    + proxyTypeString);
819    }
820  11 proxyServerHttpTB.setText(Cache.getDefault("PROXY_SERVER", ""));
821  11 proxyPortHttpTB.setText(Cache.getDefault("PROXY_PORT", ""));
822  11 proxyServerHttpsTB.setText(Cache.getDefault("PROXY_SERVER_HTTPS", ""));
823  11 proxyPortHttpsTB.setText(Cache.getDefault("PROXY_PORT_HTTPS", ""));
824  11 proxyAuth.setSelected(Cache.getDefault("PROXY_AUTH", false));
825  11 proxyAuthUsernameTB
826    .setText(Cache.getDefault("PROXY_AUTH_USERNAME", ""));
827    // we are not storing or retrieving proxy password from .jalview_properties
828  11 proxyAuthPasswordPB.setText(Cache.proxyAuthPassword == null ? ""
829    : new String(Cache.proxyAuthPassword));
830  11 setCustomProxyEnabled();
831  11 applyProxyButtonEnabled(false);
832   
833  11 defaultBrowser.setText(Cache.getDefault("DEFAULT_BROWSER", ""));
834   
835  11 usagestats.setSelected(Cache.getDefault("USAGESTATS", false));
836    // note antisense here: default is true
837  11 questionnaire
838    .setSelected(Cache.getProperty("NOQUESTIONNAIRES") == null);
839  11 versioncheck.setSelected(Cache.getDefault("VERSION_CHECK", true));
840   
841    /*
842    * Set Output tab defaults
843    */
844  11 setupOutputCombo(epsRendering, "EPS_RENDERING");
845  11 setupOutputCombo(htmlRendering, "HTML_RENDERING");
846  11 setupOutputCombo(svgRendering, "SVG_RENDERING");
847  11 autoIdWidth.setSelected(Cache.getDefault("FIGURE_AUTOIDWIDTH", false));
848  11 userIdWidth.setEnabled(!autoIdWidth.isSelected());
849  11 userIdWidthlabel.setEnabled(!autoIdWidth.isSelected());
850  11 Integer wi = Cache.getIntegerProperty("FIGURE_FIXEDIDWIDTH");
851  11 userIdWidth.setText(wi == null ? "" : wi.toString());
852    // TODO: refactor to use common enum via FormatAdapter and allow extension
853    // for new flat file formats
854  11 blcjv.setSelected(Cache.getDefault("BLC_JVSUFFIX", true));
855  11 clustaljv.setSelected(Cache.getDefault("CLUSTAL_JVSUFFIX", true));
856  11 fastajv.setSelected(Cache.getDefault("FASTA_JVSUFFIX", true));
857  11 msfjv.setSelected(Cache.getDefault("MSF_JVSUFFIX", true));
858  11 pfamjv.setSelected(Cache.getDefault("PFAM_JVSUFFIX", true));
859  11 pileupjv.setSelected(Cache.getDefault("PILEUP_JVSUFFIX", true));
860  11 pirjv.setSelected(Cache.getDefault("PIR_JVSUFFIX", true));
861  11 modellerOutput.setSelected(Cache.getDefault("PIR_MODELLER", false));
862  11 embbedBioJSON
863    .setSelected(Cache.getDefault("EXPORT_EMBBED_BIOJSON", true));
864   
865    /*
866    * Set Editing tab defaults
867    */
868  11 autoCalculateConsCheck
869    .setSelected(Cache.getDefault("AUTO_CALC_CONSENSUS", true));
870  11 padGaps.setSelected(Cache.getDefault("PAD_GAPS", false));
871  11 sortByTree.setSelected(Cache.getDefault("SORT_BY_TREE", false));
872   
873  11 annotations_actionPerformed(null); // update the display of the annotation
874    // settings
875   
876   
877   
878    /*
879    * Set Backups tab defaults
880    */
881  11 loadLastSavedBackupsOptions();
882   
883    /*
884    * Set Startup tab defaults
885    */
886   
887    // re-enable
888  11 Cache.enableSessionProperties();
889    }
890   
891    /**
892    * A helper method that sets the items and initial selection in a character
893    * rendering option list (Prompt each time/Lineart/Text)
894    *
895    * @param comboBox
896    * @param propertyKey
897    */
 
898  33 toggle protected void setupOutputCombo(JComboBox<Object> comboBox,
899    String propertyKey)
900    {
901  33 Cache.disableSessionProperties();
902   
903  33 comboBox.addItem(promptEachTimeOpt);
904  33 comboBox.addItem(lineArtOpt);
905  33 comboBox.addItem(textOpt);
906   
907   
908    /*
909    * JalviewJS doesn't support Lineart so force it to Text
910    */
911  33 String defaultOption = Platform.isJS() ? "Text"
912    : Cache.getDefault(propertyKey, "Prompt each time");
913  33 if (defaultOption.equalsIgnoreCase("Text"))
914    {
915  0 comboBox.setSelectedItem(textOpt);
916    }
917  33 else if (defaultOption.equalsIgnoreCase("Lineart"))
918    {
919  0 comboBox.setSelectedItem(lineArtOpt);
920    }
921    else
922    {
923  33 comboBox.setSelectedItem(promptEachTimeOpt);
924    }
925   
926  33 Cache.enableSessionProperties();
927    }
928   
929    /**
930    * Save user selections on the Preferences tabs to the Cache and write out to
931    * file.
932    *
933    * @param e
934    */
 
935  0 toggle @Override
936    public void ok_actionPerformed(ActionEvent e)
937    {
938  0 Cache.disableSessionProperties();
939   
940  0 if (!validateSettings())
941    {
942  0 return;
943    }
944   
945    /*
946    * Set proxy settings first (to be before web services refresh)
947    */
948  0 saveProxySettings();
949   
950    /*
951    * Save Visual settings
952    */
953   
954  0 Cache.setPropertyNoSave("SHOW_JVSUFFIX",
955    Boolean.toString(seqLimit.isSelected()));
956  0 Cache.setPropertyNoSave("RIGHT_ALIGN_IDS",
957    Boolean.toString(rightAlign.isSelected()));
958  0 Cache.setPropertyNoSave("SHOW_FULLSCREEN",
959    Boolean.toString(fullScreen.isSelected()));
960  0 Cache.setPropertyNoSave("SHOW_OVERVIEW",
961    Boolean.toString(openoverv.isSelected()));
962  0 Cache.setPropertyNoSave("SHOW_ANNOTATIONS",
963    Boolean.toString(annotations.isSelected()));
964  0 Cache.setPropertyNoSave("SHOW_CONSERVATION",
965    Boolean.toString(conservation.isSelected()));
966  0 Cache.setPropertyNoSave("SHOW_QUALITY",
967    Boolean.toString(quality.isSelected()));
968  0 Cache.setPropertyNoSave("SHOW_IDENTITY",
969    Boolean.toString(identity.isSelected()));
970   
971  0 Cache.setPropertyNoSave("SHOW_SS_CONSENSUS",
972    Boolean.toString(ssConsensus.isSelected()));
973   
974  0 Cache.setPropertyNoSave("GAP_SYMBOL",
975    gapSymbolCB.getSelectedItem().toString());
976   
977  0 Cache.setPropertyNoSave("FONT_NAME",
978    fontNameCB.getSelectedItem().toString());
979  0 Cache.setPropertyNoSave("FONT_STYLE",
980    fontStyleCB.getSelectedItem().toString());
981  0 Cache.setPropertyNoSave("FONT_SIZE",
982    fontSizeCB.getSelectedItem().toString());
983   
984  0 Cache.setPropertyNoSave("ID_ITALICS",
985    Boolean.toString(idItalics.isSelected()));
986  0 Cache.setPropertyNoSave("SHOW_UNCONSERVED",
987    Boolean.toString(showUnconserved.isSelected()));
988  0 Cache.setPropertyNoSave(SHOW_OCCUPANCY,
989    Boolean.toString(showOccupancy.isSelected()));
990  0 Cache.setPropertyNoSave("SHOW_GROUP_CONSENSUS",
991    Boolean.toString(showGroupConsensus.isSelected()));
992  0 Cache.setPropertyNoSave("SHOW_GROUP_CONSERVATION",
993    Boolean.toString(showGroupConservation.isSelected()));
994  0 Cache.setPropertyNoSave("SHOW_CONSENSUS_HISTOGRAM",
995    Boolean.toString(showConsensHistogram.isSelected()));
996  0 Cache.setPropertyNoSave("SHOW_CONSENSUS_LOGO",
997    Boolean.toString(showConsensLogo.isSelected()));
998  0 Cache.setPropertyNoSave("SHOW_INFORMATION_HISTOGRAM",
999    Boolean.toString(showConsensHistogram.isSelected()));
1000  0 Cache.setPropertyNoSave("SHOW_HMM_LOGO",
1001    Boolean.toString(showHMMLogo.isSelected()));
1002  0 Cache.setPropertyNoSave("ANTI_ALIAS",
1003    Boolean.toString(smoothFont.isSelected()));
1004  0 Cache.setPropertyNoSave(SCALE_PROTEIN_TO_CDNA,
1005    Boolean.toString(scaleProteinToCdna.isSelected()));
1006  0 Cache.setPropertyNoSave("SHOW_NPFEATS_TOOLTIP",
1007    Boolean.toString(showNpTooltip.isSelected()));
1008  0 Cache.setPropertyNoSave("SHOW_DBREFS_TOOLTIP",
1009    Boolean.toString(showDbRefTooltip.isSelected()));
1010   
1011  0 Cache.setPropertyNoSave("WRAP_ALIGNMENT",
1012    Boolean.toString(wrap.isSelected()));
1013   
1014  0 Cache.setPropertyNoSave("STARTUP_FILE",
1015    startupFileTextfield.getText());
1016  0 Cache.setPropertyNoSave("SHOW_STARTUP_FILE",
1017    Boolean.toString(startupCheckbox.isSelected()));
1018   
1019  0 Cache.setPropertyNoSave("SORT_ALIGNMENT",
1020    sortby.getSelectedItem().toString());
1021   
1022    // convert description of sort order to enum name for save
1023  0 SequenceAnnotationOrder annSortOrder = SequenceAnnotationOrder
1024    .forDescription(sortAnnBy.getSelectedItem().toString());
1025  0 if (annSortOrder != null)
1026    {
1027  0 Cache.setPropertyNoSave(SORT_ANNOTATIONS,
1028    annSortOrder.name());
1029    }
1030   
1031  0 final boolean showAutocalcFirst = sortAutocalc.getSelectedIndex() == 0;
1032  0 Cache.setPropertyNoSave(SHOW_AUTOCALC_ABOVE,
1033    Boolean.valueOf(showAutocalcFirst).toString());
1034   
1035    /*
1036    * Save Colours settings
1037    */
1038  0 Cache.setPropertyNoSave(DEFAULT_COLOUR_PROT,
1039    protColour.getSelectedItem().toString());
1040  0 Cache.setPropertyNoSave(DEFAULT_COLOUR_NUC,
1041    nucColour.getSelectedItem().toString());
1042  0 Cache.setColourPropertyNoSave("ANNOTATIONCOLOUR_MIN",
1043    minColour.getBackground());
1044  0 Cache.setColourPropertyNoSave("ANNOTATIONCOLOUR_MAX",
1045    maxColour.getBackground());
1046   
1047    /*
1048    * Save HMMER settings
1049    */
1050  0 Cache.setPropertyNoSave(HMMALIGN_TRIM_TERMINI,
1051    Boolean.toString(hmmrTrimTermini.isSelected()));
1052  0 Cache.setPropertyNoSave(HMMINFO_GLOBAL_BACKGROUND,
1053    Boolean.toString(hmmerBackgroundUniprot.isSelected()));
1054  0 Cache.setPropertyNoSave(HMMSEARCH_SEQCOUNT,
1055    hmmerSequenceCount.getText());
1056  0 Cache.setOrRemove(HMMER_PATH, hmmerPath.getText());
1057  0 if (cygwinPath != null)
1058    {
1059  0 Cache.setOrRemove(CYGWIN_PATH, cygwinPath.getText());
1060    }
1061  0 AlignFrame[] frames = Desktop.getDesktopAlignFrames();
1062  0 if (frames != null && frames.length > 0)
1063    {
1064  0 for (AlignFrame f : frames)
1065    {
1066  0 f.updateHMMERStatus();
1067    }
1068    }
1069   
1070  0 hmmrTrimTermini.setSelected(Cache.getDefault(HMMALIGN_TRIM_TERMINI, false));
1071  0 if (Cache.getDefault(HMMINFO_GLOBAL_BACKGROUND, false))
1072    {
1073  0 hmmerBackgroundUniprot.setSelected(true);
1074    }
1075    else
1076    {
1077  0 hmmerBackgroundAlignment.setSelected(true);
1078    }
1079  0 hmmerSequenceCount
1080    .setText(Cache.getProperty(HMMSEARCH_SEQCOUNT));
1081  0 hmmerPath.setText(Cache.getProperty(HMMER_PATH));
1082   
1083    /*
1084    * Save Overview settings
1085    */
1086  0 Cache.setColourPropertyNoSave(GAP_COLOUR, gapColour.getBackground());
1087  0 Cache.setColourPropertyNoSave(HIDDEN_COLOUR, hiddenColour.getBackground());
1088  0 Cache.setPropertyNoSave(USE_LEGACY_GAP,
1089    Boolean.toString(useLegacyGap.isSelected()));
1090  0 Cache.setPropertyNoSave(SHOW_OV_HIDDEN_AT_START,
1091    Boolean.toString(showHiddenAtStart.isSelected()));
1092   
1093    /*
1094    * Save Structure settings
1095    */
1096  0 Cache.setPropertyNoSave(ADD_TEMPFACT_ANN,
1097    Boolean.toString(addTempFactor.isSelected()));
1098  0 Cache.setPropertyNoSave(ADD_SS_ANN,
1099    Boolean.toString(addSecondaryStructure.isSelected()));
1100  0 Cache.setPropertyNoSave(STRUCT_FROM_PDB,
1101    Boolean.toString(structFromPdb.isSelected()));
1102  0 if (!Platform.isJS()) {
1103  0 String viewer = structViewer.getSelectedItem().toString();
1104  0 String viewerPath = structureViewerPath.getText();
1105  0 Cache.setPropertyNoSave(STRUCTURE_DISPLAY, viewer);
1106  0 if (viewer.equals(ViewerType.CHIMERA.name()))
1107    {
1108  0 Cache.setOrRemove(CHIMERA_PATH, viewerPath);
1109    }
1110  0 else if (viewer.equals(ViewerType.CHIMERAX.name()))
1111    {
1112  0 Cache.setOrRemove(CHIMERAX_PATH, viewerPath);
1113    }
1114  0 else if (viewer.equals(ViewerType.PYMOL.name()))
1115    {
1116  0 Cache.setOrRemove(PYMOL_PATH, viewerPath);
1117    }
1118    } // nojs
1119  0 Cache.setPropertyNoSave("MAP_WITH_SIFTS",
1120    Boolean.toString(siftsMapping.isSelected()));
1121  0 SiftsSettings.setMapWithSifts(siftsMapping.isSelected());
1122   
1123    /*
1124    * Save Output settings
1125    */
1126  0 Cache.setPropertyNoSave("EPS_RENDERING",
1127    ((OptionsParam) epsRendering.getSelectedItem()).getCode());
1128  0 Cache.setPropertyNoSave("HTML_RENDERING",
1129    ((OptionsParam) htmlRendering.getSelectedItem()).getCode());
1130  0 Cache.setPropertyNoSave("SVG_RENDERING",
1131    ((OptionsParam) svgRendering.getSelectedItem()).getCode());
1132   
1133    /*
1134    * Save Connections settings
1135    */
1136    // Proxy settings were already set first (to catch web services)
1137  0 Cache.setOrRemove("DEFAULT_BROWSER", defaultBrowser.getText());
1138   
1139  0 jalview.util.BrowserLauncher.resetBrowser();
1140   
1141    // save user-defined and selected links
1142  0 String menuLinks = sequenceUrlLinks.writeUrlsAsString(true);
1143  0 if (menuLinks.isEmpty())
1144    {
1145  0 Cache.removePropertyNoSave("SEQUENCE_LINKS");
1146    }
1147    else
1148    {
1149  0 Cache.setPropertyNoSave("SEQUENCE_LINKS",
1150    menuLinks.toString());
1151    }
1152   
1153  0 String nonMenuLinks = sequenceUrlLinks.writeUrlsAsString(false);
1154  0 if (nonMenuLinks.isEmpty())
1155    {
1156  0 Cache.removePropertyNoSave("STORED_LINKS");
1157    }
1158    else
1159    {
1160  0 Cache.setPropertyNoSave("STORED_LINKS",
1161    nonMenuLinks.toString());
1162    }
1163   
1164  0 Cache.setPropertyNoSave("DEFAULT_URL",
1165    sequenceUrlLinks.getPrimaryUrlId());
1166   
1167  0 Cache.setProperty("VERSION_CHECK",
1168    Boolean.toString(versioncheck.isSelected()));
1169  0 if (Cache.getProperty("USAGESTATS") != null || usagestats.isSelected())
1170    {
1171    // default is false - we only set this if the user has actively agreed
1172  0 Cache.setProperty("USAGESTATS",
1173    Boolean.toString(usagestats.isSelected()));
1174    }
1175  0 if (!questionnaire.isSelected())
1176    {
1177  0 Cache.setProperty("NOQUESTIONNAIRES", "true");
1178    }
1179    else
1180    {
1181    // special - made easy to edit a property file to disable questionnaires
1182    // by just adding the given line
1183  0 Cache.removeProperty("NOQUESTIONNAIRES");
1184    }
1185   
1186    /*
1187    * Save Output settings
1188    */
1189  0 Cache.setPropertyNoSave("BLC_JVSUFFIX",
1190    Boolean.toString(blcjv.isSelected()));
1191  0 Cache.setPropertyNoSave("CLUSTAL_JVSUFFIX",
1192    Boolean.toString(clustaljv.isSelected()));
1193  0 Cache.setPropertyNoSave("FASTA_JVSUFFIX",
1194    Boolean.toString(fastajv.isSelected()));
1195  0 Cache.setPropertyNoSave("MSF_JVSUFFIX",
1196    Boolean.toString(msfjv.isSelected()));
1197  0 Cache.setPropertyNoSave("PFAM_JVSUFFIX",
1198    Boolean.toString(pfamjv.isSelected()));
1199  0 Cache.setPropertyNoSave("PILEUP_JVSUFFIX",
1200    Boolean.toString(pileupjv.isSelected()));
1201  0 Cache.setPropertyNoSave("PIR_JVSUFFIX",
1202    Boolean.toString(pirjv.isSelected()));
1203  0 Cache.setPropertyNoSave("PIR_MODELLER",
1204    Boolean.toString(modellerOutput.isSelected()));
1205  0 Cache.setPropertyNoSave("EXPORT_EMBBED_BIOJSON",
1206    Boolean.toString(embbedBioJSON.isSelected()));
1207  0 jalview.io.PIRFile.useModellerOutput = modellerOutput.isSelected();
1208   
1209  0 Cache.setPropertyNoSave("FIGURE_AUTOIDWIDTH",
1210    Boolean.toString(autoIdWidth.isSelected()));
1211  0 userIdWidth_actionPerformed();
1212  0 Cache.setPropertyNoSave("FIGURE_FIXEDIDWIDTH",
1213    userIdWidth.getText());
1214   
1215    /*
1216    * Save Editing settings
1217    */
1218  0 Cache.setPropertyNoSave("AUTO_CALC_CONSENSUS",
1219    Boolean.toString(autoCalculateConsCheck.isSelected()));
1220  0 Cache.setPropertyNoSave("SORT_BY_TREE",
1221    Boolean.toString(sortByTree.isSelected()));
1222  0 Cache.setPropertyNoSave("PAD_GAPS",
1223    Boolean.toString(padGaps.isSelected()));
1224   
1225  0 if (!Platform.isJS())
1226    {
1227  0 wsPrefs.updateAndRefreshWsMenuConfig(false);
1228    }
1229   
1230    /*
1231    * Save Backups settings
1232    */
1233  0 Cache.setPropertyNoSave(BackupFiles.ENABLED,
1234    Boolean.toString(enableBackupFiles.isSelected()));
1235  0 int preset = getComboIntStringKey(backupfilesPresetsCombo);
1236  0 Cache.setPropertyNoSave(BackupFiles.NS + "_PRESET", Integer.toString(preset));
1237   
1238  0 if (preset == BackupFilesPresetEntry.BACKUPFILESSCHEMECUSTOM)
1239    {
1240  0 BackupFilesPresetEntry customBFPE = getBackupfilesCurrentEntry();
1241  0 BackupFilesPresetEntry.backupfilesPresetEntriesValues.put(
1242    BackupFilesPresetEntry.BACKUPFILESSCHEMECUSTOM, customBFPE);
1243  0 Cache.setPropertyNoSave(BackupFilesPresetEntry.CUSTOMCONFIG,
1244    customBFPE.toString());
1245    }
1246   
1247  0 BackupFilesPresetEntry savedBFPE = BackupFilesPresetEntry.backupfilesPresetEntriesValues
1248    .get(preset);
1249  0 Cache.setPropertyNoSave(
1250    BackupFilesPresetEntry.SAVEDCONFIG, savedBFPE.toString());
1251   
1252    /*
1253    * Save Memory Settings
1254    */
1255  0 Cache.setPropertyNoSave(
1256    MemorySetting.CUSTOMISED_SETTINGS,
1257    Boolean.toString(customiseMemorySetting.isSelected()));
1258  0 Cache.setPropertyNoSave(MemorySetting.MEMORY_JVMMEMPC,
1259    Integer.toString(jvmMemoryPercentSlider.getValue()));
1260  0 Cache.setPropertyNoSave(MemorySetting.MEMORY_JVMMEMMAX,
1261    jvmMemoryMaxTextField.getText());
1262   
1263    /*
1264    * save and close Preferences
1265    */
1266  0 Cache.saveProperties();
1267  0 Desktop.getInstance().doConfigureStructurePrefs();
1268  0 try
1269    {
1270  0 frame.setClosed(true);
1271    } catch (Exception ex)
1272    {
1273    }
1274   
1275  0 Cache.enableSessionProperties();
1276    }
1277   
 
1278  0 toggle @Override
1279    public void saveProxySettings()
1280    {
1281  0 Cache.disableSessionProperties();
1282   
1283  0 String newProxyType = customProxy.isSelected() ? Cache.PROXYTYPE_CUSTOM
1284  0 : noProxy.isSelected() ? Cache.PROXYTYPE_NONE
1285    : Cache.PROXYTYPE_SYSTEM;
1286  0 Cache.setPropertyNoSave("USE_PROXY", newProxyType);
1287  0 Cache.setOrRemove("PROXY_SERVER", proxyServerHttpTB.getText());
1288  0 Cache.setOrRemove("PROXY_PORT", proxyPortHttpTB.getText());
1289  0 Cache.setOrRemove("PROXY_SERVER_HTTPS", proxyServerHttpsTB.getText());
1290  0 Cache.setOrRemove("PROXY_PORT_HTTPS", proxyPortHttpsTB.getText());
1291  0 Cache.setOrRemove("PROXY_AUTH",
1292    Boolean.toString(proxyAuth.isSelected()));
1293  0 Cache.setOrRemove("PROXY_AUTH_USERNAME", proxyAuthUsernameTB.getText());
1294  0 Cache.proxyAuthPassword = proxyAuthPasswordPB.getPassword();
1295  0 Cache.setProxyPropertiesFromPreferences(previousProxyType);
1296  0 if (newProxyType.equals(Cache.PROXYTYPE_CUSTOM)
1297    || !newProxyType.equals(previousProxyType))
1298    {
1299    // force a re-lookup of ws if proxytype is custom or has changed
1300  0 wsPrefs.refreshWs_actionPerformed(null);
1301    }
1302  0 previousProxyType = newProxyType;
1303    }
1304   
 
1305  0 toggle public static void setAppletDefaults()
1306    {
1307   
1308    // http://www.jalview.org/old/v2_8/examples/appletParameters.html
1309   
1310    // showConservation true or false Default is true.
1311    // showQuality true or false Default is true.
1312    // showConsensus true or false Default is true.
1313    // showFeatureSettings true or false Shows the feature settings window when
1314    // startin
1315    // showTreeBootstraps true or false (default is true) show or hide branch
1316    // bootstraps
1317    // showTreeDistances true or false (default is true) show or hide branch
1318    // lengths
1319    // showUnlinkedTreeNodes true or false (default is false) indicate if
1320    // unassociated nodes should be highlighted in the tree view
1321    // showUnconserved true of false (default is false) When true, only gaps and
1322    // symbols different to the consensus sequence ions of the alignment
1323    // showGroupConsensus true of false (default is false) When true, shows
1324    // consensus annotation row for any groups on the alignment. (since 2.7)
1325    // showGroupConservation true of false (default is false) When true, shows
1326    // amino-acid property conservation annotation row for any groups on the
1327    // showConsensusHistogram true of false (default is true) When true, shows
1328    // the percentage occurence of the consensus symbol for each column as a
1329    // showSequenceLogo true of false (default is false) When true, shows a
1330    // sequence logo above the consensus sequence (overlaid above the Consensus
1331   
1332  0 Cache.setPropertyNoSave(SHOW_CONSERVATION, "true");
1333  0 Cache.setPropertyNoSave(SHOW_QUALITY, "false");
1334  0 Cache.setPropertyNoSave(SHOW_CONSENSUS, "true");
1335  0 Cache.setPropertyNoSave(SHOW_UNCONSERVED, "false");
1336  0 Cache.setPropertyNoSave(SHOW_GROUP_CONSERVATION, "false");
1337  0 Cache.setPropertyNoSave(SHOW_GROUP_CONSENSUS, "false");
1338   
1339    // TODO -- just a start here
1340    }
1341    /**
1342    * Do any necessary validation before saving settings. Return focus to the
1343    * first tab which fails validation.
1344    *
1345    * @return
1346    */
 
1347  0 toggle private boolean validateSettings()
1348    {
1349  0 if (!validateStructure())
1350    {
1351  0 structureTab.requestFocusInWindow();
1352  0 return false;
1353    }
1354  0 return true;
1355    }
1356   
 
1357  0 toggle @Override
1358    protected boolean validateStructure()
1359    {
1360  0 return validateViewerPath();
1361   
1362    }
1363   
1364    /**
1365    * DOCUMENT ME!
1366    */
 
1367  0 toggle @Override
1368    public void startupFileTextfield_mouseClicked()
1369    {
1370  0 Cache.disableSessionProperties();
1371   
1372    // TODO: JAL-3048 not needed for Jalview-JS
1373    // default file format now determined by JalviewFileChooser
1374  0 JalviewFileChooser chooser = JalviewFileChooser
1375    .forRead(Cache.getProperty("LAST_DIRECTORY"), null);
1376  0 chooser.setFileView(new JalviewFileView());
1377  0 chooser.setDialogTitle(
1378    MessageManager.getString("label.select_startup_file"));
1379   
1380  0 int value = chooser.showOpenDialog(this);
1381   
1382  0 if (value == JalviewFileChooser.APPROVE_OPTION)
1383    {
1384  0 FileFormatI format = chooser.getSelectedFormat();
1385  0 if (format != null)
1386    {
1387  0 Cache.setPropertyNoSave("DEFAULT_FILE_FORMAT",
1388    format.getName());
1389    }
1390  0 startupFileTextfield
1391    .setText(chooser.getSelectedFile().getAbsolutePath());
1392    }
1393   
1394  0 Cache.enableSessionProperties();
1395    }
1396   
1397    /**
1398    * DOCUMENT ME!
1399    *
1400    * @param e
1401    * DOCUMENT ME!
1402    */
 
1403  0 toggle @Override
1404    public void cancel_actionPerformed(ActionEvent e)
1405    {
1406  0 try
1407    {
1408  0 if (!Platform.isJS())
1409    {
1410  0 wsPrefs.updateWsMenuConfig(true);
1411  0 wsPrefs.refreshWs_actionPerformed(e);
1412    }
1413  0 frame.setClosed(true);
1414    } catch (Exception ex)
1415    {
1416    }
1417    }
1418   
1419    /**
1420    * DOCUMENT ME!
1421    *
1422    * @param e
1423    * DOCUMENT ME!
1424    */
 
1425  11 toggle @Override
1426    public void annotations_actionPerformed(ActionEvent e)
1427    {
1428  11 conservation.setEnabled(annotations.isSelected());
1429  11 quality.setEnabled(annotations.isSelected());
1430  11 identity.setEnabled(annotations.isSelected());
1431  11 ssConsensus.setEnabled(annotations.isSelected());
1432  11 showOccupancy.setEnabled(annotations.isSelected());
1433  11 showGroupConsensus.setEnabled(annotations.isSelected());
1434  11 showGroupConservation.setEnabled(annotations.isSelected());
1435  11 showConsensHistogram.setEnabled(annotations.isSelected()
1436    && (identity.isSelected() || showGroupConsensus.isSelected()));
1437  11 showConsensLogo.setEnabled(annotations.isSelected()
1438    && (identity.isSelected() || showGroupConsensus.isSelected()));
1439  11 showInformationHistogram.setEnabled(annotations.isSelected());
1440  11 showHMMLogo.setEnabled(annotations.isSelected());
1441    }
1442   
 
1443  0 toggle @Override
1444    public void newLink_actionPerformed(ActionEvent e)
1445    {
1446  0 GSequenceLink link = new GSequenceLink();
1447  0 boolean valid = false;
1448  0 while (!valid)
1449    {
1450  0 if (JvOptionPane.showInternalConfirmDialog(Desktop.getDesktopPane(), link,
1451    MessageManager.getString("label.new_sequence_url_link"),
1452    JvOptionPane.OK_CANCEL_OPTION, -1,
1453    null) == JvOptionPane.OK_OPTION)
1454    {
1455  0 if (link.checkValid())
1456    {
1457  0 if (((UrlLinkTableModel) linkUrlTable.getModel())
1458    .isUniqueName(link.getName()))
1459    {
1460  0 ((UrlLinkTableModel) linkUrlTable.getModel())
1461    .insertRow(link.getName(), link.getURL());
1462  0 valid = true;
1463    }
1464    else
1465    {
1466  0 link.notifyDuplicate();
1467  0 continue;
1468    }
1469    }
1470    }
1471    else
1472    {
1473  0 break;
1474    }
1475    }
1476    }
1477   
 
1478  0 toggle @Override
1479    public void editLink_actionPerformed(ActionEvent e)
1480    {
1481  0 GSequenceLink link = new GSequenceLink();
1482   
1483  0 int index = linkUrlTable.getSelectedRow();
1484  0 if (index == -1)
1485    {
1486    // button no longer enabled if row is not selected
1487  0 Console.debug("Edit with no row selected in linkUrlTable");
1488  0 return;
1489    }
1490   
1491  0 int nameCol = ((UrlLinkTableModel) linkUrlTable.getModel())
1492    .getNameColumn();
1493  0 int urlCol = ((UrlLinkTableModel) linkUrlTable.getModel())
1494    .getUrlColumn();
1495  0 String oldName = linkUrlTable.getValueAt(index, nameCol).toString();
1496  0 link.setName(oldName);
1497  0 link.setURL(linkUrlTable.getValueAt(index, urlCol).toString());
1498   
1499  0 boolean valid = false;
1500  0 while (!valid)
1501    {
1502  0 if (JvOptionPane.showInternalConfirmDialog(Desktop.getDesktopPane(), link,
1503    MessageManager.getString("label.edit_sequence_url_link"),
1504    JvOptionPane.OK_CANCEL_OPTION, -1,
1505    null) == JvOptionPane.OK_OPTION)
1506    {
1507  0 if (link.checkValid())
1508    {
1509  0 if ((oldName.equals(link.getName()))
1510    || (((UrlLinkTableModel) linkUrlTable.getModel())
1511    .isUniqueName(link.getName())))
1512    {
1513  0 linkUrlTable.setValueAt(link.getName(), index, nameCol);
1514  0 linkUrlTable.setValueAt(link.getURL(), index, urlCol);
1515  0 valid = true;
1516    }
1517    else
1518    {
1519  0 link.notifyDuplicate();
1520  0 continue;
1521    }
1522    }
1523    }
1524    else
1525    {
1526  0 break;
1527    }
1528    }
1529    }
1530   
 
1531  0 toggle @Override
1532    public void deleteLink_actionPerformed(ActionEvent e)
1533    {
1534  0 int index = linkUrlTable.getSelectedRow();
1535  0 int modelIndex = -1;
1536  0 if (index == -1)
1537    {
1538    // button no longer enabled if row is not selected
1539  0 Console.debug("Delete with no row selected in linkUrlTable");
1540  0 return;
1541    }
1542    else
1543    {
1544  0 modelIndex = linkUrlTable.convertRowIndexToModel(index);
1545    }
1546   
1547    // make sure we use the model index to delete, and not the table index
1548  0 ((UrlLinkTableModel) linkUrlTable.getModel()).removeRow(modelIndex);
1549    }
1550   
 
1551  0 toggle @Override
1552    public void defaultBrowser_mouseClicked(MouseEvent e)
1553    {
1554    // TODO: JAL-3048 not needed for j2s
1555  0 if (!Platform.isJS()) // BH 2019
1556    /**
1557    * Java only
1558    *
1559    * @j2sIgnore
1560    */
1561    {
1562  0 JFileChooser chooser = new JFileChooser(".");
1563  0 chooser.setDialogTitle(
1564    MessageManager.getString("label.select_default_browser"));
1565   
1566  0 int value = chooser.showOpenDialog(this);
1567   
1568  0 if (value == JFileChooser.APPROVE_OPTION)
1569    {
1570  0 defaultBrowser.setText(chooser.getSelectedFile().getAbsolutePath());
1571    }
1572    }
1573    }
1574   
1575    /*
1576    * (non-Javadoc)
1577    *
1578    * @see
1579    * jalview.jbgui.GPreferences#showunconserved_actionPerformed(java.awt.event
1580    * .ActionEvent)
1581    */
 
1582  0 toggle @Override
1583    protected void showunconserved_actionPerformed(ActionEvent e)
1584    {
1585    // TODO Auto-generated method stub
1586  0 super.showunconserved_actionPerformed(e);
1587    }
1588   
 
1589  0 toggle public static List<String> getGroupURLLinks()
1590    {
1591  0 return groupURLLinks;
1592    }
1593   
 
1594  0 toggle @Override
1595    public void minColour_actionPerformed(JPanel panel)
1596    {
1597  0 JalviewColourChooser.showColourChooser(this,
1598    MessageManager.getString("label.select_colour_minimum_value"),
1599    panel);
1600    }
1601   
 
1602  0 toggle @Override
1603    public void maxColour_actionPerformed(JPanel panel)
1604    {
1605  0 JalviewColourChooser.showColourChooser(this,
1606    MessageManager.getString("label.select_colour_maximum_value"),
1607    panel);
1608    }
1609   
 
1610  0 toggle @Override
1611    public void gapColour_actionPerformed(JPanel gap)
1612    {
1613  0 if (!useLegacyGap.isSelected())
1614    {
1615  0 JalviewColourChooser.showColourChooser(this,
1616    MessageManager.getString("label.select_gap_colour"),
1617    gap);
1618    }
1619    }
1620   
 
1621  0 toggle @Override
1622    public void hiddenColour_actionPerformed(JPanel hidden)
1623    {
1624  0 JalviewColourChooser.showColourChooser(this,
1625    MessageManager.getString("label.select_hidden_colour"),
1626    hidden);
1627    }
1628   
 
1629  0 toggle @Override
1630    protected void useLegacyGaps_actionPerformed(ActionEvent e)
1631    {
1632  0 boolean enabled = useLegacyGap.isSelected();
1633  0 if (enabled)
1634    {
1635  0 gapColour.setBackground(OverviewCanvas.OVERVIEW_DEFAULT_LEGACY_GAP);
1636    }
1637    else
1638    {
1639  0 gapColour.setBackground(OverviewCanvas.OVERVIEW_DEFAULT_GAP);
1640    }
1641  0 gapColour.setEnabled(!enabled);
1642  0 gapLabel.setEnabled(!enabled);
1643    }
1644   
 
1645  0 toggle @Override
1646    protected void resetOvDefaults_actionPerformed(ActionEvent e)
1647    {
1648  0 useLegacyGap.setSelected(false);
1649  0 useLegacyGaps_actionPerformed(null);
1650  0 showHiddenAtStart.setSelected(false);
1651  0 hiddenColour.setBackground(OverviewCanvas.OVERVIEW_DEFAULT_HIDDEN);
1652    }
1653   
 
1654  0 toggle @Override
1655    protected void userIdWidth_actionPerformed()
1656    {
1657  0 try
1658    {
1659  0 String val = userIdWidth.getText().trim();
1660  0 if (val.length() > 0)
1661    {
1662  0 Integer iw = Integer.parseInt(val);
1663  0 if (iw.intValue() < 12)
1664    {
1665  0 throw new NumberFormatException();
1666    }
1667  0 userIdWidth.setText(iw.toString());
1668    }
1669    } catch (NumberFormatException x)
1670    {
1671  0 userIdWidth.setText("");
1672  0 JvOptionPane.showInternalMessageDialog(Desktop.getDesktopPane(),
1673    MessageManager
1674    .getString("warn.user_defined_width_requirements"),
1675    MessageManager.getString("label.invalid_id_column_width"),
1676    JvOptionPane.WARNING_MESSAGE);
1677    }
1678    }
1679   
 
1680  0 toggle @Override
1681    protected void autoIdWidth_actionPerformed()
1682    {
1683  0 userIdWidth.setEnabled(!autoIdWidth.isSelected());
1684  0 userIdWidthlabel.setEnabled(!autoIdWidth.isSelected());
1685    }
1686   
1687    /**
1688    * Returns true if structure viewer path is to a valid executable, else shows an
1689    * error dialog. Does nothing if the path is empty, as is the case for Jmol
1690    * (built in to Jalview) or when Jalview is left to try default paths.
1691    */
 
1692  0 toggle private boolean validateViewerPath()
1693    {
1694  0 if (structureViewerPath.getText().trim().length() > 0)
1695    {
1696  0 File f = new File(structureViewerPath.getText());
1697  0 if (!f.canExecute())
1698    {
1699  0 JvOptionPane.showInternalMessageDialog(Desktop.getDesktopPane(),
1700    MessageManager.getString("label.invalid_viewer_path"),
1701    MessageManager.getString("label.invalid_viewer_path"),
1702    JvOptionPane.ERROR_MESSAGE);
1703  0 return false;
1704    }
1705    }
1706  0 return true;
1707    }
1708   
1709    /**
1710    * Returns true if the given text field contains a path to a folder that
1711    * contains an executable with the given name, else false (after showing a
1712    * warning dialog). The executable name will be tried with .exe appended if not
1713    * found.
1714    *
1715    * @param textField
1716    * @param executable
1717    */
 
1718  0 toggle protected boolean validateExecutablePath(JTextField textField, String executable)
1719    {
1720  0 String folder = textField.getText().trim();
1721   
1722  0 if (FileUtils.getExecutable(executable, folder) != null)
1723    {
1724  0 return true;
1725    }
1726  0 if (folder.length() > 0)
1727    {
1728  0 JvOptionPane.showInternalMessageDialog(Desktop.getInstance(),
1729    MessageManager.formatMessage("label.executable_not_found",
1730    executable),
1731    MessageManager.getString("label.invalid_folder"),
1732    JvOptionPane.ERROR_MESSAGE);
1733    }
1734  0 return false;
1735    }
1736   
1737    /**
1738    * Checks if a file can be executed
1739    *
1740    * @param path
1741    * the path to the file
1742    * @return
1743    */
 
1744  0 toggle public boolean canExecute(String path)
1745    {
1746  0 File file = new File(path);
1747  0 if (!file.canExecute())
1748    {
1749  0 file = new File(path + ".exe");
1750    {
1751  0 if (!file.canExecute())
1752    {
1753  0 return false;
1754    }
1755    }
1756    }
1757  0 return true;
1758    }
1759   
1760    /**
1761    * If Chimera or ChimeraX or Pymol is selected, check it can be found on default
1762    * or user-specified path, if not show a warning/help dialog
1763    */
 
1764  11 toggle @Override
1765    protected void structureViewer_actionPerformed(String selectedItem)
1766    {
1767  11 if (selectedItem.equals(ViewerType.JMOL.name()))
1768    {
1769  11 structureViewerPath.setEnabled(false);
1770  11 structureViewerPathLabel.setEnabled(false);
1771  11 return;
1772    }
1773  0 boolean found = false;
1774  0 structureViewerPath.setEnabled(true);
1775  0 structureViewerPathLabel.setEnabled(true);
1776  0 structureViewerPathLabel.setText(MessageManager
1777    .formatMessage("label.viewer_path", selectedItem));
1778   
1779    /*
1780    * Try user-specified and standard paths for structure viewer executable
1781    */
1782  0 String viewerPath = "";
1783  0 List<String> paths = null;
1784  0 Cache.disableSessionProperties();
1785  0 try
1786    {
1787  0 ViewerType viewerType = ViewerType.valueOf(selectedItem);
1788  0 switch (viewerType)
1789    {
1790  0 case JMOL:
1791    // dealt with above
1792  0 break;
1793  0 case CHIMERA:
1794  0 viewerPath = Cache.getDefault(CHIMERA_PATH, "");
1795  0 paths = StructureManager.getChimeraPaths(false);
1796  0 break;
1797  0 case CHIMERAX:
1798  0 viewerPath = Cache.getDefault(CHIMERAX_PATH, "");
1799  0 paths = StructureManager.getChimeraPaths(true);
1800  0 break;
1801  0 case PYMOL:
1802  0 viewerPath = Cache.getDefault(PYMOL_PATH, "");
1803  0 paths = PymolManager.getPymolPaths();
1804  0 break;
1805    }
1806    } catch (IllegalArgumentException e)
1807    {
1808    // only valid entries should be in the drop-down
1809    }
1810  0 Cache.enableSessionProperties();
1811  0 structureViewerPath.setText(viewerPath);
1812   
1813  0 jalview.bin.Console
1814  0 .debug("Found " + (paths == null ? null : paths.size())
1815    + " paths to look for " + selectedItem.toString());
1816  0 if (paths == null)
1817    {
1818  0 paths = new ArrayList<>();
1819    }
1820  0 paths.add(0, structureViewerPath.getText());
1821  0 for (String path : paths)
1822    {
1823  0 jalview.bin.Console.debug("Looking for " + selectedItem.toString()
1824    + " in " + path.trim());
1825  0 if (new File(path.trim()).canExecute())
1826    {
1827  0 jalview.bin.Console.debug(
1828    "Found " + selectedItem.toString() + " in " + path.trim());
1829  0 found = true;
1830  0 break;
1831    }
1832    }
1833   
1834  0 if (!found)
1835    {
1836  0 String[] options = { "OK", "Help" };
1837  0 int showHelp = JvOptionPane.showInternalOptionDialog(Desktop.getDesktopPane(),
1838    JvSwingUtils.wrapTooltip(true,
1839    MessageManager.getString("label.viewer_missing")),
1840    "", JvOptionPane.YES_NO_OPTION, JvOptionPane.WARNING_MESSAGE,
1841    null, options, options[0]);
1842   
1843  0 if (showHelp == JvOptionPane.NO_OPTION)
1844    {
1845  0 this.selectTab(Preferences.TabRef.STRUCTURE_TAB, null);
1846  0 try
1847    {
1848  0 Help.showHelpWindow(HelpId.StructureViewer);
1849    } catch (HelpSetException e)
1850    {
1851  0 e.printStackTrace();
1852    }
1853    }
1854  0 else if (showHelp == JvOptionPane.OK_OPTION)
1855    {
1856  0 this.selectTab(Preferences.TabRef.STRUCTURE_TAB, null);
1857  0 CompletableFuture<Void> cf = CompletableFuture.runAsync(() -> {
1858  0 try
1859    {
1860  0 for (int i = 0; i < 3; i++)
1861    {
1862  0 structureViewerPath.setBackground(Color.PINK);
1863  0 Thread.sleep(500);
1864  0 structureViewerPath.setBackground(Color.WHITE);
1865  0 Thread.sleep(500);
1866    }
1867    } catch (InterruptedException e)
1868    {
1869    }
1870    });
1871    }
1872    }
1873    }
1874   
 
1875  0 toggle @Override
1876    protected void validateHmmerPath()
1877    {
1878  0 validateExecutablePath(hmmerPath, HmmerCommand.HMMBUILD);
1879    }
1880   
 
1881  0 toggle @Override
1882    protected void validateCygwinPath()
1883    {
1884  0 validateExecutablePath(cygwinPath, "run");
1885    }
1886   
 
1887    public class OptionsParam
1888    {
1889    private String name;
1890   
1891    private String code;
1892   
 
1893  33 toggle public OptionsParam(String name, String code)
1894    {
1895  33 this.name = name;
1896  33 this.code = code;
1897    }
1898   
 
1899  0 toggle public String getName()
1900    {
1901  0 return name;
1902    }
1903   
 
1904  0 toggle public void setName(String name)
1905    {
1906  0 this.name = name;
1907    }
1908   
 
1909  0 toggle public String getCode()
1910    {
1911  0 return code;
1912    }
1913   
 
1914  0 toggle public void setCode(String code)
1915    {
1916  0 this.code = code;
1917    }
1918   
 
1919  33 toggle @Override
1920    public String toString()
1921    {
1922  33 return name;
1923    }
1924   
 
1925  66 toggle @Override
1926    public boolean equals(Object that)
1927    {
1928  66 if (!(that instanceof OptionsParam))
1929    {
1930  0 return false;
1931    }
1932  66 return this.code.equalsIgnoreCase(((OptionsParam) that).code);
1933    }
1934   
 
1935  0 toggle @Override
1936    public int hashCode()
1937    {
1938  0 return name.hashCode() + code.hashCode();
1939    }
1940    }
1941   
 
1942    private class UrlListSelectionHandler implements ListSelectionListener
1943    {
1944   
 
1945  0 toggle @Override
1946    public void valueChanged(ListSelectionEvent e)
1947    {
1948  0 ListSelectionModel lsm = (ListSelectionModel) e.getSource();
1949   
1950  0 int index = lsm.getMinSelectionIndex();
1951  0 if (index == -1)
1952    {
1953    // no selection, so disable delete/edit buttons
1954  0 editLink.setEnabled(false);
1955  0 deleteLink.setEnabled(false);
1956  0 return;
1957    }
1958  0 int modelIndex = linkUrlTable.convertRowIndexToModel(index);
1959   
1960    // enable/disable edit and delete link buttons
1961  0 if (((UrlLinkTableModel) linkUrlTable.getModel())
1962    .isRowDeletable(modelIndex))
1963    {
1964  0 deleteLink.setEnabled(true);
1965    }
1966    else
1967    {
1968  0 deleteLink.setEnabled(false);
1969    }
1970   
1971  0 if (((UrlLinkTableModel) linkUrlTable.getModel())
1972    .isRowEditable(modelIndex))
1973    {
1974  0 editLink.setEnabled(true);
1975    }
1976    else
1977    {
1978  0 editLink.setEnabled(false);
1979    }
1980    }
1981    }
1982    }