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);
371 slivkaPrefs = new SlivkaPreferences();
372 slivkaTab.add(slivkaPrefs, BorderLayout.CENTER);
374 int width = 500, height = 450;
375 if (Platform.isAMacAndNotJS())
381 Desktop.addInternalFrame(frame,
382 MessageManager.getString("label.preferences"), width, height);
383 frame.setMinimumSize(new Dimension(width, height));
386 * Set HMMER tab defaults
388 hmmrTrimTermini.setSelected(Cache.getDefault(HMMALIGN_TRIM_TERMINI, false));
389 if (Cache.getDefault(HMMINFO_GLOBAL_BACKGROUND, false))
391 hmmerBackgroundUniprot.setSelected(true);
395 hmmerBackgroundAlignment.setSelected(true);
398 .setText(Cache.getProperty(HMMSEARCH_SEQCOUNT));
399 hmmerPath.setText(Cache.getProperty(HMMER_PATH));
400 hmmerPath.addActionListener(new ActionListener()
403 public void actionPerformed(ActionEvent e)
408 hmmerPath.addFocusListener(new FocusAdapter()
411 public void focusLost(FocusEvent e)
416 if (cygwinPath != null)
418 String path = Cache.getProperty(CYGWIN_PATH);
421 path = FileUtils.getPathTo("bash");
423 cygwinPath.setText(path);
424 cygwinPath.addActionListener(new ActionListener()
427 public void actionPerformed(ActionEvent e)
429 validateCygwinPath();
432 cygwinPath.addFocusListener(new FocusAdapter()
435 public void focusLost(FocusEvent e)
437 validateCygwinPath();
443 * Set Visual tab defaults
445 seqLimit.setSelected(Cache.getDefault("SHOW_JVSUFFIX", true));
446 rightAlign.setSelected(Cache.getDefault("RIGHT_ALIGN_IDS", false));
447 fullScreen.setSelected(Cache.getDefault("SHOW_FULLSCREEN", false));
448 annotations.setSelected(Cache.getDefault("SHOW_ANNOTATIONS", true));
450 conservation.setSelected(Cache.getDefault("SHOW_CONSERVATION", true));
451 quality.setSelected(Cache.getDefault("SHOW_QUALITY", true));
452 identity.setSelected(Cache.getDefault("SHOW_IDENTITY", true));
453 openoverv.setSelected(Cache.getDefault("SHOW_OVERVIEW", false));
455 .setSelected(Cache.getDefault("SHOW_UNCONSERVED", false));
456 showOccupancy.setSelected(Cache.getDefault(SHOW_OCCUPANCY, false));
458 .setSelected(Cache.getDefault("SHOW_GROUP_CONSENSUS", false));
459 showGroupConservation.setSelected(
460 Cache.getDefault("SHOW_GROUP_CONSERVATION", false));
461 showConsensHistogram.setSelected(
462 Cache.getDefault("SHOW_CONSENSUS_HISTOGRAM", true));
464 .setSelected(Cache.getDefault("SHOW_CONSENSUS_LOGO", false));
465 showInformationHistogram.setSelected(
466 Cache.getDefault("SHOW_INFORMATION_HISTOGRAM", true));
467 showHMMLogo.setSelected(Cache.getDefault("SHOW_HMM_LOGO", false));
469 .setSelected(Cache.getDefault("SHOW_NPFEATS_TOOLTIP", true));
471 .setSelected(Cache.getDefault("SHOW_DBREFS_TOOLTIP", true));
473 String[] fonts = java.awt.GraphicsEnvironment
474 .getLocalGraphicsEnvironment().getAvailableFontFamilyNames();
475 for (int i = 0; i < fonts.length; i++)
477 fontNameCB.addItem(fonts[i]);
480 for (int i = MIN_FONT_SIZE; i <= MAX_FONT_SIZE; i++)
482 fontSizeCB.addItem(i + "");
485 fontStyleCB.addItem("plain");
486 fontStyleCB.addItem("bold");
487 fontStyleCB.addItem("italic");
489 fontNameCB.setSelectedItem(Cache.getDefault("FONT_NAME", "SansSerif"));
490 fontSizeCB.setSelectedItem(Cache.getDefault("FONT_SIZE", "10"));
491 fontStyleCB.setSelectedItem(
492 Cache.getDefault("FONT_STYLE", Font.PLAIN + ""));
494 smoothFont.setSelected(Cache.getDefault("ANTI_ALIAS", true));
496 .setSelected(Cache.getDefault(SCALE_PROTEIN_TO_CDNA, false));
498 idItalics.setSelected(Cache.getDefault("ID_ITALICS", true));
500 wrap.setSelected(Cache.getDefault("WRAP_ALIGNMENT", false));
502 gapSymbolCB.addItem("-");
503 gapSymbolCB.addItem(".");
505 gapSymbolCB.setSelectedItem(Cache.getDefault("GAP_SYMBOL", "-"));
507 sortby.addItem("No sort");
508 sortby.addItem("Id");
509 sortby.addItem("Pairwise Identity");
510 sortby.setSelectedItem(Cache.getDefault("SORT_ALIGNMENT", "No sort"));
512 sortAnnBy.addItem(SequenceAnnotationOrder.NONE.toString());
514 .addItem(SequenceAnnotationOrder.SEQUENCE_AND_LABEL.toString());
516 .addItem(SequenceAnnotationOrder.LABEL_AND_SEQUENCE.toString());
517 SequenceAnnotationOrder savedSort = SequenceAnnotationOrder
518 .valueOf(Cache.getDefault(SORT_ANNOTATIONS,
519 SequenceAnnotationOrder.NONE.name()));
520 sortAnnBy.setSelectedItem(savedSort.toString());
522 sortAutocalc.addItem("Autocalculated first");
523 sortAutocalc.addItem("Autocalculated last");
524 final boolean showAbove = Cache.getDefault(SHOW_AUTOCALC_ABOVE, true);
525 sortAutocalc.setSelectedItem(showAbove ? sortAutocalc.getItemAt(0)
526 : sortAutocalc.getItemAt(1));
528 .setSelected(Cache.getDefault("SHOW_STARTUP_FILE", true));
529 startupFileTextfield.setText(Cache.getDefault("STARTUP_FILE",
530 Cache.getDefault("www.jalview.org", "https://www.jalview.org")
531 + "/examples/exampleFile_2_7.jvp"));
534 * Set Colours tab defaults
536 protColour.addItem(ResidueColourScheme.NONE);
537 nucColour.addItem(ResidueColourScheme.NONE);
538 for (ColourSchemeI cs : ColourSchemes.getInstance().getColourSchemes())
540 String name = cs.getSchemeName();
541 protColour.addItem(name);
542 nucColour.addItem(name);
544 String oldProp = Cache.getDefault(DEFAULT_COLOUR,
545 ResidueColourScheme.NONE);
546 String newProp = Cache.getDefault(DEFAULT_COLOUR_PROT, null);
547 protColour.setSelectedItem(newProp != null ? newProp : oldProp);
548 newProp = Cache.getDefault(DEFAULT_COLOUR_NUC, null);
549 nucColour.setSelectedItem(newProp != null ? newProp : oldProp);
550 minColour.setBackground(
551 Cache.getDefaultColour("ANNOTATIONCOLOUR_MIN", Color.orange));
552 maxColour.setBackground(
553 Cache.getDefaultColour("ANNOTATIONCOLOUR_MAX", Color.red));
556 * Set overview panel defaults
558 gapColour.setBackground(Cache.getDefaultColour(GAP_COLOUR,
559 jalview.renderer.OverviewResColourFinder.OVERVIEW_DEFAULT_GAP));
560 hiddenColour.setBackground(Cache.getDefaultColour(HIDDEN_COLOUR,
561 jalview.renderer.OverviewResColourFinder.OVERVIEW_DEFAULT_HIDDEN));
562 useLegacyGap.setSelected(Cache.getDefault(USE_LEGACY_GAP, false));
563 gapLabel.setEnabled(!useLegacyGap.isSelected());
564 gapColour.setEnabled(!useLegacyGap.isSelected());
566 .setSelected(Cache.getDefault(SHOW_OV_HIDDEN_AT_START, false));
569 * Set Structure tab defaults
571 final boolean structSelected = Cache.getDefault(STRUCT_FROM_PDB, true);
572 structFromPdb.setSelected(structSelected);
573 addSecondaryStructure.setSelected(Cache.getDefault(ADD_SS_ANN, true));
574 addSecondaryStructure.setEnabled(structSelected);
575 addTempFactor.setSelected(Cache.getDefault(ADD_TEMPFACT_ANN, true));
576 addTempFactor.setEnabled(structSelected);
578 * set choice of structure viewer, and path if saved as a preference;
579 * default to Jmol (first choice) if an unexpected value is found
581 String viewerType = ViewerType.JMOL.name();
582 if (!Platform.isJS())
584 Cache.getDefault(STRUCTURE_DISPLAY,
585 ViewerType.JMOL.name());
587 // TODO - disable external viewers for JS
588 structViewer.setSelectedItem(viewerType);
589 String viewerPath = "";
590 ViewerType type = null;
593 type = ViewerType.valueOf(viewerType);
599 viewerPath = Cache.getDefault(CHIMERA_PATH, "");
602 viewerPath = Cache.getDefault(CHIMERAX_PATH, "");
605 viewerPath = Cache.getDefault(PYMOL_PATH, "");
608 } catch (IllegalArgumentException e)
610 Cache.log.error("Unknown structure viewer type: " + viewerType
611 + ", defaulting to Jmol");
612 type = ViewerType.JMOL;
614 structureViewerPath.setText(viewerPath);
616 structureViewerPath.addActionListener(new ActionListener()
619 public void actionPerformed(ActionEvent e)
621 if (validateViewerPath())
623 String path = structureViewerPath.getText();
625 ViewerType type = ViewerType.valueOf(viewerType);
631 Cache.setProperty(CHIMERA_PATH, path);
634 Cache.setProperty(CHIMERAX_PATH, path);
637 Cache.setProperty(PYMOL_PATH, path);
640 } catch (IllegalArgumentException x)
642 Cache.log.error("Failed to set path - unknown viewer type",x);
648 if (Cache.getDefault("MAP_WITH_SIFTS", false))
650 siftsMapping.setSelected(true);
654 nwMapping.setSelected(true);
658 .setMapWithSifts(Cache.getDefault("MAP_WITH_SIFTS", false));
661 * Set Connections tab defaults
665 linkUrlTable.setModel(dataModel);
666 final TableRowSorter<TableModel> sorter = new TableRowSorter<>(
667 linkUrlTable.getModel());
668 linkUrlTable.setRowSorter(sorter);
669 List<RowSorter.SortKey> sortKeys = new ArrayList<>();
671 UrlLinkTableModel m = (UrlLinkTableModel) linkUrlTable.getModel();
672 sortKeys.add(new RowSorter.SortKey(m.getPrimaryColumn(),
673 SortOrder.DESCENDING));
674 sortKeys.add(new RowSorter.SortKey(m.getSelectedColumn(),
675 SortOrder.DESCENDING));
677 new RowSorter.SortKey(m.getNameColumn(), SortOrder.ASCENDING));
679 sorter.setSortKeys(sortKeys);
680 // BH 2018 setSortKeys will do the sort
684 ActionListener onReset;
685 onReset = new ActionListener()
688 public void actionPerformed(ActionEvent e)
690 filterTB.setText("");
691 sorter.setRowFilter(RowFilter.regexFilter(""));
695 doReset.addActionListener(onReset);
697 // filter to display only custom urls
698 final RowFilter<TableModel, Object> customUrlFilter = new RowFilter<TableModel, Object>()
701 public boolean include(
702 Entry<? extends TableModel, ? extends Object> entry)
704 return ((UrlLinkTableModel) entry.getModel()).isUserEntry(entry);
708 final TableRowSorter<TableModel> customSorter = new TableRowSorter<>(
709 linkUrlTable.getModel());
710 customSorter.setRowFilter(customUrlFilter);
712 ActionListener onCustomOnly;
713 onCustomOnly = new ActionListener()
716 public void actionPerformed(ActionEvent e)
718 filterTB.setText("");
719 sorter.setRowFilter(customUrlFilter);
722 userOnly.addActionListener(onCustomOnly);
724 filterTB.getDocument().addDocumentListener(new DocumentListener()
726 String caseInsensitiveFlag = "(?i)";
729 public void changedUpdate(DocumentEvent e)
731 sorter.setRowFilter(RowFilter
732 .regexFilter(caseInsensitiveFlag + filterTB.getText()));
736 public void removeUpdate(DocumentEvent e)
738 sorter.setRowFilter(RowFilter
739 .regexFilter(caseInsensitiveFlag + filterTB.getText()));
743 public void insertUpdate(DocumentEvent e)
745 sorter.setRowFilter(RowFilter
746 .regexFilter(caseInsensitiveFlag + filterTB.getText()));
750 // set up list selection functionality
751 linkUrlTable.getSelectionModel()
752 .addListSelectionListener(new UrlListSelectionHandler());
754 // set up radio buttons
755 int onClickCol = ((UrlLinkTableModel) linkUrlTable.getModel())
757 String onClickName = linkUrlTable.getColumnName(onClickCol);
758 linkUrlTable.getColumn(onClickName)
759 .setCellRenderer(new RadioButtonRenderer());
760 linkUrlTable.getColumn(onClickName)
761 .setCellEditor(new RadioButtonEditor());
763 // get boolean columns and resize those to min possible
764 for (int column = 0; column < linkUrlTable.getColumnCount(); column++)
766 if (linkUrlTable.getModel().getColumnClass(column)
767 .equals(Boolean.class))
769 TableColumn tableColumn = linkUrlTable.getColumnModel()
771 int preferredWidth = tableColumn.getMinWidth();
773 TableCellRenderer cellRenderer = linkUrlTable.getCellRenderer(0,
775 Component c = linkUrlTable.prepareRenderer(cellRenderer, 0, column);
776 int cwidth = c.getPreferredSize().width
777 + linkUrlTable.getIntercellSpacing().width;
778 preferredWidth = Math.max(preferredWidth, cwidth);
780 tableColumn.setPreferredWidth(preferredWidth);
784 String proxyTypeString = Cache.getDefault("USE_PROXY", "false");
785 previousProxyType = proxyTypeString;
786 switch (proxyTypeString)
788 case Cache.PROXYTYPE_NONE:
789 proxyType.setSelected(noProxy.getModel(), true);
791 case Cache.PROXYTYPE_SYSTEM:
792 proxyType.setSelected(systemProxy.getModel(), true);
794 case Cache.PROXYTYPE_CUSTOM:
795 proxyType.setSelected(customProxy.getModel(), true);
799 "Incorrect PROXY_TYPE - should be 'none' (clear proxy properties), 'false' (system settings), 'true' (custom settings): "
802 proxyServerHttpTB.setText(Cache.getDefault("PROXY_SERVER", ""));
803 proxyPortHttpTB.setText(Cache.getDefault("PROXY_PORT", ""));
804 proxyServerHttpsTB.setText(Cache.getDefault("PROXY_SERVER_HTTPS", ""));
805 proxyPortHttpsTB.setText(Cache.getDefault("PROXY_PORT_HTTPS", ""));
806 proxyAuth.setSelected(Cache.getDefault("PROXY_AUTH", false));
808 .setText(Cache.getDefault("PROXY_AUTH_USERNAME", ""));
809 // we are not storing or retrieving proxy password from .jalview_properties
810 proxyAuthPasswordPB.setText(Cache.proxyAuthPassword == null ? ""
811 : new String(Cache.proxyAuthPassword));
812 setCustomProxyEnabled();
813 applyProxyButtonEnabled(false);
815 defaultBrowser.setText(Cache.getDefault("DEFAULT_BROWSER", ""));
817 usagestats.setSelected(Cache.getDefault("USAGESTATS", false));
818 // note antisense here: default is true
820 .setSelected(Cache.getProperty("NOQUESTIONNAIRES") == null);
821 versioncheck.setSelected(Cache.getDefault("VERSION_CHECK", true));
824 * Set Output tab defaults
826 setupOutputCombo(epsRendering, "EPS_RENDERING");
827 setupOutputCombo(htmlRendering, "HTML_RENDERING");
828 setupOutputCombo(svgRendering, "SVG_RENDERING");
829 autoIdWidth.setSelected(Cache.getDefault("FIGURE_AUTOIDWIDTH", false));
830 userIdWidth.setEnabled(!autoIdWidth.isSelected());
831 userIdWidthlabel.setEnabled(!autoIdWidth.isSelected());
832 Integer wi = Cache.getIntegerProperty("FIGURE_FIXEDIDWIDTH");
833 userIdWidth.setText(wi == null ? "" : wi.toString());
834 // TODO: refactor to use common enum via FormatAdapter and allow extension
835 // for new flat file formats
836 blcjv.setSelected(Cache.getDefault("BLC_JVSUFFIX", true));
837 clustaljv.setSelected(Cache.getDefault("CLUSTAL_JVSUFFIX", true));
838 fastajv.setSelected(Cache.getDefault("FASTA_JVSUFFIX", true));
839 msfjv.setSelected(Cache.getDefault("MSF_JVSUFFIX", true));
840 pfamjv.setSelected(Cache.getDefault("PFAM_JVSUFFIX", true));
841 pileupjv.setSelected(Cache.getDefault("PILEUP_JVSUFFIX", true));
842 pirjv.setSelected(Cache.getDefault("PIR_JVSUFFIX", true));
843 modellerOutput.setSelected(Cache.getDefault("PIR_MODELLER", false));
845 .setSelected(Cache.getDefault("EXPORT_EMBBED_BIOJSON", true));
848 * Set Editing tab defaults
850 autoCalculateConsCheck
851 .setSelected(Cache.getDefault("AUTO_CALC_CONSENSUS", true));
852 padGaps.setSelected(Cache.getDefault("PAD_GAPS", false));
853 sortByTree.setSelected(Cache.getDefault("SORT_BY_TREE", false));
855 annotations_actionPerformed(null); // update the display of the annotation
860 * Set Backups tab defaults
862 loadLastSavedBackupsOptions();
866 * A helper method that sets the items and initial selection in a character
867 * rendering option list (Prompt each time/Lineart/Text)
872 protected void setupOutputCombo(JComboBox<Object> comboBox,
875 comboBox.addItem(promptEachTimeOpt);
876 comboBox.addItem(lineArtOpt);
877 comboBox.addItem(textOpt);
880 * JalviewJS doesn't support Lineart so force it to Text
882 String defaultOption = Platform.isJS() ? "Text"
883 : Cache.getDefault(propertyKey, "Prompt each time");
884 if (defaultOption.equalsIgnoreCase("Text"))
886 comboBox.setSelectedItem(textOpt);
888 else if (defaultOption.equalsIgnoreCase("Lineart"))
890 comboBox.setSelectedItem(lineArtOpt);
894 comboBox.setSelectedItem(promptEachTimeOpt);
899 * Save user selections on the Preferences tabs to the Cache and write out to
905 public void ok_actionPerformed(ActionEvent e)
907 if (!validateSettings())
913 * Set proxy settings first (to be before web services refresh)
917 * Save Visual settings
919 Cache.setPropertyNoSave("SHOW_JVSUFFIX",
920 Boolean.toString(seqLimit.isSelected()));
921 Cache.setPropertyNoSave("RIGHT_ALIGN_IDS",
922 Boolean.toString(rightAlign.isSelected()));
923 Cache.setPropertyNoSave("SHOW_FULLSCREEN",
924 Boolean.toString(fullScreen.isSelected()));
925 Cache.setPropertyNoSave("SHOW_OVERVIEW",
926 Boolean.toString(openoverv.isSelected()));
927 Cache.setPropertyNoSave("SHOW_ANNOTATIONS",
928 Boolean.toString(annotations.isSelected()));
929 Cache.setPropertyNoSave("SHOW_CONSERVATION",
930 Boolean.toString(conservation.isSelected()));
931 Cache.setPropertyNoSave("SHOW_QUALITY",
932 Boolean.toString(quality.isSelected()));
933 Cache.setPropertyNoSave("SHOW_IDENTITY",
934 Boolean.toString(identity.isSelected()));
936 Cache.setPropertyNoSave("GAP_SYMBOL",
937 gapSymbolCB.getSelectedItem().toString());
939 Cache.setPropertyNoSave("FONT_NAME",
940 fontNameCB.getSelectedItem().toString());
941 Cache.setPropertyNoSave("FONT_STYLE",
942 fontStyleCB.getSelectedItem().toString());
943 Cache.setPropertyNoSave("FONT_SIZE",
944 fontSizeCB.getSelectedItem().toString());
946 Cache.setPropertyNoSave("ID_ITALICS",
947 Boolean.toString(idItalics.isSelected()));
948 Cache.setPropertyNoSave("SHOW_UNCONSERVED",
949 Boolean.toString(showUnconserved.isSelected()));
950 Cache.setPropertyNoSave(SHOW_OCCUPANCY,
951 Boolean.toString(showOccupancy.isSelected()));
952 Cache.setPropertyNoSave("SHOW_GROUP_CONSENSUS",
953 Boolean.toString(showGroupConsensus.isSelected()));
954 Cache.setPropertyNoSave("SHOW_GROUP_CONSERVATION",
955 Boolean.toString(showGroupConservation.isSelected()));
956 Cache.setPropertyNoSave("SHOW_CONSENSUS_HISTOGRAM",
957 Boolean.toString(showConsensHistogram.isSelected()));
958 Cache.setPropertyNoSave("SHOW_CONSENSUS_LOGO",
959 Boolean.toString(showConsensLogo.isSelected()));
960 Cache.setPropertyNoSave("SHOW_INFORMATION_HISTOGRAM",
961 Boolean.toString(showConsensHistogram.isSelected()));
962 Cache.setPropertyNoSave("SHOW_HMM_LOGO",
963 Boolean.toString(showHMMLogo.isSelected()));
964 Cache.setPropertyNoSave("ANTI_ALIAS",
965 Boolean.toString(smoothFont.isSelected()));
966 Cache.setPropertyNoSave(SCALE_PROTEIN_TO_CDNA,
967 Boolean.toString(scaleProteinToCdna.isSelected()));
968 Cache.setPropertyNoSave("SHOW_NPFEATS_TOOLTIP",
969 Boolean.toString(showNpTooltip.isSelected()));
970 Cache.setPropertyNoSave("SHOW_DBREFS_TOOLTIP",
971 Boolean.toString(showDbRefTooltip.isSelected()));
973 Cache.setPropertyNoSave("WRAP_ALIGNMENT",
974 Boolean.toString(wrap.isSelected()));
976 Cache.setPropertyNoSave("STARTUP_FILE",
977 startupFileTextfield.getText());
978 Cache.setPropertyNoSave("SHOW_STARTUP_FILE",
979 Boolean.toString(startupCheckbox.isSelected()));
981 Cache.setPropertyNoSave("SORT_ALIGNMENT",
982 sortby.getSelectedItem().toString());
984 // convert description of sort order to enum name for save
985 SequenceAnnotationOrder annSortOrder = SequenceAnnotationOrder
986 .forDescription(sortAnnBy.getSelectedItem().toString());
987 if (annSortOrder != null)
989 Cache.setPropertyNoSave(SORT_ANNOTATIONS,
990 annSortOrder.name());
993 final boolean showAutocalcFirst = sortAutocalc.getSelectedIndex() == 0;
994 Cache.setPropertyNoSave(SHOW_AUTOCALC_ABOVE,
995 Boolean.valueOf(showAutocalcFirst).toString());
998 * Save Colours settings
1000 Cache.setPropertyNoSave(DEFAULT_COLOUR_PROT,
1001 protColour.getSelectedItem().toString());
1002 Cache.setPropertyNoSave(DEFAULT_COLOUR_NUC,
1003 nucColour.getSelectedItem().toString());
1004 Cache.setColourPropertyNoSave("ANNOTATIONCOLOUR_MIN",
1005 minColour.getBackground());
1006 Cache.setColourPropertyNoSave("ANNOTATIONCOLOUR_MAX",
1007 maxColour.getBackground());
1010 * Save HMMER settings
1012 Cache.setPropertyNoSave(HMMALIGN_TRIM_TERMINI,
1013 Boolean.toString(hmmrTrimTermini.isSelected()));
1014 Cache.setPropertyNoSave(HMMINFO_GLOBAL_BACKGROUND,
1015 Boolean.toString(hmmerBackgroundUniprot.isSelected()));
1016 Cache.setPropertyNoSave(HMMSEARCH_SEQCOUNT,
1017 hmmerSequenceCount.getText());
1018 Cache.setOrRemove(HMMER_PATH, hmmerPath.getText());
1019 if (cygwinPath != null)
1021 Cache.setOrRemove(CYGWIN_PATH, cygwinPath.getText());
1023 AlignFrame[] frames = Desktop.getAlignFrames();
1024 if (frames != null && frames.length > 0)
1026 for (AlignFrame f : frames)
1028 f.updateHMMERStatus();
1032 hmmrTrimTermini.setSelected(Cache.getDefault(HMMALIGN_TRIM_TERMINI, false));
1033 if (Cache.getDefault(HMMINFO_GLOBAL_BACKGROUND, false))
1035 hmmerBackgroundUniprot.setSelected(true);
1039 hmmerBackgroundAlignment.setSelected(true);
1042 .setText(Cache.getProperty(HMMSEARCH_SEQCOUNT));
1043 hmmerPath.setText(Cache.getProperty(HMMER_PATH));
1046 * Save Overview settings
1048 Cache.setColourPropertyNoSave(GAP_COLOUR, gapColour.getBackground());
1049 Cache.setColourPropertyNoSave(HIDDEN_COLOUR, hiddenColour.getBackground());
1050 Cache.setPropertyNoSave(USE_LEGACY_GAP,
1051 Boolean.toString(useLegacyGap.isSelected()));
1052 Cache.setPropertyNoSave(SHOW_OV_HIDDEN_AT_START,
1053 Boolean.toString(showHiddenAtStart.isSelected()));
1056 * Save Structure settings
1058 Cache.setPropertyNoSave(ADD_TEMPFACT_ANN,
1059 Boolean.toString(addTempFactor.isSelected()));
1060 Cache.setPropertyNoSave(ADD_SS_ANN,
1061 Boolean.toString(addSecondaryStructure.isSelected()));
1062 Cache.setPropertyNoSave(STRUCT_FROM_PDB,
1063 Boolean.toString(structFromPdb.isSelected()));
1064 if (!Platform.isJS()) {
1065 String viewer = structViewer.getSelectedItem().toString();
1066 String viewerPath = structureViewerPath.getText();
1067 Cache.setPropertyNoSave(STRUCTURE_DISPLAY, viewer);
1068 if (viewer.equals(ViewerType.CHIMERA.name()))
1070 Cache.setOrRemove(CHIMERA_PATH, viewerPath);
1072 else if (viewer.equals(ViewerType.CHIMERAX.name()))
1074 Cache.setOrRemove(CHIMERAX_PATH, viewerPath);
1076 else if (viewer.equals(ViewerType.PYMOL.name()))
1078 Cache.setOrRemove(PYMOL_PATH, viewerPath);
1081 Cache.setPropertyNoSave("MAP_WITH_SIFTS",
1082 Boolean.toString(siftsMapping.isSelected()));
1083 SiftsSettings.setMapWithSifts(siftsMapping.isSelected());
1086 * Save Output settings
1088 Cache.setPropertyNoSave("EPS_RENDERING",
1089 ((OptionsParam) epsRendering.getSelectedItem()).getCode());
1090 Cache.setPropertyNoSave("HTML_RENDERING",
1091 ((OptionsParam) htmlRendering.getSelectedItem()).getCode());
1092 Cache.setPropertyNoSave("SVG_RENDERING",
1093 ((OptionsParam) svgRendering.getSelectedItem()).getCode());
1096 * Save Connections settings
1098 // Proxy settings were already set first (to catch web services)
1099 Cache.setOrRemove("DEFAULT_BROWSER", defaultBrowser.getText());
1101 jalview.util.BrowserLauncher.resetBrowser();
1103 // save user-defined and selected links
1104 String menuLinks = sequenceUrlLinks.writeUrlsAsString(true);
1105 if (menuLinks.isEmpty())
1107 Cache.removePropertyNoSave("SEQUENCE_LINKS");
1111 Cache.setPropertyNoSave("SEQUENCE_LINKS",
1112 menuLinks.toString());
1115 String nonMenuLinks = sequenceUrlLinks.writeUrlsAsString(false);
1116 if (nonMenuLinks.isEmpty())
1118 Cache.removePropertyNoSave("STORED_LINKS");
1122 Cache.setPropertyNoSave("STORED_LINKS",
1123 nonMenuLinks.toString());
1126 Cache.setPropertyNoSave("DEFAULT_URL",
1127 sequenceUrlLinks.getPrimaryUrlId());
1129 Cache.setProperty("VERSION_CHECK",
1130 Boolean.toString(versioncheck.isSelected()));
1131 if (Cache.getProperty("USAGESTATS") != null || usagestats.isSelected())
1133 // default is false - we only set this if the user has actively agreed
1134 Cache.setProperty("USAGESTATS",
1135 Boolean.toString(usagestats.isSelected()));
1137 if (!questionnaire.isSelected())
1139 Cache.setProperty("NOQUESTIONNAIRES", "true");
1143 // special - made easy to edit a property file to disable questionnaires
1144 // by just adding the given line
1145 Cache.removeProperty("NOQUESTIONNAIRES");
1149 * Save Output settings
1151 Cache.setPropertyNoSave("BLC_JVSUFFIX",
1152 Boolean.toString(blcjv.isSelected()));
1153 Cache.setPropertyNoSave("CLUSTAL_JVSUFFIX",
1154 Boolean.toString(clustaljv.isSelected()));
1155 Cache.setPropertyNoSave("FASTA_JVSUFFIX",
1156 Boolean.toString(fastajv.isSelected()));
1157 Cache.setPropertyNoSave("MSF_JVSUFFIX",
1158 Boolean.toString(msfjv.isSelected()));
1159 Cache.setPropertyNoSave("PFAM_JVSUFFIX",
1160 Boolean.toString(pfamjv.isSelected()));
1161 Cache.setPropertyNoSave("PILEUP_JVSUFFIX",
1162 Boolean.toString(pileupjv.isSelected()));
1163 Cache.setPropertyNoSave("PIR_JVSUFFIX",
1164 Boolean.toString(pirjv.isSelected()));
1165 Cache.setPropertyNoSave("PIR_MODELLER",
1166 Boolean.toString(modellerOutput.isSelected()));
1167 Cache.setPropertyNoSave("EXPORT_EMBBED_BIOJSON",
1168 Boolean.toString(embbedBioJSON.isSelected()));
1169 jalview.io.PIRFile.useModellerOutput = modellerOutput.isSelected();
1171 Cache.setPropertyNoSave("FIGURE_AUTOIDWIDTH",
1172 Boolean.toString(autoIdWidth.isSelected()));
1173 userIdWidth_actionPerformed();
1174 Cache.setPropertyNoSave("FIGURE_FIXEDIDWIDTH",
1175 userIdWidth.getText());
1178 * Save Editing settings
1180 Cache.setPropertyNoSave("AUTO_CALC_CONSENSUS",
1181 Boolean.toString(autoCalculateConsCheck.isSelected()));
1182 Cache.setPropertyNoSave("SORT_BY_TREE",
1183 Boolean.toString(sortByTree.isSelected()));
1184 Cache.setPropertyNoSave("PAD_GAPS",
1185 Boolean.toString(padGaps.isSelected()));
1187 if (!Platform.isJS())
1189 wsPrefs.updateAndRefreshWsMenuConfig(false);
1193 * Save Backups settings
1195 Cache.setPropertyNoSave(BackupFiles.ENABLED,
1196 Boolean.toString(enableBackupFiles.isSelected()));
1197 int preset = getComboIntStringKey(backupfilesPresetsCombo);
1198 Cache.applicationProperties.setProperty(BackupFiles.NS + "_PRESET", Integer.toString(preset));
1200 if (preset == BackupFilesPresetEntry.BACKUPFILESSCHEMECUSTOM)
1202 BackupFilesPresetEntry customBFPE = getBackupfilesCurrentEntry();
1203 BackupFilesPresetEntry.backupfilesPresetEntriesValues.put(
1204 BackupFilesPresetEntry.BACKUPFILESSCHEMECUSTOM, customBFPE);
1205 Cache.applicationProperties
1206 .setProperty(BackupFilesPresetEntry.CUSTOMCONFIG,
1207 customBFPE.toString());
1210 BackupFilesPresetEntry savedBFPE = BackupFilesPresetEntry.backupfilesPresetEntriesValues
1212 Cache.setPropertyNoSave(
1213 BackupFilesPresetEntry.SAVEDCONFIG, savedBFPE.toString());
1215 Cache.saveProperties();
1216 Desktop.getInstance().doConfigureStructurePrefs();
1219 frame.setClosed(true);
1220 } catch (Exception ex)
1224 public void saveProxySettings()
1226 String newProxyType = customProxy.isSelected() ? Cache.PROXYTYPE_CUSTOM
1227 : noProxy.isSelected() ? Cache.PROXYTYPE_NONE
1228 : Cache.PROXYTYPE_SYSTEM;
1229 Cache.setPropertyNoSave("USE_PROXY", newProxyType);
1230 Cache.setOrRemove("PROXY_SERVER", proxyServerHttpTB.getText());
1231 Cache.setOrRemove("PROXY_PORT", proxyPortHttpTB.getText());
1232 Cache.setOrRemove("PROXY_SERVER_HTTPS", proxyServerHttpsTB.getText());
1233 Cache.setOrRemove("PROXY_PORT_HTTPS", proxyPortHttpsTB.getText());
1234 Cache.setOrRemove("PROXY_AUTH",
1235 Boolean.toString(proxyAuth.isSelected()));
1236 Cache.setOrRemove("PROXY_AUTH_USERNAME", proxyAuthUsernameTB.getText());
1237 Cache.proxyAuthPassword = proxyAuthPasswordPB.getPassword();
1238 Cache.setProxyPropertiesFromPreferences(previousProxyType);
1239 if (newProxyType.equals(Cache.PROXYTYPE_CUSTOM)
1240 || !newProxyType.equals(previousProxyType))
1242 // force a re-lookup of ws if proxytype is custom or has changed
1245 previousProxyType = newProxyType;
1248 public static void setAppletDefaults()
1251 // http://www.jalview.org/old/v2_8/examples/appletParameters.html
1253 // showConservation true or false Default is true.
1254 // showQuality true or false Default is true.
1255 // showConsensus true or false Default is true.
1256 // showFeatureSettings true or false Shows the feature settings window when
1258 // showTreeBootstraps true or false (default is true) show or hide branch
1260 // showTreeDistances true or false (default is true) show or hide branch
1262 // showUnlinkedTreeNodes true or false (default is false) indicate if
1263 // unassociated nodes should be highlighted in the tree view
1264 // showUnconserved true of false (default is false) When true, only gaps and
1265 // symbols different to the consensus sequence ions of the alignment
1266 // showGroupConsensus true of false (default is false) When true, shows
1267 // consensus annotation row for any groups on the alignment. (since 2.7)
1268 // showGroupConservation true of false (default is false) When true, shows
1269 // amino-acid property conservation annotation row for any groups on the
1270 // showConsensusHistogram true of false (default is true) When true, shows
1271 // the percentage occurence of the consensus symbol for each column as a
1272 // showSequenceLogo true of false (default is false) When true, shows a
1273 // sequence logo above the consensus sequence (overlaid above the Consensus
1275 Cache.setPropertyNoSave(SHOW_CONSERVATION, "true");
1276 Cache.setPropertyNoSave(SHOW_QUALITY, "false");
1277 Cache.setPropertyNoSave(SHOW_CONSENSUS, "true");
1278 Cache.setPropertyNoSave(SHOW_UNCONSERVED, "false");
1279 Cache.setPropertyNoSave(SHOW_GROUP_CONSERVATION, "false");
1280 Cache.setPropertyNoSave(SHOW_GROUP_CONSENSUS, "false");
1282 // TODO -- just a start here
1285 * Do any necessary validation before saving settings. Return focus to the
1286 * first tab which fails validation.
1290 private boolean validateSettings()
1292 if (!validateStructure())
1294 structureTab.requestFocusInWindow();
1301 protected boolean validateStructure()
1303 return validateViewerPath();
1311 public void startupFileTextfield_mouseClicked()
1313 // TODO: JAL-3048 not needed for Jalview-JS
1314 String fileFormat = Cache.getProperty("DEFAULT_FILE_FORMAT");
1315 JalviewFileChooser chooser = JalviewFileChooser
1316 .forRead(Cache.getProperty("LAST_DIRECTORY"), fileFormat);
1317 chooser.setFileView(new JalviewFileView());
1318 chooser.setDialogTitle(
1319 MessageManager.getString("label.select_startup_file"));
1321 int value = chooser.showOpenDialog(this);
1323 if (value == JalviewFileChooser.APPROVE_OPTION)
1325 FileFormatI format = chooser.getSelectedFormat();
1328 Cache.setPropertyNoSave("DEFAULT_FILE_FORMAT",
1331 startupFileTextfield
1332 .setText(chooser.getSelectedFile().getAbsolutePath());
1343 public void cancel_actionPerformed(ActionEvent e)
1347 if (!Platform.isJS())
1349 wsPrefs.updateWsMenuConfig(true);
1350 wsPrefs.refreshWs_actionPerformed(e);
1352 frame.setClosed(true);
1353 } catch (Exception ex)
1365 public void annotations_actionPerformed(ActionEvent e)
1367 conservation.setEnabled(annotations.isSelected());
1368 quality.setEnabled(annotations.isSelected());
1369 identity.setEnabled(annotations.isSelected());
1370 showOccupancy.setEnabled(annotations.isSelected());
1371 showGroupConsensus.setEnabled(annotations.isSelected());
1372 showGroupConservation.setEnabled(annotations.isSelected());
1373 showConsensHistogram.setEnabled(annotations.isSelected()
1374 && (identity.isSelected() || showGroupConsensus.isSelected()));
1375 showConsensLogo.setEnabled(annotations.isSelected()
1376 && (identity.isSelected() || showGroupConsensus.isSelected()));
1377 showInformationHistogram.setEnabled(annotations.isSelected());
1378 showHMMLogo.setEnabled(annotations.isSelected());
1382 public void newLink_actionPerformed(ActionEvent e)
1384 GSequenceLink link = new GSequenceLink();
1385 boolean valid = false;
1388 if (JvOptionPane.showInternalConfirmDialog(Desktop.getDesktopPane(), link,
1389 MessageManager.getString("label.new_sequence_url_link"),
1390 JvOptionPane.OK_CANCEL_OPTION, -1,
1391 null) == JvOptionPane.OK_OPTION)
1393 if (link.checkValid())
1395 if (((UrlLinkTableModel) linkUrlTable.getModel())
1396 .isUniqueName(link.getName()))
1398 ((UrlLinkTableModel) linkUrlTable.getModel())
1399 .insertRow(link.getName(), link.getURL());
1404 link.notifyDuplicate();
1417 public void editLink_actionPerformed(ActionEvent e)
1419 GSequenceLink link = new GSequenceLink();
1421 int index = linkUrlTable.getSelectedRow();
1424 // button no longer enabled if row is not selected
1425 Cache.log.debug("Edit with no row selected in linkUrlTable");
1429 int nameCol = ((UrlLinkTableModel) linkUrlTable.getModel())
1431 int urlCol = ((UrlLinkTableModel) linkUrlTable.getModel())
1433 String oldName = linkUrlTable.getValueAt(index, nameCol).toString();
1434 link.setName(oldName);
1435 link.setURL(linkUrlTable.getValueAt(index, urlCol).toString());
1437 boolean valid = false;
1440 if (JvOptionPane.showInternalConfirmDialog(Desktop.getDesktopPane(), link,
1441 MessageManager.getString("label.edit_sequence_url_link"),
1442 JvOptionPane.OK_CANCEL_OPTION, -1,
1443 null) == JvOptionPane.OK_OPTION)
1445 if (link.checkValid())
1447 if ((oldName.equals(link.getName()))
1448 || (((UrlLinkTableModel) linkUrlTable.getModel())
1449 .isUniqueName(link.getName())))
1451 linkUrlTable.setValueAt(link.getName(), index, nameCol);
1452 linkUrlTable.setValueAt(link.getURL(), index, urlCol);
1457 link.notifyDuplicate();
1470 public void deleteLink_actionPerformed(ActionEvent e)
1472 int index = linkUrlTable.getSelectedRow();
1473 int modelIndex = -1;
1476 // button no longer enabled if row is not selected
1477 Cache.log.debug("Delete with no row selected in linkUrlTable");
1482 modelIndex = linkUrlTable.convertRowIndexToModel(index);
1485 // make sure we use the model index to delete, and not the table index
1486 ((UrlLinkTableModel) linkUrlTable.getModel()).removeRow(modelIndex);
1490 public void defaultBrowser_mouseClicked(MouseEvent e)
1492 // TODO: JAL-3048 not needed for j2s
1493 if (!Platform.isJS()) // BH 2019
1500 JFileChooser chooser = new JFileChooser(".");
1501 chooser.setDialogTitle(
1502 MessageManager.getString("label.select_default_browser"));
1504 int value = chooser.showOpenDialog(this);
1506 if (value == JFileChooser.APPROVE_OPTION)
1508 defaultBrowser.setText(chooser.getSelectedFile().getAbsolutePath());
1517 * jalview.jbgui.GPreferences#showunconserved_actionPerformed(java.awt.event
1521 protected void showunconserved_actionPerformed(ActionEvent e)
1523 // TODO Auto-generated method stub
1524 super.showunconserved_actionPerformed(e);
1527 public static List<String> getGroupURLLinks()
1529 return groupURLLinks;
1533 public void minColour_actionPerformed(JPanel panel)
1535 JalviewColourChooser.showColourChooser(this,
1536 MessageManager.getString("label.select_colour_minimum_value"),
1541 public void maxColour_actionPerformed(JPanel panel)
1543 JalviewColourChooser.showColourChooser(this,
1544 MessageManager.getString("label.select_colour_maximum_value"),
1549 public void gapColour_actionPerformed(JPanel gap)
1551 if (!useLegacyGap.isSelected())
1553 JalviewColourChooser.showColourChooser(this,
1554 MessageManager.getString("label.select_gap_colour"),
1560 public void hiddenColour_actionPerformed(JPanel hidden)
1562 JalviewColourChooser.showColourChooser(this,
1563 MessageManager.getString("label.select_hidden_colour"),
1568 protected void useLegacyGaps_actionPerformed(ActionEvent e)
1570 boolean enabled = useLegacyGap.isSelected();
1573 gapColour.setBackground(
1574 jalview.renderer.OverviewResColourFinder.OVERVIEW_DEFAULT_LEGACY_GAP);
1578 gapColour.setBackground(
1579 jalview.renderer.OverviewResColourFinder.OVERVIEW_DEFAULT_GAP);
1581 gapColour.setEnabled(!enabled);
1582 gapLabel.setEnabled(!enabled);
1586 protected void resetOvDefaults_actionPerformed(ActionEvent e)
1588 useLegacyGap.setSelected(false);
1589 useLegacyGaps_actionPerformed(null);
1590 showHiddenAtStart.setSelected(false);
1591 hiddenColour.setBackground(
1592 jalview.renderer.OverviewResColourFinder.OVERVIEW_DEFAULT_HIDDEN);
1596 protected void userIdWidth_actionPerformed()
1600 String val = userIdWidth.getText().trim();
1601 if (val.length() > 0)
1603 Integer iw = Integer.parseInt(val);
1604 if (iw.intValue() < 12)
1606 throw new NumberFormatException();
1608 userIdWidth.setText(iw.toString());
1610 } catch (NumberFormatException x)
1612 userIdWidth.setText("");
1613 JvOptionPane.showInternalMessageDialog(Desktop.getDesktopPane(),
1615 .getString("warn.user_defined_width_requirements"),
1616 MessageManager.getString("label.invalid_id_column_width"),
1617 JvOptionPane.WARNING_MESSAGE);
1622 protected void autoIdWidth_actionPerformed()
1624 userIdWidth.setEnabled(!autoIdWidth.isSelected());
1625 userIdWidthlabel.setEnabled(!autoIdWidth.isSelected());
1629 * Returns true if structure viewer path is to a valid executable, else shows an
1630 * error dialog. Does nothing if the path is empty, as is the case for Jmol
1631 * (built in to Jalview) or when Jalview is left to try default paths.
1633 private boolean validateViewerPath()
1635 if (structureViewerPath.getText().trim().length() > 0)
1637 File f = new File(structureViewerPath.getText());
1638 if (!f.canExecute())
1640 JvOptionPane.showInternalMessageDialog(Desktop.getDesktopPane(),
1641 MessageManager.getString("label.invalid_viewer_path"),
1642 MessageManager.getString("label.invalid_viewer_path"),
1643 JvOptionPane.ERROR_MESSAGE);
1651 * Returns true if the given text field contains a path to a folder that
1652 * contains an executable with the given name, else false (after showing a
1653 * warning dialog). The executable name will be tried with .exe appended if not
1659 protected boolean validateExecutablePath(JTextField textField, String executable)
1661 String folder = textField.getText().trim();
1663 if (FileUtils.getExecutable(executable, folder) != null)
1667 if (folder.length() > 0)
1669 JvOptionPane.showInternalMessageDialog(Desktop.getInstance(),
1670 MessageManager.formatMessage("label.executable_not_found",
1672 MessageManager.getString("label.invalid_folder"),
1673 JvOptionPane.ERROR_MESSAGE);
1679 * Checks if a file can be executed
1682 * the path to the file
1685 public boolean canExecute(String path)
1687 File file = new File(path);
1688 if (!file.canExecute())
1690 file = new File(path + ".exe");
1692 if (!file.canExecute())
1702 * If Chimera or ChimeraX or Pymol is selected, check it can be found on default
1703 * or user-specified path, if not show a warning/help dialog
1706 protected void structureViewer_actionPerformed(String selectedItem)
1708 if (selectedItem.equals(ViewerType.JMOL.name()))
1710 structureViewerPath.setEnabled(false);
1711 structureViewerPathLabel.setEnabled(false);
1714 boolean found = false;
1715 structureViewerPath.setEnabled(true);
1716 structureViewerPathLabel.setEnabled(true);
1717 structureViewerPathLabel.setText(MessageManager
1718 .formatMessage("label.viewer_path", selectedItem));
1721 * Try user-specified and standard paths for structure viewer executable
1723 String viewerPath = "";
1724 List<String> paths = null;
1727 ViewerType viewerType = ViewerType.valueOf(selectedItem);
1734 viewerPath = Cache.getDefault(CHIMERA_PATH, "");
1735 paths = StructureManager.getChimeraPaths(false);
1738 viewerPath = Cache.getDefault(CHIMERAX_PATH, "");
1739 paths = StructureManager.getChimeraPaths(true);
1742 viewerPath = Cache.getDefault(PYMOL_PATH, "");
1743 paths = PymolManager.getPymolPaths();
1746 } catch (IllegalArgumentException e)
1748 // only valid entries should be in the drop-down
1750 structureViewerPath.setText(viewerPath);
1752 paths.add(0, structureViewerPath.getText());
1753 for (String path : paths)
1755 if (new File(path.trim()).canExecute())
1763 String[] options = { "OK", "Help" };
1764 int showHelp = JvOptionPane.showInternalOptionDialog(Desktop.getDesktopPane(),
1765 JvSwingUtils.wrapTooltip(true,
1766 MessageManager.getString("label.viewer_missing")),
1767 "", JvOptionPane.YES_NO_OPTION, JvOptionPane.WARNING_MESSAGE,
1768 null, options, options[0]);
1769 if (showHelp == JvOptionPane.NO_OPTION)
1771 this.selectTab(Preferences.TabRef.STRUCTURE_TAB, null);
1774 Help.showHelpWindow(HelpId.StructureViewer);
1775 } catch (HelpSetException e)
1777 e.printStackTrace();
1780 else if (showHelp == JvOptionPane.OK_OPTION)
1782 this.selectTab(Preferences.TabRef.STRUCTURE_TAB, null);
1783 CompletableFuture<Void> cf = CompletableFuture.runAsync(() -> {
1786 for (int i = 0; i < 3; i++)
1788 structureViewerPath.setBackground(Color.PINK);
1790 structureViewerPath.setBackground(Color.WHITE);
1793 } catch (InterruptedException e)
1802 protected void validateHmmerPath()
1804 validateExecutablePath(hmmerPath, HmmerCommand.HMMBUILD);
1808 protected void validateCygwinPath()
1810 validateExecutablePath(cygwinPath, "run");
1813 public class OptionsParam
1815 private String name;
1817 private String code;
1819 public OptionsParam(String name, String code)
1825 public String getName()
1830 public void setName(String name)
1835 public String getCode()
1840 public void setCode(String code)
1846 public String toString()
1852 public boolean equals(Object that)
1854 if (!(that instanceof OptionsParam))
1858 return this.code.equalsIgnoreCase(((OptionsParam) that).code);
1862 public int hashCode()
1864 return name.hashCode() + code.hashCode();
1868 private class UrlListSelectionHandler implements ListSelectionListener
1872 public void valueChanged(ListSelectionEvent e)
1874 ListSelectionModel lsm = (ListSelectionModel) e.getSource();
1876 int index = lsm.getMinSelectionIndex();
1879 // no selection, so disable delete/edit buttons
1880 editLink.setEnabled(false);
1881 deleteLink.setEnabled(false);
1884 int modelIndex = linkUrlTable.convertRowIndexToModel(index);
1886 // enable/disable edit and delete link buttons
1887 if (((UrlLinkTableModel) linkUrlTable.getModel())
1888 .isRowDeletable(modelIndex))
1890 deleteLink.setEnabled(true);
1894 deleteLink.setEnabled(false);
1897 if (((UrlLinkTableModel) linkUrlTable.getModel())
1898 .isRowEditable(modelIndex))
1900 editLink.setEnabled(true);
1904 editLink.setEnabled(false);