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.JColorChooser;
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.gui.Help.HelpId;
57 import jalview.gui.StructureViewer.ViewerType;
58 import jalview.io.BackupFiles;
59 import jalview.io.BackupFilesPresetEntry;
60 import jalview.io.FileFormatI;
61 import jalview.io.JalviewFileChooser;
62 import jalview.io.JalviewFileView;
63 import jalview.jbgui.GPreferences;
64 import jalview.jbgui.GSequenceLink;
65 import jalview.schemes.ColourSchemeI;
66 import jalview.schemes.ColourSchemes;
67 import jalview.schemes.ResidueColourScheme;
68 import jalview.urls.UrlLinkTableModel;
69 import jalview.urls.api.UrlProviderFactoryI;
70 import jalview.urls.api.UrlProviderI;
71 import jalview.urls.desktop.DesktopUrlProviderFactory;
72 import jalview.util.MessageManager;
73 import jalview.util.Platform;
74 import jalview.util.UrlConstants;
75 import jalview.ws.sifts.SiftsSettings;
83 public class Preferences extends GPreferences
85 public static final String ENABLE_SPLIT_FRAME = "ENABLE_SPLIT_FRAME";
87 public static final String SCALE_PROTEIN_TO_CDNA = "SCALE_PROTEIN_TO_CDNA";
89 public static final String DEFAULT_COLOUR = "DEFAULT_COLOUR";
91 public static final String DEFAULT_COLOUR_PROT = "DEFAULT_COLOUR_PROT";
93 public static final String DEFAULT_COLOUR_NUC = "DEFAULT_COLOUR_NUC";
95 public static final String ADD_TEMPFACT_ANN = "ADD_TEMPFACT_ANN";
97 public static final String ADD_SS_ANN = "ADD_SS_ANN";
99 public static final String USE_RNAVIEW = "USE_RNAVIEW";
101 public static final String STRUCT_FROM_PDB = "STRUCT_FROM_PDB";
103 public static final String STRUCTURE_DISPLAY = "STRUCTURE_DISPLAY";
105 public static final String CHIMERA_PATH = "CHIMERA_PATH";
107 public static final String SORT_ANNOTATIONS = "SORT_ANNOTATIONS";
109 public static final String SHOW_AUTOCALC_ABOVE = "SHOW_AUTOCALC_ABOVE";
111 public static final String SHOW_OCCUPANCY = "SHOW_OCCUPANCY";
113 public static final String SHOW_OV_HIDDEN_AT_START = "SHOW_OV_HIDDEN_AT_START";
115 public static final String USE_LEGACY_GAP = "USE_LEGACY_GAP";
117 public static final String GAP_COLOUR = "GAP_COLOUR";
119 public static final String HIDDEN_COLOUR = "HIDDEN_COLOUR";
121 private static final int MIN_FONT_SIZE = 1;
123 private static final int MAX_FONT_SIZE = 30;
125 private String previousProxyType;
127 private static Preferences INSTANCE = null; // add "final"
130 * Holds name and link separated with | character. Sequence ID must be
131 * $SEQUENCE_ID$ or $SEQUENCE_ID=/.possible | chars ./=$
133 public static UrlProviderI sequenceUrlLinks;
135 public static UrlLinkTableModel dataModel;
138 * Holds name and link separated with | character. Sequence IDS and Sequences
139 * must be $SEQUENCEIDS$ or $SEQUENCEIDS=/.possible | chars ./=$ and
140 * $SEQUENCES$ or $SEQUENCES=/.possible | chars ./=$ and separation character
141 * for first and second token specified after a pipe character at end |,|.
142 * (TODO: proper escape for using | to separate ids or sequences
145 public static List<String> groupURLLinks;
148 // get links selected to be in the menu (SEQUENCE_LINKS)
149 // and links entered by the user but not selected (STORED_LINKS)
150 String inMenuString = Cache.getDefault("SEQUENCE_LINKS", "");
151 String notInMenuString = Cache.getDefault("STORED_LINKS", "");
152 String defaultUrl = Cache.getDefault("DEFAULT_URL",
153 UrlConstants.DEFAULT_LABEL);
155 // if both links lists are empty, add the DEFAULT_URL link
156 // otherwise we assume the default link is in one of the lists
157 if (inMenuString.isEmpty() && notInMenuString.isEmpty())
159 inMenuString = UrlConstants.DEFAULT_STRING;
161 UrlProviderFactoryI factory = new DesktopUrlProviderFactory(defaultUrl,
162 inMenuString, notInMenuString);
163 sequenceUrlLinks = factory.createUrlProvider();
164 dataModel = new UrlLinkTableModel(sequenceUrlLinks);
167 * TODO: reformulate groupURL encoding so two or more can be stored in the
168 * .properties file as '|' separated strings
171 groupURLLinks = new ArrayList<>();
174 JInternalFrame frame;
176 private WsPreferences wsPrefs;
178 private OptionsParam promptEachTimeOpt = new OptionsParam(
179 MessageManager.getString("label.prompt_each_time"),
182 private OptionsParam lineArtOpt = new OptionsParam(
183 MessageManager.getString("label.lineart"), "Lineart");
185 private OptionsParam textOpt = new OptionsParam(
186 MessageManager.getString("action.text"), "Text");
188 // get singleton Preferences instance
189 public static Preferences getPreferences()
191 return getPreferences(0, null);
194 public static Preferences getPreferences(int selectTab, String message)
196 if (INSTANCE == null || INSTANCE.frame == null
197 || INSTANCE.frame.isClosed())
199 INSTANCE = new Preferences();
201 INSTANCE.selectTab(selectTab);
202 INSTANCE.setMessage(message);
206 public static void openPreferences()
208 openPreferences(0, null);
211 public static void openPreferences(int selectTab, String message)
213 Preferences p = getPreferences(selectTab, message);
215 p.frame.moveToFront();
220 * Creates a new Preferences object.
222 private Preferences()
225 frame = new JInternalFrame();
226 frame.setContentPane(this);
227 wsPrefs = new WsPreferences();
228 wsTab.add(wsPrefs, BorderLayout.CENTER);
229 int width = 500, height = 450;
230 new jalview.util.Platform();
231 if (Platform.isAMac())
237 Desktop.addInternalFrame(frame,
238 MessageManager.getString("label.preferences"), width, height);
239 frame.setMinimumSize(new Dimension(width, height));
242 * Set Visual tab defaults
244 seqLimit.setSelected(Cache.getDefault("SHOW_JVSUFFIX", true));
245 rightAlign.setSelected(Cache.getDefault("RIGHT_ALIGN_IDS", false));
246 fullScreen.setSelected(Cache.getDefault("SHOW_FULLSCREEN", false));
247 annotations.setSelected(Cache.getDefault("SHOW_ANNOTATIONS", true));
249 conservation.setSelected(Cache.getDefault("SHOW_CONSERVATION", true));
250 quality.setSelected(Cache.getDefault("SHOW_QUALITY", true));
251 identity.setSelected(Cache.getDefault("SHOW_IDENTITY", true));
252 openoverv.setSelected(Cache.getDefault("SHOW_OVERVIEW", false));
254 .setSelected(Cache.getDefault("SHOW_UNCONSERVED", false));
255 showOccupancy.setSelected(Cache.getDefault(SHOW_OCCUPANCY, false));
257 .setSelected(Cache.getDefault("SHOW_GROUP_CONSENSUS", false));
258 showGroupConservation.setSelected(
259 Cache.getDefault("SHOW_GROUP_CONSERVATION", false));
260 showConsensHistogram.setSelected(
261 Cache.getDefault("SHOW_CONSENSUS_HISTOGRAM", true));
263 .setSelected(Cache.getDefault("SHOW_CONSENSUS_LOGO", false));
265 .setSelected(Cache.getDefault("SHOW_NPFEATS_TOOLTIP", true));
267 .setSelected(Cache.getDefault("SHOW_DBREFS_TOOLTIP", true));
269 String[] fonts = java.awt.GraphicsEnvironment
270 .getLocalGraphicsEnvironment().getAvailableFontFamilyNames();
271 for (int i = 0; i < fonts.length; i++)
273 fontNameCB.addItem(fonts[i]);
276 for (int i = MIN_FONT_SIZE; i <= MAX_FONT_SIZE; i++)
278 fontSizeCB.addItem(i + "");
281 fontStyleCB.addItem("plain");
282 fontStyleCB.addItem("bold");
283 fontStyleCB.addItem("italic");
285 fontNameCB.setSelectedItem(Cache.getDefault("FONT_NAME", "SansSerif"));
286 fontSizeCB.setSelectedItem(Cache.getDefault("FONT_SIZE", "10"));
287 fontStyleCB.setSelectedItem(
288 Cache.getDefault("FONT_STYLE", Font.PLAIN + ""));
290 smoothFont.setSelected(Cache.getDefault("ANTI_ALIAS", true));
292 .setSelected(Cache.getDefault(SCALE_PROTEIN_TO_CDNA, false));
294 idItalics.setSelected(Cache.getDefault("ID_ITALICS", true));
296 wrap.setSelected(Cache.getDefault("WRAP_ALIGNMENT", false));
298 gapSymbolCB.addItem("-");
299 gapSymbolCB.addItem(".");
301 gapSymbolCB.setSelectedItem(Cache.getDefault("GAP_SYMBOL", "-"));
303 sortby.addItem("No sort");
304 sortby.addItem("Id");
305 sortby.addItem("Pairwise Identity");
306 sortby.setSelectedItem(Cache.getDefault("SORT_ALIGNMENT", "No sort"));
308 sortAnnBy.addItem(SequenceAnnotationOrder.NONE.toString());
310 .addItem(SequenceAnnotationOrder.SEQUENCE_AND_LABEL.toString());
312 .addItem(SequenceAnnotationOrder.LABEL_AND_SEQUENCE.toString());
313 SequenceAnnotationOrder savedSort = SequenceAnnotationOrder
314 .valueOf(Cache.getDefault(SORT_ANNOTATIONS,
315 SequenceAnnotationOrder.NONE.name()));
316 sortAnnBy.setSelectedItem(savedSort.toString());
318 sortAutocalc.addItem("Autocalculated first");
319 sortAutocalc.addItem("Autocalculated last");
320 final boolean showAbove = Cache.getDefault(SHOW_AUTOCALC_ABOVE, true);
321 sortAutocalc.setSelectedItem(showAbove ? sortAutocalc.getItemAt(0)
322 : sortAutocalc.getItemAt(1));
324 .setSelected(Cache.getDefault("SHOW_STARTUP_FILE", true));
325 startupFileTextfield.setText(Cache.getDefault("STARTUP_FILE",
326 Cache.getDefault("www.jalview.org", "http://www.jalview.org")
327 + "/examples/exampleFile_2_3.jar"));
330 * Set Colours tab defaults
332 protColour.addItem(ResidueColourScheme.NONE);
333 nucColour.addItem(ResidueColourScheme.NONE);
334 for (ColourSchemeI cs : ColourSchemes.getInstance().getColourSchemes())
336 String name = cs.getSchemeName();
337 protColour.addItem(name);
338 nucColour.addItem(name);
340 String oldProp = Cache.getDefault(DEFAULT_COLOUR,
341 ResidueColourScheme.NONE);
342 String newProp = Cache.getDefault(DEFAULT_COLOUR_PROT, null);
343 protColour.setSelectedItem(newProp != null ? newProp : oldProp);
344 newProp = Cache.getDefault(DEFAULT_COLOUR_NUC, null);
345 nucColour.setSelectedItem(newProp != null ? newProp : oldProp);
346 minColour.setBackground(
347 Cache.getDefaultColour("ANNOTATIONCOLOUR_MIN", Color.orange));
348 maxColour.setBackground(
349 Cache.getDefaultColour("ANNOTATIONCOLOUR_MAX", Color.red));
352 * Set overview panel defaults
354 gapColour.setBackground(Cache.getDefaultColour(GAP_COLOUR,
355 jalview.renderer.OverviewResColourFinder.OVERVIEW_DEFAULT_GAP));
356 hiddenColour.setBackground(Cache.getDefaultColour(HIDDEN_COLOUR,
357 jalview.renderer.OverviewResColourFinder.OVERVIEW_DEFAULT_HIDDEN));
358 useLegacyGap.setSelected(Cache.getDefault(USE_LEGACY_GAP, false));
359 gapLabel.setEnabled(!useLegacyGap.isSelected());
360 gapColour.setEnabled(!useLegacyGap.isSelected());
362 .setSelected(Cache.getDefault(SHOW_OV_HIDDEN_AT_START, false));
365 * Set Structure tab defaults.
367 final boolean structSelected = Cache.getDefault(STRUCT_FROM_PDB, false);
368 structFromPdb.setSelected(structSelected);
369 useRnaView.setSelected(Cache.getDefault(USE_RNAVIEW, false));
370 useRnaView.setEnabled(structSelected);
371 addSecondaryStructure.setSelected(Cache.getDefault(ADD_SS_ANN, false));
372 addSecondaryStructure.setEnabled(structSelected);
373 addTempFactor.setSelected(Cache.getDefault(ADD_TEMPFACT_ANN, false));
374 addTempFactor.setEnabled(structSelected);
375 structViewer.setSelectedItem(
376 Cache.getDefault(STRUCTURE_DISPLAY, ViewerType.JMOL.name()));
377 chimeraPath.setText(Cache.getDefault(CHIMERA_PATH, ""));
378 chimeraPath.addActionListener(new ActionListener()
381 public void actionPerformed(ActionEvent e)
383 validateChimeraPath();
387 if (Cache.getDefault("MAP_WITH_SIFTS", false))
389 siftsMapping.setSelected(true);
393 nwMapping.setSelected(true);
397 .setMapWithSifts(Cache.getDefault("MAP_WITH_SIFTS", false));
400 * Set Connections tab defaults
404 linkUrlTable.setModel(dataModel);
405 final TableRowSorter<TableModel> sorter = new TableRowSorter<>(
406 linkUrlTable.getModel());
407 linkUrlTable.setRowSorter(sorter);
408 List<RowSorter.SortKey> sortKeys = new ArrayList<>();
410 UrlLinkTableModel m = (UrlLinkTableModel) linkUrlTable.getModel();
411 sortKeys.add(new RowSorter.SortKey(m.getPrimaryColumn(),
412 SortOrder.DESCENDING));
413 sortKeys.add(new RowSorter.SortKey(m.getSelectedColumn(),
414 SortOrder.DESCENDING));
416 new RowSorter.SortKey(m.getNameColumn(), SortOrder.ASCENDING));
418 sorter.setSortKeys(sortKeys);
422 ActionListener onReset;
423 onReset = new ActionListener()
426 public void actionPerformed(ActionEvent e)
428 filterTB.setText("");
429 sorter.setRowFilter(RowFilter.regexFilter(""));
433 doReset.addActionListener(onReset);
435 // filter to display only custom urls
436 final RowFilter<TableModel, Object> customUrlFilter = new RowFilter<TableModel, Object>()
439 public boolean include(
440 Entry<? extends TableModel, ? extends Object> entry)
442 return ((UrlLinkTableModel) entry.getModel()).isUserEntry(entry);
446 final TableRowSorter<TableModel> customSorter = new TableRowSorter<>(
447 linkUrlTable.getModel());
448 customSorter.setRowFilter(customUrlFilter);
450 ActionListener onCustomOnly;
451 onCustomOnly = new ActionListener()
454 public void actionPerformed(ActionEvent e)
456 filterTB.setText("");
457 sorter.setRowFilter(customUrlFilter);
460 userOnly.addActionListener(onCustomOnly);
462 filterTB.getDocument().addDocumentListener(new DocumentListener()
464 String caseInsensitiveFlag = "(?i)";
467 public void changedUpdate(DocumentEvent e)
469 sorter.setRowFilter(RowFilter
470 .regexFilter(caseInsensitiveFlag + filterTB.getText()));
474 public void removeUpdate(DocumentEvent e)
476 sorter.setRowFilter(RowFilter
477 .regexFilter(caseInsensitiveFlag + filterTB.getText()));
481 public void insertUpdate(DocumentEvent e)
483 sorter.setRowFilter(RowFilter
484 .regexFilter(caseInsensitiveFlag + filterTB.getText()));
488 // set up list selection functionality
489 linkUrlTable.getSelectionModel()
490 .addListSelectionListener(new UrlListSelectionHandler());
492 // set up radio buttons
493 int onClickCol = ((UrlLinkTableModel) linkUrlTable.getModel())
495 String onClickName = linkUrlTable.getColumnName(onClickCol);
496 linkUrlTable.getColumn(onClickName)
497 .setCellRenderer(new RadioButtonRenderer());
498 linkUrlTable.getColumn(onClickName)
499 .setCellEditor(new RadioButtonEditor());
501 // get boolean columns and resize those to min possible
502 for (int column = 0; column < linkUrlTable.getColumnCount(); column++)
504 if (linkUrlTable.getModel().getColumnClass(column)
505 .equals(Boolean.class))
507 TableColumn tableColumn = linkUrlTable.getColumnModel()
509 int preferredWidth = tableColumn.getMinWidth();
511 TableCellRenderer cellRenderer = linkUrlTable.getCellRenderer(0,
513 Component c = linkUrlTable.prepareRenderer(cellRenderer, 0, column);
514 int cwidth = c.getPreferredSize().width
515 + linkUrlTable.getIntercellSpacing().width;
516 preferredWidth = Math.max(preferredWidth, cwidth);
518 tableColumn.setPreferredWidth(preferredWidth);
522 String proxyTypeString = Cache.getDefault("USE_PROXY", "false");
523 previousProxyType = proxyTypeString;
524 switch (proxyTypeString)
526 case Cache.PROXYTYPE_NONE:
527 proxyType.setSelected(noProxy.getModel(), true);
529 case Cache.PROXYTYPE_SYSTEM:
530 proxyType.setSelected(systemProxy.getModel(), true);
532 case Cache.PROXYTYPE_CUSTOM:
533 proxyType.setSelected(customProxy.getModel(), true);
537 "Incorrect PROXY_TYPE - should be 'none' (clear proxy properties), 'false' (system settings), 'true' (custom settings): "
540 proxyServerHttpTB.setText(Cache.getDefault("PROXY_SERVER", ""));
541 proxyPortHttpTB.setText(Cache.getDefault("PROXY_PORT", ""));
542 proxyServerHttpsTB.setText(Cache.getDefault("PROXY_SERVER_HTTPS", ""));
543 proxyPortHttpsTB.setText(Cache.getDefault("PROXY_PORT_HTTPS", ""));
544 proxyAuth.setSelected(Cache.getDefault("PROXY_AUTH", false));
546 .setText(Cache.getDefault("PROXY_AUTH_USERNAME", ""));
547 // we are not storing or retrieving proxy password from .jalview_properties
548 proxyAuthPasswordPB.setText(Cache.proxyAuthPassword == null ? ""
549 : new String(Cache.proxyAuthPassword));
550 setCustomProxyEnabled();
552 defaultBrowser.setText(Cache.getDefault("DEFAULT_BROWSER", ""));
554 usagestats.setSelected(Cache.getDefault("USAGESTATS", false));
555 // note antisense here: default is true
557 .setSelected(Cache.getProperty("NOQUESTIONNAIRES") == null);
558 versioncheck.setSelected(Cache.getDefault("VERSION_CHECK", true));
561 * Set Output tab defaults
563 epsRendering.addItem(promptEachTimeOpt);
564 epsRendering.addItem(lineArtOpt);
565 epsRendering.addItem(textOpt);
566 String defaultEPS = Cache.getDefault("EPS_RENDERING",
568 if (defaultEPS.equalsIgnoreCase("Text"))
570 epsRendering.setSelectedItem(textOpt);
572 else if (defaultEPS.equalsIgnoreCase("Lineart"))
574 epsRendering.setSelectedItem(lineArtOpt);
578 epsRendering.setSelectedItem(promptEachTimeOpt);
580 autoIdWidth.setSelected(Cache.getDefault("FIGURE_AUTOIDWIDTH", false));
581 userIdWidth.setEnabled(!autoIdWidth.isSelected());
582 userIdWidthlabel.setEnabled(!autoIdWidth.isSelected());
583 Integer wi = Cache.getIntegerProperty("FIGURE_FIXEDIDWIDTH");
584 userIdWidth.setText(wi == null ? "" : wi.toString());
585 // TODO: refactor to use common enum via FormatAdapter and allow extension
586 // for new flat file formats
587 blcjv.setSelected(Cache.getDefault("BLC_JVSUFFIX", true));
588 clustaljv.setSelected(Cache.getDefault("CLUSTAL_JVSUFFIX", true));
589 fastajv.setSelected(Cache.getDefault("FASTA_JVSUFFIX", true));
590 msfjv.setSelected(Cache.getDefault("MSF_JVSUFFIX", true));
591 pfamjv.setSelected(Cache.getDefault("PFAM_JVSUFFIX", true));
592 pileupjv.setSelected(Cache.getDefault("PILEUP_JVSUFFIX", true));
593 pirjv.setSelected(Cache.getDefault("PIR_JVSUFFIX", true));
594 modellerOutput.setSelected(Cache.getDefault("PIR_MODELLER", false));
596 .setSelected(Cache.getDefault("EXPORT_EMBBED_BIOJSON", true));
599 * Set Editing tab defaults
601 autoCalculateConsCheck
602 .setSelected(Cache.getDefault("AUTO_CALC_CONSENSUS", true));
603 padGaps.setSelected(Cache.getDefault("PAD_GAPS", false));
604 sortByTree.setSelected(Cache.getDefault("SORT_BY_TREE", false));
606 annotations_actionPerformed(null); // update the display of the annotation
610 * Set Backups tab defaults
612 loadLastSavedBackupsOptions();
616 * Save user selections on the Preferences tabs to the Cache and write out to
622 public void ok_actionPerformed(ActionEvent e)
624 if (!validateSettings())
630 * Set proxy settings first (to be before web services refresh)
635 * Save Visual settings
637 Cache.applicationProperties.setProperty("SHOW_JVSUFFIX",
638 Boolean.toString(seqLimit.isSelected()));
639 Cache.applicationProperties.setProperty("RIGHT_ALIGN_IDS",
640 Boolean.toString(rightAlign.isSelected()));
641 Cache.applicationProperties.setProperty("SHOW_FULLSCREEN",
642 Boolean.toString(fullScreen.isSelected()));
643 Cache.applicationProperties.setProperty("SHOW_OVERVIEW",
644 Boolean.toString(openoverv.isSelected()));
645 Cache.applicationProperties.setProperty("SHOW_ANNOTATIONS",
646 Boolean.toString(annotations.isSelected()));
647 Cache.applicationProperties.setProperty("SHOW_CONSERVATION",
648 Boolean.toString(conservation.isSelected()));
649 Cache.applicationProperties.setProperty("SHOW_QUALITY",
650 Boolean.toString(quality.isSelected()));
651 Cache.applicationProperties.setProperty("SHOW_IDENTITY",
652 Boolean.toString(identity.isSelected()));
654 Cache.applicationProperties.setProperty("GAP_SYMBOL",
655 gapSymbolCB.getSelectedItem().toString());
657 Cache.applicationProperties.setProperty("FONT_NAME",
658 fontNameCB.getSelectedItem().toString());
659 Cache.applicationProperties.setProperty("FONT_STYLE",
660 fontStyleCB.getSelectedItem().toString());
661 Cache.applicationProperties.setProperty("FONT_SIZE",
662 fontSizeCB.getSelectedItem().toString());
664 Cache.applicationProperties.setProperty("ID_ITALICS",
665 Boolean.toString(idItalics.isSelected()));
666 Cache.applicationProperties.setProperty("SHOW_UNCONSERVED",
667 Boolean.toString(showUnconserved.isSelected()));
668 Cache.applicationProperties.setProperty(SHOW_OCCUPANCY,
669 Boolean.toString(showOccupancy.isSelected()));
670 Cache.applicationProperties.setProperty("SHOW_GROUP_CONSENSUS",
671 Boolean.toString(showGroupConsensus.isSelected()));
672 Cache.applicationProperties.setProperty("SHOW_GROUP_CONSERVATION",
673 Boolean.toString(showGroupConservation.isSelected()));
674 Cache.applicationProperties.setProperty("SHOW_CONSENSUS_HISTOGRAM",
675 Boolean.toString(showConsensHistogram.isSelected()));
676 Cache.applicationProperties.setProperty("SHOW_CONSENSUS_LOGO",
677 Boolean.toString(showConsensLogo.isSelected()));
678 Cache.applicationProperties.setProperty("ANTI_ALIAS",
679 Boolean.toString(smoothFont.isSelected()));
680 Cache.applicationProperties.setProperty(SCALE_PROTEIN_TO_CDNA,
681 Boolean.toString(scaleProteinToCdna.isSelected()));
682 Cache.applicationProperties.setProperty("SHOW_NPFEATS_TOOLTIP",
683 Boolean.toString(showNpTooltip.isSelected()));
684 Cache.applicationProperties.setProperty("SHOW_DBREFS_TOOLTIP",
685 Boolean.toString(showDbRefTooltip.isSelected()));
687 Cache.applicationProperties.setProperty("WRAP_ALIGNMENT",
688 Boolean.toString(wrap.isSelected()));
690 Cache.applicationProperties.setProperty("STARTUP_FILE",
691 startupFileTextfield.getText());
692 Cache.applicationProperties.setProperty("SHOW_STARTUP_FILE",
693 Boolean.toString(startupCheckbox.isSelected()));
695 Cache.applicationProperties.setProperty("SORT_ALIGNMENT",
696 sortby.getSelectedItem().toString());
698 // convert description of sort order to enum name for save
699 SequenceAnnotationOrder annSortOrder = SequenceAnnotationOrder
700 .forDescription(sortAnnBy.getSelectedItem().toString());
701 if (annSortOrder != null)
703 Cache.applicationProperties.setProperty(SORT_ANNOTATIONS,
704 annSortOrder.name());
707 final boolean showAutocalcFirst = sortAutocalc.getSelectedIndex() == 0;
708 Cache.applicationProperties.setProperty(SHOW_AUTOCALC_ABOVE,
709 Boolean.valueOf(showAutocalcFirst).toString());
712 * Save Colours settings
714 Cache.applicationProperties.setProperty(DEFAULT_COLOUR_PROT,
715 protColour.getSelectedItem().toString());
716 Cache.applicationProperties.setProperty(DEFAULT_COLOUR_NUC,
717 nucColour.getSelectedItem().toString());
718 Cache.setColourProperty("ANNOTATIONCOLOUR_MIN",
719 minColour.getBackground());
720 Cache.setColourProperty("ANNOTATIONCOLOUR_MAX",
721 maxColour.getBackground());
724 * Save Overview settings
726 Cache.setColourProperty(GAP_COLOUR, gapColour.getBackground());
727 Cache.setColourProperty(HIDDEN_COLOUR, hiddenColour.getBackground());
728 Cache.applicationProperties.setProperty(USE_LEGACY_GAP,
729 Boolean.toString(useLegacyGap.isSelected()));
730 Cache.applicationProperties.setProperty(SHOW_OV_HIDDEN_AT_START,
731 Boolean.toString(showHiddenAtStart.isSelected()));
734 * Save Structure settings
736 Cache.applicationProperties.setProperty(ADD_TEMPFACT_ANN,
737 Boolean.toString(addTempFactor.isSelected()));
738 Cache.applicationProperties.setProperty(ADD_SS_ANN,
739 Boolean.toString(addSecondaryStructure.isSelected()));
740 Cache.applicationProperties.setProperty(USE_RNAVIEW,
741 Boolean.toString(useRnaView.isSelected()));
742 Cache.applicationProperties.setProperty(STRUCT_FROM_PDB,
743 Boolean.toString(structFromPdb.isSelected()));
744 Cache.applicationProperties.setProperty(STRUCTURE_DISPLAY,
745 structViewer.getSelectedItem().toString());
746 Cache.setOrRemove(CHIMERA_PATH, chimeraPath.getText());
747 Cache.applicationProperties.setProperty("MAP_WITH_SIFTS",
748 Boolean.toString(siftsMapping.isSelected()));
749 SiftsSettings.setMapWithSifts(siftsMapping.isSelected());
752 * Save Output settings
754 Cache.applicationProperties.setProperty("EPS_RENDERING",
755 ((OptionsParam) epsRendering.getSelectedItem()).getCode());
758 * Save Connections settings
760 // Proxy settings set first (to catch web services)
762 Cache.setOrRemove("DEFAULT_BROWSER", defaultBrowser.getText());
764 jalview.util.BrowserLauncher.resetBrowser();
766 // save user-defined and selected links
767 String menuLinks = sequenceUrlLinks.writeUrlsAsString(true);
768 if (menuLinks.isEmpty())
770 Cache.applicationProperties.remove("SEQUENCE_LINKS");
774 Cache.applicationProperties.setProperty("SEQUENCE_LINKS",
775 menuLinks.toString());
778 String nonMenuLinks = sequenceUrlLinks.writeUrlsAsString(false);
779 if (nonMenuLinks.isEmpty())
781 Cache.applicationProperties.remove("STORED_LINKS");
785 Cache.applicationProperties.setProperty("STORED_LINKS",
786 nonMenuLinks.toString());
789 Cache.applicationProperties.setProperty("DEFAULT_URL",
790 sequenceUrlLinks.getPrimaryUrlId());
792 Cache.setProperty("VERSION_CHECK",
793 Boolean.toString(versioncheck.isSelected()));
794 if (Cache.getProperty("USAGESTATS") != null || usagestats.isSelected())
796 // default is false - we only set this if the user has actively agreed
797 Cache.setProperty("USAGESTATS",
798 Boolean.toString(usagestats.isSelected()));
800 if (!questionnaire.isSelected())
802 Cache.setProperty("NOQUESTIONNAIRES", "true");
806 // special - made easy to edit a property file to disable questionnaires
807 // by just adding the given line
808 Cache.removeProperty("NOQUESTIONNAIRES");
812 * Save Output settings
814 Cache.applicationProperties.setProperty("BLC_JVSUFFIX",
815 Boolean.toString(blcjv.isSelected()));
816 Cache.applicationProperties.setProperty("CLUSTAL_JVSUFFIX",
817 Boolean.toString(clustaljv.isSelected()));
818 Cache.applicationProperties.setProperty("FASTA_JVSUFFIX",
819 Boolean.toString(fastajv.isSelected()));
820 Cache.applicationProperties.setProperty("MSF_JVSUFFIX",
821 Boolean.toString(msfjv.isSelected()));
822 Cache.applicationProperties.setProperty("PFAM_JVSUFFIX",
823 Boolean.toString(pfamjv.isSelected()));
824 Cache.applicationProperties.setProperty("PILEUP_JVSUFFIX",
825 Boolean.toString(pileupjv.isSelected()));
826 Cache.applicationProperties.setProperty("PIR_JVSUFFIX",
827 Boolean.toString(pirjv.isSelected()));
828 Cache.applicationProperties.setProperty("PIR_MODELLER",
829 Boolean.toString(modellerOutput.isSelected()));
830 Cache.applicationProperties.setProperty("EXPORT_EMBBED_BIOJSON",
831 Boolean.toString(embbedBioJSON.isSelected()));
832 jalview.io.PIRFile.useModellerOutput = modellerOutput.isSelected();
834 Cache.applicationProperties.setProperty("FIGURE_AUTOIDWIDTH",
835 Boolean.toString(autoIdWidth.isSelected()));
836 userIdWidth_actionPerformed();
837 Cache.applicationProperties.setProperty("FIGURE_FIXEDIDWIDTH",
838 userIdWidth.getText());
841 * Save Editing settings
843 Cache.applicationProperties.setProperty("AUTO_CALC_CONSENSUS",
844 Boolean.toString(autoCalculateConsCheck.isSelected()));
845 Cache.applicationProperties.setProperty("SORT_BY_TREE",
846 Boolean.toString(sortByTree.isSelected()));
847 Cache.applicationProperties.setProperty("PAD_GAPS",
848 Boolean.toString(padGaps.isSelected()));
850 wsPrefs.updateAndRefreshWsMenuConfig(false);
853 * Save Backups settings
855 Cache.applicationProperties.setProperty(BackupFiles.ENABLED,
856 Boolean.toString(enableBackupFiles.isSelected()));
857 int preset = getComboIntStringKey(backupfilesPresetsCombo);
858 Cache.applicationProperties.setProperty(BackupFiles.NS + "_PRESET",
859 Integer.toString(preset));
861 if (preset == BackupFilesPresetEntry.BACKUPFILESSCHEMECUSTOM)
863 BackupFilesPresetEntry customBFPE = getBackupfilesCurrentEntry();
864 BackupFilesPresetEntry.backupfilesPresetEntriesValues.put(
865 BackupFilesPresetEntry.BACKUPFILESSCHEMECUSTOM, customBFPE);
866 Cache.applicationProperties.setProperty(
867 BackupFilesPresetEntry.CUSTOMCONFIG, customBFPE.toString());
870 BackupFilesPresetEntry savedBFPE = BackupFilesPresetEntry.backupfilesPresetEntriesValues
872 Cache.applicationProperties.setProperty(
873 BackupFilesPresetEntry.SAVEDCONFIG, savedBFPE.toString());
875 Cache.saveProperties();
876 Desktop.instance.doConfigureStructurePrefs();
879 frame.setClosed(true);
880 } catch (Exception ex)
885 public void saveProxySettings()
887 String newProxyType = customProxy.isSelected() ? Cache.PROXYTYPE_CUSTOM
888 : noProxy.isSelected() ? Cache.PROXYTYPE_NONE
889 : Cache.PROXYTYPE_SYSTEM;
890 Cache.applicationProperties.setProperty("USE_PROXY", newProxyType);
891 Cache.setOrRemove("PROXY_SERVER", proxyServerHttpTB.getText());
892 Cache.setOrRemove("PROXY_PORT", proxyPortHttpTB.getText());
893 Cache.setOrRemove("PROXY_SERVER_HTTPS", proxyServerHttpsTB.getText());
894 Cache.setOrRemove("PROXY_PORT_HTTPS", proxyPortHttpsTB.getText());
895 Cache.setOrRemove("PROXY_AUTH",
896 Boolean.toString(proxyAuth.isSelected()));
897 Cache.setOrRemove("PROXY_AUTH_USERNAME", proxyAuthUsernameTB.getText());
898 Cache.proxyAuthPassword = proxyAuthPasswordPB.getPassword();
899 Cache.setProxyPropertiesFromPreferences(previousProxyType);
900 if (newProxyType.equals(Cache.PROXYTYPE_CUSTOM)
901 || !newProxyType.equals(previousProxyType))
903 // force a re-lookup of ws if proxytype is custom or has changed
906 previousProxyType = newProxyType;
910 * Do any necessary validation before saving settings. Return focus to the
911 * first tab which fails validation.
915 private boolean validateSettings()
917 if (!validateStructure())
919 structureTab.requestFocusInWindow();
926 protected boolean validateStructure()
928 return validateChimeraPath();
936 public void startupFileTextfield_mouseClicked()
938 String fileFormat = Cache.getProperty("DEFAULT_FILE_FORMAT");
939 JalviewFileChooser chooser = JalviewFileChooser
940 .forRead(Cache.getProperty("LAST_DIRECTORY"), fileFormat);
941 chooser.setFileView(new JalviewFileView());
942 chooser.setDialogTitle(
943 MessageManager.getString("label.select_startup_file"));
945 int value = chooser.showOpenDialog(this);
947 if (value == JalviewFileChooser.APPROVE_OPTION)
949 FileFormatI format = chooser.getSelectedFormat();
952 Cache.applicationProperties.setProperty("DEFAULT_FILE_FORMAT",
956 .setText(chooser.getSelectedFile().getAbsolutePath());
967 public void cancel_actionPerformed(ActionEvent e)
971 wsPrefs.updateWsMenuConfig(true);
972 wsPrefs.refreshWs_actionPerformed(e);
973 frame.setClosed(true);
974 } catch (Exception ex)
986 public void annotations_actionPerformed(ActionEvent e)
988 conservation.setEnabled(annotations.isSelected());
989 quality.setEnabled(annotations.isSelected());
990 identity.setEnabled(annotations.isSelected());
991 showOccupancy.setEnabled(annotations.isSelected());
992 showGroupConsensus.setEnabled(annotations.isSelected());
993 showGroupConservation.setEnabled(annotations.isSelected());
994 showConsensHistogram.setEnabled(annotations.isSelected()
995 && (identity.isSelected() || showGroupConsensus.isSelected()));
996 showConsensLogo.setEnabled(annotations.isSelected()
997 && (identity.isSelected() || showGroupConsensus.isSelected()));
1001 public void newLink_actionPerformed(ActionEvent e)
1003 GSequenceLink link = new GSequenceLink();
1004 boolean valid = false;
1007 if (JvOptionPane.showInternalConfirmDialog(Desktop.desktop, link,
1008 MessageManager.getString("label.new_sequence_url_link"),
1009 JvOptionPane.OK_CANCEL_OPTION, -1,
1010 null) == JvOptionPane.OK_OPTION)
1012 if (link.checkValid())
1014 if (((UrlLinkTableModel) linkUrlTable.getModel())
1015 .isUniqueName(link.getName()))
1017 ((UrlLinkTableModel) linkUrlTable.getModel())
1018 .insertRow(link.getName(), link.getURL());
1023 link.notifyDuplicate();
1036 public void editLink_actionPerformed(ActionEvent e)
1038 GSequenceLink link = new GSequenceLink();
1040 int index = linkUrlTable.getSelectedRow();
1043 // button no longer enabled if row is not selected
1044 Cache.log.debug("Edit with no row selected in linkUrlTable");
1048 int nameCol = ((UrlLinkTableModel) linkUrlTable.getModel())
1050 int urlCol = ((UrlLinkTableModel) linkUrlTable.getModel())
1052 String oldName = linkUrlTable.getValueAt(index, nameCol).toString();
1053 link.setName(oldName);
1054 link.setURL(linkUrlTable.getValueAt(index, urlCol).toString());
1056 boolean valid = false;
1059 if (JvOptionPane.showInternalConfirmDialog(Desktop.desktop, link,
1060 MessageManager.getString("label.edit_sequence_url_link"),
1061 JvOptionPane.OK_CANCEL_OPTION, -1,
1062 null) == JvOptionPane.OK_OPTION)
1064 if (link.checkValid())
1066 if ((oldName.equals(link.getName()))
1067 || (((UrlLinkTableModel) linkUrlTable.getModel())
1068 .isUniqueName(link.getName())))
1070 linkUrlTable.setValueAt(link.getName(), index, nameCol);
1071 linkUrlTable.setValueAt(link.getURL(), index, urlCol);
1076 link.notifyDuplicate();
1089 public void deleteLink_actionPerformed(ActionEvent e)
1091 int index = linkUrlTable.getSelectedRow();
1092 int modelIndex = -1;
1095 // button no longer enabled if row is not selected
1096 Cache.log.debug("Delete with no row selected in linkUrlTable");
1101 modelIndex = linkUrlTable.convertRowIndexToModel(index);
1104 // make sure we use the model index to delete, and not the table index
1105 ((UrlLinkTableModel) linkUrlTable.getModel()).removeRow(modelIndex);
1109 public void defaultBrowser_mouseClicked(MouseEvent e)
1111 JFileChooser chooser = new JFileChooser(".");
1112 chooser.setDialogTitle(
1113 MessageManager.getString("label.select_default_browser"));
1115 int value = chooser.showOpenDialog(this);
1117 if (value == JFileChooser.APPROVE_OPTION)
1119 defaultBrowser.setText(chooser.getSelectedFile().getAbsolutePath());
1128 * jalview.jbgui.GPreferences#showunconserved_actionPerformed(java.awt.event
1132 protected void showunconserved_actionPerformed(ActionEvent e)
1134 // TODO Auto-generated method stub
1135 super.showunconserved_actionPerformed(e);
1138 public static List<String> getGroupURLLinks()
1140 return groupURLLinks;
1144 public void minColour_actionPerformed(JPanel panel)
1146 Color col = JColorChooser.showDialog(this,
1147 MessageManager.getString("label.select_colour_minimum_value"),
1148 minColour.getBackground());
1151 panel.setBackground(col);
1157 public void maxColour_actionPerformed(JPanel panel)
1159 Color col = JColorChooser.showDialog(this,
1160 MessageManager.getString("label.select_colour_maximum_value"),
1161 maxColour.getBackground());
1164 panel.setBackground(col);
1170 public void gapColour_actionPerformed(JPanel gap)
1172 if (!useLegacyGap.isSelected())
1174 Color col = JColorChooser.showDialog(this,
1175 MessageManager.getString("label.select_gap_colour"),
1176 gapColour.getBackground());
1179 gap.setBackground(col);
1186 public void hiddenColour_actionPerformed(JPanel hidden)
1188 Color col = JColorChooser.showDialog(this,
1189 MessageManager.getString("label.select_hidden_colour"),
1190 hiddenColour.getBackground());
1193 hidden.setBackground(col);
1199 protected void useLegacyGaps_actionPerformed(ActionEvent e)
1201 boolean enabled = useLegacyGap.isSelected();
1204 gapColour.setBackground(
1205 jalview.renderer.OverviewResColourFinder.OVERVIEW_DEFAULT_LEGACY_GAP);
1209 gapColour.setBackground(
1210 jalview.renderer.OverviewResColourFinder.OVERVIEW_DEFAULT_GAP);
1212 gapColour.setEnabled(!enabled);
1213 gapLabel.setEnabled(!enabled);
1217 protected void resetOvDefaults_actionPerformed(ActionEvent e)
1219 useLegacyGap.setSelected(false);
1220 useLegacyGaps_actionPerformed(null);
1221 showHiddenAtStart.setSelected(false);
1222 hiddenColour.setBackground(
1223 jalview.renderer.OverviewResColourFinder.OVERVIEW_DEFAULT_HIDDEN);
1227 protected void userIdWidth_actionPerformed()
1231 String val = userIdWidth.getText().trim();
1232 if (val.length() > 0)
1234 Integer iw = Integer.parseInt(val);
1235 if (iw.intValue() < 12)
1237 throw new NumberFormatException();
1239 userIdWidth.setText(iw.toString());
1241 } catch (NumberFormatException x)
1243 JvOptionPane.showInternalMessageDialog(Desktop.desktop,
1245 .getString("warn.user_defined_width_requirements"),
1246 MessageManager.getString("label.invalid_id_column_width"),
1247 JvOptionPane.WARNING_MESSAGE);
1248 userIdWidth.setText("");
1253 protected void autoIdWidth_actionPerformed()
1255 userIdWidth.setEnabled(!autoIdWidth.isSelected());
1256 userIdWidthlabel.setEnabled(!autoIdWidth.isSelected());
1260 * Returns true if chimera path is to a valid executable, else show an error
1263 private boolean validateChimeraPath()
1265 if (chimeraPath.getText().trim().length() > 0)
1267 File f = new File(chimeraPath.getText());
1268 if (!f.canExecute())
1270 JvOptionPane.showInternalMessageDialog(Desktop.desktop,
1271 MessageManager.getString("label.invalid_chimera_path"),
1272 MessageManager.getString("label.invalid_name"),
1273 JvOptionPane.ERROR_MESSAGE);
1281 * If Chimera is selected, check it can be found on default or user-specified
1282 * path, if not show a warning/help dialog.
1285 protected void structureViewer_actionPerformed(String selectedItem)
1287 if (!selectedItem.equals(ViewerType.CHIMERA.name()))
1291 boolean found = false;
1294 * Try user-specified and standard paths for Chimera executable.
1296 List<String> paths = StructureManager.getChimeraPaths();
1297 paths.add(0, chimeraPath.getText());
1298 for (String path : paths)
1300 if (new File(path.trim()).canExecute())
1308 String[] options = { "OK", "Help" };
1309 int showHelp = JvOptionPane.showInternalOptionDialog(Desktop.desktop,
1310 JvSwingUtils.wrapTooltip(true,
1311 MessageManager.getString("label.chimera_missing")),
1312 "", JvOptionPane.YES_NO_OPTION, JvOptionPane.WARNING_MESSAGE,
1313 null, options, options[0]);
1314 if (showHelp == JvOptionPane.NO_OPTION)
1318 Help.showHelpWindow(HelpId.StructureViewer);
1319 } catch (HelpSetException e)
1321 e.printStackTrace();
1327 public class OptionsParam
1329 private String name;
1331 private String code;
1333 public OptionsParam(String name, String code)
1339 public String getName()
1344 public void setName(String name)
1349 public String getCode()
1354 public void setCode(String code)
1360 public String toString()
1366 public boolean equals(Object that)
1368 if (!(that instanceof OptionsParam))
1372 return this.code.equalsIgnoreCase(((OptionsParam) that).code);
1376 public int hashCode()
1378 return name.hashCode() + code.hashCode();
1382 private class UrlListSelectionHandler implements ListSelectionListener
1386 public void valueChanged(ListSelectionEvent e)
1388 ListSelectionModel lsm = (ListSelectionModel) e.getSource();
1390 int index = lsm.getMinSelectionIndex();
1393 // no selection, so disable delete/edit buttons
1394 editLink.setEnabled(false);
1395 deleteLink.setEnabled(false);
1398 int modelIndex = linkUrlTable.convertRowIndexToModel(index);
1400 // enable/disable edit and delete link buttons
1401 if (((UrlLinkTableModel) linkUrlTable.getModel())
1402 .isRowDeletable(modelIndex))
1404 deleteLink.setEnabled(true);
1408 deleteLink.setEnabled(false);
1411 if (((UrlLinkTableModel) linkUrlTable.getModel())
1412 .isRowEditable(modelIndex))
1414 editLink.setEnabled(true);
1418 editLink.setEnabled(false);