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 jalview.analysis.AnnotationSorter.SequenceAnnotationOrder;
24 import jalview.bin.Cache;
25 import jalview.gui.Help.HelpId;
26 import jalview.gui.StructureViewer.ViewerType;
27 import jalview.io.BackupFiles;
28 import jalview.io.BackupFilesPresetEntry;
29 import jalview.io.FileFormatI;
30 import jalview.io.JalviewFileChooser;
31 import jalview.io.JalviewFileView;
32 import jalview.jbgui.GPreferences;
33 import jalview.jbgui.GSequenceLink;
34 import jalview.schemes.ColourSchemeI;
35 import jalview.schemes.ColourSchemes;
36 import jalview.schemes.ResidueColourScheme;
37 import jalview.urls.UrlLinkTableModel;
38 import jalview.urls.api.UrlProviderFactoryI;
39 import jalview.urls.api.UrlProviderI;
40 import jalview.urls.desktop.DesktopUrlProviderFactory;
41 import jalview.util.MessageManager;
42 import jalview.util.Platform;
43 import jalview.util.UrlConstants;
44 import jalview.ws.sifts.SiftsSettings;
46 import java.awt.BorderLayout;
47 import java.awt.Color;
48 import java.awt.Component;
49 import java.awt.Dimension;
51 import java.awt.event.ActionEvent;
52 import java.awt.event.ActionListener;
53 import java.awt.event.MouseEvent;
55 import java.util.ArrayList;
56 import java.util.List;
58 import javax.help.HelpSetException;
59 import javax.swing.JColorChooser;
60 import javax.swing.JFileChooser;
61 import javax.swing.JInternalFrame;
62 import javax.swing.JPanel;
63 import javax.swing.ListSelectionModel;
64 import javax.swing.RowFilter;
65 import javax.swing.RowSorter;
66 import javax.swing.SortOrder;
67 import javax.swing.event.DocumentEvent;
68 import javax.swing.event.DocumentListener;
69 import javax.swing.event.ListSelectionEvent;
70 import javax.swing.event.ListSelectionListener;
71 import javax.swing.table.TableCellRenderer;
72 import javax.swing.table.TableColumn;
73 import javax.swing.table.TableModel;
74 import javax.swing.table.TableRowSorter;
76 import ext.edu.ucsf.rbvi.strucviz2.StructureManager;
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 SORT_ANNOTATIONS = "SORT_ANNOTATIONS";
112 public static final String SHOW_AUTOCALC_ABOVE = "SHOW_AUTOCALC_ABOVE";
114 public static final String SHOW_OCCUPANCY = "SHOW_OCCUPANCY";
116 public static final String SHOW_OV_HIDDEN_AT_START = "SHOW_OV_HIDDEN_AT_START";
118 public static final String USE_LEGACY_GAP = "USE_LEGACY_GAP";
120 public static final String GAP_COLOUR = "GAP_COLOUR";
122 public static final String HIDDEN_COLOUR = "HIDDEN_COLOUR";
124 private static final int MIN_FONT_SIZE = 1;
126 private static final int MAX_FONT_SIZE = 30;
129 * Holds name and link separated with | character. Sequence ID must be
130 * $SEQUENCE_ID$ or $SEQUENCE_ID=/.possible | chars ./=$
132 public static UrlProviderI sequenceUrlLinks;
134 public static UrlLinkTableModel dataModel;
137 * Holds name and link separated with | character. Sequence IDS and Sequences
138 * must be $SEQUENCEIDS$ or $SEQUENCEIDS=/.possible | chars ./=$ and
139 * $SEQUENCES$ or $SEQUENCES=/.possible | chars ./=$ and separation character
140 * for first and second token specified after a pipe character at end |,|.
141 * (TODO: proper escape for using | to separate ids or sequences
144 public static List<String> groupURLLinks;
147 // get links selected to be in the menu (SEQUENCE_LINKS)
148 // and links entered by the user but not selected (STORED_LINKS)
149 String inMenuString = Cache.getDefault("SEQUENCE_LINKS", "");
150 String notInMenuString = Cache.getDefault("STORED_LINKS", "");
151 String defaultUrl = Cache.getDefault("DEFAULT_URL",
152 UrlConstants.DEFAULT_LABEL);
154 // if both links lists are empty, add the DEFAULT_URL link
155 // otherwise we assume the default link is in one of the lists
156 if (inMenuString.isEmpty() && notInMenuString.isEmpty())
158 inMenuString = UrlConstants.DEFAULT_STRING;
160 UrlProviderFactoryI factory = new DesktopUrlProviderFactory(defaultUrl,
161 inMenuString, notInMenuString);
162 sequenceUrlLinks = factory.createUrlProvider();
163 dataModel = new UrlLinkTableModel(sequenceUrlLinks);
166 * TODO: reformulate groupURL encoding so two or more can be stored in the
167 * .properties file as '|' separated strings
170 groupURLLinks = new ArrayList<>();
173 JInternalFrame frame;
175 private WsPreferences wsPrefs;
177 private OptionsParam promptEachTimeOpt = new OptionsParam(
178 MessageManager.getString("label.prompt_each_time"),
181 private OptionsParam lineArtOpt = new OptionsParam(
182 MessageManager.getString("label.lineart"), "Lineart");
184 private OptionsParam textOpt = new OptionsParam(
185 MessageManager.getString("action.text"), "Text");
188 * Creates a new Preferences object.
193 frame = new JInternalFrame();
194 frame.setContentPane(this);
195 wsPrefs = new WsPreferences();
196 wsTab.add(wsPrefs, BorderLayout.CENTER);
197 int width = 500, height = 450;
198 new jalview.util.Platform();
199 if (Platform.isAMac())
205 Desktop.addInternalFrame(frame,
206 MessageManager.getString("label.preferences"), width, height);
207 frame.setMinimumSize(new Dimension(width, height));
210 * Set Visual tab defaults
212 seqLimit.setSelected(Cache.getDefault("SHOW_JVSUFFIX", true));
213 rightAlign.setSelected(Cache.getDefault("RIGHT_ALIGN_IDS", false));
214 fullScreen.setSelected(Cache.getDefault("SHOW_FULLSCREEN", false));
215 annotations.setSelected(Cache.getDefault("SHOW_ANNOTATIONS", true));
217 conservation.setSelected(Cache.getDefault("SHOW_CONSERVATION", true));
218 quality.setSelected(Cache.getDefault("SHOW_QUALITY", true));
219 identity.setSelected(Cache.getDefault("SHOW_IDENTITY", true));
220 openoverv.setSelected(Cache.getDefault("SHOW_OVERVIEW", false));
222 .setSelected(Cache.getDefault("SHOW_UNCONSERVED", false));
223 showOccupancy.setSelected(Cache.getDefault(SHOW_OCCUPANCY, false));
225 .setSelected(Cache.getDefault("SHOW_GROUP_CONSENSUS", false));
226 showGroupConservation.setSelected(
227 Cache.getDefault("SHOW_GROUP_CONSERVATION", false));
228 showConsensHistogram.setSelected(
229 Cache.getDefault("SHOW_CONSENSUS_HISTOGRAM", true));
231 .setSelected(Cache.getDefault("SHOW_CONSENSUS_LOGO", false));
233 .setSelected(Cache.getDefault("SHOW_NPFEATS_TOOLTIP", true));
235 .setSelected(Cache.getDefault("SHOW_DBREFS_TOOLTIP", true));
237 String[] fonts = java.awt.GraphicsEnvironment
238 .getLocalGraphicsEnvironment().getAvailableFontFamilyNames();
239 for (int i = 0; i < fonts.length; i++)
241 fontNameCB.addItem(fonts[i]);
244 for (int i = MIN_FONT_SIZE; i <= MAX_FONT_SIZE; i++)
246 fontSizeCB.addItem(i + "");
249 fontStyleCB.addItem("plain");
250 fontStyleCB.addItem("bold");
251 fontStyleCB.addItem("italic");
253 fontNameCB.setSelectedItem(Cache.getDefault("FONT_NAME", "SansSerif"));
254 fontSizeCB.setSelectedItem(Cache.getDefault("FONT_SIZE", "10"));
255 fontStyleCB.setSelectedItem(
256 Cache.getDefault("FONT_STYLE", Font.PLAIN + ""));
258 smoothFont.setSelected(Cache.getDefault("ANTI_ALIAS", true));
260 .setSelected(Cache.getDefault(SCALE_PROTEIN_TO_CDNA, false));
262 idItalics.setSelected(Cache.getDefault("ID_ITALICS", true));
264 wrap.setSelected(Cache.getDefault("WRAP_ALIGNMENT", false));
266 gapSymbolCB.addItem("-");
267 gapSymbolCB.addItem(".");
269 gapSymbolCB.setSelectedItem(Cache.getDefault("GAP_SYMBOL", "-"));
271 sortby.addItem("No sort");
272 sortby.addItem("Id");
273 sortby.addItem("Pairwise Identity");
274 sortby.setSelectedItem(Cache.getDefault("SORT_ALIGNMENT", "No sort"));
276 sortAnnBy.addItem(SequenceAnnotationOrder.NONE.toString());
278 .addItem(SequenceAnnotationOrder.SEQUENCE_AND_LABEL.toString());
280 .addItem(SequenceAnnotationOrder.LABEL_AND_SEQUENCE.toString());
281 SequenceAnnotationOrder savedSort = SequenceAnnotationOrder
282 .valueOf(Cache.getDefault(SORT_ANNOTATIONS,
283 SequenceAnnotationOrder.NONE.name()));
284 sortAnnBy.setSelectedItem(savedSort.toString());
286 sortAutocalc.addItem("Autocalculated first");
287 sortAutocalc.addItem("Autocalculated last");
288 final boolean showAbove = Cache.getDefault(SHOW_AUTOCALC_ABOVE, true);
289 sortAutocalc.setSelectedItem(showAbove ? sortAutocalc.getItemAt(0)
290 : sortAutocalc.getItemAt(1));
292 .setSelected(Cache.getDefault("SHOW_STARTUP_FILE", true));
293 startupFileTextfield.setText(Cache.getDefault("STARTUP_FILE",
294 Cache.getDefault("www.jalview.org", "http://www.jalview.org")
295 + "/examples/exampleFile_2_3.jar"));
298 * Set Colours tab defaults
300 protColour.addItem(ResidueColourScheme.NONE);
301 nucColour.addItem(ResidueColourScheme.NONE);
302 for (ColourSchemeI cs : ColourSchemes.getInstance().getColourSchemes())
304 String name = cs.getSchemeName();
305 protColour.addItem(name);
306 nucColour.addItem(name);
308 String oldProp = Cache.getDefault(DEFAULT_COLOUR,
309 ResidueColourScheme.NONE);
310 String newProp = Cache.getDefault(DEFAULT_COLOUR_PROT, null);
311 protColour.setSelectedItem(newProp != null ? newProp : oldProp);
312 newProp = Cache.getDefault(DEFAULT_COLOUR_NUC, null);
313 nucColour.setSelectedItem(newProp != null ? newProp : oldProp);
314 minColour.setBackground(
315 Cache.getDefaultColour("ANNOTATIONCOLOUR_MIN", Color.orange));
316 maxColour.setBackground(
317 Cache.getDefaultColour("ANNOTATIONCOLOUR_MAX", Color.red));
320 * Set overview panel defaults
322 gapColour.setBackground(
323 Cache.getDefaultColour(GAP_COLOUR,
324 jalview.renderer.OverviewResColourFinder.OVERVIEW_DEFAULT_GAP));
325 hiddenColour.setBackground(
326 Cache.getDefaultColour(HIDDEN_COLOUR,
327 jalview.renderer.OverviewResColourFinder.OVERVIEW_DEFAULT_HIDDEN));
328 useLegacyGap.setSelected(Cache.getDefault(USE_LEGACY_GAP, false));
329 gapLabel.setEnabled(!useLegacyGap.isSelected());
330 gapColour.setEnabled(!useLegacyGap.isSelected());
332 .setSelected(Cache.getDefault(SHOW_OV_HIDDEN_AT_START, false));
335 * Set Structure tab defaults.
337 final boolean structSelected = Cache.getDefault(STRUCT_FROM_PDB, false);
338 structFromPdb.setSelected(structSelected);
339 useRnaView.setSelected(Cache.getDefault(USE_RNAVIEW, false));
340 useRnaView.setEnabled(structSelected);
341 addSecondaryStructure.setSelected(Cache.getDefault(ADD_SS_ANN, false));
342 addSecondaryStructure.setEnabled(structSelected);
343 addTempFactor.setSelected(Cache.getDefault(ADD_TEMPFACT_ANN, false));
344 addTempFactor.setEnabled(structSelected);
345 String viewerType = Cache.getDefault(STRUCTURE_DISPLAY, ViewerType.JMOL.name());
346 structViewer.setSelectedItem(viewerType);
347 boolean isChimeraX = viewerType.equals(ViewerType.CHIMERAX.name());
348 if (viewerType.equals(ViewerType.JMOL.name()))
350 chimeraPath.setText("");
354 chimeraPath.setText(Cache
355 .getDefault(isChimeraX ? CHIMERAX_PATH : CHIMERA_PATH, ""));
357 chimeraPath.addActionListener(new ActionListener()
360 public void actionPerformed(ActionEvent e)
362 if (validateChimeraPath())
364 Cache.setProperty(structViewer.getSelectedItem()
365 .equals(ViewerType.CHIMERAX.name())
367 : CHIMERA_PATH, chimeraPath.getText());
372 if (Cache.getDefault("MAP_WITH_SIFTS", false))
374 siftsMapping.setSelected(true);
378 nwMapping.setSelected(true);
382 .setMapWithSifts(Cache.getDefault("MAP_WITH_SIFTS", false));
385 * Set Connections tab defaults
389 linkUrlTable.setModel(dataModel);
390 final TableRowSorter<TableModel> sorter = new TableRowSorter<>(
391 linkUrlTable.getModel());
392 linkUrlTable.setRowSorter(sorter);
393 List<RowSorter.SortKey> sortKeys = new ArrayList<>();
395 UrlLinkTableModel m = (UrlLinkTableModel) linkUrlTable.getModel();
396 sortKeys.add(new RowSorter.SortKey(m.getPrimaryColumn(),
397 SortOrder.DESCENDING));
398 sortKeys.add(new RowSorter.SortKey(m.getSelectedColumn(),
399 SortOrder.DESCENDING));
401 new RowSorter.SortKey(m.getNameColumn(), SortOrder.ASCENDING));
403 sorter.setSortKeys(sortKeys);
407 ActionListener onReset;
408 onReset = new ActionListener()
411 public void actionPerformed(ActionEvent e)
413 filterTB.setText("");
414 sorter.setRowFilter(RowFilter.regexFilter(""));
418 doReset.addActionListener(onReset);
420 // filter to display only custom urls
421 final RowFilter<TableModel, Object> customUrlFilter = new RowFilter<>()
424 public boolean include(
425 Entry<? extends TableModel, ? extends Object> entry)
427 return ((UrlLinkTableModel) entry.getModel()).isUserEntry(entry);
431 final TableRowSorter<TableModel> customSorter = new TableRowSorter<>(
432 linkUrlTable.getModel());
433 customSorter.setRowFilter(customUrlFilter);
435 ActionListener onCustomOnly;
436 onCustomOnly = new ActionListener()
439 public void actionPerformed(ActionEvent e)
441 filterTB.setText("");
442 sorter.setRowFilter(customUrlFilter);
445 userOnly.addActionListener(onCustomOnly);
447 filterTB.getDocument().addDocumentListener(new DocumentListener()
449 String caseInsensitiveFlag = "(?i)";
452 public void changedUpdate(DocumentEvent e)
454 sorter.setRowFilter(RowFilter
455 .regexFilter(caseInsensitiveFlag + filterTB.getText()));
459 public void removeUpdate(DocumentEvent e)
461 sorter.setRowFilter(RowFilter
462 .regexFilter(caseInsensitiveFlag + filterTB.getText()));
466 public void insertUpdate(DocumentEvent e)
468 sorter.setRowFilter(RowFilter
469 .regexFilter(caseInsensitiveFlag + filterTB.getText()));
473 // set up list selection functionality
474 linkUrlTable.getSelectionModel()
475 .addListSelectionListener(new UrlListSelectionHandler());
477 // set up radio buttons
478 int onClickCol = ((UrlLinkTableModel) linkUrlTable.getModel())
480 String onClickName = linkUrlTable.getColumnName(onClickCol);
481 linkUrlTable.getColumn(onClickName)
482 .setCellRenderer(new RadioButtonRenderer());
483 linkUrlTable.getColumn(onClickName)
484 .setCellEditor(new RadioButtonEditor());
486 // get boolean columns and resize those to min possible
487 for (int column = 0; column < linkUrlTable.getColumnCount(); column++)
489 if (linkUrlTable.getModel().getColumnClass(column)
490 .equals(Boolean.class))
492 TableColumn tableColumn = linkUrlTable.getColumnModel()
494 int preferredWidth = tableColumn.getMinWidth();
496 TableCellRenderer cellRenderer = linkUrlTable.getCellRenderer(0,
498 Component c = linkUrlTable.prepareRenderer(cellRenderer, 0, column);
499 int cwidth = c.getPreferredSize().width
500 + linkUrlTable.getIntercellSpacing().width;
501 preferredWidth = Math.max(preferredWidth, cwidth);
503 tableColumn.setPreferredWidth(preferredWidth);
507 useProxy.setSelected(Cache.getDefault("USE_PROXY", false));
508 useProxy_actionPerformed(); // make sure useProxy is correctly initialised
509 proxyServerTB.setText(Cache.getDefault("PROXY_SERVER", ""));
510 proxyPortTB.setText(Cache.getDefault("PROXY_PORT", ""));
512 defaultBrowser.setText(Cache.getDefault("DEFAULT_BROWSER", ""));
514 usagestats.setSelected(Cache.getDefault("USAGESTATS", false));
515 // note antisense here: default is true
517 .setSelected(Cache.getProperty("NOQUESTIONNAIRES") == null);
518 versioncheck.setSelected(Cache.getDefault("VERSION_CHECK", true));
521 * Set Output tab defaults
523 epsRendering.addItem(promptEachTimeOpt);
524 epsRendering.addItem(lineArtOpt);
525 epsRendering.addItem(textOpt);
526 String defaultEPS = Cache.getDefault("EPS_RENDERING",
528 if (defaultEPS.equalsIgnoreCase("Text"))
530 epsRendering.setSelectedItem(textOpt);
532 else if (defaultEPS.equalsIgnoreCase("Lineart"))
534 epsRendering.setSelectedItem(lineArtOpt);
538 epsRendering.setSelectedItem(promptEachTimeOpt);
540 autoIdWidth.setSelected(Cache.getDefault("FIGURE_AUTOIDWIDTH", false));
541 userIdWidth.setEnabled(!autoIdWidth.isSelected());
542 userIdWidthlabel.setEnabled(!autoIdWidth.isSelected());
543 Integer wi = Cache.getIntegerProperty("FIGURE_FIXEDIDWIDTH");
544 userIdWidth.setText(wi == null ? "" : wi.toString());
545 // TODO: refactor to use common enum via FormatAdapter and allow extension
546 // for new flat file formats
547 blcjv.setSelected(Cache.getDefault("BLC_JVSUFFIX", true));
548 clustaljv.setSelected(Cache.getDefault("CLUSTAL_JVSUFFIX", true));
549 fastajv.setSelected(Cache.getDefault("FASTA_JVSUFFIX", true));
550 msfjv.setSelected(Cache.getDefault("MSF_JVSUFFIX", true));
551 pfamjv.setSelected(Cache.getDefault("PFAM_JVSUFFIX", true));
552 pileupjv.setSelected(Cache.getDefault("PILEUP_JVSUFFIX", true));
553 pirjv.setSelected(Cache.getDefault("PIR_JVSUFFIX", true));
554 modellerOutput.setSelected(Cache.getDefault("PIR_MODELLER", false));
556 .setSelected(Cache.getDefault("EXPORT_EMBBED_BIOJSON", true));
559 * Set Editing tab defaults
561 autoCalculateConsCheck
562 .setSelected(Cache.getDefault("AUTO_CALC_CONSENSUS", true));
563 padGaps.setSelected(Cache.getDefault("PAD_GAPS", false));
564 sortByTree.setSelected(Cache.getDefault("SORT_BY_TREE", false));
566 annotations_actionPerformed(null); // update the display of the annotation
571 * Set Backups tab defaults
573 loadLastSavedBackupsOptions();
577 * Save user selections on the Preferences tabs to the Cache and write out to
583 public void ok_actionPerformed(ActionEvent e)
585 if (!validateSettings())
591 * Save Visual settings
593 Cache.applicationProperties.setProperty("SHOW_JVSUFFIX",
594 Boolean.toString(seqLimit.isSelected()));
595 Cache.applicationProperties.setProperty("RIGHT_ALIGN_IDS",
596 Boolean.toString(rightAlign.isSelected()));
597 Cache.applicationProperties.setProperty("SHOW_FULLSCREEN",
598 Boolean.toString(fullScreen.isSelected()));
599 Cache.applicationProperties.setProperty("SHOW_OVERVIEW",
600 Boolean.toString(openoverv.isSelected()));
601 Cache.applicationProperties.setProperty("SHOW_ANNOTATIONS",
602 Boolean.toString(annotations.isSelected()));
603 Cache.applicationProperties.setProperty("SHOW_CONSERVATION",
604 Boolean.toString(conservation.isSelected()));
605 Cache.applicationProperties.setProperty("SHOW_QUALITY",
606 Boolean.toString(quality.isSelected()));
607 Cache.applicationProperties.setProperty("SHOW_IDENTITY",
608 Boolean.toString(identity.isSelected()));
610 Cache.applicationProperties.setProperty("GAP_SYMBOL",
611 gapSymbolCB.getSelectedItem().toString());
613 Cache.applicationProperties.setProperty("FONT_NAME",
614 fontNameCB.getSelectedItem().toString());
615 Cache.applicationProperties.setProperty("FONT_STYLE",
616 fontStyleCB.getSelectedItem().toString());
617 Cache.applicationProperties.setProperty("FONT_SIZE",
618 fontSizeCB.getSelectedItem().toString());
620 Cache.applicationProperties.setProperty("ID_ITALICS",
621 Boolean.toString(idItalics.isSelected()));
622 Cache.applicationProperties.setProperty("SHOW_UNCONSERVED",
623 Boolean.toString(showUnconserved.isSelected()));
624 Cache.applicationProperties.setProperty(SHOW_OCCUPANCY,
625 Boolean.toString(showOccupancy.isSelected()));
626 Cache.applicationProperties.setProperty("SHOW_GROUP_CONSENSUS",
627 Boolean.toString(showGroupConsensus.isSelected()));
628 Cache.applicationProperties.setProperty("SHOW_GROUP_CONSERVATION",
629 Boolean.toString(showGroupConservation.isSelected()));
630 Cache.applicationProperties.setProperty("SHOW_CONSENSUS_HISTOGRAM",
631 Boolean.toString(showConsensHistogram.isSelected()));
632 Cache.applicationProperties.setProperty("SHOW_CONSENSUS_LOGO",
633 Boolean.toString(showConsensLogo.isSelected()));
634 Cache.applicationProperties.setProperty("ANTI_ALIAS",
635 Boolean.toString(smoothFont.isSelected()));
636 Cache.applicationProperties.setProperty(SCALE_PROTEIN_TO_CDNA,
637 Boolean.toString(scaleProteinToCdna.isSelected()));
638 Cache.applicationProperties.setProperty("SHOW_NPFEATS_TOOLTIP",
639 Boolean.toString(showNpTooltip.isSelected()));
640 Cache.applicationProperties.setProperty("SHOW_DBREFS_TOOLTIP",
641 Boolean.toString(showDbRefTooltip.isSelected()));
643 Cache.applicationProperties.setProperty("WRAP_ALIGNMENT",
644 Boolean.toString(wrap.isSelected()));
646 Cache.applicationProperties.setProperty("STARTUP_FILE",
647 startupFileTextfield.getText());
648 Cache.applicationProperties.setProperty("SHOW_STARTUP_FILE",
649 Boolean.toString(startupCheckbox.isSelected()));
651 Cache.applicationProperties.setProperty("SORT_ALIGNMENT",
652 sortby.getSelectedItem().toString());
654 // convert description of sort order to enum name for save
655 SequenceAnnotationOrder annSortOrder = SequenceAnnotationOrder
656 .forDescription(sortAnnBy.getSelectedItem().toString());
657 if (annSortOrder != null)
659 Cache.applicationProperties.setProperty(SORT_ANNOTATIONS,
660 annSortOrder.name());
663 final boolean showAutocalcFirst = sortAutocalc.getSelectedIndex() == 0;
664 Cache.applicationProperties.setProperty(SHOW_AUTOCALC_ABOVE,
665 Boolean.valueOf(showAutocalcFirst).toString());
668 * Save Colours settings
670 Cache.applicationProperties.setProperty(DEFAULT_COLOUR_PROT,
671 protColour.getSelectedItem().toString());
672 Cache.applicationProperties.setProperty(DEFAULT_COLOUR_NUC,
673 nucColour.getSelectedItem().toString());
674 Cache.setColourProperty("ANNOTATIONCOLOUR_MIN",
675 minColour.getBackground());
676 Cache.setColourProperty("ANNOTATIONCOLOUR_MAX",
677 maxColour.getBackground());
680 * Save Overview settings
682 Cache.setColourProperty(GAP_COLOUR, gapColour.getBackground());
683 Cache.setColourProperty(HIDDEN_COLOUR, hiddenColour.getBackground());
684 Cache.applicationProperties.setProperty(USE_LEGACY_GAP,
685 Boolean.toString(useLegacyGap.isSelected()));
686 Cache.applicationProperties.setProperty(SHOW_OV_HIDDEN_AT_START,
687 Boolean.toString(showHiddenAtStart.isSelected()));
690 * Save Structure settings
692 Cache.applicationProperties.setProperty(ADD_TEMPFACT_ANN,
693 Boolean.toString(addTempFactor.isSelected()));
694 Cache.applicationProperties.setProperty(ADD_SS_ANN,
695 Boolean.toString(addSecondaryStructure.isSelected()));
696 Cache.applicationProperties.setProperty(USE_RNAVIEW,
697 Boolean.toString(useRnaView.isSelected()));
698 Cache.applicationProperties.setProperty(STRUCT_FROM_PDB,
699 Boolean.toString(structFromPdb.isSelected()));
700 Cache.applicationProperties.setProperty(STRUCTURE_DISPLAY,
701 structViewer.getSelectedItem().toString());
702 boolean isChimeraX = structViewer.getSelectedItem().toString()
703 .equals(ViewerType.CHIMERAX.name());
704 Cache.setOrRemove(isChimeraX ? CHIMERAX_PATH : CHIMERA_PATH,
705 chimeraPath.getText());
706 Cache.applicationProperties.setProperty("MAP_WITH_SIFTS",
707 Boolean.toString(siftsMapping.isSelected()));
708 SiftsSettings.setMapWithSifts(siftsMapping.isSelected());
711 * Save Output settings
713 Cache.applicationProperties.setProperty("EPS_RENDERING",
714 ((OptionsParam) epsRendering.getSelectedItem()).getCode());
717 * Save Connections settings
719 Cache.setOrRemove("DEFAULT_BROWSER", defaultBrowser.getText());
721 jalview.util.BrowserLauncher.resetBrowser();
723 // save user-defined and selected links
724 String menuLinks = sequenceUrlLinks.writeUrlsAsString(true);
725 if (menuLinks.isEmpty())
727 Cache.applicationProperties.remove("SEQUENCE_LINKS");
731 Cache.applicationProperties.setProperty("SEQUENCE_LINKS",
732 menuLinks.toString());
735 String nonMenuLinks = sequenceUrlLinks.writeUrlsAsString(false);
736 if (nonMenuLinks.isEmpty())
738 Cache.applicationProperties.remove("STORED_LINKS");
742 Cache.applicationProperties.setProperty("STORED_LINKS",
743 nonMenuLinks.toString());
746 Cache.applicationProperties.setProperty("DEFAULT_URL",
747 sequenceUrlLinks.getPrimaryUrlId());
749 Cache.applicationProperties.setProperty("USE_PROXY",
750 Boolean.toString(useProxy.isSelected()));
752 Cache.setOrRemove("PROXY_SERVER", proxyServerTB.getText());
754 Cache.setOrRemove("PROXY_PORT", proxyPortTB.getText());
756 if (useProxy.isSelected())
758 System.setProperty("http.proxyHost", proxyServerTB.getText());
759 System.setProperty("http.proxyPort", proxyPortTB.getText());
763 System.setProperty("http.proxyHost", "");
764 System.setProperty("http.proxyPort", "");
766 Cache.setProperty("VERSION_CHECK",
767 Boolean.toString(versioncheck.isSelected()));
768 if (Cache.getProperty("USAGESTATS") != null || usagestats.isSelected())
770 // default is false - we only set this if the user has actively agreed
771 Cache.setProperty("USAGESTATS",
772 Boolean.toString(usagestats.isSelected()));
774 if (!questionnaire.isSelected())
776 Cache.setProperty("NOQUESTIONNAIRES", "true");
780 // special - made easy to edit a property file to disable questionnaires
781 // by just adding the given line
782 Cache.removeProperty("NOQUESTIONNAIRES");
786 * Save Output settings
788 Cache.applicationProperties.setProperty("BLC_JVSUFFIX",
789 Boolean.toString(blcjv.isSelected()));
790 Cache.applicationProperties.setProperty("CLUSTAL_JVSUFFIX",
791 Boolean.toString(clustaljv.isSelected()));
792 Cache.applicationProperties.setProperty("FASTA_JVSUFFIX",
793 Boolean.toString(fastajv.isSelected()));
794 Cache.applicationProperties.setProperty("MSF_JVSUFFIX",
795 Boolean.toString(msfjv.isSelected()));
796 Cache.applicationProperties.setProperty("PFAM_JVSUFFIX",
797 Boolean.toString(pfamjv.isSelected()));
798 Cache.applicationProperties.setProperty("PILEUP_JVSUFFIX",
799 Boolean.toString(pileupjv.isSelected()));
800 Cache.applicationProperties.setProperty("PIR_JVSUFFIX",
801 Boolean.toString(pirjv.isSelected()));
802 Cache.applicationProperties.setProperty("PIR_MODELLER",
803 Boolean.toString(modellerOutput.isSelected()));
804 Cache.applicationProperties.setProperty("EXPORT_EMBBED_BIOJSON",
805 Boolean.toString(embbedBioJSON.isSelected()));
806 jalview.io.PIRFile.useModellerOutput = modellerOutput.isSelected();
808 Cache.applicationProperties.setProperty("FIGURE_AUTOIDWIDTH",
809 Boolean.toString(autoIdWidth.isSelected()));
810 userIdWidth_actionPerformed();
811 Cache.applicationProperties.setProperty("FIGURE_FIXEDIDWIDTH",
812 userIdWidth.getText());
815 * Save Editing settings
817 Cache.applicationProperties.setProperty("AUTO_CALC_CONSENSUS",
818 Boolean.toString(autoCalculateConsCheck.isSelected()));
819 Cache.applicationProperties.setProperty("SORT_BY_TREE",
820 Boolean.toString(sortByTree.isSelected()));
821 Cache.applicationProperties.setProperty("PAD_GAPS",
822 Boolean.toString(padGaps.isSelected()));
824 wsPrefs.updateAndRefreshWsMenuConfig(false);
827 * Save Backups settings
829 Cache.applicationProperties.setProperty(BackupFiles.ENABLED,
830 Boolean.toString(enableBackupFiles.isSelected()));
831 int preset = getComboIntStringKey(backupfilesPresetsCombo);
832 Cache.applicationProperties.setProperty(BackupFiles.NS + "_PRESET", Integer.toString(preset));
834 if (preset == BackupFilesPresetEntry.BACKUPFILESSCHEMECUSTOM)
836 BackupFilesPresetEntry customBFPE = getBackupfilesCurrentEntry();
837 BackupFilesPresetEntry.backupfilesPresetEntriesValues.put(
838 BackupFilesPresetEntry.BACKUPFILESSCHEMECUSTOM, customBFPE);
839 Cache.applicationProperties
840 .setProperty(BackupFilesPresetEntry.CUSTOMCONFIG,
841 customBFPE.toString());
844 BackupFilesPresetEntry savedBFPE = BackupFilesPresetEntry.backupfilesPresetEntriesValues
846 Cache.applicationProperties.setProperty(
847 BackupFilesPresetEntry.SAVEDCONFIG, savedBFPE.toString());
849 Cache.saveProperties();
850 Desktop.instance.doConfigureStructurePrefs();
853 frame.setClosed(true);
854 } catch (Exception ex)
860 * Do any necessary validation before saving settings. Return focus to the
861 * first tab which fails validation.
865 private boolean validateSettings()
867 if (!validateStructure())
869 structureTab.requestFocusInWindow();
876 protected boolean validateStructure()
878 return validateChimeraPath();
886 public void startupFileTextfield_mouseClicked()
888 String fileFormat = Cache.getProperty("DEFAULT_FILE_FORMAT");
889 JalviewFileChooser chooser = JalviewFileChooser
890 .forRead(Cache.getProperty("LAST_DIRECTORY"), fileFormat);
891 chooser.setFileView(new JalviewFileView());
892 chooser.setDialogTitle(
893 MessageManager.getString("label.select_startup_file"));
895 int value = chooser.showOpenDialog(this);
897 if (value == JalviewFileChooser.APPROVE_OPTION)
899 FileFormatI format = chooser.getSelectedFormat();
902 Cache.applicationProperties.setProperty("DEFAULT_FILE_FORMAT",
906 .setText(chooser.getSelectedFile().getAbsolutePath());
917 public void cancel_actionPerformed(ActionEvent e)
921 wsPrefs.updateWsMenuConfig(true);
922 wsPrefs.refreshWs_actionPerformed(e);
923 frame.setClosed(true);
924 } catch (Exception ex)
936 public void annotations_actionPerformed(ActionEvent e)
938 conservation.setEnabled(annotations.isSelected());
939 quality.setEnabled(annotations.isSelected());
940 identity.setEnabled(annotations.isSelected());
941 showOccupancy.setEnabled(annotations.isSelected());
942 showGroupConsensus.setEnabled(annotations.isSelected());
943 showGroupConservation.setEnabled(annotations.isSelected());
944 showConsensHistogram.setEnabled(annotations.isSelected()
945 && (identity.isSelected() || showGroupConsensus.isSelected()));
946 showConsensLogo.setEnabled(annotations.isSelected()
947 && (identity.isSelected() || showGroupConsensus.isSelected()));
951 public void newLink_actionPerformed(ActionEvent e)
953 GSequenceLink link = new GSequenceLink();
954 boolean valid = false;
957 if (JvOptionPane.showInternalConfirmDialog(Desktop.desktop, link,
958 MessageManager.getString("label.new_sequence_url_link"),
959 JvOptionPane.OK_CANCEL_OPTION, -1,
960 null) == JvOptionPane.OK_OPTION)
962 if (link.checkValid())
964 if (((UrlLinkTableModel) linkUrlTable.getModel())
965 .isUniqueName(link.getName()))
967 ((UrlLinkTableModel) linkUrlTable.getModel())
968 .insertRow(link.getName(), link.getURL());
973 link.notifyDuplicate();
986 public void editLink_actionPerformed(ActionEvent e)
988 GSequenceLink link = new GSequenceLink();
990 int index = linkUrlTable.getSelectedRow();
993 // button no longer enabled if row is not selected
994 Cache.log.debug("Edit with no row selected in linkUrlTable");
998 int nameCol = ((UrlLinkTableModel) linkUrlTable.getModel())
1000 int urlCol = ((UrlLinkTableModel) linkUrlTable.getModel())
1002 String oldName = linkUrlTable.getValueAt(index, nameCol).toString();
1003 link.setName(oldName);
1004 link.setURL(linkUrlTable.getValueAt(index, urlCol).toString());
1006 boolean valid = false;
1009 if (JvOptionPane.showInternalConfirmDialog(Desktop.desktop, link,
1010 MessageManager.getString("label.edit_sequence_url_link"),
1011 JvOptionPane.OK_CANCEL_OPTION, -1,
1012 null) == JvOptionPane.OK_OPTION)
1014 if (link.checkValid())
1016 if ((oldName.equals(link.getName()))
1017 || (((UrlLinkTableModel) linkUrlTable.getModel())
1018 .isUniqueName(link.getName())))
1020 linkUrlTable.setValueAt(link.getName(), index, nameCol);
1021 linkUrlTable.setValueAt(link.getURL(), index, urlCol);
1026 link.notifyDuplicate();
1039 public void deleteLink_actionPerformed(ActionEvent e)
1041 int index = linkUrlTable.getSelectedRow();
1042 int modelIndex = -1;
1045 // button no longer enabled if row is not selected
1046 Cache.log.debug("Delete with no row selected in linkUrlTable");
1051 modelIndex = linkUrlTable.convertRowIndexToModel(index);
1054 // make sure we use the model index to delete, and not the table index
1055 ((UrlLinkTableModel) linkUrlTable.getModel()).removeRow(modelIndex);
1059 public void defaultBrowser_mouseClicked(MouseEvent e)
1061 JFileChooser chooser = new JFileChooser(".");
1062 chooser.setDialogTitle(
1063 MessageManager.getString("label.select_default_browser"));
1065 int value = chooser.showOpenDialog(this);
1067 if (value == JFileChooser.APPROVE_OPTION)
1069 defaultBrowser.setText(chooser.getSelectedFile().getAbsolutePath());
1078 * jalview.jbgui.GPreferences#showunconserved_actionPerformed(java.awt.event
1082 protected void showunconserved_actionPerformed(ActionEvent e)
1084 // TODO Auto-generated method stub
1085 super.showunconserved_actionPerformed(e);
1088 public static List<String> getGroupURLLinks()
1090 return groupURLLinks;
1094 public void minColour_actionPerformed(JPanel panel)
1096 Color col = JColorChooser.showDialog(this,
1097 MessageManager.getString("label.select_colour_minimum_value"),
1098 minColour.getBackground());
1101 panel.setBackground(col);
1107 public void maxColour_actionPerformed(JPanel panel)
1109 Color col = JColorChooser.showDialog(this,
1110 MessageManager.getString("label.select_colour_maximum_value"),
1111 maxColour.getBackground());
1114 panel.setBackground(col);
1120 public void gapColour_actionPerformed(JPanel gap)
1122 if (!useLegacyGap.isSelected())
1124 Color col = JColorChooser.showDialog(this,
1125 MessageManager.getString("label.select_gap_colour"),
1126 gapColour.getBackground());
1129 gap.setBackground(col);
1136 public void hiddenColour_actionPerformed(JPanel hidden)
1138 Color col = JColorChooser.showDialog(this,
1139 MessageManager.getString("label.select_hidden_colour"),
1140 hiddenColour.getBackground());
1143 hidden.setBackground(col);
1149 protected void useLegacyGaps_actionPerformed(ActionEvent e)
1151 boolean enabled = useLegacyGap.isSelected();
1154 gapColour.setBackground(
1155 jalview.renderer.OverviewResColourFinder.OVERVIEW_DEFAULT_LEGACY_GAP);
1159 gapColour.setBackground(
1160 jalview.renderer.OverviewResColourFinder.OVERVIEW_DEFAULT_GAP);
1162 gapColour.setEnabled(!enabled);
1163 gapLabel.setEnabled(!enabled);
1167 protected void resetOvDefaults_actionPerformed(ActionEvent e)
1169 useLegacyGap.setSelected(false);
1170 useLegacyGaps_actionPerformed(null);
1171 showHiddenAtStart.setSelected(false);
1172 hiddenColour.setBackground(
1173 jalview.renderer.OverviewResColourFinder.OVERVIEW_DEFAULT_HIDDEN);
1177 protected void userIdWidth_actionPerformed()
1181 String val = userIdWidth.getText().trim();
1182 if (val.length() > 0)
1184 Integer iw = Integer.parseInt(val);
1185 if (iw.intValue() < 12)
1187 throw new NumberFormatException();
1189 userIdWidth.setText(iw.toString());
1191 } catch (NumberFormatException x)
1193 JvOptionPane.showInternalMessageDialog(Desktop.desktop,
1195 .getString("warn.user_defined_width_requirements"),
1196 MessageManager.getString("label.invalid_id_column_width"),
1197 JvOptionPane.WARNING_MESSAGE);
1198 userIdWidth.setText("");
1203 protected void autoIdWidth_actionPerformed()
1205 userIdWidth.setEnabled(!autoIdWidth.isSelected());
1206 userIdWidthlabel.setEnabled(!autoIdWidth.isSelected());
1210 * Returns true if chimera path is to a valid executable, else show an error
1213 private boolean validateChimeraPath()
1215 if (chimeraPath.getText().trim().length() > 0)
1217 File f = new File(chimeraPath.getText());
1218 if (!f.canExecute())
1220 JvOptionPane.showInternalMessageDialog(Desktop.desktop,
1221 MessageManager.getString("label.invalid_chimera_path"),
1222 MessageManager.getString("label.invalid_name"),
1223 JvOptionPane.ERROR_MESSAGE);
1231 * If Chimera or ChimeraX is selected, check it can be found on default or
1232 * user-specified path, if not show a warning/help dialog.
1235 protected void structureViewer_actionPerformed(String selectedItem)
1237 if (selectedItem.equals(ViewerType.JMOL.name()))
1239 chimeraPath.setEnabled(false);
1240 chimeraPathLabel.setEnabled(false);
1243 boolean found = false;
1244 chimeraPath.setEnabled(true);
1245 chimeraPathLabel.setEnabled(true);
1246 chimeraPathLabel.setText(MessageManager
1247 .formatMessage("label.chimera_path", selectedItem));
1250 * Try user-specified and standard paths for Chimera executable
1252 boolean isChimeraX = selectedItem.equals(ViewerType.CHIMERAX.name());
1253 chimeraPath.setText(Cache
1254 .getDefault(isChimeraX ? CHIMERAX_PATH : CHIMERA_PATH, ""));
1256 List<String> paths = StructureManager.getChimeraPaths(isChimeraX);
1257 paths.add(0, chimeraPath.getText());
1258 for (String path : paths)
1260 if (new File(path.trim()).canExecute())
1268 String[] options = { "OK", "Help" };
1269 int showHelp = JvOptionPane.showInternalOptionDialog(Desktop.desktop,
1270 JvSwingUtils.wrapTooltip(true,
1271 MessageManager.getString("label.chimera_missing")),
1272 "", JvOptionPane.YES_NO_OPTION, JvOptionPane.WARNING_MESSAGE,
1273 null, options, options[0]);
1274 if (showHelp == JvOptionPane.NO_OPTION)
1278 Help.showHelpWindow(HelpId.StructureViewer);
1279 } catch (HelpSetException e)
1281 e.printStackTrace();
1287 public class OptionsParam
1289 private String name;
1291 private String code;
1293 public OptionsParam(String name, String code)
1299 public String getName()
1304 public void setName(String name)
1309 public String getCode()
1314 public void setCode(String code)
1320 public String toString()
1326 public boolean equals(Object that)
1328 if (!(that instanceof OptionsParam))
1332 return this.code.equalsIgnoreCase(((OptionsParam) that).code);
1336 public int hashCode()
1338 return name.hashCode() + code.hashCode();
1342 private class UrlListSelectionHandler implements ListSelectionListener
1346 public void valueChanged(ListSelectionEvent e)
1348 ListSelectionModel lsm = (ListSelectionModel) e.getSource();
1350 int index = lsm.getMinSelectionIndex();
1353 // no selection, so disable delete/edit buttons
1354 editLink.setEnabled(false);
1355 deleteLink.setEnabled(false);
1358 int modelIndex = linkUrlTable.convertRowIndexToModel(index);
1360 // enable/disable edit and delete link buttons
1361 if (((UrlLinkTableModel) linkUrlTable.getModel())
1362 .isRowDeletable(modelIndex))
1364 deleteLink.setEnabled(true);
1368 deleteLink.setEnabled(false);
1371 if (((UrlLinkTableModel) linkUrlTable.getModel())
1372 .isRowEditable(modelIndex))
1374 editLink.setEnabled(true);
1378 editLink.setEnabled(false);