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.
23 import java.awt.BorderLayout;
24 import java.awt.Color;
25 import java.awt.Component;
26 import java.awt.Dimension;
28 import java.awt.event.ActionEvent;
29 import java.awt.event.ActionListener;
30 import java.awt.event.MouseEvent;
32 import java.util.ArrayList;
33 import java.util.List;
35 import javax.help.HelpSetException;
36 import javax.swing.JComboBox;
37 import javax.swing.JFileChooser;
38 import javax.swing.JInternalFrame;
39 import javax.swing.JPanel;
40 import javax.swing.ListSelectionModel;
41 import javax.swing.RowFilter;
42 import javax.swing.RowSorter;
43 import javax.swing.SortOrder;
44 import javax.swing.event.DocumentEvent;
45 import javax.swing.event.DocumentListener;
46 import javax.swing.event.ListSelectionEvent;
47 import javax.swing.event.ListSelectionListener;
48 import javax.swing.table.TableCellRenderer;
49 import javax.swing.table.TableColumn;
50 import javax.swing.table.TableModel;
51 import javax.swing.table.TableRowSorter;
53 import ext.edu.ucsf.rbvi.strucviz2.StructureManager;
54 import jalview.analysis.AnnotationSorter.SequenceAnnotationOrder;
55 import jalview.bin.Cache;
56 import jalview.ext.pymol.PymolManager;
57 import jalview.gui.Help.HelpId;
58 import jalview.gui.StructureViewer.ViewerType;
59 import jalview.io.BackupFiles;
60 import jalview.io.BackupFilesPresetEntry;
61 import jalview.io.FileFormatI;
62 import jalview.io.JalviewFileChooser;
63 import jalview.io.JalviewFileView;
64 import jalview.jbgui.GPreferences;
65 import jalview.jbgui.GSequenceLink;
66 import jalview.schemes.ColourSchemeI;
67 import jalview.schemes.ColourSchemes;
68 import jalview.schemes.ResidueColourScheme;
69 import jalview.urls.UrlLinkTableModel;
70 import jalview.urls.api.UrlProviderFactoryI;
71 import jalview.urls.api.UrlProviderI;
72 import jalview.urls.desktop.DesktopUrlProviderFactory;
73 import jalview.util.MessageManager;
74 import jalview.util.Platform;
75 import jalview.util.UrlConstants;
76 import jalview.ws.sifts.SiftsSettings;
84 public class Preferences extends GPreferences
86 public static final String ENABLE_SPLIT_FRAME = "ENABLE_SPLIT_FRAME";
88 public static final String SCALE_PROTEIN_TO_CDNA = "SCALE_PROTEIN_TO_CDNA";
90 public static final String DEFAULT_COLOUR = "DEFAULT_COLOUR";
92 public static final String DEFAULT_COLOUR_PROT = "DEFAULT_COLOUR_PROT";
94 public static final String DEFAULT_COLOUR_NUC = "DEFAULT_COLOUR_NUC";
96 public static final String ADD_TEMPFACT_ANN = "ADD_TEMPFACT_ANN";
98 public static final String ADD_SS_ANN = "ADD_SS_ANN";
100 public static final String USE_RNAVIEW = "USE_RNAVIEW";
102 public static final String STRUCT_FROM_PDB = "STRUCT_FROM_PDB";
104 public static final String STRUCTURE_DISPLAY = "STRUCTURE_DISPLAY";
106 public static final String CHIMERA_PATH = "CHIMERA_PATH";
108 public static final String CHIMERAX_PATH = "CHIMERAX_PATH";
110 public static final String PYMOL_PATH = "PYMOL_PATH";
112 public static final String SORT_ANNOTATIONS = "SORT_ANNOTATIONS";
114 public static final String SHOW_AUTOCALC_ABOVE = "SHOW_AUTOCALC_ABOVE";
116 public static final String SHOW_OCCUPANCY = "SHOW_OCCUPANCY";
118 public static final String SHOW_OV_HIDDEN_AT_START = "SHOW_OV_HIDDEN_AT_START";
120 public static final String USE_LEGACY_GAP = "USE_LEGACY_GAP";
122 public static final String GAP_COLOUR = "GAP_COLOUR";
124 public static final String HIDDEN_COLOUR = "HIDDEN_COLOUR";
126 private static final int MIN_FONT_SIZE = 1;
128 private static final int MAX_FONT_SIZE = 30;
131 * Holds name and link separated with | character. Sequence ID must be
132 * $SEQUENCE_ID$ or $SEQUENCE_ID=/.possible | chars ./=$
134 public static UrlProviderI sequenceUrlLinks;
136 public static UrlLinkTableModel dataModel;
139 * Holds name and link separated with | character. Sequence IDS and Sequences
140 * must be $SEQUENCEIDS$ or $SEQUENCEIDS=/.possible | chars ./=$ and
141 * $SEQUENCES$ or $SEQUENCES=/.possible | chars ./=$ and separation character
142 * for first and second token specified after a pipe character at end |,|.
143 * (TODO: proper escape for using | to separate ids or sequences
146 public static List<String> groupURLLinks;
149 // get links selected to be in the menu (SEQUENCE_LINKS)
150 // and links entered by the user but not selected (STORED_LINKS)
151 String inMenuString = Cache.getDefault("SEQUENCE_LINKS", "");
152 String notInMenuString = Cache.getDefault("STORED_LINKS", "");
153 String defaultUrl = Cache.getDefault("DEFAULT_URL",
154 UrlConstants.DEFAULT_LABEL);
156 // if both links lists are empty, add the DEFAULT_URL link
157 // otherwise we assume the default link is in one of the lists
158 if (inMenuString.isEmpty() && notInMenuString.isEmpty())
160 inMenuString = UrlConstants.DEFAULT_STRING;
162 UrlProviderFactoryI factory = new DesktopUrlProviderFactory(defaultUrl,
163 inMenuString, notInMenuString);
164 sequenceUrlLinks = factory.createUrlProvider();
165 dataModel = new UrlLinkTableModel(sequenceUrlLinks);
168 * TODO: reformulate groupURL encoding so two or more can be stored in the
169 * .properties file as '|' separated strings
172 groupURLLinks = new ArrayList<>();
175 JInternalFrame frame;
177 private WsPreferences wsPrefs;
179 private OptionsParam promptEachTimeOpt = new OptionsParam(
180 MessageManager.getString("label.prompt_each_time"),
183 private OptionsParam lineArtOpt = new OptionsParam(
184 MessageManager.getString("label.lineart"), "Lineart");
186 private OptionsParam textOpt = new OptionsParam(
187 MessageManager.getString("action.text"), "Text");
190 * Creates a new Preferences object.
195 frame = new JInternalFrame();
196 frame.setContentPane(this);
197 if (!Platform.isJS())
204 wsPrefs = new WsPreferences();
205 wsTab.add(wsPrefs, BorderLayout.CENTER);
207 int width = 500, height = 450;
208 if (Platform.isAMacAndNotJS())
214 Desktop.addInternalFrame(frame,
215 MessageManager.getString("label.preferences"), width, height);
216 frame.setMinimumSize(new Dimension(width, height));
219 * Set Visual tab defaults
221 seqLimit.setSelected(Cache.getDefault("SHOW_JVSUFFIX", true));
222 rightAlign.setSelected(Cache.getDefault("RIGHT_ALIGN_IDS", false));
223 fullScreen.setSelected(Cache.getDefault("SHOW_FULLSCREEN", false));
224 annotations.setSelected(Cache.getDefault("SHOW_ANNOTATIONS", true));
226 conservation.setSelected(Cache.getDefault("SHOW_CONSERVATION", true));
227 quality.setSelected(Cache.getDefault("SHOW_QUALITY", true));
228 identity.setSelected(Cache.getDefault("SHOW_IDENTITY", true));
229 openoverv.setSelected(Cache.getDefault("SHOW_OVERVIEW", false));
231 .setSelected(Cache.getDefault("SHOW_UNCONSERVED", false));
232 showOccupancy.setSelected(Cache.getDefault(SHOW_OCCUPANCY, false));
234 .setSelected(Cache.getDefault("SHOW_GROUP_CONSENSUS", false));
235 showGroupConservation.setSelected(
236 Cache.getDefault("SHOW_GROUP_CONSERVATION", false));
237 showConsensHistogram.setSelected(
238 Cache.getDefault("SHOW_CONSENSUS_HISTOGRAM", true));
240 .setSelected(Cache.getDefault("SHOW_CONSENSUS_LOGO", false));
242 .setSelected(Cache.getDefault("SHOW_NPFEATS_TOOLTIP", true));
244 .setSelected(Cache.getDefault("SHOW_DBREFS_TOOLTIP", true));
246 String[] fonts = java.awt.GraphicsEnvironment
247 .getLocalGraphicsEnvironment().getAvailableFontFamilyNames();
248 for (int i = 0; i < fonts.length; i++)
250 fontNameCB.addItem(fonts[i]);
253 for (int i = MIN_FONT_SIZE; i <= MAX_FONT_SIZE; i++)
255 fontSizeCB.addItem(i + "");
258 fontStyleCB.addItem("plain");
259 fontStyleCB.addItem("bold");
260 fontStyleCB.addItem("italic");
262 fontNameCB.setSelectedItem(Cache.getDefault("FONT_NAME", "SansSerif"));
263 fontSizeCB.setSelectedItem(Cache.getDefault("FONT_SIZE", "10"));
264 fontStyleCB.setSelectedItem(
265 Cache.getDefault("FONT_STYLE", Font.PLAIN + ""));
267 smoothFont.setSelected(Cache.getDefault("ANTI_ALIAS", true));
269 .setSelected(Cache.getDefault(SCALE_PROTEIN_TO_CDNA, false));
271 idItalics.setSelected(Cache.getDefault("ID_ITALICS", true));
273 wrap.setSelected(Cache.getDefault("WRAP_ALIGNMENT", false));
275 gapSymbolCB.addItem("-");
276 gapSymbolCB.addItem(".");
278 gapSymbolCB.setSelectedItem(Cache.getDefault("GAP_SYMBOL", "-"));
280 sortby.addItem("No sort");
281 sortby.addItem("Id");
282 sortby.addItem("Pairwise Identity");
283 sortby.setSelectedItem(Cache.getDefault("SORT_ALIGNMENT", "No sort"));
285 sortAnnBy.addItem(SequenceAnnotationOrder.NONE.toString());
287 .addItem(SequenceAnnotationOrder.SEQUENCE_AND_LABEL.toString());
289 .addItem(SequenceAnnotationOrder.LABEL_AND_SEQUENCE.toString());
290 SequenceAnnotationOrder savedSort = SequenceAnnotationOrder
291 .valueOf(Cache.getDefault(SORT_ANNOTATIONS,
292 SequenceAnnotationOrder.NONE.name()));
293 sortAnnBy.setSelectedItem(savedSort.toString());
295 sortAutocalc.addItem("Autocalculated first");
296 sortAutocalc.addItem("Autocalculated last");
297 final boolean showAbove = Cache.getDefault(SHOW_AUTOCALC_ABOVE, true);
298 sortAutocalc.setSelectedItem(showAbove ? sortAutocalc.getItemAt(0)
299 : sortAutocalc.getItemAt(1));
301 .setSelected(Cache.getDefault("SHOW_STARTUP_FILE", true));
302 startupFileTextfield.setText(Cache.getDefault("STARTUP_FILE",
303 Cache.getDefault("www.jalview.org", "http://www.jalview.org")
304 + "/examples/exampleFile_2_3.jar"));
307 * Set Colours tab defaults
309 protColour.addItem(ResidueColourScheme.NONE);
310 nucColour.addItem(ResidueColourScheme.NONE);
311 for (ColourSchemeI cs : ColourSchemes.getInstance().getColourSchemes())
313 String name = cs.getSchemeName();
314 protColour.addItem(name);
315 nucColour.addItem(name);
317 String oldProp = Cache.getDefault(DEFAULT_COLOUR,
318 ResidueColourScheme.NONE);
319 String newProp = Cache.getDefault(DEFAULT_COLOUR_PROT, null);
320 protColour.setSelectedItem(newProp != null ? newProp : oldProp);
321 newProp = Cache.getDefault(DEFAULT_COLOUR_NUC, null);
322 nucColour.setSelectedItem(newProp != null ? newProp : oldProp);
323 minColour.setBackground(
324 Cache.getDefaultColour("ANNOTATIONCOLOUR_MIN", Color.orange));
325 maxColour.setBackground(
326 Cache.getDefaultColour("ANNOTATIONCOLOUR_MAX", Color.red));
329 * Set overview panel defaults
331 gapColour.setBackground(
332 Cache.getDefaultColour(GAP_COLOUR,
333 jalview.renderer.OverviewResColourFinder.OVERVIEW_DEFAULT_GAP));
334 hiddenColour.setBackground(
335 Cache.getDefaultColour(HIDDEN_COLOUR,
336 jalview.renderer.OverviewResColourFinder.OVERVIEW_DEFAULT_HIDDEN));
337 useLegacyGap.setSelected(Cache.getDefault(USE_LEGACY_GAP, false));
338 gapLabel.setEnabled(!useLegacyGap.isSelected());
339 gapColour.setEnabled(!useLegacyGap.isSelected());
341 .setSelected(Cache.getDefault(SHOW_OV_HIDDEN_AT_START, false));
344 * Set Structure tab defaults
346 final boolean structSelected = Cache.getDefault(STRUCT_FROM_PDB, false);
347 structFromPdb.setSelected(structSelected);
348 useRnaView.setSelected(Cache.getDefault(USE_RNAVIEW, false));
349 useRnaView.setEnabled(structSelected);
350 addSecondaryStructure.setSelected(Cache.getDefault(ADD_SS_ANN, false));
351 addSecondaryStructure.setEnabled(structSelected);
352 addTempFactor.setSelected(Cache.getDefault(ADD_TEMPFACT_ANN, false));
353 addTempFactor.setEnabled(structSelected);
356 * set choice of structure viewer, and path if saved as a preference;
357 * default to Jmol (first choice) if an unexpected value is found
359 String viewerType = Cache.getDefault(STRUCTURE_DISPLAY, ViewerType.JMOL.name());
360 structViewer.setSelectedItem(viewerType);
361 String viewerPath = "";
362 ViewerType type = null;
365 type = ViewerType.valueOf(viewerType);
371 viewerPath = Cache.getDefault(CHIMERA_PATH, "");
374 viewerPath = Cache.getDefault(CHIMERAX_PATH, "");
377 viewerPath = Cache.getDefault(PYMOL_PATH, "");
380 } catch (IllegalArgumentException e)
382 Cache.log.error("Unknown structure viewer type: " + viewerType
383 + ", defaulting to Jmol");
384 type = ViewerType.JMOL;
386 structureViewerPath.setText(viewerPath);
388 structureViewerPath.addActionListener(new ActionListener()
391 public void actionPerformed(ActionEvent e)
393 if (validateViewerPath())
395 Cache.setProperty(structViewer.getSelectedItem()
396 .equals(ViewerType.CHIMERAX.name())
398 : CHIMERA_PATH, structureViewerPath.getText());
403 if (Cache.getDefault("MAP_WITH_SIFTS", false))
405 siftsMapping.setSelected(true);
409 nwMapping.setSelected(true);
413 .setMapWithSifts(Cache.getDefault("MAP_WITH_SIFTS", false));
416 * Set Connections tab defaults
420 linkUrlTable.setModel(dataModel);
421 final TableRowSorter<TableModel> sorter = new TableRowSorter<>(
422 linkUrlTable.getModel());
423 linkUrlTable.setRowSorter(sorter);
424 List<RowSorter.SortKey> sortKeys = new ArrayList<>();
426 UrlLinkTableModel m = (UrlLinkTableModel) linkUrlTable.getModel();
427 sortKeys.add(new RowSorter.SortKey(m.getPrimaryColumn(),
428 SortOrder.DESCENDING));
429 sortKeys.add(new RowSorter.SortKey(m.getSelectedColumn(),
430 SortOrder.DESCENDING));
432 new RowSorter.SortKey(m.getNameColumn(), SortOrder.ASCENDING));
434 sorter.setSortKeys(sortKeys);
435 // BH 2018 setSortKeys will do the sort
439 ActionListener onReset;
440 onReset = new ActionListener()
443 public void actionPerformed(ActionEvent e)
445 filterTB.setText("");
446 sorter.setRowFilter(RowFilter.regexFilter(""));
450 doReset.addActionListener(onReset);
452 // filter to display only custom urls
453 final RowFilter<TableModel, Object> customUrlFilter = new RowFilter<TableModel, Object>()
456 public boolean include(
457 Entry<? extends TableModel, ? extends Object> entry)
459 return ((UrlLinkTableModel) entry.getModel()).isUserEntry(entry);
463 final TableRowSorter<TableModel> customSorter = new TableRowSorter<>(
464 linkUrlTable.getModel());
465 customSorter.setRowFilter(customUrlFilter);
467 ActionListener onCustomOnly;
468 onCustomOnly = new ActionListener()
471 public void actionPerformed(ActionEvent e)
473 filterTB.setText("");
474 sorter.setRowFilter(customUrlFilter);
477 userOnly.addActionListener(onCustomOnly);
479 filterTB.getDocument().addDocumentListener(new DocumentListener()
481 String caseInsensitiveFlag = "(?i)";
484 public void changedUpdate(DocumentEvent e)
486 sorter.setRowFilter(RowFilter
487 .regexFilter(caseInsensitiveFlag + filterTB.getText()));
491 public void removeUpdate(DocumentEvent e)
493 sorter.setRowFilter(RowFilter
494 .regexFilter(caseInsensitiveFlag + filterTB.getText()));
498 public void insertUpdate(DocumentEvent e)
500 sorter.setRowFilter(RowFilter
501 .regexFilter(caseInsensitiveFlag + filterTB.getText()));
505 // set up list selection functionality
506 linkUrlTable.getSelectionModel()
507 .addListSelectionListener(new UrlListSelectionHandler());
509 // set up radio buttons
510 int onClickCol = ((UrlLinkTableModel) linkUrlTable.getModel())
512 String onClickName = linkUrlTable.getColumnName(onClickCol);
513 linkUrlTable.getColumn(onClickName)
514 .setCellRenderer(new RadioButtonRenderer());
515 linkUrlTable.getColumn(onClickName)
516 .setCellEditor(new RadioButtonEditor());
518 // get boolean columns and resize those to min possible
519 for (int column = 0; column < linkUrlTable.getColumnCount(); column++)
521 if (linkUrlTable.getModel().getColumnClass(column)
522 .equals(Boolean.class))
524 TableColumn tableColumn = linkUrlTable.getColumnModel()
526 int preferredWidth = tableColumn.getMinWidth();
528 TableCellRenderer cellRenderer = linkUrlTable.getCellRenderer(0,
530 Component c = linkUrlTable.prepareRenderer(cellRenderer, 0, column);
531 int cwidth = c.getPreferredSize().width
532 + linkUrlTable.getIntercellSpacing().width;
533 preferredWidth = Math.max(preferredWidth, cwidth);
535 tableColumn.setPreferredWidth(preferredWidth);
539 String proxyTypeString = Cache.getDefault("USE_PROXY", "false");
540 switch (proxyTypeString)
543 proxyType.setSelected(noProxy.getModel(), true);
546 proxyType.setSelected(systemProxy.getModel(), true);
549 proxyType.setSelected(customProxy.getModel(), true);
552 String message = "Incorrect PROXY_TYPE - should be 'none' (clear proxy properties), 'false' (system settings), 'true' (custom settings): "
554 Cache.log.warn(message);
556 proxyServerHttpTB.setText(Cache.getDefault("PROXY_SERVER", ""));
557 proxyPortHttpTB.setText(Cache.getDefault("PROXY_PORT", ""));
558 proxyServerHttpsTB.setText(Cache.getDefault("PROXY_SERVER_HTTPS", ""));
559 proxyPortHttpsTB.setText(Cache.getDefault("PROXY_PORT_HTTPS", ""));
561 defaultBrowser.setText(Cache.getDefault("DEFAULT_BROWSER", ""));
563 usagestats.setSelected(Cache.getDefault("USAGESTATS", false));
564 // note antisense here: default is true
566 .setSelected(Cache.getProperty("NOQUESTIONNAIRES") == null);
567 versioncheck.setSelected(Cache.getDefault("VERSION_CHECK", true));
570 * Set Output tab defaults
572 setupOutputCombo(epsRendering, "EPS_RENDERING");
573 setupOutputCombo(htmlRendering, "HTML_RENDERING");
574 setupOutputCombo(svgRendering, "SVG_RENDERING");
575 autoIdWidth.setSelected(Cache.getDefault("FIGURE_AUTOIDWIDTH", false));
576 userIdWidth.setEnabled(!autoIdWidth.isSelected());
577 userIdWidthlabel.setEnabled(!autoIdWidth.isSelected());
578 Integer wi = Cache.getIntegerProperty("FIGURE_FIXEDIDWIDTH");
579 userIdWidth.setText(wi == null ? "" : wi.toString());
580 // TODO: refactor to use common enum via FormatAdapter and allow extension
581 // for new flat file formats
582 blcjv.setSelected(Cache.getDefault("BLC_JVSUFFIX", true));
583 clustaljv.setSelected(Cache.getDefault("CLUSTAL_JVSUFFIX", true));
584 fastajv.setSelected(Cache.getDefault("FASTA_JVSUFFIX", true));
585 msfjv.setSelected(Cache.getDefault("MSF_JVSUFFIX", true));
586 pfamjv.setSelected(Cache.getDefault("PFAM_JVSUFFIX", true));
587 pileupjv.setSelected(Cache.getDefault("PILEUP_JVSUFFIX", true));
588 pirjv.setSelected(Cache.getDefault("PIR_JVSUFFIX", true));
589 modellerOutput.setSelected(Cache.getDefault("PIR_MODELLER", false));
591 .setSelected(Cache.getDefault("EXPORT_EMBBED_BIOJSON", true));
594 * Set Editing tab defaults
596 autoCalculateConsCheck
597 .setSelected(Cache.getDefault("AUTO_CALC_CONSENSUS", true));
598 padGaps.setSelected(Cache.getDefault("PAD_GAPS", false));
599 sortByTree.setSelected(Cache.getDefault("SORT_BY_TREE", false));
601 annotations_actionPerformed(null); // update the display of the annotation
606 * Set Backups tab defaults
608 loadLastSavedBackupsOptions();
612 * A helper method that sets the items and initial selection in a character
613 * rendering option list (Prompt each time/Lineart/Text)
618 protected void setupOutputCombo(JComboBox<Object> comboBox,
621 comboBox.addItem(promptEachTimeOpt);
622 comboBox.addItem(lineArtOpt);
623 comboBox.addItem(textOpt);
626 * JalviewJS doesn't support Lineart so force it to Text
628 String defaultOption = Platform.isJS() ? "Text"
629 : Cache.getDefault(propertyKey, "Prompt each time");
630 if (defaultOption.equalsIgnoreCase("Text"))
632 comboBox.setSelectedItem(textOpt);
634 else if (defaultOption.equalsIgnoreCase("Lineart"))
636 comboBox.setSelectedItem(lineArtOpt);
640 comboBox.setSelectedItem(promptEachTimeOpt);
645 * Save user selections on the Preferences tabs to the Cache and write out to
651 public void ok_actionPerformed(ActionEvent e)
653 if (!validateSettings())
659 * Save Visual settings
661 Cache.applicationProperties.setProperty("SHOW_JVSUFFIX",
662 Boolean.toString(seqLimit.isSelected()));
663 Cache.applicationProperties.setProperty("RIGHT_ALIGN_IDS",
664 Boolean.toString(rightAlign.isSelected()));
665 Cache.applicationProperties.setProperty("SHOW_FULLSCREEN",
666 Boolean.toString(fullScreen.isSelected()));
667 Cache.applicationProperties.setProperty("SHOW_OVERVIEW",
668 Boolean.toString(openoverv.isSelected()));
669 Cache.applicationProperties.setProperty("SHOW_ANNOTATIONS",
670 Boolean.toString(annotations.isSelected()));
671 Cache.applicationProperties.setProperty("SHOW_CONSERVATION",
672 Boolean.toString(conservation.isSelected()));
673 Cache.applicationProperties.setProperty("SHOW_QUALITY",
674 Boolean.toString(quality.isSelected()));
675 Cache.applicationProperties.setProperty("SHOW_IDENTITY",
676 Boolean.toString(identity.isSelected()));
678 Cache.applicationProperties.setProperty("GAP_SYMBOL",
679 gapSymbolCB.getSelectedItem().toString());
681 Cache.applicationProperties.setProperty("FONT_NAME",
682 fontNameCB.getSelectedItem().toString());
683 Cache.applicationProperties.setProperty("FONT_STYLE",
684 fontStyleCB.getSelectedItem().toString());
685 Cache.applicationProperties.setProperty("FONT_SIZE",
686 fontSizeCB.getSelectedItem().toString());
688 Cache.applicationProperties.setProperty("ID_ITALICS",
689 Boolean.toString(idItalics.isSelected()));
690 Cache.applicationProperties.setProperty("SHOW_UNCONSERVED",
691 Boolean.toString(showUnconserved.isSelected()));
692 Cache.applicationProperties.setProperty(SHOW_OCCUPANCY,
693 Boolean.toString(showOccupancy.isSelected()));
694 Cache.applicationProperties.setProperty("SHOW_GROUP_CONSENSUS",
695 Boolean.toString(showGroupConsensus.isSelected()));
696 Cache.applicationProperties.setProperty("SHOW_GROUP_CONSERVATION",
697 Boolean.toString(showGroupConservation.isSelected()));
698 Cache.applicationProperties.setProperty("SHOW_CONSENSUS_HISTOGRAM",
699 Boolean.toString(showConsensHistogram.isSelected()));
700 Cache.applicationProperties.setProperty("SHOW_CONSENSUS_LOGO",
701 Boolean.toString(showConsensLogo.isSelected()));
702 Cache.applicationProperties.setProperty("ANTI_ALIAS",
703 Boolean.toString(smoothFont.isSelected()));
704 Cache.applicationProperties.setProperty(SCALE_PROTEIN_TO_CDNA,
705 Boolean.toString(scaleProteinToCdna.isSelected()));
706 Cache.applicationProperties.setProperty("SHOW_NPFEATS_TOOLTIP",
707 Boolean.toString(showNpTooltip.isSelected()));
708 Cache.applicationProperties.setProperty("SHOW_DBREFS_TOOLTIP",
709 Boolean.toString(showDbRefTooltip.isSelected()));
711 Cache.applicationProperties.setProperty("WRAP_ALIGNMENT",
712 Boolean.toString(wrap.isSelected()));
714 Cache.applicationProperties.setProperty("STARTUP_FILE",
715 startupFileTextfield.getText());
716 Cache.applicationProperties.setProperty("SHOW_STARTUP_FILE",
717 Boolean.toString(startupCheckbox.isSelected()));
719 Cache.applicationProperties.setProperty("SORT_ALIGNMENT",
720 sortby.getSelectedItem().toString());
722 // convert description of sort order to enum name for save
723 SequenceAnnotationOrder annSortOrder = SequenceAnnotationOrder
724 .forDescription(sortAnnBy.getSelectedItem().toString());
725 if (annSortOrder != null)
727 Cache.applicationProperties.setProperty(SORT_ANNOTATIONS,
728 annSortOrder.name());
731 final boolean showAutocalcFirst = sortAutocalc.getSelectedIndex() == 0;
732 Cache.applicationProperties.setProperty(SHOW_AUTOCALC_ABOVE,
733 Boolean.valueOf(showAutocalcFirst).toString());
736 * Save Colours settings
738 Cache.applicationProperties.setProperty(DEFAULT_COLOUR_PROT,
739 protColour.getSelectedItem().toString());
740 Cache.applicationProperties.setProperty(DEFAULT_COLOUR_NUC,
741 nucColour.getSelectedItem().toString());
742 Cache.setColourProperty("ANNOTATIONCOLOUR_MIN",
743 minColour.getBackground());
744 Cache.setColourProperty("ANNOTATIONCOLOUR_MAX",
745 maxColour.getBackground());
748 * Save Overview settings
750 Cache.setColourProperty(GAP_COLOUR, gapColour.getBackground());
751 Cache.setColourProperty(HIDDEN_COLOUR, hiddenColour.getBackground());
752 Cache.applicationProperties.setProperty(USE_LEGACY_GAP,
753 Boolean.toString(useLegacyGap.isSelected()));
754 Cache.applicationProperties.setProperty(SHOW_OV_HIDDEN_AT_START,
755 Boolean.toString(showHiddenAtStart.isSelected()));
758 * Save Structure settings
760 Cache.applicationProperties.setProperty(ADD_TEMPFACT_ANN,
761 Boolean.toString(addTempFactor.isSelected()));
762 Cache.applicationProperties.setProperty(ADD_SS_ANN,
763 Boolean.toString(addSecondaryStructure.isSelected()));
764 Cache.applicationProperties.setProperty(USE_RNAVIEW,
765 Boolean.toString(useRnaView.isSelected()));
766 Cache.applicationProperties.setProperty(STRUCT_FROM_PDB,
767 Boolean.toString(structFromPdb.isSelected()));
768 String viewer = structViewer.getSelectedItem().toString();
769 String viewerPath = structureViewerPath.getText();
770 Cache.applicationProperties.setProperty(STRUCTURE_DISPLAY,
772 if (viewer.equals(ViewerType.CHIMERA.name()))
774 Cache.setOrRemove(CHIMERA_PATH, viewerPath);
776 else if (viewer.equals(ViewerType.CHIMERAX.name()))
778 Cache.setOrRemove(CHIMERAX_PATH, viewerPath);
780 else if (viewer.equals(ViewerType.PYMOL.name()))
782 Cache.setOrRemove(PYMOL_PATH, viewerPath);
784 Cache.applicationProperties.setProperty("MAP_WITH_SIFTS",
785 Boolean.toString(siftsMapping.isSelected()));
786 SiftsSettings.setMapWithSifts(siftsMapping.isSelected());
789 * Save Output settings
791 Cache.applicationProperties.setProperty("EPS_RENDERING",
792 ((OptionsParam) epsRendering.getSelectedItem()).getCode());
793 Cache.applicationProperties.setProperty("HTML_RENDERING",
794 ((OptionsParam) htmlRendering.getSelectedItem()).getCode());
795 Cache.applicationProperties.setProperty("SVG_RENDERING",
796 ((OptionsParam) svgRendering.getSelectedItem()).getCode());
799 * Save Connections settings
801 Cache.setOrRemove("DEFAULT_BROWSER", defaultBrowser.getText());
803 jalview.util.BrowserLauncher.resetBrowser();
805 // save user-defined and selected links
806 String menuLinks = sequenceUrlLinks.writeUrlsAsString(true);
807 if (menuLinks.isEmpty())
809 Cache.applicationProperties.remove("SEQUENCE_LINKS");
813 Cache.applicationProperties.setProperty("SEQUENCE_LINKS",
814 menuLinks.toString());
817 String nonMenuLinks = sequenceUrlLinks.writeUrlsAsString(false);
818 if (nonMenuLinks.isEmpty())
820 Cache.applicationProperties.remove("STORED_LINKS");
824 Cache.applicationProperties.setProperty("STORED_LINKS",
825 nonMenuLinks.toString());
828 Cache.applicationProperties.setProperty("DEFAULT_URL",
829 sequenceUrlLinks.getPrimaryUrlId());
831 Cache.applicationProperties.setProperty("USE_PROXY",
832 customProxy.isSelected() ? "true"
833 : noProxy.isSelected() ? "none" : "false");
835 Cache.setOrRemove("PROXY_SERVER", proxyServerHttpTB.getText());
837 Cache.setOrRemove("PROXY_PORT", proxyPortHttpTB.getText());
839 Cache.setOrRemove("PROXY_SERVER_HTTPS", proxyServerHttpsTB.getText());
841 Cache.setOrRemove("PROXY_PORT_HTTPS", proxyPortHttpsTB.getText());
843 if (noProxy.isSelected())
845 Cache.log.warn("Setting no proxy settings");
846 Cache.setProxyProperties(null, null, null, null);
848 else if (customProxy.isSelected())
850 Cache.log.warn("Setting custom proxy settings");
851 Cache.setProxyProperties(proxyServerHttpTB.getText(),
852 proxyPortHttpTB.getText(), proxyServerHttpsTB.getText(),
853 proxyPortHttpsTB.getText());
855 else // systemProxy should be selected and is sensible default
857 Cache.log.warn("Setting system proxy settings");
858 Cache.resetProxyProperties();
861 Cache.setProperty("VERSION_CHECK",
862 Boolean.toString(versioncheck.isSelected()));
863 if (Cache.getProperty("USAGESTATS") != null || usagestats.isSelected())
865 // default is false - we only set this if the user has actively agreed
866 Cache.setProperty("USAGESTATS",
867 Boolean.toString(usagestats.isSelected()));
869 if (!questionnaire.isSelected())
871 Cache.setProperty("NOQUESTIONNAIRES", "true");
875 // special - made easy to edit a property file to disable questionnaires
876 // by just adding the given line
877 Cache.removeProperty("NOQUESTIONNAIRES");
881 * Save Output settings
883 Cache.applicationProperties.setProperty("BLC_JVSUFFIX",
884 Boolean.toString(blcjv.isSelected()));
885 Cache.applicationProperties.setProperty("CLUSTAL_JVSUFFIX",
886 Boolean.toString(clustaljv.isSelected()));
887 Cache.applicationProperties.setProperty("FASTA_JVSUFFIX",
888 Boolean.toString(fastajv.isSelected()));
889 Cache.applicationProperties.setProperty("MSF_JVSUFFIX",
890 Boolean.toString(msfjv.isSelected()));
891 Cache.applicationProperties.setProperty("PFAM_JVSUFFIX",
892 Boolean.toString(pfamjv.isSelected()));
893 Cache.applicationProperties.setProperty("PILEUP_JVSUFFIX",
894 Boolean.toString(pileupjv.isSelected()));
895 Cache.applicationProperties.setProperty("PIR_JVSUFFIX",
896 Boolean.toString(pirjv.isSelected()));
897 Cache.applicationProperties.setProperty("PIR_MODELLER",
898 Boolean.toString(modellerOutput.isSelected()));
899 Cache.applicationProperties.setProperty("EXPORT_EMBBED_BIOJSON",
900 Boolean.toString(embbedBioJSON.isSelected()));
901 jalview.io.PIRFile.useModellerOutput = modellerOutput.isSelected();
903 Cache.applicationProperties.setProperty("FIGURE_AUTOIDWIDTH",
904 Boolean.toString(autoIdWidth.isSelected()));
905 userIdWidth_actionPerformed();
906 Cache.applicationProperties.setProperty("FIGURE_FIXEDIDWIDTH",
907 userIdWidth.getText());
910 * Save Editing settings
912 Cache.applicationProperties.setProperty("AUTO_CALC_CONSENSUS",
913 Boolean.toString(autoCalculateConsCheck.isSelected()));
914 Cache.applicationProperties.setProperty("SORT_BY_TREE",
915 Boolean.toString(sortByTree.isSelected()));
916 Cache.applicationProperties.setProperty("PAD_GAPS",
917 Boolean.toString(padGaps.isSelected()));
919 if (!Platform.isJS())
921 wsPrefs.updateAndRefreshWsMenuConfig(false);
925 * Save Backups settings
927 Cache.applicationProperties.setProperty(BackupFiles.ENABLED,
928 Boolean.toString(enableBackupFiles.isSelected()));
929 int preset = getComboIntStringKey(backupfilesPresetsCombo);
930 Cache.applicationProperties.setProperty(BackupFiles.NS + "_PRESET", Integer.toString(preset));
932 if (preset == BackupFilesPresetEntry.BACKUPFILESSCHEMECUSTOM)
934 BackupFilesPresetEntry customBFPE = getBackupfilesCurrentEntry();
935 BackupFilesPresetEntry.backupfilesPresetEntriesValues.put(
936 BackupFilesPresetEntry.BACKUPFILESSCHEMECUSTOM, customBFPE);
937 Cache.applicationProperties
938 .setProperty(BackupFilesPresetEntry.CUSTOMCONFIG,
939 customBFPE.toString());
942 BackupFilesPresetEntry savedBFPE = BackupFilesPresetEntry.backupfilesPresetEntriesValues
944 Cache.applicationProperties.setProperty(
945 BackupFilesPresetEntry.SAVEDCONFIG, savedBFPE.toString());
947 Cache.saveProperties();
948 Desktop.instance.doConfigureStructurePrefs();
951 frame.setClosed(true);
952 } catch (Exception ex)
958 * Do any necessary validation before saving settings. Return focus to the
959 * first tab which fails validation.
963 private boolean validateSettings()
965 if (!validateStructure())
967 structureTab.requestFocusInWindow();
974 protected boolean validateStructure()
976 return validateViewerPath();
984 public void startupFileTextfield_mouseClicked()
986 // TODO: JAL-3048 not needed for Jalview-JS
987 String fileFormat = Cache.getProperty("DEFAULT_FILE_FORMAT");
988 JalviewFileChooser chooser = JalviewFileChooser
989 .forRead(Cache.getProperty("LAST_DIRECTORY"), fileFormat);
990 chooser.setFileView(new JalviewFileView());
991 chooser.setDialogTitle(
992 MessageManager.getString("label.select_startup_file"));
994 int value = chooser.showOpenDialog(this);
996 if (value == JalviewFileChooser.APPROVE_OPTION)
998 FileFormatI format = chooser.getSelectedFormat();
1001 Cache.applicationProperties.setProperty("DEFAULT_FILE_FORMAT",
1004 startupFileTextfield
1005 .setText(chooser.getSelectedFile().getAbsolutePath());
1016 public void cancel_actionPerformed(ActionEvent e)
1020 if (!Platform.isJS())
1022 wsPrefs.updateWsMenuConfig(true);
1023 wsPrefs.refreshWs_actionPerformed(e);
1025 frame.setClosed(true);
1026 } catch (Exception ex)
1038 public void annotations_actionPerformed(ActionEvent e)
1040 conservation.setEnabled(annotations.isSelected());
1041 quality.setEnabled(annotations.isSelected());
1042 identity.setEnabled(annotations.isSelected());
1043 showOccupancy.setEnabled(annotations.isSelected());
1044 showGroupConsensus.setEnabled(annotations.isSelected());
1045 showGroupConservation.setEnabled(annotations.isSelected());
1046 showConsensHistogram.setEnabled(annotations.isSelected()
1047 && (identity.isSelected() || showGroupConsensus.isSelected()));
1048 showConsensLogo.setEnabled(annotations.isSelected()
1049 && (identity.isSelected() || showGroupConsensus.isSelected()));
1053 public void newLink_actionPerformed(ActionEvent e)
1055 GSequenceLink link = new GSequenceLink();
1056 boolean valid = false;
1059 if (JvOptionPane.showInternalConfirmDialog(Desktop.desktop, link,
1060 MessageManager.getString("label.new_sequence_url_link"),
1061 JvOptionPane.OK_CANCEL_OPTION, -1,
1062 null) == JvOptionPane.OK_OPTION)
1064 if (link.checkValid())
1066 if (((UrlLinkTableModel) linkUrlTable.getModel())
1067 .isUniqueName(link.getName()))
1069 ((UrlLinkTableModel) linkUrlTable.getModel())
1070 .insertRow(link.getName(), link.getURL());
1075 link.notifyDuplicate();
1088 public void editLink_actionPerformed(ActionEvent e)
1090 GSequenceLink link = new GSequenceLink();
1092 int index = linkUrlTable.getSelectedRow();
1095 // button no longer enabled if row is not selected
1096 Cache.log.debug("Edit with no row selected in linkUrlTable");
1100 int nameCol = ((UrlLinkTableModel) linkUrlTable.getModel())
1102 int urlCol = ((UrlLinkTableModel) linkUrlTable.getModel())
1104 String oldName = linkUrlTable.getValueAt(index, nameCol).toString();
1105 link.setName(oldName);
1106 link.setURL(linkUrlTable.getValueAt(index, urlCol).toString());
1108 boolean valid = false;
1111 if (JvOptionPane.showInternalConfirmDialog(Desktop.desktop, link,
1112 MessageManager.getString("label.edit_sequence_url_link"),
1113 JvOptionPane.OK_CANCEL_OPTION, -1,
1114 null) == JvOptionPane.OK_OPTION)
1116 if (link.checkValid())
1118 if ((oldName.equals(link.getName()))
1119 || (((UrlLinkTableModel) linkUrlTable.getModel())
1120 .isUniqueName(link.getName())))
1122 linkUrlTable.setValueAt(link.getName(), index, nameCol);
1123 linkUrlTable.setValueAt(link.getURL(), index, urlCol);
1128 link.notifyDuplicate();
1141 public void deleteLink_actionPerformed(ActionEvent e)
1143 int index = linkUrlTable.getSelectedRow();
1144 int modelIndex = -1;
1147 // button no longer enabled if row is not selected
1148 Cache.log.debug("Delete with no row selected in linkUrlTable");
1153 modelIndex = linkUrlTable.convertRowIndexToModel(index);
1156 // make sure we use the model index to delete, and not the table index
1157 ((UrlLinkTableModel) linkUrlTable.getModel()).removeRow(modelIndex);
1161 public void defaultBrowser_mouseClicked(MouseEvent e)
1163 // TODO: JAL-3048 not needed for j2s
1164 if (!Platform.isJS()) // BH 2019
1171 JFileChooser chooser = new JFileChooser(".");
1172 chooser.setDialogTitle(
1173 MessageManager.getString("label.select_default_browser"));
1175 int value = chooser.showOpenDialog(this);
1177 if (value == JFileChooser.APPROVE_OPTION)
1179 defaultBrowser.setText(chooser.getSelectedFile().getAbsolutePath());
1188 * jalview.jbgui.GPreferences#showunconserved_actionPerformed(java.awt.event
1192 protected void showunconserved_actionPerformed(ActionEvent e)
1194 // TODO Auto-generated method stub
1195 super.showunconserved_actionPerformed(e);
1198 public static List<String> getGroupURLLinks()
1200 return groupURLLinks;
1204 public void minColour_actionPerformed(JPanel panel)
1206 JalviewColourChooser.showColourChooser(this,
1207 MessageManager.getString("label.select_colour_minimum_value"),
1212 public void maxColour_actionPerformed(JPanel panel)
1214 JalviewColourChooser.showColourChooser(this,
1215 MessageManager.getString("label.select_colour_maximum_value"),
1220 public void gapColour_actionPerformed(JPanel gap)
1222 if (!useLegacyGap.isSelected())
1224 JalviewColourChooser.showColourChooser(this,
1225 MessageManager.getString("label.select_gap_colour"),
1231 public void hiddenColour_actionPerformed(JPanel hidden)
1233 JalviewColourChooser.showColourChooser(this,
1234 MessageManager.getString("label.select_hidden_colour"),
1239 protected void useLegacyGaps_actionPerformed(ActionEvent e)
1241 boolean enabled = useLegacyGap.isSelected();
1244 gapColour.setBackground(
1245 jalview.renderer.OverviewResColourFinder.OVERVIEW_DEFAULT_LEGACY_GAP);
1249 gapColour.setBackground(
1250 jalview.renderer.OverviewResColourFinder.OVERVIEW_DEFAULT_GAP);
1252 gapColour.setEnabled(!enabled);
1253 gapLabel.setEnabled(!enabled);
1257 protected void resetOvDefaults_actionPerformed(ActionEvent e)
1259 useLegacyGap.setSelected(false);
1260 useLegacyGaps_actionPerformed(null);
1261 showHiddenAtStart.setSelected(false);
1262 hiddenColour.setBackground(
1263 jalview.renderer.OverviewResColourFinder.OVERVIEW_DEFAULT_HIDDEN);
1267 protected void userIdWidth_actionPerformed()
1271 String val = userIdWidth.getText().trim();
1272 if (val.length() > 0)
1274 Integer iw = Integer.parseInt(val);
1275 if (iw.intValue() < 12)
1277 throw new NumberFormatException();
1279 userIdWidth.setText(iw.toString());
1281 } catch (NumberFormatException x)
1283 userIdWidth.setText("");
1284 JvOptionPane.showInternalMessageDialog(Desktop.desktop,
1286 .getString("warn.user_defined_width_requirements"),
1287 MessageManager.getString("label.invalid_id_column_width"),
1288 JvOptionPane.WARNING_MESSAGE);
1293 protected void autoIdWidth_actionPerformed()
1295 userIdWidth.setEnabled(!autoIdWidth.isSelected());
1296 userIdWidthlabel.setEnabled(!autoIdWidth.isSelected());
1300 * Returns true if structure viewer path is to a valid executable, else shows
1301 * an error dialog. Does nothing if the path is empty, as is the case for Jmol
1302 * (built in to Jalview) or when Jalview is left to try default paths.
1304 private boolean validateViewerPath()
1306 if (structureViewerPath.getText().trim().length() > 0)
1308 File f = new File(structureViewerPath.getText());
1309 if (!f.canExecute())
1311 JvOptionPane.showInternalMessageDialog(Desktop.desktop,
1312 MessageManager.getString("label.invalid_viewer_path"),
1313 MessageManager.getString("label.invalid_viewer_path"),
1314 JvOptionPane.ERROR_MESSAGE);
1322 * If Chimera or ChimeraX or Pymol is selected, check it can be found on
1323 * default or user-specified path, if not show a warning/help dialog
1326 protected void structureViewer_actionPerformed(String selectedItem)
1328 if (selectedItem.equals(ViewerType.JMOL.name()))
1330 structureViewerPath.setEnabled(false);
1331 structureViewerPathLabel.setEnabled(false);
1334 boolean found = false;
1335 structureViewerPath.setEnabled(true);
1336 structureViewerPathLabel.setEnabled(true);
1337 structureViewerPathLabel.setText(MessageManager
1338 .formatMessage("label.viewer_path", selectedItem));
1341 * Try user-specified and standard paths for structure viewer executable
1343 String viewerPath = "";
1344 List<String> paths = null;
1347 ViewerType viewerType = ViewerType.valueOf(selectedItem);
1354 viewerPath = Cache.getDefault(CHIMERA_PATH, "");
1355 paths = StructureManager.getChimeraPaths(false);
1358 viewerPath = Cache.getDefault(CHIMERAX_PATH, "");
1359 paths = StructureManager.getChimeraPaths(true);
1362 viewerPath = Cache.getDefault(PYMOL_PATH, "");
1363 paths = PymolManager.getPymolPaths();
1366 } catch (IllegalArgumentException e)
1368 // only valid entries should be in the drop-down
1370 structureViewerPath.setText(viewerPath);
1372 paths.add(0, structureViewerPath.getText());
1373 for (String path : paths)
1375 if (new File(path.trim()).canExecute())
1384 String[] options = { "OK", "Help" };
1385 int showHelp = JvOptionPane.showInternalOptionDialog(Desktop.desktop,
1386 JvSwingUtils.wrapTooltip(true,
1387 MessageManager.getString("label.viewer_missing")),
1388 "", JvOptionPane.YES_NO_OPTION, JvOptionPane.WARNING_MESSAGE,
1389 null, options, options[0]);
1390 if (showHelp == JvOptionPane.NO_OPTION)
1394 Help.showHelpWindow(HelpId.StructureViewer);
1395 } catch (HelpSetException e)
1397 e.printStackTrace();
1403 public class OptionsParam
1405 private String name;
1407 private String code;
1409 public OptionsParam(String name, String code)
1415 public String getName()
1420 public void setName(String name)
1425 public String getCode()
1430 public void setCode(String code)
1436 public String toString()
1442 public boolean equals(Object that)
1444 if (!(that instanceof OptionsParam))
1448 return this.code.equalsIgnoreCase(((OptionsParam) that).code);
1452 public int hashCode()
1454 return name.hashCode() + code.hashCode();
1458 private class UrlListSelectionHandler implements ListSelectionListener
1462 public void valueChanged(ListSelectionEvent e)
1464 ListSelectionModel lsm = (ListSelectionModel) e.getSource();
1466 int index = lsm.getMinSelectionIndex();
1469 // no selection, so disable delete/edit buttons
1470 editLink.setEnabled(false);
1471 deleteLink.setEnabled(false);
1474 int modelIndex = linkUrlTable.convertRowIndexToModel(index);
1476 // enable/disable edit and delete link buttons
1477 if (((UrlLinkTableModel) linkUrlTable.getModel())
1478 .isRowDeletable(modelIndex))
1480 deleteLink.setEnabled(true);
1484 deleteLink.setEnabled(false);
1487 if (((UrlLinkTableModel) linkUrlTable.getModel())
1488 .isRowEditable(modelIndex))
1490 editLink.setEnabled(true);
1494 editLink.setEnabled(false);