Clover icon

Coverage Report

  1. Project Clover database Thu Dec 4 2025 14:43:25 GMT
  2. Package jalview.gui

File Preferences.java

 

Coverage histogram

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

Code metrics

162
645
56
3
1,989
1,458
167
0.26
11.52
18.67
2.98

Classes

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