2 * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
3 * Copyright (C) $$Year-Rel$$ The Jalview Authors
5 * This file is part of Jalview.
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.
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.
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.
24 import java.awt.BorderLayout;
25 import java.awt.Color;
26 import java.awt.Component;
27 import java.awt.Dimension;
29 import java.awt.event.ActionEvent;
30 import java.awt.event.ActionListener;
31 import java.awt.event.FocusAdapter;
32 import java.awt.event.FocusEvent;
33 import java.awt.event.MouseEvent;
35 import java.util.ArrayList;
36 import java.util.List;
37 import java.util.concurrent.CompletableFuture;
39 import javax.help.HelpSetException;
40 import javax.swing.JComboBox;
41 import javax.swing.JFileChooser;
42 import javax.swing.JInternalFrame;
43 import javax.swing.JPanel;
44 import javax.swing.JTextField;
45 import javax.swing.ListSelectionModel;
46 import javax.swing.RowFilter;
47 import javax.swing.RowSorter;
48 import javax.swing.SortOrder;
49 import javax.swing.event.DocumentEvent;
50 import javax.swing.event.DocumentListener;
51 import javax.swing.event.ListSelectionEvent;
52 import javax.swing.event.ListSelectionListener;
53 import javax.swing.table.TableCellRenderer;
54 import javax.swing.table.TableColumn;
55 import javax.swing.table.TableModel;
56 import javax.swing.table.TableRowSorter;
58 import jalview.hmmer.HmmerCommand;
59 import jalview.util.FileUtils;
60 import ext.edu.ucsf.rbvi.strucviz2.StructureManager;
61 import jalview.analysis.AnnotationSorter.SequenceAnnotationOrder;
62 import jalview.bin.Cache;
63 import jalview.ext.pymol.PymolManager;
64 import jalview.gui.Help.HelpId;
65 import jalview.gui.StructureViewer.ViewerType;
66 import jalview.io.BackupFiles;
67 import jalview.io.BackupFilesPresetEntry;
68 import jalview.io.FileFormatI;
69 import jalview.io.JalviewFileChooser;
70 import jalview.io.JalviewFileView;
71 import jalview.jbgui.GPreferences;
72 import jalview.jbgui.GSequenceLink;
73 import jalview.schemes.ColourSchemeI;
74 import jalview.schemes.ColourSchemes;
75 import jalview.schemes.ResidueColourScheme;
76 import jalview.urls.UrlLinkTableModel;
77 import jalview.urls.api.UrlProviderFactoryI;
78 import jalview.urls.api.UrlProviderI;
79 import jalview.urls.desktop.DesktopUrlProviderFactory;
80 import jalview.util.MessageManager;
81 import jalview.util.Platform;
82 import jalview.util.UrlConstants;
83 import jalview.ws.sifts.SiftsSettings;
92 public class Preferences extends GPreferences implements ApplicationSingletonI
94 // suggested list delimiter character
95 public static final String COMMA = ",";
97 public static final String HMMSEARCH_SEQCOUNT = "HMMSEARCH_SEQCOUNT";
99 public static final String HMMINFO_GLOBAL_BACKGROUND = "HMMINFO_GLOBAL_BACKGROUND";
101 public static final String HMMALIGN_TRIM_TERMINI = "HMMALIGN_TRIM_TERMINI";
103 public static final String ADD_SS_ANN = "ADD_SS_ANN";
105 public static final String ADD_TEMPFACT_ANN = "ADD_TEMPFACT_ANN";
107 public static final String ALLOW_UNPUBLISHED_PDB_QUERYING = "ALLOW_UNPUBLISHED_PDB_QUERYING";
109 public static final String ANNOTATIONCOLOUR_MAX = "ANNOTATIONCOLOUR_MAX";
111 public static final String ANNOTATIONCOLOUR_MIN = "ANNOTATIONCOLOUR_MIN";
113 public static final String ANTI_ALIAS = "ANTI_ALIAS";
115 public static final String AUTO_CALC_CONSENSUS = "AUTO_CALC_CONSENSUS";
117 public static final String AUTOASSOCIATE_PDBANDSEQS = "AUTOASSOCIATE_PDBANDSEQS";
119 public static final String BLOSUM62_PCA_FOR_NUCLEOTIDE = "BLOSUM62_PCA_FOR_NUCLEOTIDE";
121 public static final String CENTRE_COLUMN_LABELS = "CENTRE_COLUMN_LABELS";
123 public static final String CHIMERA_PATH = "CHIMERA_PATH";
125 public static final String CHIMERAX_PATH = "CHIMERAX_PATH";
127 public static final String DBREFFETCH_USEPICR = "DBREFFETCH_USEPICR";
129 public static final String DEFAULT_COLOUR = "DEFAULT_COLOUR";
131 public static final String DEFAULT_COLOUR_NUC = "DEFAULT_COLOUR_NUC";
132 public static final String DEFAULT_COLOUR_PROT = "DEFAULT_COLOUR_PROT";
134 public static final String ENABLE_SPLIT_FRAME = "ENABLE_SPLIT_FRAME";
136 public static final String FIGURE_AUTOIDWIDTH = "FIGURE_AUTOIDWIDTH";
138 public static final String FIGURE_FIXEDIDWIDTH = "FIGURE_FIXEDIDWIDTH";
140 public static final String FOLLOW_SELECTIONS = "FOLLOW_SELECTIONS";
142 public static final String FONT_NAME = "FONT_NAME";
144 public static final String FONT_SIZE = "FONT_SIZE";
146 public static final String FONT_STYLE = "FONT_STYLE";
148 public static final String HMMER_PATH = "HMMER_PATH";
150 public static final String CYGWIN_PATH = "CYGWIN_PATH";
152 public static final String HMMSEARCH_DBS = "HMMSEARCH_DBS";
154 public static final String GAP_COLOUR = "GAP_COLOUR";
156 public static final String GAP_SYMBOL = "GAP_SYMBOL";
158 public static final String HIDDEN_COLOUR = "HIDDEN_COLOUR";
160 public static final String HIDE_INTRONS = "HIDE_INTRONS";
162 public static final String ID_ITALICS = "ID_ITALICS";
164 public static final String ID_ORG_HOSTURL = "ID_ORG_HOSTURL";
166 public static final String MAP_WITH_SIFTS = "MAP_WITH_SIFTS";
168 public static final String NOQUESTIONNAIRES = "NOQUESTIONNAIRES";
170 public static final String NORMALISE_CONSENSUS_LOGO = "NORMALISE_CONSENSUS_LOGO";
172 public static final String NORMALISE_LOGO = "NORMALISE_LOGO";
174 public static final String PAD_GAPS = "PAD_GAPS";
176 public static final String PDB_DOWNLOAD_FORMAT = "PDB_DOWNLOAD_FORMAT";
178 public static final String PYMOL_PATH = "PYMOL_PATH";
180 public static final String QUESTIONNAIRE = "QUESTIONNAIRE";
182 public static final String RELAXEDSEQIDMATCHING = "RELAXEDSEQIDMATCHING";
184 public static final String RIGHT_ALIGN_IDS = "RIGHT_ALIGN_IDS";
186 public static final String SCALE_PROTEIN_TO_CDNA = "SCALE_PROTEIN_TO_CDNA";
188 public static final String SHOW_ANNOTATIONS = "SHOW_ANNOTATIONS";
190 public static final String SHOW_AUTOCALC_ABOVE = "SHOW_AUTOCALC_ABOVE";
192 public static final String SHOW_CONSENSUS = "SHOW_CONSENSUS";
194 public static final String SHOW_CONSENSUS_HISTOGRAM = "SHOW_CONSENSUS_HISTOGRAM";
196 public static final String SHOW_CONSENSUS_LOGO = "SHOW_CONSENSUS_LOGO";
198 public static final String SHOW_CONSERVATION = "SHOW_CONSERVATION";
200 public static final String SHOW_DBREFS_TOOLTIP = "SHOW_DBREFS_TOOLTIP";
202 public static final String SHOW_GROUP_CONSENSUS = "SHOW_GROUP_CONSENSUS";
204 public static final String SHOW_GROUP_CONSERVATION = "SHOW_GROUP_CONSERVATION";
206 public static final String SHOW_JVSUFFIX = "SHOW_JVSUFFIX";
208 public static final String SHOW_NPFEATS_TOOLTIP = "SHOW_NPFEATS_TOOLTIP";
209 public static final String SHOW_OCCUPANCY = "SHOW_OCCUPANCY";
211 public static final String SHOW_OV_HIDDEN_AT_START = "SHOW_OV_HIDDEN_AT_START";
213 public static final String SHOW_OVERVIEW = "SHOW_OVERVIEW";
215 public static final String SHOW_QUALITY = "SHOW_QUALITY";
217 public static final String SHOW_UNCONSERVED = "SHOW_UNCONSERVED";
219 public static final String SORT_ALIGNMENT = "SORT_ALIGNMENT";
221 public static final String SORT_ANNOTATIONS = "SORT_ANNOTATIONS";
223 public static final String SORT_BY_TREE = "SORT_BY_TREE";
225 public static final String STRUCT_FROM_PDB = "STRUCT_FROM_PDB";
227 public static final String STRUCTURE_DISPLAY = "STRUCTURE_DISPLAY";
229 public static final String STRUCTURE_DIMENSIONS = "STRUCTURE_DIMENSIONS";
231 public static final String UNIPROT_DOMAIN = "UNIPROT_DOMAIN";
233 public static final String USE_FULL_SO = "USE_FULL_SO";
234 public static final String USE_LEGACY_GAP = "USE_LEGACY_GAP";
236 public static final String USE_RNAVIEW = "USE_RNAVIEW";
238 public static final String USER_DEFINED_COLOURS = "USER_DEFINED_COLOURS";
240 public static final String WRAP_ALIGNMENT = "WRAP_ALIGNMENT";
242 private static final int MIN_FONT_SIZE = 1;
244 private static final int MAX_FONT_SIZE = 30;
246 private String previousProxyType;
248 private static Preferences INSTANCE = null; // add "final"
250 * Holds name and link separated with | character. Sequence ID must be
251 * $SEQUENCE_ID$ or $SEQUENCE_ID=/.possible | chars ./=$
253 public static UrlProviderI sequenceUrlLinks;
255 public static UrlLinkTableModel dataModel;
258 * Holds name and link separated with | character. Sequence IDS and Sequences
259 * must be $SEQUENCEIDS$ or $SEQUENCEIDS=/.possible | chars ./=$ and $SEQUENCES$
260 * or $SEQUENCES=/.possible | chars ./=$ and separation character for first and
261 * second token specified after a pipe character at end |,|. (TODO: proper
262 * escape for using | to separate ids or sequences
265 public static List<String> groupURLLinks;
268 // get links selected to be in the menu (SEQUENCE_LINKS)
269 // and links entered by the user but not selected (STORED_LINKS)
270 String inMenuString = Cache.getDefault("SEQUENCE_LINKS", "");
271 String notInMenuString = Cache.getDefault("STORED_LINKS", "");
272 String defaultUrl = Cache.getDefault("DEFAULT_URL",
273 UrlConstants.DEFAULT_LABEL);
275 // if both links lists are empty, add the DEFAULT_URL link
276 // otherwise we assume the default link is in one of the lists
277 if (inMenuString.isEmpty() && notInMenuString.isEmpty())
279 inMenuString = UrlConstants.DEFAULT_STRING;
281 UrlProviderFactoryI factory = new DesktopUrlProviderFactory(defaultUrl,
282 inMenuString, notInMenuString);
283 sequenceUrlLinks = factory.createUrlProvider();
284 dataModel = new UrlLinkTableModel(sequenceUrlLinks);
287 * TODO: reformulate groupURL encoding so two or more can be stored in the
288 * .properties file as '|' separated strings
291 groupURLLinks = new ArrayList<>();
294 JInternalFrame frame;
296 private WsPreferences wsPrefs;
298 private SlivkaPreferences slivkaPrefs;
299 private OptionsParam promptEachTimeOpt = new OptionsParam(
300 MessageManager.getString("label.prompt_each_time"),
303 private OptionsParam lineArtOpt = new OptionsParam(
304 MessageManager.getString("label.lineart"), "Lineart");
306 private OptionsParam textOpt = new OptionsParam(
307 MessageManager.getString("action.text"), "Text");
309 // get singleton Preferences instance
310 public static Preferences getInstance()
312 if (INSTANCE == null || INSTANCE.frame == null
313 || INSTANCE.frame.isClosed())
315 INSTANCE = new Preferences();
320 * Replace code with the following for Jalvew-JS
321 Preferences INSTANCE = ApplicationSingletonProvider.getInstance(Preferences.class);
322 if (INSTANCE == null || INSTANCE.frame == null
323 || INSTANCE.frame.isClosed())
325 ApplicationSingletonProvider.remove(Preferences.class);
326 INSTANCE = ApplicationSingletonProvider.getInstance(Preferences.class);
332 public static void openPreferences()
334 openPreferences(null, null);
337 public static void openPreferences(TabRef selectTab, String message)
339 Preferences p = getInstance();
340 if (selectTab != null)
341 p.selectTab(selectTab, message);
343 p.frame.moveToFront();
347 public void selectTab(TabRef selectTab, String message)
349 this.selectTab(selectTab);
351 this.setMessage(message);
355 * Creates a new Preferences object.
357 private Preferences()
360 frame = new JInternalFrame();
361 frame.setContentPane(this);
362 if (!Platform.isJS())
369 wsPrefs = new WsPreferences();
370 wsTab.add(wsPrefs, BorderLayout.CENTER);
373 slivkaPrefs = new SlivkaPreferences();
374 slivkaTab.add(slivkaPrefs, BorderLayout.CENTER);
376 int width = 500, height = 450;
377 if (Platform.isAMacAndNotJS())
383 Desktop.addInternalFrame(frame,
384 MessageManager.getString("label.preferences"), width, height);
385 frame.setMinimumSize(new Dimension(width, height));
388 * Set HMMER tab defaults
390 hmmrTrimTermini.setSelected(Cache.getDefault(HMMALIGN_TRIM_TERMINI, false));
391 if (Cache.getDefault(HMMINFO_GLOBAL_BACKGROUND, false))
393 hmmerBackgroundUniprot.setSelected(true);
397 hmmerBackgroundAlignment.setSelected(true);
400 .setText(Cache.getProperty(HMMSEARCH_SEQCOUNT));
401 hmmerPath.setText(Cache.getProperty(HMMER_PATH));
402 hmmerPath.addActionListener(new ActionListener()
405 public void actionPerformed(ActionEvent e)
410 hmmerPath.addFocusListener(new FocusAdapter()
413 public void focusLost(FocusEvent e)
418 if (cygwinPath != null)
420 String path = Cache.getProperty(CYGWIN_PATH);
423 path = FileUtils.getPathTo("bash");
425 cygwinPath.setText(path);
426 cygwinPath.addActionListener(new ActionListener()
429 public void actionPerformed(ActionEvent e)
431 validateCygwinPath();
434 cygwinPath.addFocusListener(new FocusAdapter()
437 public void focusLost(FocusEvent e)
439 validateCygwinPath();
445 * Set Visual tab defaults
447 seqLimit.setSelected(Cache.getDefault("SHOW_JVSUFFIX", true));
448 rightAlign.setSelected(Cache.getDefault("RIGHT_ALIGN_IDS", false));
449 fullScreen.setSelected(Cache.getDefault("SHOW_FULLSCREEN", false));
450 annotations.setSelected(Cache.getDefault("SHOW_ANNOTATIONS", true));
452 conservation.setSelected(Cache.getDefault("SHOW_CONSERVATION", true));
453 quality.setSelected(Cache.getDefault("SHOW_QUALITY", true));
454 identity.setSelected(Cache.getDefault("SHOW_IDENTITY", true));
455 openoverv.setSelected(Cache.getDefault("SHOW_OVERVIEW", false));
457 .setSelected(Cache.getDefault("SHOW_UNCONSERVED", false));
458 showOccupancy.setSelected(Cache.getDefault(SHOW_OCCUPANCY, false));
460 .setSelected(Cache.getDefault("SHOW_GROUP_CONSENSUS", false));
461 showGroupConservation.setSelected(
462 Cache.getDefault("SHOW_GROUP_CONSERVATION", false));
463 showConsensHistogram.setSelected(
464 Cache.getDefault("SHOW_CONSENSUS_HISTOGRAM", true));
466 .setSelected(Cache.getDefault("SHOW_CONSENSUS_LOGO", false));
467 showInformationHistogram.setSelected(
468 Cache.getDefault("SHOW_INFORMATION_HISTOGRAM", true));
469 showHMMLogo.setSelected(Cache.getDefault("SHOW_HMM_LOGO", false));
471 .setSelected(Cache.getDefault("SHOW_NPFEATS_TOOLTIP", true));
473 .setSelected(Cache.getDefault("SHOW_DBREFS_TOOLTIP", true));
475 String[] fonts = java.awt.GraphicsEnvironment
476 .getLocalGraphicsEnvironment().getAvailableFontFamilyNames();
477 for (int i = 0; i < fonts.length; i++)
479 fontNameCB.addItem(fonts[i]);
482 for (int i = MIN_FONT_SIZE; i <= MAX_FONT_SIZE; i++)
484 fontSizeCB.addItem(i + "");
487 fontStyleCB.addItem("plain");
488 fontStyleCB.addItem("bold");
489 fontStyleCB.addItem("italic");
491 fontNameCB.setSelectedItem(Cache.getDefault("FONT_NAME", "SansSerif"));
492 fontSizeCB.setSelectedItem(Cache.getDefault("FONT_SIZE", "10"));
493 fontStyleCB.setSelectedItem(
494 Cache.getDefault("FONT_STYLE", Font.PLAIN + ""));
496 smoothFont.setSelected(Cache.getDefault("ANTI_ALIAS", true));
498 .setSelected(Cache.getDefault(SCALE_PROTEIN_TO_CDNA, false));
500 idItalics.setSelected(Cache.getDefault("ID_ITALICS", true));
502 wrap.setSelected(Cache.getDefault("WRAP_ALIGNMENT", false));
504 gapSymbolCB.addItem("-");
505 gapSymbolCB.addItem(".");
507 gapSymbolCB.setSelectedItem(Cache.getDefault("GAP_SYMBOL", "-"));
509 sortby.addItem("No sort");
510 sortby.addItem("Id");
511 sortby.addItem("Pairwise Identity");
512 sortby.setSelectedItem(Cache.getDefault("SORT_ALIGNMENT", "No sort"));
514 sortAnnBy.addItem(SequenceAnnotationOrder.NONE.toString());
516 .addItem(SequenceAnnotationOrder.SEQUENCE_AND_LABEL.toString());
518 .addItem(SequenceAnnotationOrder.LABEL_AND_SEQUENCE.toString());
519 SequenceAnnotationOrder savedSort = SequenceAnnotationOrder
520 .valueOf(Cache.getDefault(SORT_ANNOTATIONS,
521 SequenceAnnotationOrder.NONE.name()));
522 sortAnnBy.setSelectedItem(savedSort.toString());
524 sortAutocalc.addItem("Autocalculated first");
525 sortAutocalc.addItem("Autocalculated last");
526 final boolean showAbove = Cache.getDefault(SHOW_AUTOCALC_ABOVE, true);
527 sortAutocalc.setSelectedItem(showAbove ? sortAutocalc.getItemAt(0)
528 : sortAutocalc.getItemAt(1));
530 .setSelected(Cache.getDefault("SHOW_STARTUP_FILE", true));
531 startupFileTextfield.setText(Cache.getDefault("STARTUP_FILE",
532 Cache.getDefault("www.jalview.org", "https://www.jalview.org")
533 + "/examples/exampleFile_2_7.jvp"));
536 * Set Colours tab defaults
538 protColour.addItem(ResidueColourScheme.NONE);
539 nucColour.addItem(ResidueColourScheme.NONE);
540 for (ColourSchemeI cs : ColourSchemes.getInstance().getColourSchemes())
542 String name = cs.getSchemeName();
543 protColour.addItem(name);
544 nucColour.addItem(name);
546 String oldProp = Cache.getDefault(DEFAULT_COLOUR,
547 ResidueColourScheme.NONE);
548 String newProp = Cache.getDefault(DEFAULT_COLOUR_PROT, null);
549 protColour.setSelectedItem(newProp != null ? newProp : oldProp);
550 newProp = Cache.getDefault(DEFAULT_COLOUR_NUC, null);
551 nucColour.setSelectedItem(newProp != null ? newProp : oldProp);
552 minColour.setBackground(
553 Cache.getDefaultColour("ANNOTATIONCOLOUR_MIN", Color.orange));
554 maxColour.setBackground(
555 Cache.getDefaultColour("ANNOTATIONCOLOUR_MAX", Color.red));
558 * Set overview panel defaults
560 gapColour.setBackground(Cache.getDefaultColour(GAP_COLOUR,
561 jalview.renderer.OverviewResColourFinder.OVERVIEW_DEFAULT_GAP));
562 hiddenColour.setBackground(Cache.getDefaultColour(HIDDEN_COLOUR,
563 jalview.renderer.OverviewResColourFinder.OVERVIEW_DEFAULT_HIDDEN));
564 useLegacyGap.setSelected(Cache.getDefault(USE_LEGACY_GAP, false));
565 gapLabel.setEnabled(!useLegacyGap.isSelected());
566 gapColour.setEnabled(!useLegacyGap.isSelected());
568 .setSelected(Cache.getDefault(SHOW_OV_HIDDEN_AT_START, false));
571 * Set Structure tab defaults
573 final boolean structSelected = Cache.getDefault(STRUCT_FROM_PDB, true);
574 structFromPdb.setSelected(structSelected);
575 addSecondaryStructure.setSelected(Cache.getDefault(ADD_SS_ANN, true));
576 addSecondaryStructure.setEnabled(structSelected);
577 addTempFactor.setSelected(Cache.getDefault(ADD_TEMPFACT_ANN, true));
578 addTempFactor.setEnabled(structSelected);
580 * set choice of structure viewer, and path if saved as a preference;
581 * default to Jmol (first choice) if an unexpected value is found
583 String viewerType = ViewerType.JMOL.name();
584 if (!Platform.isJS())
586 Cache.getDefault(STRUCTURE_DISPLAY,
587 ViewerType.JMOL.name());
589 // TODO - disable external viewers for JS
590 structViewer.setSelectedItem(viewerType);
591 String viewerPath = "";
592 ViewerType type = null;
595 type = ViewerType.valueOf(viewerType);
601 viewerPath = Cache.getDefault(CHIMERA_PATH, "");
604 viewerPath = Cache.getDefault(CHIMERAX_PATH, "");
607 viewerPath = Cache.getDefault(PYMOL_PATH, "");
610 } catch (IllegalArgumentException e)
612 Cache.log.error("Unknown structure viewer type: " + viewerType
613 + ", defaulting to Jmol");
614 type = ViewerType.JMOL;
616 structureViewerPath.setText(viewerPath);
618 structureViewerPath.addActionListener(new ActionListener()
621 public void actionPerformed(ActionEvent e)
623 if (validateViewerPath())
625 String path = structureViewerPath.getText();
627 ViewerType type = ViewerType.valueOf(viewerType);
633 Cache.setProperty(CHIMERA_PATH, path);
636 Cache.setProperty(CHIMERAX_PATH, path);
639 Cache.setProperty(PYMOL_PATH, path);
642 } catch (IllegalArgumentException x)
644 Cache.log.error("Failed to set path - unknown viewer type",x);
650 if (Cache.getDefault("MAP_WITH_SIFTS", false))
652 siftsMapping.setSelected(true);
656 nwMapping.setSelected(true);
660 .setMapWithSifts(Cache.getDefault("MAP_WITH_SIFTS", false));
663 * Set Connections tab defaults
667 linkUrlTable.setModel(dataModel);
668 final TableRowSorter<TableModel> sorter = new TableRowSorter<>(
669 linkUrlTable.getModel());
670 linkUrlTable.setRowSorter(sorter);
671 List<RowSorter.SortKey> sortKeys = new ArrayList<>();
673 UrlLinkTableModel m = (UrlLinkTableModel) linkUrlTable.getModel();
674 sortKeys.add(new RowSorter.SortKey(m.getPrimaryColumn(),
675 SortOrder.DESCENDING));
676 sortKeys.add(new RowSorter.SortKey(m.getSelectedColumn(),
677 SortOrder.DESCENDING));
679 new RowSorter.SortKey(m.getNameColumn(), SortOrder.ASCENDING));
681 sorter.setSortKeys(sortKeys);
682 // BH 2018 setSortKeys will do the sort
686 ActionListener onReset;
687 onReset = new ActionListener()
690 public void actionPerformed(ActionEvent e)
692 filterTB.setText("");
693 sorter.setRowFilter(RowFilter.regexFilter(""));
697 doReset.addActionListener(onReset);
699 // filter to display only custom urls
700 final RowFilter<TableModel, Object> customUrlFilter = new RowFilter<TableModel, Object>()
703 public boolean include(
704 Entry<? extends TableModel, ? extends Object> entry)
706 return ((UrlLinkTableModel) entry.getModel()).isUserEntry(entry);
710 final TableRowSorter<TableModel> customSorter = new TableRowSorter<>(
711 linkUrlTable.getModel());
712 customSorter.setRowFilter(customUrlFilter);
714 ActionListener onCustomOnly;
715 onCustomOnly = new ActionListener()
718 public void actionPerformed(ActionEvent e)
720 filterTB.setText("");
721 sorter.setRowFilter(customUrlFilter);
724 userOnly.addActionListener(onCustomOnly);
726 filterTB.getDocument().addDocumentListener(new DocumentListener()
728 String caseInsensitiveFlag = "(?i)";
731 public void changedUpdate(DocumentEvent e)
733 sorter.setRowFilter(RowFilter
734 .regexFilter(caseInsensitiveFlag + filterTB.getText()));
738 public void removeUpdate(DocumentEvent e)
740 sorter.setRowFilter(RowFilter
741 .regexFilter(caseInsensitiveFlag + filterTB.getText()));
745 public void insertUpdate(DocumentEvent e)
747 sorter.setRowFilter(RowFilter
748 .regexFilter(caseInsensitiveFlag + filterTB.getText()));
752 // set up list selection functionality
753 linkUrlTable.getSelectionModel()
754 .addListSelectionListener(new UrlListSelectionHandler());
756 // set up radio buttons
757 int onClickCol = ((UrlLinkTableModel) linkUrlTable.getModel())
759 String onClickName = linkUrlTable.getColumnName(onClickCol);
760 linkUrlTable.getColumn(onClickName)
761 .setCellRenderer(new RadioButtonRenderer());
762 linkUrlTable.getColumn(onClickName)
763 .setCellEditor(new RadioButtonEditor());
765 // get boolean columns and resize those to min possible
766 for (int column = 0; column < linkUrlTable.getColumnCount(); column++)
768 if (linkUrlTable.getModel().getColumnClass(column)
769 .equals(Boolean.class))
771 TableColumn tableColumn = linkUrlTable.getColumnModel()
773 int preferredWidth = tableColumn.getMinWidth();
775 TableCellRenderer cellRenderer = linkUrlTable.getCellRenderer(0,
777 Component c = linkUrlTable.prepareRenderer(cellRenderer, 0, column);
778 int cwidth = c.getPreferredSize().width
779 + linkUrlTable.getIntercellSpacing().width;
780 preferredWidth = Math.max(preferredWidth, cwidth);
782 tableColumn.setPreferredWidth(preferredWidth);
786 String proxyTypeString = Cache.getDefault("USE_PROXY", "false");
787 previousProxyType = proxyTypeString;
788 switch (proxyTypeString)
790 case Cache.PROXYTYPE_NONE:
791 proxyType.setSelected(noProxy.getModel(), true);
793 case Cache.PROXYTYPE_SYSTEM:
794 proxyType.setSelected(systemProxy.getModel(), true);
796 case Cache.PROXYTYPE_CUSTOM:
797 proxyType.setSelected(customProxy.getModel(), true);
801 "Incorrect PROXY_TYPE - should be 'none' (clear proxy properties), 'false' (system settings), 'true' (custom settings): "
804 proxyServerHttpTB.setText(Cache.getDefault("PROXY_SERVER", ""));
805 proxyPortHttpTB.setText(Cache.getDefault("PROXY_PORT", ""));
806 proxyServerHttpsTB.setText(Cache.getDefault("PROXY_SERVER_HTTPS", ""));
807 proxyPortHttpsTB.setText(Cache.getDefault("PROXY_PORT_HTTPS", ""));
808 proxyAuth.setSelected(Cache.getDefault("PROXY_AUTH", false));
810 .setText(Cache.getDefault("PROXY_AUTH_USERNAME", ""));
811 // we are not storing or retrieving proxy password from .jalview_properties
812 proxyAuthPasswordPB.setText(Cache.proxyAuthPassword == null ? ""
813 : new String(Cache.proxyAuthPassword));
814 setCustomProxyEnabled();
815 applyProxyButtonEnabled(false);
817 defaultBrowser.setText(Cache.getDefault("DEFAULT_BROWSER", ""));
819 usagestats.setSelected(Cache.getDefault("USAGESTATS", false));
820 // note antisense here: default is true
822 .setSelected(Cache.getProperty("NOQUESTIONNAIRES") == null);
823 versioncheck.setSelected(Cache.getDefault("VERSION_CHECK", true));
826 * Set Output tab defaults
828 setupOutputCombo(epsRendering, "EPS_RENDERING");
829 setupOutputCombo(htmlRendering, "HTML_RENDERING");
830 setupOutputCombo(svgRendering, "SVG_RENDERING");
831 autoIdWidth.setSelected(Cache.getDefault("FIGURE_AUTOIDWIDTH", false));
832 userIdWidth.setEnabled(!autoIdWidth.isSelected());
833 userIdWidthlabel.setEnabled(!autoIdWidth.isSelected());
834 Integer wi = Cache.getIntegerProperty("FIGURE_FIXEDIDWIDTH");
835 userIdWidth.setText(wi == null ? "" : wi.toString());
836 // TODO: refactor to use common enum via FormatAdapter and allow extension
837 // for new flat file formats
838 blcjv.setSelected(Cache.getDefault("BLC_JVSUFFIX", true));
839 clustaljv.setSelected(Cache.getDefault("CLUSTAL_JVSUFFIX", true));
840 fastajv.setSelected(Cache.getDefault("FASTA_JVSUFFIX", true));
841 msfjv.setSelected(Cache.getDefault("MSF_JVSUFFIX", true));
842 pfamjv.setSelected(Cache.getDefault("PFAM_JVSUFFIX", true));
843 pileupjv.setSelected(Cache.getDefault("PILEUP_JVSUFFIX", true));
844 pirjv.setSelected(Cache.getDefault("PIR_JVSUFFIX", true));
845 modellerOutput.setSelected(Cache.getDefault("PIR_MODELLER", false));
847 .setSelected(Cache.getDefault("EXPORT_EMBBED_BIOJSON", true));
850 * Set Editing tab defaults
852 autoCalculateConsCheck
853 .setSelected(Cache.getDefault("AUTO_CALC_CONSENSUS", true));
854 padGaps.setSelected(Cache.getDefault("PAD_GAPS", false));
855 sortByTree.setSelected(Cache.getDefault("SORT_BY_TREE", false));
857 annotations_actionPerformed(null); // update the display of the annotation
862 * Set Backups tab defaults
864 loadLastSavedBackupsOptions();
868 * A helper method that sets the items and initial selection in a character
869 * rendering option list (Prompt each time/Lineart/Text)
874 protected void setupOutputCombo(JComboBox<Object> comboBox,
877 comboBox.addItem(promptEachTimeOpt);
878 comboBox.addItem(lineArtOpt);
879 comboBox.addItem(textOpt);
882 * JalviewJS doesn't support Lineart so force it to Text
884 String defaultOption = Platform.isJS() ? "Text"
885 : Cache.getDefault(propertyKey, "Prompt each time");
886 if (defaultOption.equalsIgnoreCase("Text"))
888 comboBox.setSelectedItem(textOpt);
890 else if (defaultOption.equalsIgnoreCase("Lineart"))
892 comboBox.setSelectedItem(lineArtOpt);
896 comboBox.setSelectedItem(promptEachTimeOpt);
901 * Save user selections on the Preferences tabs to the Cache and write out to
907 public void ok_actionPerformed(ActionEvent e)
909 if (!validateSettings())
915 * Set proxy settings first (to be before web services refresh)
919 * Save Visual settings
921 Cache.setPropertyNoSave("SHOW_JVSUFFIX",
922 Boolean.toString(seqLimit.isSelected()));
923 Cache.setPropertyNoSave("RIGHT_ALIGN_IDS",
924 Boolean.toString(rightAlign.isSelected()));
925 Cache.setPropertyNoSave("SHOW_FULLSCREEN",
926 Boolean.toString(fullScreen.isSelected()));
927 Cache.setPropertyNoSave("SHOW_OVERVIEW",
928 Boolean.toString(openoverv.isSelected()));
929 Cache.setPropertyNoSave("SHOW_ANNOTATIONS",
930 Boolean.toString(annotations.isSelected()));
931 Cache.setPropertyNoSave("SHOW_CONSERVATION",
932 Boolean.toString(conservation.isSelected()));
933 Cache.setPropertyNoSave("SHOW_QUALITY",
934 Boolean.toString(quality.isSelected()));
935 Cache.setPropertyNoSave("SHOW_IDENTITY",
936 Boolean.toString(identity.isSelected()));
938 Cache.setPropertyNoSave("GAP_SYMBOL",
939 gapSymbolCB.getSelectedItem().toString());
941 Cache.setPropertyNoSave("FONT_NAME",
942 fontNameCB.getSelectedItem().toString());
943 Cache.setPropertyNoSave("FONT_STYLE",
944 fontStyleCB.getSelectedItem().toString());
945 Cache.setPropertyNoSave("FONT_SIZE",
946 fontSizeCB.getSelectedItem().toString());
948 Cache.setPropertyNoSave("ID_ITALICS",
949 Boolean.toString(idItalics.isSelected()));
950 Cache.setPropertyNoSave("SHOW_UNCONSERVED",
951 Boolean.toString(showUnconserved.isSelected()));
952 Cache.setPropertyNoSave(SHOW_OCCUPANCY,
953 Boolean.toString(showOccupancy.isSelected()));
954 Cache.setPropertyNoSave("SHOW_GROUP_CONSENSUS",
955 Boolean.toString(showGroupConsensus.isSelected()));
956 Cache.setPropertyNoSave("SHOW_GROUP_CONSERVATION",
957 Boolean.toString(showGroupConservation.isSelected()));
958 Cache.setPropertyNoSave("SHOW_CONSENSUS_HISTOGRAM",
959 Boolean.toString(showConsensHistogram.isSelected()));
960 Cache.setPropertyNoSave("SHOW_CONSENSUS_LOGO",
961 Boolean.toString(showConsensLogo.isSelected()));
962 Cache.setPropertyNoSave("SHOW_INFORMATION_HISTOGRAM",
963 Boolean.toString(showConsensHistogram.isSelected()));
964 Cache.setPropertyNoSave("SHOW_HMM_LOGO",
965 Boolean.toString(showHMMLogo.isSelected()));
966 Cache.setPropertyNoSave("ANTI_ALIAS",
967 Boolean.toString(smoothFont.isSelected()));
968 Cache.setPropertyNoSave(SCALE_PROTEIN_TO_CDNA,
969 Boolean.toString(scaleProteinToCdna.isSelected()));
970 Cache.setPropertyNoSave("SHOW_NPFEATS_TOOLTIP",
971 Boolean.toString(showNpTooltip.isSelected()));
972 Cache.setPropertyNoSave("SHOW_DBREFS_TOOLTIP",
973 Boolean.toString(showDbRefTooltip.isSelected()));
975 Cache.setPropertyNoSave("WRAP_ALIGNMENT",
976 Boolean.toString(wrap.isSelected()));
978 Cache.setPropertyNoSave("STARTUP_FILE",
979 startupFileTextfield.getText());
980 Cache.setPropertyNoSave("SHOW_STARTUP_FILE",
981 Boolean.toString(startupCheckbox.isSelected()));
983 Cache.setPropertyNoSave("SORT_ALIGNMENT",
984 sortby.getSelectedItem().toString());
986 // convert description of sort order to enum name for save
987 SequenceAnnotationOrder annSortOrder = SequenceAnnotationOrder
988 .forDescription(sortAnnBy.getSelectedItem().toString());
989 if (annSortOrder != null)
991 Cache.setPropertyNoSave(SORT_ANNOTATIONS,
992 annSortOrder.name());
995 final boolean showAutocalcFirst = sortAutocalc.getSelectedIndex() == 0;
996 Cache.setPropertyNoSave(SHOW_AUTOCALC_ABOVE,
997 Boolean.valueOf(showAutocalcFirst).toString());
1000 * Save Colours settings
1002 Cache.setPropertyNoSave(DEFAULT_COLOUR_PROT,
1003 protColour.getSelectedItem().toString());
1004 Cache.setPropertyNoSave(DEFAULT_COLOUR_NUC,
1005 nucColour.getSelectedItem().toString());
1006 Cache.setColourPropertyNoSave("ANNOTATIONCOLOUR_MIN",
1007 minColour.getBackground());
1008 Cache.setColourPropertyNoSave("ANNOTATIONCOLOUR_MAX",
1009 maxColour.getBackground());
1012 * Save HMMER settings
1014 Cache.setPropertyNoSave(HMMALIGN_TRIM_TERMINI,
1015 Boolean.toString(hmmrTrimTermini.isSelected()));
1016 Cache.setPropertyNoSave(HMMINFO_GLOBAL_BACKGROUND,
1017 Boolean.toString(hmmerBackgroundUniprot.isSelected()));
1018 Cache.setPropertyNoSave(HMMSEARCH_SEQCOUNT,
1019 hmmerSequenceCount.getText());
1020 Cache.setOrRemove(HMMER_PATH, hmmerPath.getText());
1021 if (cygwinPath != null)
1023 Cache.setOrRemove(CYGWIN_PATH, cygwinPath.getText());
1025 AlignFrame[] frames = Desktop.getAlignFrames();
1026 if (frames != null && frames.length > 0)
1028 for (AlignFrame f : frames)
1030 f.updateHMMERStatus();
1034 hmmrTrimTermini.setSelected(Cache.getDefault(HMMALIGN_TRIM_TERMINI, false));
1035 if (Cache.getDefault(HMMINFO_GLOBAL_BACKGROUND, false))
1037 hmmerBackgroundUniprot.setSelected(true);
1041 hmmerBackgroundAlignment.setSelected(true);
1044 .setText(Cache.getProperty(HMMSEARCH_SEQCOUNT));
1045 hmmerPath.setText(Cache.getProperty(HMMER_PATH));
1048 * Save Overview settings
1050 Cache.setColourPropertyNoSave(GAP_COLOUR, gapColour.getBackground());
1051 Cache.setColourPropertyNoSave(HIDDEN_COLOUR, hiddenColour.getBackground());
1052 Cache.setPropertyNoSave(USE_LEGACY_GAP,
1053 Boolean.toString(useLegacyGap.isSelected()));
1054 Cache.setPropertyNoSave(SHOW_OV_HIDDEN_AT_START,
1055 Boolean.toString(showHiddenAtStart.isSelected()));
1058 * Save Structure settings
1060 Cache.setPropertyNoSave(ADD_TEMPFACT_ANN,
1061 Boolean.toString(addTempFactor.isSelected()));
1062 Cache.setPropertyNoSave(ADD_SS_ANN,
1063 Boolean.toString(addSecondaryStructure.isSelected()));
1064 Cache.setPropertyNoSave(STRUCT_FROM_PDB,
1065 Boolean.toString(structFromPdb.isSelected()));
1066 if (!Platform.isJS()) {
1067 String viewer = structViewer.getSelectedItem().toString();
1068 String viewerPath = structureViewerPath.getText();
1069 Cache.setPropertyNoSave(STRUCTURE_DISPLAY, viewer);
1070 if (viewer.equals(ViewerType.CHIMERA.name()))
1072 Cache.setOrRemove(CHIMERA_PATH, viewerPath);
1074 else if (viewer.equals(ViewerType.CHIMERAX.name()))
1076 Cache.setOrRemove(CHIMERAX_PATH, viewerPath);
1078 else if (viewer.equals(ViewerType.PYMOL.name()))
1080 Cache.setOrRemove(PYMOL_PATH, viewerPath);
1083 Cache.setPropertyNoSave("MAP_WITH_SIFTS",
1084 Boolean.toString(siftsMapping.isSelected()));
1085 SiftsSettings.setMapWithSifts(siftsMapping.isSelected());
1088 * Save Output settings
1090 Cache.setPropertyNoSave("EPS_RENDERING",
1091 ((OptionsParam) epsRendering.getSelectedItem()).getCode());
1092 Cache.setPropertyNoSave("HTML_RENDERING",
1093 ((OptionsParam) htmlRendering.getSelectedItem()).getCode());
1094 Cache.setPropertyNoSave("SVG_RENDERING",
1095 ((OptionsParam) svgRendering.getSelectedItem()).getCode());
1098 * Save Connections settings
1100 // Proxy settings were already set first (to catch web services)
1101 Cache.setOrRemove("DEFAULT_BROWSER", defaultBrowser.getText());
1103 jalview.util.BrowserLauncher.resetBrowser();
1105 // save user-defined and selected links
1106 String menuLinks = sequenceUrlLinks.writeUrlsAsString(true);
1107 if (menuLinks.isEmpty())
1109 Cache.removePropertyNoSave("SEQUENCE_LINKS");
1113 Cache.setPropertyNoSave("SEQUENCE_LINKS",
1114 menuLinks.toString());
1117 String nonMenuLinks = sequenceUrlLinks.writeUrlsAsString(false);
1118 if (nonMenuLinks.isEmpty())
1120 Cache.removePropertyNoSave("STORED_LINKS");
1124 Cache.setPropertyNoSave("STORED_LINKS",
1125 nonMenuLinks.toString());
1128 Cache.setPropertyNoSave("DEFAULT_URL",
1129 sequenceUrlLinks.getPrimaryUrlId());
1131 Cache.setProperty("VERSION_CHECK",
1132 Boolean.toString(versioncheck.isSelected()));
1133 if (Cache.getProperty("USAGESTATS") != null || usagestats.isSelected())
1135 // default is false - we only set this if the user has actively agreed
1136 Cache.setProperty("USAGESTATS",
1137 Boolean.toString(usagestats.isSelected()));
1139 if (!questionnaire.isSelected())
1141 Cache.setProperty("NOQUESTIONNAIRES", "true");
1145 // special - made easy to edit a property file to disable questionnaires
1146 // by just adding the given line
1147 Cache.removeProperty("NOQUESTIONNAIRES");
1151 * Save Output settings
1153 Cache.setPropertyNoSave("BLC_JVSUFFIX",
1154 Boolean.toString(blcjv.isSelected()));
1155 Cache.setPropertyNoSave("CLUSTAL_JVSUFFIX",
1156 Boolean.toString(clustaljv.isSelected()));
1157 Cache.setPropertyNoSave("FASTA_JVSUFFIX",
1158 Boolean.toString(fastajv.isSelected()));
1159 Cache.setPropertyNoSave("MSF_JVSUFFIX",
1160 Boolean.toString(msfjv.isSelected()));
1161 Cache.setPropertyNoSave("PFAM_JVSUFFIX",
1162 Boolean.toString(pfamjv.isSelected()));
1163 Cache.setPropertyNoSave("PILEUP_JVSUFFIX",
1164 Boolean.toString(pileupjv.isSelected()));
1165 Cache.setPropertyNoSave("PIR_JVSUFFIX",
1166 Boolean.toString(pirjv.isSelected()));
1167 Cache.setPropertyNoSave("PIR_MODELLER",
1168 Boolean.toString(modellerOutput.isSelected()));
1169 Cache.setPropertyNoSave("EXPORT_EMBBED_BIOJSON",
1170 Boolean.toString(embbedBioJSON.isSelected()));
1171 jalview.io.PIRFile.useModellerOutput = modellerOutput.isSelected();
1173 Cache.setPropertyNoSave("FIGURE_AUTOIDWIDTH",
1174 Boolean.toString(autoIdWidth.isSelected()));
1175 userIdWidth_actionPerformed();
1176 Cache.setPropertyNoSave("FIGURE_FIXEDIDWIDTH",
1177 userIdWidth.getText());
1180 * Save Editing settings
1182 Cache.setPropertyNoSave("AUTO_CALC_CONSENSUS",
1183 Boolean.toString(autoCalculateConsCheck.isSelected()));
1184 Cache.setPropertyNoSave("SORT_BY_TREE",
1185 Boolean.toString(sortByTree.isSelected()));
1186 Cache.setPropertyNoSave("PAD_GAPS",
1187 Boolean.toString(padGaps.isSelected()));
1189 if (!Platform.isJS())
1191 wsPrefs.updateAndRefreshWsMenuConfig(false);
1195 * Save Backups settings
1197 Cache.setPropertyNoSave(BackupFiles.ENABLED,
1198 Boolean.toString(enableBackupFiles.isSelected()));
1199 int preset = getComboIntStringKey(backupfilesPresetsCombo);
1200 Cache.applicationProperties.setProperty(BackupFiles.NS + "_PRESET", Integer.toString(preset));
1202 if (preset == BackupFilesPresetEntry.BACKUPFILESSCHEMECUSTOM)
1204 BackupFilesPresetEntry customBFPE = getBackupfilesCurrentEntry();
1205 BackupFilesPresetEntry.backupfilesPresetEntriesValues.put(
1206 BackupFilesPresetEntry.BACKUPFILESSCHEMECUSTOM, customBFPE);
1207 Cache.applicationProperties
1208 .setProperty(BackupFilesPresetEntry.CUSTOMCONFIG,
1209 customBFPE.toString());
1212 BackupFilesPresetEntry savedBFPE = BackupFilesPresetEntry.backupfilesPresetEntriesValues
1214 Cache.setPropertyNoSave(
1215 BackupFilesPresetEntry.SAVEDCONFIG, savedBFPE.toString());
1217 Cache.saveProperties();
1218 Desktop.getInstance().doConfigureStructurePrefs();
1221 frame.setClosed(true);
1222 } catch (Exception ex)
1226 public void saveProxySettings()
1228 String newProxyType = customProxy.isSelected() ? Cache.PROXYTYPE_CUSTOM
1229 : noProxy.isSelected() ? Cache.PROXYTYPE_NONE
1230 : Cache.PROXYTYPE_SYSTEM;
1231 Cache.setPropertyNoSave("USE_PROXY", newProxyType);
1232 Cache.setOrRemove("PROXY_SERVER", proxyServerHttpTB.getText());
1233 Cache.setOrRemove("PROXY_PORT", proxyPortHttpTB.getText());
1234 Cache.setOrRemove("PROXY_SERVER_HTTPS", proxyServerHttpsTB.getText());
1235 Cache.setOrRemove("PROXY_PORT_HTTPS", proxyPortHttpsTB.getText());
1236 Cache.setOrRemove("PROXY_AUTH",
1237 Boolean.toString(proxyAuth.isSelected()));
1238 Cache.setOrRemove("PROXY_AUTH_USERNAME", proxyAuthUsernameTB.getText());
1239 Cache.proxyAuthPassword = proxyAuthPasswordPB.getPassword();
1240 Cache.setProxyPropertiesFromPreferences(previousProxyType);
1241 if (newProxyType.equals(Cache.PROXYTYPE_CUSTOM)
1242 || !newProxyType.equals(previousProxyType))
1244 // force a re-lookup of ws if proxytype is custom or has changed
1247 previousProxyType = newProxyType;
1250 public static void setAppletDefaults()
1253 // http://www.jalview.org/old/v2_8/examples/appletParameters.html
1255 // showConservation true or false Default is true.
1256 // showQuality true or false Default is true.
1257 // showConsensus true or false Default is true.
1258 // showFeatureSettings true or false Shows the feature settings window when
1260 // showTreeBootstraps true or false (default is true) show or hide branch
1262 // showTreeDistances true or false (default is true) show or hide branch
1264 // showUnlinkedTreeNodes true or false (default is false) indicate if
1265 // unassociated nodes should be highlighted in the tree view
1266 // showUnconserved true of false (default is false) When true, only gaps and
1267 // symbols different to the consensus sequence ions of the alignment
1268 // showGroupConsensus true of false (default is false) When true, shows
1269 // consensus annotation row for any groups on the alignment. (since 2.7)
1270 // showGroupConservation true of false (default is false) When true, shows
1271 // amino-acid property conservation annotation row for any groups on the
1272 // showConsensusHistogram true of false (default is true) When true, shows
1273 // the percentage occurence of the consensus symbol for each column as a
1274 // showSequenceLogo true of false (default is false) When true, shows a
1275 // sequence logo above the consensus sequence (overlaid above the Consensus
1277 Cache.setPropertyNoSave(SHOW_CONSERVATION, "true");
1278 Cache.setPropertyNoSave(SHOW_QUALITY, "false");
1279 Cache.setPropertyNoSave(SHOW_CONSENSUS, "true");
1280 Cache.setPropertyNoSave(SHOW_UNCONSERVED, "false");
1281 Cache.setPropertyNoSave(SHOW_GROUP_CONSERVATION, "false");
1282 Cache.setPropertyNoSave(SHOW_GROUP_CONSENSUS, "false");
1284 // TODO -- just a start here
1287 * Do any necessary validation before saving settings. Return focus to the
1288 * first tab which fails validation.
1292 private boolean validateSettings()
1294 if (!validateStructure())
1296 structureTab.requestFocusInWindow();
1303 protected boolean validateStructure()
1305 return validateViewerPath();
1313 public void startupFileTextfield_mouseClicked()
1315 // TODO: JAL-3048 not needed for Jalview-JS
1316 String fileFormat = Cache.getProperty("DEFAULT_FILE_FORMAT");
1317 JalviewFileChooser chooser = JalviewFileChooser
1318 .forRead(Cache.getProperty("LAST_DIRECTORY"), fileFormat);
1319 chooser.setFileView(new JalviewFileView());
1320 chooser.setDialogTitle(
1321 MessageManager.getString("label.select_startup_file"));
1323 int value = chooser.showOpenDialog(this);
1325 if (value == JalviewFileChooser.APPROVE_OPTION)
1327 FileFormatI format = chooser.getSelectedFormat();
1330 Cache.setPropertyNoSave("DEFAULT_FILE_FORMAT",
1333 startupFileTextfield
1334 .setText(chooser.getSelectedFile().getAbsolutePath());
1345 public void cancel_actionPerformed(ActionEvent e)
1349 if (!Platform.isJS())
1351 wsPrefs.updateWsMenuConfig(true);
1352 wsPrefs.refreshWs_actionPerformed(e);
1354 frame.setClosed(true);
1355 } catch (Exception ex)
1367 public void annotations_actionPerformed(ActionEvent e)
1369 conservation.setEnabled(annotations.isSelected());
1370 quality.setEnabled(annotations.isSelected());
1371 identity.setEnabled(annotations.isSelected());
1372 showOccupancy.setEnabled(annotations.isSelected());
1373 showGroupConsensus.setEnabled(annotations.isSelected());
1374 showGroupConservation.setEnabled(annotations.isSelected());
1375 showConsensHistogram.setEnabled(annotations.isSelected()
1376 && (identity.isSelected() || showGroupConsensus.isSelected()));
1377 showConsensLogo.setEnabled(annotations.isSelected()
1378 && (identity.isSelected() || showGroupConsensus.isSelected()));
1379 showInformationHistogram.setEnabled(annotations.isSelected());
1380 showHMMLogo.setEnabled(annotations.isSelected());
1384 public void newLink_actionPerformed(ActionEvent e)
1386 GSequenceLink link = new GSequenceLink();
1387 boolean valid = false;
1390 if (JvOptionPane.showInternalConfirmDialog(Desktop.getDesktopPane(), link,
1391 MessageManager.getString("label.new_sequence_url_link"),
1392 JvOptionPane.OK_CANCEL_OPTION, -1,
1393 null) == JvOptionPane.OK_OPTION)
1395 if (link.checkValid())
1397 if (((UrlLinkTableModel) linkUrlTable.getModel())
1398 .isUniqueName(link.getName()))
1400 ((UrlLinkTableModel) linkUrlTable.getModel())
1401 .insertRow(link.getName(), link.getURL());
1406 link.notifyDuplicate();
1419 public void editLink_actionPerformed(ActionEvent e)
1421 GSequenceLink link = new GSequenceLink();
1423 int index = linkUrlTable.getSelectedRow();
1426 // button no longer enabled if row is not selected
1427 Cache.log.debug("Edit with no row selected in linkUrlTable");
1431 int nameCol = ((UrlLinkTableModel) linkUrlTable.getModel())
1433 int urlCol = ((UrlLinkTableModel) linkUrlTable.getModel())
1435 String oldName = linkUrlTable.getValueAt(index, nameCol).toString();
1436 link.setName(oldName);
1437 link.setURL(linkUrlTable.getValueAt(index, urlCol).toString());
1439 boolean valid = false;
1442 if (JvOptionPane.showInternalConfirmDialog(Desktop.getDesktopPane(), link,
1443 MessageManager.getString("label.edit_sequence_url_link"),
1444 JvOptionPane.OK_CANCEL_OPTION, -1,
1445 null) == JvOptionPane.OK_OPTION)
1447 if (link.checkValid())
1449 if ((oldName.equals(link.getName()))
1450 || (((UrlLinkTableModel) linkUrlTable.getModel())
1451 .isUniqueName(link.getName())))
1453 linkUrlTable.setValueAt(link.getName(), index, nameCol);
1454 linkUrlTable.setValueAt(link.getURL(), index, urlCol);
1459 link.notifyDuplicate();
1472 public void deleteLink_actionPerformed(ActionEvent e)
1474 int index = linkUrlTable.getSelectedRow();
1475 int modelIndex = -1;
1478 // button no longer enabled if row is not selected
1479 Cache.log.debug("Delete with no row selected in linkUrlTable");
1484 modelIndex = linkUrlTable.convertRowIndexToModel(index);
1487 // make sure we use the model index to delete, and not the table index
1488 ((UrlLinkTableModel) linkUrlTable.getModel()).removeRow(modelIndex);
1492 public void defaultBrowser_mouseClicked(MouseEvent e)
1494 // TODO: JAL-3048 not needed for j2s
1495 if (!Platform.isJS()) // BH 2019
1502 JFileChooser chooser = new JFileChooser(".");
1503 chooser.setDialogTitle(
1504 MessageManager.getString("label.select_default_browser"));
1506 int value = chooser.showOpenDialog(this);
1508 if (value == JFileChooser.APPROVE_OPTION)
1510 defaultBrowser.setText(chooser.getSelectedFile().getAbsolutePath());
1519 * jalview.jbgui.GPreferences#showunconserved_actionPerformed(java.awt.event
1523 protected void showunconserved_actionPerformed(ActionEvent e)
1525 // TODO Auto-generated method stub
1526 super.showunconserved_actionPerformed(e);
1529 public static List<String> getGroupURLLinks()
1531 return groupURLLinks;
1535 public void minColour_actionPerformed(JPanel panel)
1537 JalviewColourChooser.showColourChooser(this,
1538 MessageManager.getString("label.select_colour_minimum_value"),
1543 public void maxColour_actionPerformed(JPanel panel)
1545 JalviewColourChooser.showColourChooser(this,
1546 MessageManager.getString("label.select_colour_maximum_value"),
1551 public void gapColour_actionPerformed(JPanel gap)
1553 if (!useLegacyGap.isSelected())
1555 JalviewColourChooser.showColourChooser(this,
1556 MessageManager.getString("label.select_gap_colour"),
1562 public void hiddenColour_actionPerformed(JPanel hidden)
1564 JalviewColourChooser.showColourChooser(this,
1565 MessageManager.getString("label.select_hidden_colour"),
1570 protected void useLegacyGaps_actionPerformed(ActionEvent e)
1572 boolean enabled = useLegacyGap.isSelected();
1575 gapColour.setBackground(
1576 jalview.renderer.OverviewResColourFinder.OVERVIEW_DEFAULT_LEGACY_GAP);
1580 gapColour.setBackground(
1581 jalview.renderer.OverviewResColourFinder.OVERVIEW_DEFAULT_GAP);
1583 gapColour.setEnabled(!enabled);
1584 gapLabel.setEnabled(!enabled);
1588 protected void resetOvDefaults_actionPerformed(ActionEvent e)
1590 useLegacyGap.setSelected(false);
1591 useLegacyGaps_actionPerformed(null);
1592 showHiddenAtStart.setSelected(false);
1593 hiddenColour.setBackground(
1594 jalview.renderer.OverviewResColourFinder.OVERVIEW_DEFAULT_HIDDEN);
1598 protected void userIdWidth_actionPerformed()
1602 String val = userIdWidth.getText().trim();
1603 if (val.length() > 0)
1605 Integer iw = Integer.parseInt(val);
1606 if (iw.intValue() < 12)
1608 throw new NumberFormatException();
1610 userIdWidth.setText(iw.toString());
1612 } catch (NumberFormatException x)
1614 userIdWidth.setText("");
1615 JvOptionPane.showInternalMessageDialog(Desktop.getDesktopPane(),
1617 .getString("warn.user_defined_width_requirements"),
1618 MessageManager.getString("label.invalid_id_column_width"),
1619 JvOptionPane.WARNING_MESSAGE);
1624 protected void autoIdWidth_actionPerformed()
1626 userIdWidth.setEnabled(!autoIdWidth.isSelected());
1627 userIdWidthlabel.setEnabled(!autoIdWidth.isSelected());
1631 * Returns true if structure viewer path is to a valid executable, else shows an
1632 * error dialog. Does nothing if the path is empty, as is the case for Jmol
1633 * (built in to Jalview) or when Jalview is left to try default paths.
1635 private boolean validateViewerPath()
1637 if (structureViewerPath.getText().trim().length() > 0)
1639 File f = new File(structureViewerPath.getText());
1640 if (!f.canExecute())
1642 JvOptionPane.showInternalMessageDialog(Desktop.getDesktopPane(),
1643 MessageManager.getString("label.invalid_viewer_path"),
1644 MessageManager.getString("label.invalid_viewer_path"),
1645 JvOptionPane.ERROR_MESSAGE);
1653 * Returns true if the given text field contains a path to a folder that
1654 * contains an executable with the given name, else false (after showing a
1655 * warning dialog). The executable name will be tried with .exe appended if not
1661 protected boolean validateExecutablePath(JTextField textField, String executable)
1663 String folder = textField.getText().trim();
1665 if (FileUtils.getExecutable(executable, folder) != null)
1669 if (folder.length() > 0)
1671 JvOptionPane.showInternalMessageDialog(Desktop.getInstance(),
1672 MessageManager.formatMessage("label.executable_not_found",
1674 MessageManager.getString("label.invalid_folder"),
1675 JvOptionPane.ERROR_MESSAGE);
1681 * Checks if a file can be executed
1684 * the path to the file
1687 public boolean canExecute(String path)
1689 File file = new File(path);
1690 if (!file.canExecute())
1692 file = new File(path + ".exe");
1694 if (!file.canExecute())
1704 * If Chimera or ChimeraX or Pymol is selected, check it can be found on default
1705 * or user-specified path, if not show a warning/help dialog
1708 protected void structureViewer_actionPerformed(String selectedItem)
1710 if (selectedItem.equals(ViewerType.JMOL.name()))
1712 structureViewerPath.setEnabled(false);
1713 structureViewerPathLabel.setEnabled(false);
1716 boolean found = false;
1717 structureViewerPath.setEnabled(true);
1718 structureViewerPathLabel.setEnabled(true);
1719 structureViewerPathLabel.setText(MessageManager
1720 .formatMessage("label.viewer_path", selectedItem));
1723 * Try user-specified and standard paths for structure viewer executable
1725 String viewerPath = "";
1726 List<String> paths = null;
1729 ViewerType viewerType = ViewerType.valueOf(selectedItem);
1736 viewerPath = Cache.getDefault(CHIMERA_PATH, "");
1737 paths = StructureManager.getChimeraPaths(false);
1740 viewerPath = Cache.getDefault(CHIMERAX_PATH, "");
1741 paths = StructureManager.getChimeraPaths(true);
1744 viewerPath = Cache.getDefault(PYMOL_PATH, "");
1745 paths = PymolManager.getPymolPaths();
1748 } catch (IllegalArgumentException e)
1750 // only valid entries should be in the drop-down
1752 structureViewerPath.setText(viewerPath);
1754 paths.add(0, structureViewerPath.getText());
1755 for (String path : paths)
1757 if (new File(path.trim()).canExecute())
1765 String[] options = { "OK", "Help" };
1766 int showHelp = JvOptionPane.showInternalOptionDialog(Desktop.getDesktopPane(),
1767 JvSwingUtils.wrapTooltip(true,
1768 MessageManager.getString("label.viewer_missing")),
1769 "", JvOptionPane.YES_NO_OPTION, JvOptionPane.WARNING_MESSAGE,
1770 null, options, options[0]);
1771 if (showHelp == JvOptionPane.NO_OPTION)
1773 this.selectTab(Preferences.TabRef.STRUCTURE_TAB, null);
1776 Help.showHelpWindow(HelpId.StructureViewer);
1777 } catch (HelpSetException e)
1779 e.printStackTrace();
1782 else if (showHelp == JvOptionPane.OK_OPTION)
1784 this.selectTab(Preferences.TabRef.STRUCTURE_TAB, null);
1785 CompletableFuture<Void> cf = CompletableFuture.runAsync(() -> {
1788 for (int i = 0; i < 3; i++)
1790 structureViewerPath.setBackground(Color.PINK);
1792 structureViewerPath.setBackground(Color.WHITE);
1795 } catch (InterruptedException e)
1804 protected void validateHmmerPath()
1806 validateExecutablePath(hmmerPath, HmmerCommand.HMMBUILD);
1810 protected void validateCygwinPath()
1812 validateExecutablePath(cygwinPath, "run");
1815 public class OptionsParam
1817 private String name;
1819 private String code;
1821 public OptionsParam(String name, String code)
1827 public String getName()
1832 public void setName(String name)
1837 public String getCode()
1842 public void setCode(String code)
1848 public String toString()
1854 public boolean equals(Object that)
1856 if (!(that instanceof OptionsParam))
1860 return this.code.equalsIgnoreCase(((OptionsParam) that).code);
1864 public int hashCode()
1866 return name.hashCode() + code.hashCode();
1870 private class UrlListSelectionHandler implements ListSelectionListener
1874 public void valueChanged(ListSelectionEvent e)
1876 ListSelectionModel lsm = (ListSelectionModel) e.getSource();
1878 int index = lsm.getMinSelectionIndex();
1881 // no selection, so disable delete/edit buttons
1882 editLink.setEnabled(false);
1883 deleteLink.setEnabled(false);
1886 int modelIndex = linkUrlTable.convertRowIndexToModel(index);
1888 // enable/disable edit and delete link buttons
1889 if (((UrlLinkTableModel) linkUrlTable.getModel())
1890 .isRowDeletable(modelIndex))
1892 deleteLink.setEnabled(true);
1896 deleteLink.setEnabled(false);
1899 if (((UrlLinkTableModel) linkUrlTable.getModel())
1900 .isRowEditable(modelIndex))
1902 editLink.setEnabled(true);
1906 editLink.setEnabled(false);