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(Cache.getDefaultColour(GAP_COLOUR,
332 OverviewCanvas.OVERVIEW_DEFAULT_GAP));
333 hiddenColour.setBackground(Cache.getDefaultColour(HIDDEN_COLOUR,
334 OverviewCanvas.OVERVIEW_DEFAULT_HIDDEN));
335 useLegacyGap.setSelected(Cache.getDefault(USE_LEGACY_GAP, false));
336 gapLabel.setEnabled(!useLegacyGap.isSelected());
337 gapColour.setEnabled(!useLegacyGap.isSelected());
339 .setSelected(Cache.getDefault(SHOW_OV_HIDDEN_AT_START, false));
342 * Set Structure tab defaults
344 final boolean structSelected = Cache.getDefault(STRUCT_FROM_PDB, false);
345 structFromPdb.setSelected(structSelected);
346 useRnaView.setSelected(Cache.getDefault(USE_RNAVIEW, false));
347 useRnaView.setEnabled(structSelected);
348 addSecondaryStructure.setSelected(Cache.getDefault(ADD_SS_ANN, false));
349 addSecondaryStructure.setEnabled(structSelected);
350 addTempFactor.setSelected(Cache.getDefault(ADD_TEMPFACT_ANN, false));
351 addTempFactor.setEnabled(structSelected);
354 * set choice of structure viewer, and path if saved as a preference;
355 * default to Jmol (first choice) if an unexpected value is found
357 String viewerType = Cache.getDefault(STRUCTURE_DISPLAY,
358 ViewerType.JMOL.name());
359 structViewer.setSelectedItem(viewerType);
360 String viewerPath = "";
361 ViewerType type = null;
364 type = ViewerType.valueOf(viewerType);
370 viewerPath = Cache.getDefault(CHIMERA_PATH, "");
373 viewerPath = Cache.getDefault(CHIMERAX_PATH, "");
376 viewerPath = Cache.getDefault(PYMOL_PATH, "");
379 } catch (IllegalArgumentException e)
381 Cache.log.error("Unknown structure viewer type: " + viewerType
382 + ", defaulting to Jmol");
383 type = ViewerType.JMOL;
385 structureViewerPath.setText(viewerPath);
387 structureViewerPath.addActionListener(new ActionListener()
390 public void actionPerformed(ActionEvent e)
392 if (validateViewerPath())
395 structViewer.getSelectedItem().equals(
396 ViewerType.CHIMERAX.name()) ? CHIMERAX_PATH
398 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 useProxy.setSelected(Cache.getDefault("USE_PROXY", false));
540 useProxy_actionPerformed(); // make sure useProxy is correctly initialised
541 proxyServerTB.setText(Cache.getDefault("PROXY_SERVER", ""));
542 proxyPortTB.setText(Cache.getDefault("PROXY_PORT", ""));
544 defaultBrowser.setText(Cache.getDefault("DEFAULT_BROWSER", ""));
546 usagestats.setSelected(Cache.getDefault("USAGESTATS", false));
547 // note antisense here: default is true
549 .setSelected(Cache.getProperty("NOQUESTIONNAIRES") == null);
550 versioncheck.setSelected(Cache.getDefault("VERSION_CHECK", true));
553 * Set Output tab defaults
555 setupOutputCombo(epsRendering, "EPS_RENDERING");
556 setupOutputCombo(htmlRendering, "HTML_RENDERING");
557 setupOutputCombo(svgRendering, "SVG_RENDERING");
558 autoIdWidth.setSelected(Cache.getDefault("FIGURE_AUTOIDWIDTH", false));
559 userIdWidth.setEnabled(!autoIdWidth.isSelected());
560 userIdWidthlabel.setEnabled(!autoIdWidth.isSelected());
561 Integer wi = Cache.getIntegerProperty("FIGURE_FIXEDIDWIDTH");
562 userIdWidth.setText(wi == null ? "" : wi.toString());
563 // TODO: refactor to use common enum via FormatAdapter and allow extension
564 // for new flat file formats
565 blcjv.setSelected(Cache.getDefault("BLC_JVSUFFIX", true));
566 clustaljv.setSelected(Cache.getDefault("CLUSTAL_JVSUFFIX", true));
567 fastajv.setSelected(Cache.getDefault("FASTA_JVSUFFIX", true));
568 msfjv.setSelected(Cache.getDefault("MSF_JVSUFFIX", true));
569 pfamjv.setSelected(Cache.getDefault("PFAM_JVSUFFIX", true));
570 pileupjv.setSelected(Cache.getDefault("PILEUP_JVSUFFIX", true));
571 pirjv.setSelected(Cache.getDefault("PIR_JVSUFFIX", true));
572 modellerOutput.setSelected(Cache.getDefault("PIR_MODELLER", false));
574 .setSelected(Cache.getDefault("EXPORT_EMBBED_BIOJSON", true));
577 * Set Editing tab defaults
579 autoCalculateConsCheck
580 .setSelected(Cache.getDefault("AUTO_CALC_CONSENSUS", true));
581 padGaps.setSelected(Cache.getDefault("PAD_GAPS", false));
582 sortByTree.setSelected(Cache.getDefault("SORT_BY_TREE", false));
584 annotations_actionPerformed(null); // update the display of the annotation
588 * Set Backups tab defaults
590 loadLastSavedBackupsOptions();
594 * A helper method that sets the items and initial selection in a character
595 * rendering option list (Prompt each time/Lineart/Text)
600 protected void setupOutputCombo(JComboBox<Object> comboBox,
603 comboBox.addItem(promptEachTimeOpt);
604 comboBox.addItem(lineArtOpt);
605 comboBox.addItem(textOpt);
608 * JalviewJS doesn't support Lineart so force it to Text
610 String defaultOption = Platform.isJS() ? "Text"
611 : Cache.getDefault(propertyKey, "Prompt each time");
612 if (defaultOption.equalsIgnoreCase("Text"))
614 comboBox.setSelectedItem(textOpt);
616 else if (defaultOption.equalsIgnoreCase("Lineart"))
618 comboBox.setSelectedItem(lineArtOpt);
622 comboBox.setSelectedItem(promptEachTimeOpt);
627 * Save user selections on the Preferences tabs to the Cache and write out to
633 public void ok_actionPerformed(ActionEvent e)
635 if (!validateSettings())
641 * Save Visual settings
643 Cache.applicationProperties.setProperty("SHOW_JVSUFFIX",
644 Boolean.toString(seqLimit.isSelected()));
645 Cache.applicationProperties.setProperty("RIGHT_ALIGN_IDS",
646 Boolean.toString(rightAlign.isSelected()));
647 Cache.applicationProperties.setProperty("SHOW_FULLSCREEN",
648 Boolean.toString(fullScreen.isSelected()));
649 Cache.applicationProperties.setProperty("SHOW_OVERVIEW",
650 Boolean.toString(openoverv.isSelected()));
651 Cache.applicationProperties.setProperty("SHOW_ANNOTATIONS",
652 Boolean.toString(annotations.isSelected()));
653 Cache.applicationProperties.setProperty("SHOW_CONSERVATION",
654 Boolean.toString(conservation.isSelected()));
655 Cache.applicationProperties.setProperty("SHOW_QUALITY",
656 Boolean.toString(quality.isSelected()));
657 Cache.applicationProperties.setProperty("SHOW_IDENTITY",
658 Boolean.toString(identity.isSelected()));
660 Cache.applicationProperties.setProperty("GAP_SYMBOL",
661 gapSymbolCB.getSelectedItem().toString());
663 Cache.applicationProperties.setProperty("FONT_NAME",
664 fontNameCB.getSelectedItem().toString());
665 Cache.applicationProperties.setProperty("FONT_STYLE",
666 fontStyleCB.getSelectedItem().toString());
667 Cache.applicationProperties.setProperty("FONT_SIZE",
668 fontSizeCB.getSelectedItem().toString());
670 Cache.applicationProperties.setProperty("ID_ITALICS",
671 Boolean.toString(idItalics.isSelected()));
672 Cache.applicationProperties.setProperty("SHOW_UNCONSERVED",
673 Boolean.toString(showUnconserved.isSelected()));
674 Cache.applicationProperties.setProperty(SHOW_OCCUPANCY,
675 Boolean.toString(showOccupancy.isSelected()));
676 Cache.applicationProperties.setProperty("SHOW_GROUP_CONSENSUS",
677 Boolean.toString(showGroupConsensus.isSelected()));
678 Cache.applicationProperties.setProperty("SHOW_GROUP_CONSERVATION",
679 Boolean.toString(showGroupConservation.isSelected()));
680 Cache.applicationProperties.setProperty("SHOW_CONSENSUS_HISTOGRAM",
681 Boolean.toString(showConsensHistogram.isSelected()));
682 Cache.applicationProperties.setProperty("SHOW_CONSENSUS_LOGO",
683 Boolean.toString(showConsensLogo.isSelected()));
684 Cache.applicationProperties.setProperty("ANTI_ALIAS",
685 Boolean.toString(smoothFont.isSelected()));
686 Cache.applicationProperties.setProperty(SCALE_PROTEIN_TO_CDNA,
687 Boolean.toString(scaleProteinToCdna.isSelected()));
688 Cache.applicationProperties.setProperty("SHOW_NPFEATS_TOOLTIP",
689 Boolean.toString(showNpTooltip.isSelected()));
690 Cache.applicationProperties.setProperty("SHOW_DBREFS_TOOLTIP",
691 Boolean.toString(showDbRefTooltip.isSelected()));
693 Cache.applicationProperties.setProperty("WRAP_ALIGNMENT",
694 Boolean.toString(wrap.isSelected()));
696 Cache.applicationProperties.setProperty("STARTUP_FILE",
697 startupFileTextfield.getText());
698 Cache.applicationProperties.setProperty("SHOW_STARTUP_FILE",
699 Boolean.toString(startupCheckbox.isSelected()));
701 Cache.applicationProperties.setProperty("SORT_ALIGNMENT",
702 sortby.getSelectedItem().toString());
704 // convert description of sort order to enum name for save
705 SequenceAnnotationOrder annSortOrder = SequenceAnnotationOrder
706 .forDescription(sortAnnBy.getSelectedItem().toString());
707 if (annSortOrder != null)
709 Cache.applicationProperties.setProperty(SORT_ANNOTATIONS,
710 annSortOrder.name());
713 final boolean showAutocalcFirst = sortAutocalc.getSelectedIndex() == 0;
714 Cache.applicationProperties.setProperty(SHOW_AUTOCALC_ABOVE,
715 Boolean.valueOf(showAutocalcFirst).toString());
718 * Save Colours settings
720 Cache.applicationProperties.setProperty(DEFAULT_COLOUR_PROT,
721 protColour.getSelectedItem().toString());
722 Cache.applicationProperties.setProperty(DEFAULT_COLOUR_NUC,
723 nucColour.getSelectedItem().toString());
724 Cache.setColourProperty("ANNOTATIONCOLOUR_MIN",
725 minColour.getBackground());
726 Cache.setColourProperty("ANNOTATIONCOLOUR_MAX",
727 maxColour.getBackground());
730 * Save Overview settings
732 Cache.setColourProperty(GAP_COLOUR, gapColour.getBackground());
733 Cache.setColourProperty(HIDDEN_COLOUR, hiddenColour.getBackground());
734 Cache.applicationProperties.setProperty(USE_LEGACY_GAP,
735 Boolean.toString(useLegacyGap.isSelected()));
736 Cache.applicationProperties.setProperty(SHOW_OV_HIDDEN_AT_START,
737 Boolean.toString(showHiddenAtStart.isSelected()));
740 * Save Structure settings
742 Cache.applicationProperties.setProperty(ADD_TEMPFACT_ANN,
743 Boolean.toString(addTempFactor.isSelected()));
744 Cache.applicationProperties.setProperty(ADD_SS_ANN,
745 Boolean.toString(addSecondaryStructure.isSelected()));
746 Cache.applicationProperties.setProperty(USE_RNAVIEW,
747 Boolean.toString(useRnaView.isSelected()));
748 Cache.applicationProperties.setProperty(STRUCT_FROM_PDB,
749 Boolean.toString(structFromPdb.isSelected()));
750 String viewer = structViewer.getSelectedItem().toString();
751 String viewerPath = structureViewerPath.getText();
752 Cache.applicationProperties.setProperty(STRUCTURE_DISPLAY, viewer);
753 if (viewer.equals(ViewerType.CHIMERA.name()))
755 Cache.setOrRemove(CHIMERA_PATH, viewerPath);
757 else if (viewer.equals(ViewerType.CHIMERAX.name()))
759 Cache.setOrRemove(CHIMERAX_PATH, viewerPath);
761 else if (viewer.equals(ViewerType.PYMOL.name()))
763 Cache.setOrRemove(PYMOL_PATH, viewerPath);
765 Cache.applicationProperties.setProperty("MAP_WITH_SIFTS",
766 Boolean.toString(siftsMapping.isSelected()));
767 SiftsSettings.setMapWithSifts(siftsMapping.isSelected());
770 * Save Output settings
772 Cache.applicationProperties.setProperty("EPS_RENDERING",
773 ((OptionsParam) epsRendering.getSelectedItem()).getCode());
774 Cache.applicationProperties.setProperty("HTML_RENDERING",
775 ((OptionsParam) htmlRendering.getSelectedItem()).getCode());
776 Cache.applicationProperties.setProperty("SVG_RENDERING",
777 ((OptionsParam) svgRendering.getSelectedItem()).getCode());
780 * Save Connections settings
782 Cache.setOrRemove("DEFAULT_BROWSER", defaultBrowser.getText());
784 jalview.util.BrowserLauncher.resetBrowser();
786 // save user-defined and selected links
787 String menuLinks = sequenceUrlLinks.writeUrlsAsString(true);
788 if (menuLinks.isEmpty())
790 Cache.applicationProperties.remove("SEQUENCE_LINKS");
794 Cache.applicationProperties.setProperty("SEQUENCE_LINKS",
795 menuLinks.toString());
798 String nonMenuLinks = sequenceUrlLinks.writeUrlsAsString(false);
799 if (nonMenuLinks.isEmpty())
801 Cache.applicationProperties.remove("STORED_LINKS");
805 Cache.applicationProperties.setProperty("STORED_LINKS",
806 nonMenuLinks.toString());
809 Cache.applicationProperties.setProperty("DEFAULT_URL",
810 sequenceUrlLinks.getPrimaryUrlId());
812 Cache.applicationProperties.setProperty("USE_PROXY",
813 Boolean.toString(useProxy.isSelected()));
815 Cache.setOrRemove("PROXY_SERVER", proxyServerTB.getText());
817 Cache.setOrRemove("PROXY_PORT", proxyPortTB.getText());
819 if (useProxy.isSelected())
821 System.setProperty("http.proxyHost", proxyServerTB.getText());
822 System.setProperty("http.proxyPort", proxyPortTB.getText());
826 System.setProperty("http.proxyHost", "");
827 System.setProperty("http.proxyPort", "");
829 Cache.setProperty("VERSION_CHECK",
830 Boolean.toString(versioncheck.isSelected()));
831 if (Cache.getProperty("USAGESTATS") != null || usagestats.isSelected())
833 // default is false - we only set this if the user has actively agreed
834 Cache.setProperty("USAGESTATS",
835 Boolean.toString(usagestats.isSelected()));
837 if (!questionnaire.isSelected())
839 Cache.setProperty("NOQUESTIONNAIRES", "true");
843 // special - made easy to edit a property file to disable questionnaires
844 // by just adding the given line
845 Cache.removeProperty("NOQUESTIONNAIRES");
849 * Save Output settings
851 Cache.applicationProperties.setProperty("BLC_JVSUFFIX",
852 Boolean.toString(blcjv.isSelected()));
853 Cache.applicationProperties.setProperty("CLUSTAL_JVSUFFIX",
854 Boolean.toString(clustaljv.isSelected()));
855 Cache.applicationProperties.setProperty("FASTA_JVSUFFIX",
856 Boolean.toString(fastajv.isSelected()));
857 Cache.applicationProperties.setProperty("MSF_JVSUFFIX",
858 Boolean.toString(msfjv.isSelected()));
859 Cache.applicationProperties.setProperty("PFAM_JVSUFFIX",
860 Boolean.toString(pfamjv.isSelected()));
861 Cache.applicationProperties.setProperty("PILEUP_JVSUFFIX",
862 Boolean.toString(pileupjv.isSelected()));
863 Cache.applicationProperties.setProperty("PIR_JVSUFFIX",
864 Boolean.toString(pirjv.isSelected()));
865 Cache.applicationProperties.setProperty("PIR_MODELLER",
866 Boolean.toString(modellerOutput.isSelected()));
867 Cache.applicationProperties.setProperty("EXPORT_EMBBED_BIOJSON",
868 Boolean.toString(embbedBioJSON.isSelected()));
869 jalview.io.PIRFile.useModellerOutput = modellerOutput.isSelected();
871 Cache.applicationProperties.setProperty("FIGURE_AUTOIDWIDTH",
872 Boolean.toString(autoIdWidth.isSelected()));
873 userIdWidth_actionPerformed();
874 Cache.applicationProperties.setProperty("FIGURE_FIXEDIDWIDTH",
875 userIdWidth.getText());
878 * Save Editing settings
880 Cache.applicationProperties.setProperty("AUTO_CALC_CONSENSUS",
881 Boolean.toString(autoCalculateConsCheck.isSelected()));
882 Cache.applicationProperties.setProperty("SORT_BY_TREE",
883 Boolean.toString(sortByTree.isSelected()));
884 Cache.applicationProperties.setProperty("PAD_GAPS",
885 Boolean.toString(padGaps.isSelected()));
887 if (!Platform.isJS())
889 wsPrefs.updateAndRefreshWsMenuConfig(false);
893 * Save Backups settings
895 Cache.applicationProperties.setProperty(BackupFiles.ENABLED,
896 Boolean.toString(enableBackupFiles.isSelected()));
897 int preset = getComboIntStringKey(backupfilesPresetsCombo);
898 Cache.applicationProperties.setProperty(BackupFiles.NS + "_PRESET",
899 Integer.toString(preset));
901 if (preset == BackupFilesPresetEntry.BACKUPFILESSCHEMECUSTOM)
903 BackupFilesPresetEntry customBFPE = getBackupfilesCurrentEntry();
904 BackupFilesPresetEntry.backupfilesPresetEntriesValues.put(
905 BackupFilesPresetEntry.BACKUPFILESSCHEMECUSTOM, customBFPE);
906 Cache.applicationProperties.setProperty(
907 BackupFilesPresetEntry.CUSTOMCONFIG, customBFPE.toString());
910 BackupFilesPresetEntry savedBFPE = BackupFilesPresetEntry.backupfilesPresetEntriesValues
912 Cache.applicationProperties.setProperty(
913 BackupFilesPresetEntry.SAVEDCONFIG, savedBFPE.toString());
915 Cache.saveProperties();
916 Desktop.instance.doConfigureStructurePrefs();
919 frame.setClosed(true);
920 } catch (Exception ex)
926 * Do any necessary validation before saving settings. Return focus to the
927 * first tab which fails validation.
931 private boolean validateSettings()
933 if (!validateStructure())
935 structureTab.requestFocusInWindow();
942 protected boolean validateStructure()
944 return validateViewerPath();
952 public void startupFileTextfield_mouseClicked()
954 // TODO: JAL-3048 not needed for Jalview-JS
955 String fileFormat = Cache.getProperty("DEFAULT_FILE_FORMAT");
956 JalviewFileChooser chooser = JalviewFileChooser
957 .forRead(Cache.getProperty("LAST_DIRECTORY"), fileFormat);
958 chooser.setFileView(new JalviewFileView());
959 chooser.setDialogTitle(
960 MessageManager.getString("label.select_startup_file"));
962 int value = chooser.showOpenDialog(this);
964 if (value == JalviewFileChooser.APPROVE_OPTION)
966 FileFormatI format = chooser.getSelectedFormat();
969 Cache.applicationProperties.setProperty("DEFAULT_FILE_FORMAT",
973 .setText(chooser.getSelectedFile().getAbsolutePath());
984 public void cancel_actionPerformed(ActionEvent e)
988 if (!Platform.isJS())
990 wsPrefs.updateWsMenuConfig(true);
991 wsPrefs.refreshWs_actionPerformed(e);
993 frame.setClosed(true);
994 } catch (Exception ex)
1006 public void annotations_actionPerformed(ActionEvent e)
1008 conservation.setEnabled(annotations.isSelected());
1009 quality.setEnabled(annotations.isSelected());
1010 identity.setEnabled(annotations.isSelected());
1011 showOccupancy.setEnabled(annotations.isSelected());
1012 showGroupConsensus.setEnabled(annotations.isSelected());
1013 showGroupConservation.setEnabled(annotations.isSelected());
1014 showConsensHistogram.setEnabled(annotations.isSelected()
1015 && (identity.isSelected() || showGroupConsensus.isSelected()));
1016 showConsensLogo.setEnabled(annotations.isSelected()
1017 && (identity.isSelected() || showGroupConsensus.isSelected()));
1021 public void newLink_actionPerformed(ActionEvent e)
1023 GSequenceLink link = new GSequenceLink();
1024 boolean valid = false;
1027 if (JvOptionPane.showInternalConfirmDialog(Desktop.desktop, link,
1028 MessageManager.getString("label.new_sequence_url_link"),
1029 JvOptionPane.OK_CANCEL_OPTION, -1,
1030 null) == JvOptionPane.OK_OPTION)
1032 if (link.checkValid())
1034 if (((UrlLinkTableModel) linkUrlTable.getModel())
1035 .isUniqueName(link.getName()))
1037 ((UrlLinkTableModel) linkUrlTable.getModel())
1038 .insertRow(link.getName(), link.getURL());
1043 link.notifyDuplicate();
1056 public void editLink_actionPerformed(ActionEvent e)
1058 GSequenceLink link = new GSequenceLink();
1060 int index = linkUrlTable.getSelectedRow();
1063 // button no longer enabled if row is not selected
1064 Cache.log.debug("Edit with no row selected in linkUrlTable");
1068 int nameCol = ((UrlLinkTableModel) linkUrlTable.getModel())
1070 int urlCol = ((UrlLinkTableModel) linkUrlTable.getModel())
1072 String oldName = linkUrlTable.getValueAt(index, nameCol).toString();
1073 link.setName(oldName);
1074 link.setURL(linkUrlTable.getValueAt(index, urlCol).toString());
1076 boolean valid = false;
1079 if (JvOptionPane.showInternalConfirmDialog(Desktop.desktop, link,
1080 MessageManager.getString("label.edit_sequence_url_link"),
1081 JvOptionPane.OK_CANCEL_OPTION, -1,
1082 null) == JvOptionPane.OK_OPTION)
1084 if (link.checkValid())
1086 if ((oldName.equals(link.getName()))
1087 || (((UrlLinkTableModel) linkUrlTable.getModel())
1088 .isUniqueName(link.getName())))
1090 linkUrlTable.setValueAt(link.getName(), index, nameCol);
1091 linkUrlTable.setValueAt(link.getURL(), index, urlCol);
1096 link.notifyDuplicate();
1109 public void deleteLink_actionPerformed(ActionEvent e)
1111 int index = linkUrlTable.getSelectedRow();
1112 int modelIndex = -1;
1115 // button no longer enabled if row is not selected
1116 Cache.log.debug("Delete with no row selected in linkUrlTable");
1121 modelIndex = linkUrlTable.convertRowIndexToModel(index);
1124 // make sure we use the model index to delete, and not the table index
1125 ((UrlLinkTableModel) linkUrlTable.getModel()).removeRow(modelIndex);
1129 public void defaultBrowser_mouseClicked(MouseEvent e)
1131 // TODO: JAL-3048 not needed for j2s
1132 if (!Platform.isJS()) // BH 2019
1139 JFileChooser chooser = new JFileChooser(".");
1140 chooser.setDialogTitle(
1141 MessageManager.getString("label.select_default_browser"));
1143 int value = chooser.showOpenDialog(this);
1145 if (value == JFileChooser.APPROVE_OPTION)
1147 defaultBrowser.setText(chooser.getSelectedFile().getAbsolutePath());
1156 * jalview.jbgui.GPreferences#showunconserved_actionPerformed(java.awt.event
1160 protected void showunconserved_actionPerformed(ActionEvent e)
1162 // TODO Auto-generated method stub
1163 super.showunconserved_actionPerformed(e);
1166 public static List<String> getGroupURLLinks()
1168 return groupURLLinks;
1172 public void minColour_actionPerformed(JPanel panel)
1174 JalviewColourChooser.showColourChooser(this,
1175 MessageManager.getString("label.select_colour_minimum_value"),
1180 public void maxColour_actionPerformed(JPanel panel)
1182 JalviewColourChooser.showColourChooser(this,
1183 MessageManager.getString("label.select_colour_maximum_value"),
1188 public void gapColour_actionPerformed(JPanel gap)
1190 if (!useLegacyGap.isSelected())
1192 JalviewColourChooser.showColourChooser(this,
1193 MessageManager.getString("label.select_gap_colour"), gap);
1198 public void hiddenColour_actionPerformed(JPanel hidden)
1200 JalviewColourChooser.showColourChooser(this,
1201 MessageManager.getString("label.select_hidden_colour"), hidden);
1205 protected void useLegacyGaps_actionPerformed(ActionEvent e)
1207 boolean enabled = useLegacyGap.isSelected();
1210 gapColour.setBackground(OverviewCanvas.OVERVIEW_DEFAULT_LEGACY_GAP);
1214 gapColour.setBackground(OverviewCanvas.OVERVIEW_DEFAULT_GAP);
1216 gapColour.setEnabled(!enabled);
1217 gapLabel.setEnabled(!enabled);
1221 protected void resetOvDefaults_actionPerformed(ActionEvent e)
1223 useLegacyGap.setSelected(false);
1224 useLegacyGaps_actionPerformed(null);
1225 showHiddenAtStart.setSelected(false);
1226 hiddenColour.setBackground(OverviewCanvas.OVERVIEW_DEFAULT_HIDDEN);
1230 protected void userIdWidth_actionPerformed()
1234 String val = userIdWidth.getText().trim();
1235 if (val.length() > 0)
1237 Integer iw = Integer.parseInt(val);
1238 if (iw.intValue() < 12)
1240 throw new NumberFormatException();
1242 userIdWidth.setText(iw.toString());
1244 } catch (NumberFormatException x)
1246 userIdWidth.setText("");
1247 JvOptionPane.showInternalMessageDialog(Desktop.desktop,
1249 .getString("warn.user_defined_width_requirements"),
1250 MessageManager.getString("label.invalid_id_column_width"),
1251 JvOptionPane.WARNING_MESSAGE);
1256 protected void autoIdWidth_actionPerformed()
1258 userIdWidth.setEnabled(!autoIdWidth.isSelected());
1259 userIdWidthlabel.setEnabled(!autoIdWidth.isSelected());
1263 * Returns true if structure viewer path is to a valid executable, else shows
1264 * an error dialog. Does nothing if the path is empty, as is the case for Jmol
1265 * (built in to Jalview) or when Jalview is left to try default paths.
1267 private boolean validateViewerPath()
1269 if (structureViewerPath.getText().trim().length() > 0)
1271 File f = new File(structureViewerPath.getText());
1272 if (!f.canExecute())
1274 JvOptionPane.showInternalMessageDialog(Desktop.desktop,
1275 MessageManager.getString("label.invalid_viewer_path"),
1276 MessageManager.getString("label.invalid_viewer_path"),
1277 JvOptionPane.ERROR_MESSAGE);
1285 * If Chimera or ChimeraX or Pymol is selected, check it can be found on
1286 * default or user-specified path, if not show a warning/help dialog
1289 protected void structureViewer_actionPerformed(String selectedItem)
1291 if (selectedItem.equals(ViewerType.JMOL.name()))
1293 structureViewerPath.setEnabled(false);
1294 structureViewerPathLabel.setEnabled(false);
1297 boolean found = false;
1298 structureViewerPath.setEnabled(true);
1299 structureViewerPathLabel.setEnabled(true);
1300 structureViewerPathLabel.setText(MessageManager
1301 .formatMessage("label.viewer_path", selectedItem));
1304 * Try user-specified and standard paths for structure viewer executable
1306 String viewerPath = "";
1307 List<String> paths = null;
1310 ViewerType viewerType = ViewerType.valueOf(selectedItem);
1317 viewerPath = Cache.getDefault(CHIMERA_PATH, "");
1318 paths = StructureManager.getChimeraPaths(false);
1321 viewerPath = Cache.getDefault(CHIMERAX_PATH, "");
1322 paths = StructureManager.getChimeraPaths(true);
1325 viewerPath = Cache.getDefault(PYMOL_PATH, "");
1326 paths = PymolManager.getPymolPaths();
1329 } catch (IllegalArgumentException e)
1331 // only valid entries should be in the drop-down
1333 structureViewerPath.setText(viewerPath);
1335 paths.add(0, structureViewerPath.getText());
1336 for (String path : paths)
1338 if (new File(path.trim()).canExecute())
1347 String[] options = { "OK", "Help" };
1348 int showHelp = JvOptionPane.showInternalOptionDialog(Desktop.desktop,
1349 JvSwingUtils.wrapTooltip(true,
1350 MessageManager.getString("label.viewer_missing")),
1351 "", JvOptionPane.YES_NO_OPTION, JvOptionPane.WARNING_MESSAGE,
1352 null, options, options[0]);
1353 if (showHelp == JvOptionPane.NO_OPTION)
1357 Help.showHelpWindow(HelpId.StructureViewer);
1358 } catch (HelpSetException e)
1360 e.printStackTrace();
1366 public class OptionsParam
1368 private String name;
1370 private String code;
1372 public OptionsParam(String name, String code)
1378 public String getName()
1383 public void setName(String name)
1388 public String getCode()
1393 public void setCode(String code)
1399 public String toString()
1405 public boolean equals(Object that)
1407 if (!(that instanceof OptionsParam))
1411 return this.code.equalsIgnoreCase(((OptionsParam) that).code);
1415 public int hashCode()
1417 return name.hashCode() + code.hashCode();
1421 private class UrlListSelectionHandler implements ListSelectionListener
1425 public void valueChanged(ListSelectionEvent e)
1427 ListSelectionModel lsm = (ListSelectionModel) e.getSource();
1429 int index = lsm.getMinSelectionIndex();
1432 // no selection, so disable delete/edit buttons
1433 editLink.setEnabled(false);
1434 deleteLink.setEnabled(false);
1437 int modelIndex = linkUrlTable.convertRowIndexToModel(index);
1439 // enable/disable edit and delete link buttons
1440 if (((UrlLinkTableModel) linkUrlTable.getModel())
1441 .isRowDeletable(modelIndex))
1443 deleteLink.setEnabled(true);
1447 deleteLink.setEnabled(false);
1450 if (((UrlLinkTableModel) linkUrlTable.getModel())
1451 .isRowEditable(modelIndex))
1453 editLink.setEnabled(true);
1457 editLink.setEnabled(false);