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 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
589 * Set Backups tab defaults
591 loadLastSavedBackupsOptions();
595 * A helper method that sets the items and initial selection in a character
596 * rendering option list (Prompt each time/Lineart/Text)
601 protected void setupOutputCombo(JComboBox<Object> comboBox,
604 comboBox.addItem(promptEachTimeOpt);
605 comboBox.addItem(lineArtOpt);
606 comboBox.addItem(textOpt);
609 * JalviewJS doesn't support Lineart so force it to Text
611 String defaultOption = Platform.isJS() ? "Text"
612 : Cache.getDefault(propertyKey, "Prompt each time");
613 if (defaultOption.equalsIgnoreCase("Text"))
615 comboBox.setSelectedItem(textOpt);
617 else if (defaultOption.equalsIgnoreCase("Lineart"))
619 comboBox.setSelectedItem(lineArtOpt);
623 comboBox.setSelectedItem(promptEachTimeOpt);
628 * Save user selections on the Preferences tabs to the Cache and write out to
634 public void ok_actionPerformed(ActionEvent e)
636 if (!validateSettings())
642 * Save Visual settings
644 Cache.applicationProperties.setProperty("SHOW_JVSUFFIX",
645 Boolean.toString(seqLimit.isSelected()));
646 Cache.applicationProperties.setProperty("RIGHT_ALIGN_IDS",
647 Boolean.toString(rightAlign.isSelected()));
648 Cache.applicationProperties.setProperty("SHOW_FULLSCREEN",
649 Boolean.toString(fullScreen.isSelected()));
650 Cache.applicationProperties.setProperty("SHOW_OVERVIEW",
651 Boolean.toString(openoverv.isSelected()));
652 Cache.applicationProperties.setProperty("SHOW_ANNOTATIONS",
653 Boolean.toString(annotations.isSelected()));
654 Cache.applicationProperties.setProperty("SHOW_CONSERVATION",
655 Boolean.toString(conservation.isSelected()));
656 Cache.applicationProperties.setProperty("SHOW_QUALITY",
657 Boolean.toString(quality.isSelected()));
658 Cache.applicationProperties.setProperty("SHOW_IDENTITY",
659 Boolean.toString(identity.isSelected()));
661 Cache.applicationProperties.setProperty("GAP_SYMBOL",
662 gapSymbolCB.getSelectedItem().toString());
664 Cache.applicationProperties.setProperty("FONT_NAME",
665 fontNameCB.getSelectedItem().toString());
666 Cache.applicationProperties.setProperty("FONT_STYLE",
667 fontStyleCB.getSelectedItem().toString());
668 Cache.applicationProperties.setProperty("FONT_SIZE",
669 fontSizeCB.getSelectedItem().toString());
671 Cache.applicationProperties.setProperty("ID_ITALICS",
672 Boolean.toString(idItalics.isSelected()));
673 Cache.applicationProperties.setProperty("SHOW_UNCONSERVED",
674 Boolean.toString(showUnconserved.isSelected()));
675 Cache.applicationProperties.setProperty(SHOW_OCCUPANCY,
676 Boolean.toString(showOccupancy.isSelected()));
677 Cache.applicationProperties.setProperty("SHOW_GROUP_CONSENSUS",
678 Boolean.toString(showGroupConsensus.isSelected()));
679 Cache.applicationProperties.setProperty("SHOW_GROUP_CONSERVATION",
680 Boolean.toString(showGroupConservation.isSelected()));
681 Cache.applicationProperties.setProperty("SHOW_CONSENSUS_HISTOGRAM",
682 Boolean.toString(showConsensHistogram.isSelected()));
683 Cache.applicationProperties.setProperty("SHOW_CONSENSUS_LOGO",
684 Boolean.toString(showConsensLogo.isSelected()));
685 Cache.applicationProperties.setProperty("ANTI_ALIAS",
686 Boolean.toString(smoothFont.isSelected()));
687 Cache.applicationProperties.setProperty(SCALE_PROTEIN_TO_CDNA,
688 Boolean.toString(scaleProteinToCdna.isSelected()));
689 Cache.applicationProperties.setProperty("SHOW_NPFEATS_TOOLTIP",
690 Boolean.toString(showNpTooltip.isSelected()));
691 Cache.applicationProperties.setProperty("SHOW_DBREFS_TOOLTIP",
692 Boolean.toString(showDbRefTooltip.isSelected()));
694 Cache.applicationProperties.setProperty("WRAP_ALIGNMENT",
695 Boolean.toString(wrap.isSelected()));
697 Cache.applicationProperties.setProperty("STARTUP_FILE",
698 startupFileTextfield.getText());
699 Cache.applicationProperties.setProperty("SHOW_STARTUP_FILE",
700 Boolean.toString(startupCheckbox.isSelected()));
702 Cache.applicationProperties.setProperty("SORT_ALIGNMENT",
703 sortby.getSelectedItem().toString());
705 // convert description of sort order to enum name for save
706 SequenceAnnotationOrder annSortOrder = SequenceAnnotationOrder
707 .forDescription(sortAnnBy.getSelectedItem().toString());
708 if (annSortOrder != null)
710 Cache.applicationProperties.setProperty(SORT_ANNOTATIONS,
711 annSortOrder.name());
714 final boolean showAutocalcFirst = sortAutocalc.getSelectedIndex() == 0;
715 Cache.applicationProperties.setProperty(SHOW_AUTOCALC_ABOVE,
716 Boolean.valueOf(showAutocalcFirst).toString());
719 * Save Colours settings
721 Cache.applicationProperties.setProperty(DEFAULT_COLOUR_PROT,
722 protColour.getSelectedItem().toString());
723 Cache.applicationProperties.setProperty(DEFAULT_COLOUR_NUC,
724 nucColour.getSelectedItem().toString());
725 Cache.setColourProperty("ANNOTATIONCOLOUR_MIN",
726 minColour.getBackground());
727 Cache.setColourProperty("ANNOTATIONCOLOUR_MAX",
728 maxColour.getBackground());
731 * Save Overview settings
733 Cache.setColourProperty(GAP_COLOUR, gapColour.getBackground());
734 Cache.setColourProperty(HIDDEN_COLOUR, hiddenColour.getBackground());
735 Cache.applicationProperties.setProperty(USE_LEGACY_GAP,
736 Boolean.toString(useLegacyGap.isSelected()));
737 Cache.applicationProperties.setProperty(SHOW_OV_HIDDEN_AT_START,
738 Boolean.toString(showHiddenAtStart.isSelected()));
741 * Save Structure settings
743 Cache.applicationProperties.setProperty(ADD_TEMPFACT_ANN,
744 Boolean.toString(addTempFactor.isSelected()));
745 Cache.applicationProperties.setProperty(ADD_SS_ANN,
746 Boolean.toString(addSecondaryStructure.isSelected()));
747 Cache.applicationProperties.setProperty(USE_RNAVIEW,
748 Boolean.toString(useRnaView.isSelected()));
749 Cache.applicationProperties.setProperty(STRUCT_FROM_PDB,
750 Boolean.toString(structFromPdb.isSelected()));
751 String viewer = structViewer.getSelectedItem().toString();
752 String viewerPath = structureViewerPath.getText();
753 Cache.applicationProperties.setProperty(STRUCTURE_DISPLAY,
755 if (viewer.equals(ViewerType.CHIMERA.name()))
757 Cache.setOrRemove(CHIMERA_PATH, viewerPath);
759 else if (viewer.equals(ViewerType.CHIMERAX.name()))
761 Cache.setOrRemove(CHIMERAX_PATH, viewerPath);
763 else if (viewer.equals(ViewerType.PYMOL.name()))
765 Cache.setOrRemove(PYMOL_PATH, viewerPath);
767 Cache.applicationProperties.setProperty("MAP_WITH_SIFTS",
768 Boolean.toString(siftsMapping.isSelected()));
769 SiftsSettings.setMapWithSifts(siftsMapping.isSelected());
772 * Save Output settings
774 Cache.applicationProperties.setProperty("EPS_RENDERING",
775 ((OptionsParam) epsRendering.getSelectedItem()).getCode());
776 Cache.applicationProperties.setProperty("HTML_RENDERING",
777 ((OptionsParam) htmlRendering.getSelectedItem()).getCode());
778 Cache.applicationProperties.setProperty("SVG_RENDERING",
779 ((OptionsParam) svgRendering.getSelectedItem()).getCode());
782 * Save Connections settings
784 Cache.setOrRemove("DEFAULT_BROWSER", defaultBrowser.getText());
786 jalview.util.BrowserLauncher.resetBrowser();
788 // save user-defined and selected links
789 String menuLinks = sequenceUrlLinks.writeUrlsAsString(true);
790 if (menuLinks.isEmpty())
792 Cache.applicationProperties.remove("SEQUENCE_LINKS");
796 Cache.applicationProperties.setProperty("SEQUENCE_LINKS",
797 menuLinks.toString());
800 String nonMenuLinks = sequenceUrlLinks.writeUrlsAsString(false);
801 if (nonMenuLinks.isEmpty())
803 Cache.applicationProperties.remove("STORED_LINKS");
807 Cache.applicationProperties.setProperty("STORED_LINKS",
808 nonMenuLinks.toString());
811 Cache.applicationProperties.setProperty("DEFAULT_URL",
812 sequenceUrlLinks.getPrimaryUrlId());
814 Cache.applicationProperties.setProperty("USE_PROXY",
815 Boolean.toString(useProxy.isSelected()));
817 Cache.setOrRemove("PROXY_SERVER", proxyServerTB.getText());
819 Cache.setOrRemove("PROXY_PORT", proxyPortTB.getText());
821 if (useProxy.isSelected())
823 System.setProperty("http.proxyHost", proxyServerTB.getText());
824 System.setProperty("http.proxyPort", proxyPortTB.getText());
828 System.setProperty("http.proxyHost", "");
829 System.setProperty("http.proxyPort", "");
831 Cache.setProperty("VERSION_CHECK",
832 Boolean.toString(versioncheck.isSelected()));
833 if (Cache.getProperty("USAGESTATS") != null || usagestats.isSelected())
835 // default is false - we only set this if the user has actively agreed
836 Cache.setProperty("USAGESTATS",
837 Boolean.toString(usagestats.isSelected()));
839 if (!questionnaire.isSelected())
841 Cache.setProperty("NOQUESTIONNAIRES", "true");
845 // special - made easy to edit a property file to disable questionnaires
846 // by just adding the given line
847 Cache.removeProperty("NOQUESTIONNAIRES");
851 * Save Output settings
853 Cache.applicationProperties.setProperty("BLC_JVSUFFIX",
854 Boolean.toString(blcjv.isSelected()));
855 Cache.applicationProperties.setProperty("CLUSTAL_JVSUFFIX",
856 Boolean.toString(clustaljv.isSelected()));
857 Cache.applicationProperties.setProperty("FASTA_JVSUFFIX",
858 Boolean.toString(fastajv.isSelected()));
859 Cache.applicationProperties.setProperty("MSF_JVSUFFIX",
860 Boolean.toString(msfjv.isSelected()));
861 Cache.applicationProperties.setProperty("PFAM_JVSUFFIX",
862 Boolean.toString(pfamjv.isSelected()));
863 Cache.applicationProperties.setProperty("PILEUP_JVSUFFIX",
864 Boolean.toString(pileupjv.isSelected()));
865 Cache.applicationProperties.setProperty("PIR_JVSUFFIX",
866 Boolean.toString(pirjv.isSelected()));
867 Cache.applicationProperties.setProperty("PIR_MODELLER",
868 Boolean.toString(modellerOutput.isSelected()));
869 Cache.applicationProperties.setProperty("EXPORT_EMBBED_BIOJSON",
870 Boolean.toString(embbedBioJSON.isSelected()));
871 jalview.io.PIRFile.useModellerOutput = modellerOutput.isSelected();
873 Cache.applicationProperties.setProperty("FIGURE_AUTOIDWIDTH",
874 Boolean.toString(autoIdWidth.isSelected()));
875 userIdWidth_actionPerformed();
876 Cache.applicationProperties.setProperty("FIGURE_FIXEDIDWIDTH",
877 userIdWidth.getText());
880 * Save Editing settings
882 Cache.applicationProperties.setProperty("AUTO_CALC_CONSENSUS",
883 Boolean.toString(autoCalculateConsCheck.isSelected()));
884 Cache.applicationProperties.setProperty("SORT_BY_TREE",
885 Boolean.toString(sortByTree.isSelected()));
886 Cache.applicationProperties.setProperty("PAD_GAPS",
887 Boolean.toString(padGaps.isSelected()));
889 if (!Platform.isJS())
891 wsPrefs.updateAndRefreshWsMenuConfig(false);
895 * Save Backups settings
897 Cache.applicationProperties.setProperty(BackupFiles.ENABLED,
898 Boolean.toString(enableBackupFiles.isSelected()));
899 int preset = getComboIntStringKey(backupfilesPresetsCombo);
900 Cache.applicationProperties.setProperty(BackupFiles.NS + "_PRESET", Integer.toString(preset));
902 if (preset == BackupFilesPresetEntry.BACKUPFILESSCHEMECUSTOM)
904 BackupFilesPresetEntry customBFPE = getBackupfilesCurrentEntry();
905 BackupFilesPresetEntry.backupfilesPresetEntriesValues.put(
906 BackupFilesPresetEntry.BACKUPFILESSCHEMECUSTOM, customBFPE);
907 Cache.applicationProperties
908 .setProperty(BackupFilesPresetEntry.CUSTOMCONFIG,
909 customBFPE.toString());
912 BackupFilesPresetEntry savedBFPE = BackupFilesPresetEntry.backupfilesPresetEntriesValues
914 Cache.applicationProperties.setProperty(
915 BackupFilesPresetEntry.SAVEDCONFIG, savedBFPE.toString());
917 Cache.saveProperties();
918 Desktop.instance.doConfigureStructurePrefs();
921 frame.setClosed(true);
922 } catch (Exception ex)
928 * Do any necessary validation before saving settings. Return focus to the
929 * first tab which fails validation.
933 private boolean validateSettings()
935 if (!validateStructure())
937 structureTab.requestFocusInWindow();
944 protected boolean validateStructure()
946 return validateViewerPath();
954 public void startupFileTextfield_mouseClicked()
956 // TODO: JAL-3048 not needed for Jalview-JS
957 String fileFormat = Cache.getProperty("DEFAULT_FILE_FORMAT");
958 JalviewFileChooser chooser = JalviewFileChooser
959 .forRead(Cache.getProperty("LAST_DIRECTORY"), fileFormat);
960 chooser.setFileView(new JalviewFileView());
961 chooser.setDialogTitle(
962 MessageManager.getString("label.select_startup_file"));
964 int value = chooser.showOpenDialog(this);
966 if (value == JalviewFileChooser.APPROVE_OPTION)
968 FileFormatI format = chooser.getSelectedFormat();
971 Cache.applicationProperties.setProperty("DEFAULT_FILE_FORMAT",
975 .setText(chooser.getSelectedFile().getAbsolutePath());
986 public void cancel_actionPerformed(ActionEvent e)
990 if (!Platform.isJS())
992 wsPrefs.updateWsMenuConfig(true);
993 wsPrefs.refreshWs_actionPerformed(e);
995 frame.setClosed(true);
996 } catch (Exception ex)
1008 public void annotations_actionPerformed(ActionEvent e)
1010 conservation.setEnabled(annotations.isSelected());
1011 quality.setEnabled(annotations.isSelected());
1012 identity.setEnabled(annotations.isSelected());
1013 showOccupancy.setEnabled(annotations.isSelected());
1014 showGroupConsensus.setEnabled(annotations.isSelected());
1015 showGroupConservation.setEnabled(annotations.isSelected());
1016 showConsensHistogram.setEnabled(annotations.isSelected()
1017 && (identity.isSelected() || showGroupConsensus.isSelected()));
1018 showConsensLogo.setEnabled(annotations.isSelected()
1019 && (identity.isSelected() || showGroupConsensus.isSelected()));
1023 public void newLink_actionPerformed(ActionEvent e)
1025 GSequenceLink link = new GSequenceLink();
1026 boolean valid = false;
1029 if (JvOptionPane.showInternalConfirmDialog(Desktop.desktop, link,
1030 MessageManager.getString("label.new_sequence_url_link"),
1031 JvOptionPane.OK_CANCEL_OPTION, -1,
1032 null) == JvOptionPane.OK_OPTION)
1034 if (link.checkValid())
1036 if (((UrlLinkTableModel) linkUrlTable.getModel())
1037 .isUniqueName(link.getName()))
1039 ((UrlLinkTableModel) linkUrlTable.getModel())
1040 .insertRow(link.getName(), link.getURL());
1045 link.notifyDuplicate();
1058 public void editLink_actionPerformed(ActionEvent e)
1060 GSequenceLink link = new GSequenceLink();
1062 int index = linkUrlTable.getSelectedRow();
1065 // button no longer enabled if row is not selected
1066 Cache.log.debug("Edit with no row selected in linkUrlTable");
1070 int nameCol = ((UrlLinkTableModel) linkUrlTable.getModel())
1072 int urlCol = ((UrlLinkTableModel) linkUrlTable.getModel())
1074 String oldName = linkUrlTable.getValueAt(index, nameCol).toString();
1075 link.setName(oldName);
1076 link.setURL(linkUrlTable.getValueAt(index, urlCol).toString());
1078 boolean valid = false;
1081 if (JvOptionPane.showInternalConfirmDialog(Desktop.desktop, link,
1082 MessageManager.getString("label.edit_sequence_url_link"),
1083 JvOptionPane.OK_CANCEL_OPTION, -1,
1084 null) == JvOptionPane.OK_OPTION)
1086 if (link.checkValid())
1088 if ((oldName.equals(link.getName()))
1089 || (((UrlLinkTableModel) linkUrlTable.getModel())
1090 .isUniqueName(link.getName())))
1092 linkUrlTable.setValueAt(link.getName(), index, nameCol);
1093 linkUrlTable.setValueAt(link.getURL(), index, urlCol);
1098 link.notifyDuplicate();
1111 public void deleteLink_actionPerformed(ActionEvent e)
1113 int index = linkUrlTable.getSelectedRow();
1114 int modelIndex = -1;
1117 // button no longer enabled if row is not selected
1118 Cache.log.debug("Delete with no row selected in linkUrlTable");
1123 modelIndex = linkUrlTable.convertRowIndexToModel(index);
1126 // make sure we use the model index to delete, and not the table index
1127 ((UrlLinkTableModel) linkUrlTable.getModel()).removeRow(modelIndex);
1131 public void defaultBrowser_mouseClicked(MouseEvent e)
1133 // TODO: JAL-3048 not needed for j2s
1134 if (!Platform.isJS()) // BH 2019
1141 JFileChooser chooser = new JFileChooser(".");
1142 chooser.setDialogTitle(
1143 MessageManager.getString("label.select_default_browser"));
1145 int value = chooser.showOpenDialog(this);
1147 if (value == JFileChooser.APPROVE_OPTION)
1149 defaultBrowser.setText(chooser.getSelectedFile().getAbsolutePath());
1158 * jalview.jbgui.GPreferences#showunconserved_actionPerformed(java.awt.event
1162 protected void showunconserved_actionPerformed(ActionEvent e)
1164 // TODO Auto-generated method stub
1165 super.showunconserved_actionPerformed(e);
1168 public static List<String> getGroupURLLinks()
1170 return groupURLLinks;
1174 public void minColour_actionPerformed(JPanel panel)
1176 JalviewColourChooser.showColourChooser(this,
1177 MessageManager.getString("label.select_colour_minimum_value"),
1182 public void maxColour_actionPerformed(JPanel panel)
1184 JalviewColourChooser.showColourChooser(this,
1185 MessageManager.getString("label.select_colour_maximum_value"),
1190 public void gapColour_actionPerformed(JPanel gap)
1192 if (!useLegacyGap.isSelected())
1194 JalviewColourChooser.showColourChooser(this,
1195 MessageManager.getString("label.select_gap_colour"),
1201 public void hiddenColour_actionPerformed(JPanel hidden)
1203 JalviewColourChooser.showColourChooser(this,
1204 MessageManager.getString("label.select_hidden_colour"),
1209 protected void useLegacyGaps_actionPerformed(ActionEvent e)
1211 boolean enabled = useLegacyGap.isSelected();
1214 gapColour.setBackground(
1215 jalview.renderer.OverviewResColourFinder.OVERVIEW_DEFAULT_LEGACY_GAP);
1219 gapColour.setBackground(
1220 jalview.renderer.OverviewResColourFinder.OVERVIEW_DEFAULT_GAP);
1222 gapColour.setEnabled(!enabled);
1223 gapLabel.setEnabled(!enabled);
1227 protected void resetOvDefaults_actionPerformed(ActionEvent e)
1229 useLegacyGap.setSelected(false);
1230 useLegacyGaps_actionPerformed(null);
1231 showHiddenAtStart.setSelected(false);
1232 hiddenColour.setBackground(
1233 jalview.renderer.OverviewResColourFinder.OVERVIEW_DEFAULT_HIDDEN);
1237 protected void userIdWidth_actionPerformed()
1241 String val = userIdWidth.getText().trim();
1242 if (val.length() > 0)
1244 Integer iw = Integer.parseInt(val);
1245 if (iw.intValue() < 12)
1247 throw new NumberFormatException();
1249 userIdWidth.setText(iw.toString());
1251 } catch (NumberFormatException x)
1253 userIdWidth.setText("");
1254 JvOptionPane.showInternalMessageDialog(Desktop.desktop,
1256 .getString("warn.user_defined_width_requirements"),
1257 MessageManager.getString("label.invalid_id_column_width"),
1258 JvOptionPane.WARNING_MESSAGE);
1263 protected void autoIdWidth_actionPerformed()
1265 userIdWidth.setEnabled(!autoIdWidth.isSelected());
1266 userIdWidthlabel.setEnabled(!autoIdWidth.isSelected());
1270 * Returns true if structure viewer path is to a valid executable, else shows
1271 * an error dialog. Does nothing if the path is empty, as is the case for Jmol
1272 * (built in to Jalview) or when Jalview is left to try default paths.
1274 private boolean validateViewerPath()
1276 if (structureViewerPath.getText().trim().length() > 0)
1278 File f = new File(structureViewerPath.getText());
1279 if (!f.canExecute())
1281 JvOptionPane.showInternalMessageDialog(Desktop.desktop,
1282 MessageManager.getString("label.invalid_viewer_path"),
1283 MessageManager.getString("label.invalid_viewer_path"),
1284 JvOptionPane.ERROR_MESSAGE);
1292 * If Chimera or ChimeraX or Pymol is selected, check it can be found on
1293 * default or user-specified path, if not show a warning/help dialog
1296 protected void structureViewer_actionPerformed(String selectedItem)
1298 if (selectedItem.equals(ViewerType.JMOL.name()))
1300 structureViewerPath.setEnabled(false);
1301 structureViewerPathLabel.setEnabled(false);
1304 boolean found = false;
1305 structureViewerPath.setEnabled(true);
1306 structureViewerPathLabel.setEnabled(true);
1307 structureViewerPathLabel.setText(MessageManager
1308 .formatMessage("label.viewer_path", selectedItem));
1311 * Try user-specified and standard paths for structure viewer executable
1313 String viewerPath = "";
1314 List<String> paths = null;
1317 ViewerType viewerType = ViewerType.valueOf(selectedItem);
1324 viewerPath = Cache.getDefault(CHIMERA_PATH, "");
1325 paths = StructureManager.getChimeraPaths(false);
1328 viewerPath = Cache.getDefault(CHIMERAX_PATH, "");
1329 paths = StructureManager.getChimeraPaths(true);
1332 viewerPath = Cache.getDefault(PYMOL_PATH, "");
1333 paths = PymolManager.getPymolPaths();
1336 } catch (IllegalArgumentException e)
1338 // only valid entries should be in the drop-down
1340 structureViewerPath.setText(viewerPath);
1342 paths.add(0, structureViewerPath.getText());
1343 for (String path : paths)
1345 if (new File(path.trim()).canExecute())
1354 String[] options = { "OK", "Help" };
1355 int showHelp = JvOptionPane.showInternalOptionDialog(Desktop.desktop,
1356 JvSwingUtils.wrapTooltip(true,
1357 MessageManager.getString("label.viewer_missing")),
1358 "", JvOptionPane.YES_NO_OPTION, JvOptionPane.WARNING_MESSAGE,
1359 null, options, options[0]);
1360 if (showHelp == JvOptionPane.NO_OPTION)
1364 Help.showHelpWindow(HelpId.StructureViewer);
1365 } catch (HelpSetException e)
1367 e.printStackTrace();
1373 public class OptionsParam
1375 private String name;
1377 private String code;
1379 public OptionsParam(String name, String code)
1385 public String getName()
1390 public void setName(String name)
1395 public String getCode()
1400 public void setCode(String code)
1406 public String toString()
1412 public boolean equals(Object that)
1414 if (!(that instanceof OptionsParam))
1418 return this.code.equalsIgnoreCase(((OptionsParam) that).code);
1422 public int hashCode()
1424 return name.hashCode() + code.hashCode();
1428 private class UrlListSelectionHandler implements ListSelectionListener
1432 public void valueChanged(ListSelectionEvent e)
1434 ListSelectionModel lsm = (ListSelectionModel) e.getSource();
1436 int index = lsm.getMinSelectionIndex();
1439 // no selection, so disable delete/edit buttons
1440 editLink.setEnabled(false);
1441 deleteLink.setEnabled(false);
1444 int modelIndex = linkUrlTable.convertRowIndexToModel(index);
1446 // enable/disable edit and delete link buttons
1447 if (((UrlLinkTableModel) linkUrlTable.getModel())
1448 .isRowDeletable(modelIndex))
1450 deleteLink.setEnabled(true);
1454 deleteLink.setEnabled(false);
1457 if (((UrlLinkTableModel) linkUrlTable.getModel())
1458 .isRowEditable(modelIndex))
1460 editLink.setEnabled(true);
1464 editLink.setEnabled(false);