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;
34 import java.util.concurrent.CompletableFuture;
36 import javax.help.HelpSetException;
37 import javax.swing.JComboBox;
38 import javax.swing.JFileChooser;
39 import javax.swing.JInternalFrame;
40 import javax.swing.JPanel;
41 import javax.swing.ListSelectionModel;
42 import javax.swing.RowFilter;
43 import javax.swing.RowSorter;
44 import javax.swing.SortOrder;
45 import javax.swing.event.DocumentEvent;
46 import javax.swing.event.DocumentListener;
47 import javax.swing.event.ListSelectionEvent;
48 import javax.swing.event.ListSelectionListener;
49 import javax.swing.table.TableCellRenderer;
50 import javax.swing.table.TableColumn;
51 import javax.swing.table.TableModel;
52 import javax.swing.table.TableRowSorter;
54 import ext.edu.ucsf.rbvi.strucviz2.StructureManager;
55 import jalview.analysis.AnnotationSorter.SequenceAnnotationOrder;
56 import jalview.bin.Cache;
57 import jalview.bin.MemorySetting;
58 import jalview.ext.pymol.PymolManager;
59 import jalview.gui.Help.HelpId;
60 import jalview.gui.StructureViewer.ViewerType;
61 import jalview.io.BackupFiles;
62 import jalview.io.BackupFilesPresetEntry;
63 import jalview.io.FileFormatI;
64 import jalview.io.JalviewFileChooser;
65 import jalview.io.JalviewFileView;
66 import jalview.jbgui.GPreferences;
67 import jalview.jbgui.GSequenceLink;
68 import jalview.schemes.ColourSchemeI;
69 import jalview.schemes.ColourSchemes;
70 import jalview.schemes.ResidueColourScheme;
71 import jalview.urls.UrlLinkTableModel;
72 import jalview.urls.api.UrlProviderFactoryI;
73 import jalview.urls.api.UrlProviderI;
74 import jalview.urls.desktop.DesktopUrlProviderFactory;
75 import jalview.util.MessageManager;
76 import jalview.util.Platform;
77 import jalview.util.UrlConstants;
78 import jalview.ws.sifts.SiftsSettings;
87 * for merge with Jalview-JS
88 public class Preferences extends GPreferences implements ApplicationSingletonI
90 public class Preferences extends GPreferences
92 public static final String ENABLE_SPLIT_FRAME = "ENABLE_SPLIT_FRAME";
94 public static final String SCALE_PROTEIN_TO_CDNA = "SCALE_PROTEIN_TO_CDNA";
96 public static final String DEFAULT_COLOUR = "DEFAULT_COLOUR";
98 public static final String DEFAULT_COLOUR_PROT = "DEFAULT_COLOUR_PROT";
100 public static final String DEFAULT_COLOUR_NUC = "DEFAULT_COLOUR_NUC";
102 public static final String ADD_TEMPFACT_ANN = "ADD_TEMPFACT_ANN";
104 public static final String ADD_SS_ANN = "ADD_SS_ANN";
106 public static final String USE_RNAVIEW = "USE_RNAVIEW";
108 public static final String STRUCT_FROM_PDB = "STRUCT_FROM_PDB";
110 public static final String STRUCTURE_DISPLAY = "STRUCTURE_DISPLAY";
112 public static final String CHIMERA_PATH = "CHIMERA_PATH";
114 public static final String CHIMERAX_PATH = "CHIMERAX_PATH";
116 public static final String PYMOL_PATH = "PYMOL_PATH";
118 public static final String SORT_ANNOTATIONS = "SORT_ANNOTATIONS";
120 public static final String SHOW_AUTOCALC_ABOVE = "SHOW_AUTOCALC_ABOVE";
122 public static final String SHOW_OCCUPANCY = "SHOW_OCCUPANCY";
124 public static final String SHOW_OV_HIDDEN_AT_START = "SHOW_OV_HIDDEN_AT_START";
126 public static final String USE_LEGACY_GAP = "USE_LEGACY_GAP";
128 public static final String GAP_COLOUR = "GAP_COLOUR";
130 public static final String HIDDEN_COLOUR = "HIDDEN_COLOUR";
132 private static final int MIN_FONT_SIZE = 1;
134 private static final int MAX_FONT_SIZE = 30;
136 private String previousProxyType;
138 private static Preferences INSTANCE = null; // add "final"
141 * Holds name and link separated with | character. Sequence ID must be
142 * $SEQUENCE_ID$ or $SEQUENCE_ID=/.possible | chars ./=$
144 public static UrlProviderI sequenceUrlLinks;
146 public static UrlLinkTableModel dataModel;
149 * Holds name and link separated with | character. Sequence IDS and Sequences
150 * must be $SEQUENCEIDS$ or $SEQUENCEIDS=/.possible | chars ./=$ and $SEQUENCES$
151 * or $SEQUENCES=/.possible | chars ./=$ and separation character for first and
152 * second token specified after a pipe character at end |,|. (TODO: proper
153 * escape for using | to separate ids or sequences
156 public static List<String> groupURLLinks;
159 // get links selected to be in the menu (SEQUENCE_LINKS)
160 // and links entered by the user but not selected (STORED_LINKS)
161 String inMenuString = Cache.getDefault("SEQUENCE_LINKS", "");
162 String notInMenuString = Cache.getDefault("STORED_LINKS", "");
163 String defaultUrl = Cache.getDefault("DEFAULT_URL",
164 UrlConstants.DEFAULT_LABEL);
166 // if both links lists are empty, add the DEFAULT_URL link
167 // otherwise we assume the default link is in one of the lists
168 if (inMenuString.isEmpty() && notInMenuString.isEmpty())
170 inMenuString = UrlConstants.DEFAULT_STRING;
172 UrlProviderFactoryI factory = new DesktopUrlProviderFactory(defaultUrl,
173 inMenuString, notInMenuString);
174 sequenceUrlLinks = factory.createUrlProvider();
175 dataModel = new UrlLinkTableModel(sequenceUrlLinks);
178 * TODO: reformulate groupURL encoding so two or more can be stored in the
179 * .properties file as '|' separated strings
182 groupURLLinks = new ArrayList<>();
185 JInternalFrame frame;
187 private WsPreferences wsPrefs;
189 private OptionsParam promptEachTimeOpt = new OptionsParam(
190 MessageManager.getString("label.prompt_each_time"),
193 private OptionsParam lineArtOpt = new OptionsParam(
194 MessageManager.getString("label.lineart"), "Lineart");
196 private OptionsParam textOpt = new OptionsParam(
197 MessageManager.getString("action.text"), "Text");
199 // get singleton Preferences instance
200 public static Preferences getInstance()
202 if (INSTANCE == null || INSTANCE.frame == null
203 || INSTANCE.frame.isClosed())
205 INSTANCE = new Preferences();
210 * Replace code with the following for Jalvew-JS
211 Preferences INSTANCE = ApplicationSingletonProvider.getInstance(Preferences.class);
212 if (INSTANCE == null || INSTANCE.frame == null
213 || INSTANCE.frame.isClosed())
215 ApplicationSingletonProvider.remove(Preferences.class);
216 INSTANCE = ApplicationSingletonProvider.getInstance(Preferences.class);
222 public static void openPreferences()
224 openPreferences(null, null);
227 public static void openPreferences(TabRef selectTab, String message)
229 Preferences p = getInstance();
230 if (selectTab != null)
231 p.selectTab(selectTab, message);
233 p.frame.moveToFront();
237 public void selectTab(TabRef selectTab, String message)
239 this.selectTab(selectTab);
241 this.setMessage(message);
246 * Creates a new Preferences object.
248 private Preferences()
251 frame = new JInternalFrame();
252 frame.setContentPane(this);
253 if (!Platform.isJS())
260 wsPrefs = new WsPreferences();
261 wsTab.add(wsPrefs, BorderLayout.CENTER);
263 int width = 500, height = 450;
264 if (Platform.isAMacAndNotJS())
270 Desktop.addInternalFrame(frame,
271 MessageManager.getString("label.preferences"), width, height);
272 frame.setMinimumSize(new Dimension(width, height));
275 * Set Visual tab defaults
277 seqLimit.setSelected(Cache.getDefault("SHOW_JVSUFFIX", true));
278 rightAlign.setSelected(Cache.getDefault("RIGHT_ALIGN_IDS", false));
279 fullScreen.setSelected(Cache.getDefault("SHOW_FULLSCREEN", false));
280 annotations.setSelected(Cache.getDefault("SHOW_ANNOTATIONS", true));
282 conservation.setSelected(Cache.getDefault("SHOW_CONSERVATION", true));
283 quality.setSelected(Cache.getDefault("SHOW_QUALITY", true));
284 identity.setSelected(Cache.getDefault("SHOW_IDENTITY", true));
285 openoverv.setSelected(Cache.getDefault("SHOW_OVERVIEW", false));
287 .setSelected(Cache.getDefault("SHOW_UNCONSERVED", false));
288 showOccupancy.setSelected(Cache.getDefault(SHOW_OCCUPANCY, false));
290 .setSelected(Cache.getDefault("SHOW_GROUP_CONSENSUS", false));
291 showGroupConservation.setSelected(
292 Cache.getDefault("SHOW_GROUP_CONSERVATION", false));
293 showConsensHistogram.setSelected(
294 Cache.getDefault("SHOW_CONSENSUS_HISTOGRAM", true));
296 .setSelected(Cache.getDefault("SHOW_CONSENSUS_LOGO", false));
298 .setSelected(Cache.getDefault("SHOW_NPFEATS_TOOLTIP", true));
300 .setSelected(Cache.getDefault("SHOW_DBREFS_TOOLTIP", true));
302 String[] fonts = java.awt.GraphicsEnvironment
303 .getLocalGraphicsEnvironment().getAvailableFontFamilyNames();
304 for (int i = 0; i < fonts.length; i++)
306 fontNameCB.addItem(fonts[i]);
309 for (int i = MIN_FONT_SIZE; i <= MAX_FONT_SIZE; i++)
311 fontSizeCB.addItem(i + "");
314 fontStyleCB.addItem("plain");
315 fontStyleCB.addItem("bold");
316 fontStyleCB.addItem("italic");
318 fontNameCB.setSelectedItem(Cache.getDefault("FONT_NAME", "SansSerif"));
319 fontSizeCB.setSelectedItem(Cache.getDefault("FONT_SIZE", "10"));
320 fontStyleCB.setSelectedItem(
321 Cache.getDefault("FONT_STYLE", Font.PLAIN + ""));
323 smoothFont.setSelected(Cache.getDefault("ANTI_ALIAS", true));
325 .setSelected(Cache.getDefault(SCALE_PROTEIN_TO_CDNA, false));
327 idItalics.setSelected(Cache.getDefault("ID_ITALICS", true));
329 wrap.setSelected(Cache.getDefault("WRAP_ALIGNMENT", false));
331 gapSymbolCB.addItem("-");
332 gapSymbolCB.addItem(".");
334 gapSymbolCB.setSelectedItem(Cache.getDefault("GAP_SYMBOL", "-"));
336 sortby.addItem("No sort");
337 sortby.addItem("Id");
338 sortby.addItem("Pairwise Identity");
339 sortby.setSelectedItem(Cache.getDefault("SORT_ALIGNMENT", "No sort"));
341 sortAnnBy.addItem(SequenceAnnotationOrder.NONE.toString());
343 .addItem(SequenceAnnotationOrder.SEQUENCE_AND_LABEL.toString());
345 .addItem(SequenceAnnotationOrder.LABEL_AND_SEQUENCE.toString());
346 SequenceAnnotationOrder savedSort = SequenceAnnotationOrder
347 .valueOf(Cache.getDefault(SORT_ANNOTATIONS,
348 SequenceAnnotationOrder.NONE.name()));
349 sortAnnBy.setSelectedItem(savedSort.toString());
351 sortAutocalc.addItem("Autocalculated first");
352 sortAutocalc.addItem("Autocalculated last");
353 final boolean showAbove = Cache.getDefault(SHOW_AUTOCALC_ABOVE, true);
354 sortAutocalc.setSelectedItem(showAbove ? sortAutocalc.getItemAt(0)
355 : sortAutocalc.getItemAt(1));
357 .setSelected(Cache.getDefault("SHOW_STARTUP_FILE", true));
358 startupFileTextfield.setText(Cache.getDefault("STARTUP_FILE",
359 Cache.getDefault("www.jalview.org", "https://www.jalview.org")
360 + "/examples/exampleFile_2_7.jvp"));
363 * Set Colours tab defaults
365 protColour.addItem(ResidueColourScheme.NONE);
366 nucColour.addItem(ResidueColourScheme.NONE);
367 for (ColourSchemeI cs : ColourSchemes.getInstance().getColourSchemes())
369 String name = cs.getSchemeName();
370 protColour.addItem(name);
371 nucColour.addItem(name);
373 String oldProp = Cache.getDefault(DEFAULT_COLOUR,
374 ResidueColourScheme.NONE);
375 String newProp = Cache.getDefault(DEFAULT_COLOUR_PROT, null);
376 protColour.setSelectedItem(newProp != null ? newProp : oldProp);
377 newProp = Cache.getDefault(DEFAULT_COLOUR_NUC, null);
378 nucColour.setSelectedItem(newProp != null ? newProp : oldProp);
379 minColour.setBackground(
380 Cache.getDefaultColour("ANNOTATIONCOLOUR_MIN", Color.orange));
381 maxColour.setBackground(
382 Cache.getDefaultColour("ANNOTATIONCOLOUR_MAX", Color.red));
385 * Set overview panel defaults
387 gapColour.setBackground(Cache.getDefaultColour(GAP_COLOUR,
388 OverviewCanvas.OVERVIEW_DEFAULT_GAP));
389 hiddenColour.setBackground(Cache.getDefaultColour(HIDDEN_COLOUR,
390 OverviewCanvas.OVERVIEW_DEFAULT_HIDDEN));
391 useLegacyGap.setSelected(Cache.getDefault(USE_LEGACY_GAP, false));
392 gapLabel.setEnabled(!useLegacyGap.isSelected());
393 gapColour.setEnabled(!useLegacyGap.isSelected());
395 .setSelected(Cache.getDefault(SHOW_OV_HIDDEN_AT_START, false));
398 * Set Structure tab defaults
400 final boolean structSelected = Cache.getDefault(STRUCT_FROM_PDB, true);
401 structFromPdb.setSelected(structSelected);
402 addSecondaryStructure.setSelected(Cache.getDefault(ADD_SS_ANN, true));
403 addSecondaryStructure.setEnabled(structSelected);
404 addTempFactor.setSelected(Cache.getDefault(ADD_TEMPFACT_ANN, true));
405 addTempFactor.setEnabled(structSelected);
408 * set choice of structure viewer, and path if saved as a preference;
409 * default to Jmol (first choice) if an unexpected value is found
411 String viewerType = Cache.getDefault(STRUCTURE_DISPLAY,
412 ViewerType.JMOL.name());
413 structViewer.setSelectedItem(viewerType);
414 String viewerPath = "";
415 ViewerType type = null;
418 type = ViewerType.valueOf(viewerType);
424 viewerPath = Cache.getDefault(CHIMERA_PATH, "");
427 viewerPath = Cache.getDefault(CHIMERAX_PATH, "");
430 viewerPath = Cache.getDefault(PYMOL_PATH, "");
433 } catch (IllegalArgumentException e)
435 Cache.log.error("Unknown structure viewer type: " + viewerType
436 + ", defaulting to Jmol");
437 type = ViewerType.JMOL;
439 structureViewerPath.setText(viewerPath);
441 structureViewerPath.addActionListener(new ActionListener()
444 public void actionPerformed(ActionEvent e)
446 if (validateViewerPath())
448 String path = structureViewerPath.getText();
450 ViewerType type = ViewerType.valueOf(viewerType);
456 Cache.setProperty(CHIMERA_PATH, path);
459 Cache.setProperty(CHIMERAX_PATH, path);
462 Cache.setProperty(PYMOL_PATH, path);
465 } catch (IllegalArgumentException x)
467 Cache.log.error("Failed to set path - unknown viewer type",x);
473 if (Cache.getDefault("MAP_WITH_SIFTS", false))
475 siftsMapping.setSelected(true);
479 nwMapping.setSelected(true);
483 .setMapWithSifts(Cache.getDefault("MAP_WITH_SIFTS", false));
486 * Set Connections tab defaults
490 linkUrlTable.setModel(dataModel);
491 final TableRowSorter<TableModel> sorter = new TableRowSorter<>(
492 linkUrlTable.getModel());
493 linkUrlTable.setRowSorter(sorter);
494 List<RowSorter.SortKey> sortKeys = new ArrayList<>();
496 UrlLinkTableModel m = (UrlLinkTableModel) linkUrlTable.getModel();
497 sortKeys.add(new RowSorter.SortKey(m.getPrimaryColumn(),
498 SortOrder.DESCENDING));
499 sortKeys.add(new RowSorter.SortKey(m.getSelectedColumn(),
500 SortOrder.DESCENDING));
502 new RowSorter.SortKey(m.getNameColumn(), SortOrder.ASCENDING));
504 sorter.setSortKeys(sortKeys);
505 // BH 2018 setSortKeys will do the sort
509 ActionListener onReset;
510 onReset = new ActionListener()
513 public void actionPerformed(ActionEvent e)
515 filterTB.setText("");
516 sorter.setRowFilter(RowFilter.regexFilter(""));
520 doReset.addActionListener(onReset);
522 // filter to display only custom urls
523 final RowFilter<TableModel, Object> customUrlFilter = new RowFilter<TableModel, Object>()
526 public boolean include(
527 Entry<? extends TableModel, ? extends Object> entry)
529 return ((UrlLinkTableModel) entry.getModel()).isUserEntry(entry);
533 final TableRowSorter<TableModel> customSorter = new TableRowSorter<>(
534 linkUrlTable.getModel());
535 customSorter.setRowFilter(customUrlFilter);
537 ActionListener onCustomOnly;
538 onCustomOnly = new ActionListener()
541 public void actionPerformed(ActionEvent e)
543 filterTB.setText("");
544 sorter.setRowFilter(customUrlFilter);
547 userOnly.addActionListener(onCustomOnly);
549 filterTB.getDocument().addDocumentListener(new DocumentListener()
551 String caseInsensitiveFlag = "(?i)";
554 public void changedUpdate(DocumentEvent e)
556 sorter.setRowFilter(RowFilter
557 .regexFilter(caseInsensitiveFlag + filterTB.getText()));
561 public void removeUpdate(DocumentEvent e)
563 sorter.setRowFilter(RowFilter
564 .regexFilter(caseInsensitiveFlag + filterTB.getText()));
568 public void insertUpdate(DocumentEvent e)
570 sorter.setRowFilter(RowFilter
571 .regexFilter(caseInsensitiveFlag + filterTB.getText()));
575 // set up list selection functionality
576 linkUrlTable.getSelectionModel()
577 .addListSelectionListener(new UrlListSelectionHandler());
579 // set up radio buttons
580 int onClickCol = ((UrlLinkTableModel) linkUrlTable.getModel())
582 String onClickName = linkUrlTable.getColumnName(onClickCol);
583 linkUrlTable.getColumn(onClickName)
584 .setCellRenderer(new RadioButtonRenderer());
585 linkUrlTable.getColumn(onClickName)
586 .setCellEditor(new RadioButtonEditor());
588 // get boolean columns and resize those to min possible
589 for (int column = 0; column < linkUrlTable.getColumnCount(); column++)
591 if (linkUrlTable.getModel().getColumnClass(column)
592 .equals(Boolean.class))
594 TableColumn tableColumn = linkUrlTable.getColumnModel()
596 int preferredWidth = tableColumn.getMinWidth();
598 TableCellRenderer cellRenderer = linkUrlTable.getCellRenderer(0,
600 Component c = linkUrlTable.prepareRenderer(cellRenderer, 0, column);
601 int cwidth = c.getPreferredSize().width
602 + linkUrlTable.getIntercellSpacing().width;
603 preferredWidth = Math.max(preferredWidth, cwidth);
605 tableColumn.setPreferredWidth(preferredWidth);
609 String proxyTypeString = Cache.getDefault("USE_PROXY", "false");
610 previousProxyType = proxyTypeString;
611 switch (proxyTypeString)
613 case Cache.PROXYTYPE_NONE:
614 proxyType.setSelected(noProxy.getModel(), true);
616 case Cache.PROXYTYPE_SYSTEM:
617 proxyType.setSelected(systemProxy.getModel(), true);
619 case Cache.PROXYTYPE_CUSTOM:
620 proxyType.setSelected(customProxy.getModel(), true);
624 "Incorrect PROXY_TYPE - should be 'none' (clear proxy properties), 'false' (system settings), 'true' (custom settings): "
627 proxyServerHttpTB.setText(Cache.getDefault("PROXY_SERVER", ""));
628 proxyPortHttpTB.setText(Cache.getDefault("PROXY_PORT", ""));
629 proxyServerHttpsTB.setText(Cache.getDefault("PROXY_SERVER_HTTPS", ""));
630 proxyPortHttpsTB.setText(Cache.getDefault("PROXY_PORT_HTTPS", ""));
631 proxyAuth.setSelected(Cache.getDefault("PROXY_AUTH", false));
633 .setText(Cache.getDefault("PROXY_AUTH_USERNAME", ""));
634 // we are not storing or retrieving proxy password from .jalview_properties
635 proxyAuthPasswordPB.setText(Cache.proxyAuthPassword == null ? ""
636 : new String(Cache.proxyAuthPassword));
637 setCustomProxyEnabled();
638 applyProxyButtonEnabled(false);
640 defaultBrowser.setText(Cache.getDefault("DEFAULT_BROWSER", ""));
642 usagestats.setSelected(Cache.getDefault("USAGESTATS", false));
643 // note antisense here: default is true
645 .setSelected(Cache.getProperty("NOQUESTIONNAIRES") == null);
646 versioncheck.setSelected(Cache.getDefault("VERSION_CHECK", true));
649 * Set Output tab defaults
651 setupOutputCombo(epsRendering, "EPS_RENDERING");
652 setupOutputCombo(htmlRendering, "HTML_RENDERING");
653 setupOutputCombo(svgRendering, "SVG_RENDERING");
654 autoIdWidth.setSelected(Cache.getDefault("FIGURE_AUTOIDWIDTH", false));
655 userIdWidth.setEnabled(!autoIdWidth.isSelected());
656 userIdWidthlabel.setEnabled(!autoIdWidth.isSelected());
657 Integer wi = Cache.getIntegerProperty("FIGURE_FIXEDIDWIDTH");
658 userIdWidth.setText(wi == null ? "" : wi.toString());
659 // TODO: refactor to use common enum via FormatAdapter and allow extension
660 // for new flat file formats
661 blcjv.setSelected(Cache.getDefault("BLC_JVSUFFIX", true));
662 clustaljv.setSelected(Cache.getDefault("CLUSTAL_JVSUFFIX", true));
663 fastajv.setSelected(Cache.getDefault("FASTA_JVSUFFIX", true));
664 msfjv.setSelected(Cache.getDefault("MSF_JVSUFFIX", true));
665 pfamjv.setSelected(Cache.getDefault("PFAM_JVSUFFIX", true));
666 pileupjv.setSelected(Cache.getDefault("PILEUP_JVSUFFIX", true));
667 pirjv.setSelected(Cache.getDefault("PIR_JVSUFFIX", true));
668 modellerOutput.setSelected(Cache.getDefault("PIR_MODELLER", false));
670 .setSelected(Cache.getDefault("EXPORT_EMBBED_BIOJSON", true));
673 * Set Editing tab defaults
675 autoCalculateConsCheck
676 .setSelected(Cache.getDefault("AUTO_CALC_CONSENSUS", true));
677 padGaps.setSelected(Cache.getDefault("PAD_GAPS", false));
678 sortByTree.setSelected(Cache.getDefault("SORT_BY_TREE", false));
680 annotations_actionPerformed(null); // update the display of the annotation
684 * Set Backups tab defaults
686 loadLastSavedBackupsOptions();
689 * Set Startup tab defaults
695 * A helper method that sets the items and initial selection in a character
696 * rendering option list (Prompt each time/Lineart/Text)
701 protected void setupOutputCombo(JComboBox<Object> comboBox,
704 comboBox.addItem(promptEachTimeOpt);
705 comboBox.addItem(lineArtOpt);
706 comboBox.addItem(textOpt);
709 * JalviewJS doesn't support Lineart so force it to Text
711 String defaultOption = Platform.isJS() ? "Text"
712 : Cache.getDefault(propertyKey, "Prompt each time");
713 if (defaultOption.equalsIgnoreCase("Text"))
715 comboBox.setSelectedItem(textOpt);
717 else if (defaultOption.equalsIgnoreCase("Lineart"))
719 comboBox.setSelectedItem(lineArtOpt);
723 comboBox.setSelectedItem(promptEachTimeOpt);
728 * Save user selections on the Preferences tabs to the Cache and write out to
734 public void ok_actionPerformed(ActionEvent e)
736 if (!validateSettings())
742 * Set proxy settings first (to be before web services refresh)
747 * Save Visual settings
749 Cache.applicationProperties.setProperty("SHOW_JVSUFFIX",
750 Boolean.toString(seqLimit.isSelected()));
751 Cache.applicationProperties.setProperty("RIGHT_ALIGN_IDS",
752 Boolean.toString(rightAlign.isSelected()));
753 Cache.applicationProperties.setProperty("SHOW_FULLSCREEN",
754 Boolean.toString(fullScreen.isSelected()));
755 Cache.applicationProperties.setProperty("SHOW_OVERVIEW",
756 Boolean.toString(openoverv.isSelected()));
757 Cache.applicationProperties.setProperty("SHOW_ANNOTATIONS",
758 Boolean.toString(annotations.isSelected()));
759 Cache.applicationProperties.setProperty("SHOW_CONSERVATION",
760 Boolean.toString(conservation.isSelected()));
761 Cache.applicationProperties.setProperty("SHOW_QUALITY",
762 Boolean.toString(quality.isSelected()));
763 Cache.applicationProperties.setProperty("SHOW_IDENTITY",
764 Boolean.toString(identity.isSelected()));
766 Cache.applicationProperties.setProperty("GAP_SYMBOL",
767 gapSymbolCB.getSelectedItem().toString());
769 Cache.applicationProperties.setProperty("FONT_NAME",
770 fontNameCB.getSelectedItem().toString());
771 Cache.applicationProperties.setProperty("FONT_STYLE",
772 fontStyleCB.getSelectedItem().toString());
773 Cache.applicationProperties.setProperty("FONT_SIZE",
774 fontSizeCB.getSelectedItem().toString());
776 Cache.applicationProperties.setProperty("ID_ITALICS",
777 Boolean.toString(idItalics.isSelected()));
778 Cache.applicationProperties.setProperty("SHOW_UNCONSERVED",
779 Boolean.toString(showUnconserved.isSelected()));
780 Cache.applicationProperties.setProperty(SHOW_OCCUPANCY,
781 Boolean.toString(showOccupancy.isSelected()));
782 Cache.applicationProperties.setProperty("SHOW_GROUP_CONSENSUS",
783 Boolean.toString(showGroupConsensus.isSelected()));
784 Cache.applicationProperties.setProperty("SHOW_GROUP_CONSERVATION",
785 Boolean.toString(showGroupConservation.isSelected()));
786 Cache.applicationProperties.setProperty("SHOW_CONSENSUS_HISTOGRAM",
787 Boolean.toString(showConsensHistogram.isSelected()));
788 Cache.applicationProperties.setProperty("SHOW_CONSENSUS_LOGO",
789 Boolean.toString(showConsensLogo.isSelected()));
790 Cache.applicationProperties.setProperty("ANTI_ALIAS",
791 Boolean.toString(smoothFont.isSelected()));
792 Cache.applicationProperties.setProperty(SCALE_PROTEIN_TO_CDNA,
793 Boolean.toString(scaleProteinToCdna.isSelected()));
794 Cache.applicationProperties.setProperty("SHOW_NPFEATS_TOOLTIP",
795 Boolean.toString(showNpTooltip.isSelected()));
796 Cache.applicationProperties.setProperty("SHOW_DBREFS_TOOLTIP",
797 Boolean.toString(showDbRefTooltip.isSelected()));
799 Cache.applicationProperties.setProperty("WRAP_ALIGNMENT",
800 Boolean.toString(wrap.isSelected()));
802 Cache.applicationProperties.setProperty("STARTUP_FILE",
803 startupFileTextfield.getText());
804 Cache.applicationProperties.setProperty("SHOW_STARTUP_FILE",
805 Boolean.toString(startupCheckbox.isSelected()));
807 Cache.applicationProperties.setProperty("SORT_ALIGNMENT",
808 sortby.getSelectedItem().toString());
810 // convert description of sort order to enum name for save
811 SequenceAnnotationOrder annSortOrder = SequenceAnnotationOrder
812 .forDescription(sortAnnBy.getSelectedItem().toString());
813 if (annSortOrder != null)
815 Cache.applicationProperties.setProperty(SORT_ANNOTATIONS,
816 annSortOrder.name());
819 final boolean showAutocalcFirst = sortAutocalc.getSelectedIndex() == 0;
820 Cache.applicationProperties.setProperty(SHOW_AUTOCALC_ABOVE,
821 Boolean.valueOf(showAutocalcFirst).toString());
824 * Save Colours settings
826 Cache.applicationProperties.setProperty(DEFAULT_COLOUR_PROT,
827 protColour.getSelectedItem().toString());
828 Cache.applicationProperties.setProperty(DEFAULT_COLOUR_NUC,
829 nucColour.getSelectedItem().toString());
830 Cache.setColourProperty("ANNOTATIONCOLOUR_MIN",
831 minColour.getBackground());
832 Cache.setColourProperty("ANNOTATIONCOLOUR_MAX",
833 maxColour.getBackground());
836 * Save Overview settings
838 Cache.setColourProperty(GAP_COLOUR, gapColour.getBackground());
839 Cache.setColourProperty(HIDDEN_COLOUR, hiddenColour.getBackground());
840 Cache.applicationProperties.setProperty(USE_LEGACY_GAP,
841 Boolean.toString(useLegacyGap.isSelected()));
842 Cache.applicationProperties.setProperty(SHOW_OV_HIDDEN_AT_START,
843 Boolean.toString(showHiddenAtStart.isSelected()));
846 * Save Structure settings
848 Cache.applicationProperties.setProperty(ADD_TEMPFACT_ANN,
849 Boolean.toString(addTempFactor.isSelected()));
850 Cache.applicationProperties.setProperty(ADD_SS_ANN,
851 Boolean.toString(addSecondaryStructure.isSelected()));
852 Cache.applicationProperties.setProperty(STRUCT_FROM_PDB,
853 Boolean.toString(structFromPdb.isSelected()));
854 String viewer = structViewer.getSelectedItem().toString();
855 String viewerPath = structureViewerPath.getText();
856 Cache.applicationProperties.setProperty(STRUCTURE_DISPLAY, viewer);
857 if (viewer.equals(ViewerType.CHIMERA.name()))
859 Cache.setOrRemove(CHIMERA_PATH, viewerPath);
861 else if (viewer.equals(ViewerType.CHIMERAX.name()))
863 Cache.setOrRemove(CHIMERAX_PATH, viewerPath);
865 else if (viewer.equals(ViewerType.PYMOL.name()))
867 Cache.setOrRemove(PYMOL_PATH, viewerPath);
869 Cache.applicationProperties.setProperty("MAP_WITH_SIFTS",
870 Boolean.toString(siftsMapping.isSelected()));
871 SiftsSettings.setMapWithSifts(siftsMapping.isSelected());
874 * Save Output settings
876 Cache.applicationProperties.setProperty("EPS_RENDERING",
877 ((OptionsParam) epsRendering.getSelectedItem()).getCode());
878 Cache.applicationProperties.setProperty("HTML_RENDERING",
879 ((OptionsParam) htmlRendering.getSelectedItem()).getCode());
880 Cache.applicationProperties.setProperty("SVG_RENDERING",
881 ((OptionsParam) svgRendering.getSelectedItem()).getCode());
884 * Save Connections settings
886 // Proxy settings set first (to catch web services)
888 Cache.setOrRemove("DEFAULT_BROWSER", defaultBrowser.getText());
890 jalview.util.BrowserLauncher.resetBrowser();
892 // save user-defined and selected links
893 String menuLinks = sequenceUrlLinks.writeUrlsAsString(true);
894 if (menuLinks.isEmpty())
896 Cache.applicationProperties.remove("SEQUENCE_LINKS");
900 Cache.applicationProperties.setProperty("SEQUENCE_LINKS",
901 menuLinks.toString());
904 String nonMenuLinks = sequenceUrlLinks.writeUrlsAsString(false);
905 if (nonMenuLinks.isEmpty())
907 Cache.applicationProperties.remove("STORED_LINKS");
911 Cache.applicationProperties.setProperty("STORED_LINKS",
912 nonMenuLinks.toString());
915 Cache.applicationProperties.setProperty("DEFAULT_URL",
916 sequenceUrlLinks.getPrimaryUrlId());
918 Cache.setProperty("VERSION_CHECK",
919 Boolean.toString(versioncheck.isSelected()));
920 if (Cache.getProperty("USAGESTATS") != null || usagestats.isSelected())
922 // default is false - we only set this if the user has actively agreed
923 Cache.setProperty("USAGESTATS",
924 Boolean.toString(usagestats.isSelected()));
926 if (!questionnaire.isSelected())
928 Cache.setProperty("NOQUESTIONNAIRES", "true");
932 // special - made easy to edit a property file to disable questionnaires
933 // by just adding the given line
934 Cache.removeProperty("NOQUESTIONNAIRES");
938 * Save Output settings
940 Cache.applicationProperties.setProperty("BLC_JVSUFFIX",
941 Boolean.toString(blcjv.isSelected()));
942 Cache.applicationProperties.setProperty("CLUSTAL_JVSUFFIX",
943 Boolean.toString(clustaljv.isSelected()));
944 Cache.applicationProperties.setProperty("FASTA_JVSUFFIX",
945 Boolean.toString(fastajv.isSelected()));
946 Cache.applicationProperties.setProperty("MSF_JVSUFFIX",
947 Boolean.toString(msfjv.isSelected()));
948 Cache.applicationProperties.setProperty("PFAM_JVSUFFIX",
949 Boolean.toString(pfamjv.isSelected()));
950 Cache.applicationProperties.setProperty("PILEUP_JVSUFFIX",
951 Boolean.toString(pileupjv.isSelected()));
952 Cache.applicationProperties.setProperty("PIR_JVSUFFIX",
953 Boolean.toString(pirjv.isSelected()));
954 Cache.applicationProperties.setProperty("PIR_MODELLER",
955 Boolean.toString(modellerOutput.isSelected()));
956 Cache.applicationProperties.setProperty("EXPORT_EMBBED_BIOJSON",
957 Boolean.toString(embbedBioJSON.isSelected()));
958 jalview.io.PIRFile.useModellerOutput = modellerOutput.isSelected();
960 Cache.applicationProperties.setProperty("FIGURE_AUTOIDWIDTH",
961 Boolean.toString(autoIdWidth.isSelected()));
962 userIdWidth_actionPerformed();
963 Cache.applicationProperties.setProperty("FIGURE_FIXEDIDWIDTH",
964 userIdWidth.getText());
967 * Save Editing settings
969 Cache.applicationProperties.setProperty("AUTO_CALC_CONSENSUS",
970 Boolean.toString(autoCalculateConsCheck.isSelected()));
971 Cache.applicationProperties.setProperty("SORT_BY_TREE",
972 Boolean.toString(sortByTree.isSelected()));
973 Cache.applicationProperties.setProperty("PAD_GAPS",
974 Boolean.toString(padGaps.isSelected()));
976 if (!Platform.isJS())
978 wsPrefs.updateAndRefreshWsMenuConfig(false);
982 * Save Backups settings
984 Cache.applicationProperties.setProperty(BackupFiles.ENABLED,
985 Boolean.toString(enableBackupFiles.isSelected()));
986 int preset = getComboIntStringKey(backupfilesPresetsCombo);
987 Cache.applicationProperties.setProperty(BackupFiles.NS + "_PRESET",
988 Integer.toString(preset));
990 if (preset == BackupFilesPresetEntry.BACKUPFILESSCHEMECUSTOM)
992 BackupFilesPresetEntry customBFPE = getBackupfilesCurrentEntry();
993 BackupFilesPresetEntry.backupfilesPresetEntriesValues.put(
994 BackupFilesPresetEntry.BACKUPFILESSCHEMECUSTOM, customBFPE);
995 Cache.applicationProperties.setProperty(
996 BackupFilesPresetEntry.CUSTOMCONFIG, customBFPE.toString());
999 BackupFilesPresetEntry savedBFPE = BackupFilesPresetEntry.backupfilesPresetEntriesValues
1001 Cache.applicationProperties.setProperty(
1002 BackupFilesPresetEntry.SAVEDCONFIG, savedBFPE.toString());
1005 * Save Memory Settings
1007 Cache.applicationProperties.setProperty(
1008 MemorySetting.CUSTOMISED_SETTINGS,
1009 Boolean.toString(customiseMemorySetting.isSelected()));
1010 Cache.applicationProperties.setProperty(MemorySetting.MEMORY_JVMMEMPC,
1011 Integer.toString(jvmMemoryPercentSlider.getValue()));
1012 Cache.applicationProperties.setProperty(MemorySetting.MEMORY_JVMMEMMAX,
1013 jvmMemoryMaxTextField.getText());
1016 * save and close Preferences
1019 Cache.saveProperties();
1020 Desktop.instance.doConfigureStructurePrefs();
1023 frame.setClosed(true);
1024 } catch (Exception ex)
1029 public void saveProxySettings()
1031 String newProxyType = customProxy.isSelected() ? Cache.PROXYTYPE_CUSTOM
1032 : noProxy.isSelected() ? Cache.PROXYTYPE_NONE
1033 : Cache.PROXYTYPE_SYSTEM;
1034 Cache.applicationProperties.setProperty("USE_PROXY", newProxyType);
1035 Cache.setOrRemove("PROXY_SERVER", proxyServerHttpTB.getText());
1036 Cache.setOrRemove("PROXY_PORT", proxyPortHttpTB.getText());
1037 Cache.setOrRemove("PROXY_SERVER_HTTPS", proxyServerHttpsTB.getText());
1038 Cache.setOrRemove("PROXY_PORT_HTTPS", proxyPortHttpsTB.getText());
1039 Cache.setOrRemove("PROXY_AUTH",
1040 Boolean.toString(proxyAuth.isSelected()));
1041 Cache.setOrRemove("PROXY_AUTH_USERNAME", proxyAuthUsernameTB.getText());
1042 Cache.proxyAuthPassword = proxyAuthPasswordPB.getPassword();
1043 Cache.setProxyPropertiesFromPreferences(previousProxyType);
1044 if (newProxyType.equals(Cache.PROXYTYPE_CUSTOM)
1045 || !newProxyType.equals(previousProxyType))
1047 // force a re-lookup of ws if proxytype is custom or has changed
1050 previousProxyType = newProxyType;
1054 * Do any necessary validation before saving settings. Return focus to the first
1055 * tab which fails validation.
1059 private boolean validateSettings()
1061 if (!validateStructure())
1063 structureTab.requestFocusInWindow();
1070 protected boolean validateStructure()
1072 return validateViewerPath();
1080 public void startupFileTextfield_mouseClicked()
1082 // TODO: JAL-3048 not needed for Jalview-JS
1083 String fileFormat = Cache.getProperty("DEFAULT_FILE_FORMAT");
1084 JalviewFileChooser chooser = JalviewFileChooser
1085 .forRead(Cache.getProperty("LAST_DIRECTORY"), fileFormat);
1086 chooser.setFileView(new JalviewFileView());
1087 chooser.setDialogTitle(
1088 MessageManager.getString("label.select_startup_file"));
1090 int value = chooser.showOpenDialog(this);
1092 if (value == JalviewFileChooser.APPROVE_OPTION)
1094 FileFormatI format = chooser.getSelectedFormat();
1097 Cache.applicationProperties.setProperty("DEFAULT_FILE_FORMAT",
1100 startupFileTextfield
1101 .setText(chooser.getSelectedFile().getAbsolutePath());
1112 public void cancel_actionPerformed(ActionEvent e)
1116 if (!Platform.isJS())
1118 wsPrefs.updateWsMenuConfig(true);
1119 wsPrefs.refreshWs_actionPerformed(e);
1121 frame.setClosed(true);
1122 } catch (Exception ex)
1134 public void annotations_actionPerformed(ActionEvent e)
1136 conservation.setEnabled(annotations.isSelected());
1137 quality.setEnabled(annotations.isSelected());
1138 identity.setEnabled(annotations.isSelected());
1139 showOccupancy.setEnabled(annotations.isSelected());
1140 showGroupConsensus.setEnabled(annotations.isSelected());
1141 showGroupConservation.setEnabled(annotations.isSelected());
1142 showConsensHistogram.setEnabled(annotations.isSelected()
1143 && (identity.isSelected() || showGroupConsensus.isSelected()));
1144 showConsensLogo.setEnabled(annotations.isSelected()
1145 && (identity.isSelected() || showGroupConsensus.isSelected()));
1149 public void newLink_actionPerformed(ActionEvent e)
1151 GSequenceLink link = new GSequenceLink();
1152 boolean valid = false;
1155 if (JvOptionPane.showInternalConfirmDialog(Desktop.desktop, link,
1156 MessageManager.getString("label.new_sequence_url_link"),
1157 JvOptionPane.OK_CANCEL_OPTION, -1,
1158 null) == JvOptionPane.OK_OPTION)
1160 if (link.checkValid())
1162 if (((UrlLinkTableModel) linkUrlTable.getModel())
1163 .isUniqueName(link.getName()))
1165 ((UrlLinkTableModel) linkUrlTable.getModel())
1166 .insertRow(link.getName(), link.getURL());
1171 link.notifyDuplicate();
1184 public void editLink_actionPerformed(ActionEvent e)
1186 GSequenceLink link = new GSequenceLink();
1188 int index = linkUrlTable.getSelectedRow();
1191 // button no longer enabled if row is not selected
1192 Cache.log.debug("Edit with no row selected in linkUrlTable");
1196 int nameCol = ((UrlLinkTableModel) linkUrlTable.getModel())
1198 int urlCol = ((UrlLinkTableModel) linkUrlTable.getModel())
1200 String oldName = linkUrlTable.getValueAt(index, nameCol).toString();
1201 link.setName(oldName);
1202 link.setURL(linkUrlTable.getValueAt(index, urlCol).toString());
1204 boolean valid = false;
1207 if (JvOptionPane.showInternalConfirmDialog(Desktop.desktop, link,
1208 MessageManager.getString("label.edit_sequence_url_link"),
1209 JvOptionPane.OK_CANCEL_OPTION, -1,
1210 null) == JvOptionPane.OK_OPTION)
1212 if (link.checkValid())
1214 if ((oldName.equals(link.getName()))
1215 || (((UrlLinkTableModel) linkUrlTable.getModel())
1216 .isUniqueName(link.getName())))
1218 linkUrlTable.setValueAt(link.getName(), index, nameCol);
1219 linkUrlTable.setValueAt(link.getURL(), index, urlCol);
1224 link.notifyDuplicate();
1237 public void deleteLink_actionPerformed(ActionEvent e)
1239 int index = linkUrlTable.getSelectedRow();
1240 int modelIndex = -1;
1243 // button no longer enabled if row is not selected
1244 Cache.log.debug("Delete with no row selected in linkUrlTable");
1249 modelIndex = linkUrlTable.convertRowIndexToModel(index);
1252 // make sure we use the model index to delete, and not the table index
1253 ((UrlLinkTableModel) linkUrlTable.getModel()).removeRow(modelIndex);
1257 public void defaultBrowser_mouseClicked(MouseEvent e)
1259 // TODO: JAL-3048 not needed for j2s
1260 if (!Platform.isJS()) // BH 2019
1267 JFileChooser chooser = new JFileChooser(".");
1268 chooser.setDialogTitle(
1269 MessageManager.getString("label.select_default_browser"));
1271 int value = chooser.showOpenDialog(this);
1273 if (value == JFileChooser.APPROVE_OPTION)
1275 defaultBrowser.setText(chooser.getSelectedFile().getAbsolutePath());
1284 * jalview.jbgui.GPreferences#showunconserved_actionPerformed(java.awt.event
1288 protected void showunconserved_actionPerformed(ActionEvent e)
1290 // TODO Auto-generated method stub
1291 super.showunconserved_actionPerformed(e);
1294 public static List<String> getGroupURLLinks()
1296 return groupURLLinks;
1300 public void minColour_actionPerformed(JPanel panel)
1302 JalviewColourChooser.showColourChooser(this,
1303 MessageManager.getString("label.select_colour_minimum_value"),
1308 public void maxColour_actionPerformed(JPanel panel)
1310 JalviewColourChooser.showColourChooser(this,
1311 MessageManager.getString("label.select_colour_maximum_value"),
1316 public void gapColour_actionPerformed(JPanel gap)
1318 if (!useLegacyGap.isSelected())
1320 JalviewColourChooser.showColourChooser(this,
1321 MessageManager.getString("label.select_gap_colour"), gap);
1326 public void hiddenColour_actionPerformed(JPanel hidden)
1328 JalviewColourChooser.showColourChooser(this,
1329 MessageManager.getString("label.select_hidden_colour"), hidden);
1333 protected void useLegacyGaps_actionPerformed(ActionEvent e)
1335 boolean enabled = useLegacyGap.isSelected();
1338 gapColour.setBackground(OverviewCanvas.OVERVIEW_DEFAULT_LEGACY_GAP);
1342 gapColour.setBackground(OverviewCanvas.OVERVIEW_DEFAULT_GAP);
1344 gapColour.setEnabled(!enabled);
1345 gapLabel.setEnabled(!enabled);
1349 protected void resetOvDefaults_actionPerformed(ActionEvent e)
1351 useLegacyGap.setSelected(false);
1352 useLegacyGaps_actionPerformed(null);
1353 showHiddenAtStart.setSelected(false);
1354 hiddenColour.setBackground(OverviewCanvas.OVERVIEW_DEFAULT_HIDDEN);
1358 protected void userIdWidth_actionPerformed()
1362 String val = userIdWidth.getText().trim();
1363 if (val.length() > 0)
1365 Integer iw = Integer.parseInt(val);
1366 if (iw.intValue() < 12)
1368 throw new NumberFormatException();
1370 userIdWidth.setText(iw.toString());
1372 } catch (NumberFormatException x)
1374 userIdWidth.setText("");
1375 JvOptionPane.showInternalMessageDialog(Desktop.desktop,
1377 .getString("warn.user_defined_width_requirements"),
1378 MessageManager.getString("label.invalid_id_column_width"),
1379 JvOptionPane.WARNING_MESSAGE);
1384 protected void autoIdWidth_actionPerformed()
1386 userIdWidth.setEnabled(!autoIdWidth.isSelected());
1387 userIdWidthlabel.setEnabled(!autoIdWidth.isSelected());
1391 * Returns true if structure viewer path is to a valid executable, else shows an
1392 * error dialog. Does nothing if the path is empty, as is the case for Jmol
1393 * (built in to Jalview) or when Jalview is left to try default paths.
1395 private boolean validateViewerPath()
1397 if (structureViewerPath.getText().trim().length() > 0)
1399 File f = new File(structureViewerPath.getText());
1400 if (!f.canExecute())
1402 JvOptionPane.showInternalMessageDialog(Desktop.desktop,
1403 MessageManager.getString("label.invalid_viewer_path"),
1404 MessageManager.getString("label.invalid_viewer_path"),
1405 JvOptionPane.ERROR_MESSAGE);
1413 * If Chimera or ChimeraX or Pymol is selected, check it can be found on default
1414 * or user-specified path, if not show a warning/help dialog
1417 protected void structureViewer_actionPerformed(String selectedItem)
1419 if (selectedItem.equals(ViewerType.JMOL.name()))
1421 structureViewerPath.setEnabled(false);
1422 structureViewerPathLabel.setEnabled(false);
1425 boolean found = false;
1426 structureViewerPath.setEnabled(true);
1427 structureViewerPathLabel.setEnabled(true);
1428 structureViewerPathLabel.setText(MessageManager
1429 .formatMessage("label.viewer_path", selectedItem));
1432 * Try user-specified and standard paths for structure viewer executable
1434 String viewerPath = "";
1435 List<String> paths = null;
1438 ViewerType viewerType = ViewerType.valueOf(selectedItem);
1445 viewerPath = Cache.getDefault(CHIMERA_PATH, "");
1446 paths = StructureManager.getChimeraPaths(false);
1449 viewerPath = Cache.getDefault(CHIMERAX_PATH, "");
1450 paths = StructureManager.getChimeraPaths(true);
1453 viewerPath = Cache.getDefault(PYMOL_PATH, "");
1454 paths = PymolManager.getPymolPaths();
1457 } catch (IllegalArgumentException e)
1459 // only valid entries should be in the drop-down
1461 structureViewerPath.setText(viewerPath);
1463 paths.add(0, structureViewerPath.getText());
1464 for (String path : paths)
1466 if (new File(path.trim()).canExecute())
1475 String[] options = { "OK", "Help" };
1476 int showHelp = JvOptionPane.showInternalOptionDialog(Desktop.desktop,
1477 JvSwingUtils.wrapTooltip(true,
1478 MessageManager.getString("label.viewer_missing")),
1479 "", JvOptionPane.YES_NO_OPTION, JvOptionPane.WARNING_MESSAGE,
1480 null, options, options[0]);
1482 if (showHelp == JvOptionPane.NO_OPTION)
1484 this.selectTab(Preferences.TabRef.STRUCTURE_TAB, null);
1487 Help.showHelpWindow(HelpId.StructureViewer);
1488 } catch (HelpSetException e)
1490 e.printStackTrace();
1493 else if (showHelp == JvOptionPane.OK_OPTION)
1495 this.selectTab(Preferences.TabRef.STRUCTURE_TAB, null);
1496 CompletableFuture<Void> cf = CompletableFuture.runAsync(() -> {
1499 for (int i = 0; i < 3; i++)
1501 structureViewerPath.setBackground(Color.PINK);
1503 structureViewerPath.setBackground(Color.WHITE);
1506 } catch (InterruptedException e)
1514 public class OptionsParam
1516 private String name;
1518 private String code;
1520 public OptionsParam(String name, String code)
1526 public String getName()
1531 public void setName(String name)
1536 public String getCode()
1541 public void setCode(String code)
1547 public String toString()
1553 public boolean equals(Object that)
1555 if (!(that instanceof OptionsParam))
1559 return this.code.equalsIgnoreCase(((OptionsParam) that).code);
1563 public int hashCode()
1565 return name.hashCode() + code.hashCode();
1569 private class UrlListSelectionHandler implements ListSelectionListener
1573 public void valueChanged(ListSelectionEvent e)
1575 ListSelectionModel lsm = (ListSelectionModel) e.getSource();
1577 int index = lsm.getMinSelectionIndex();
1580 // no selection, so disable delete/edit buttons
1581 editLink.setEnabled(false);
1582 deleteLink.setEnabled(false);
1585 int modelIndex = linkUrlTable.convertRowIndexToModel(index);
1587 // enable/disable edit and delete link buttons
1588 if (((UrlLinkTableModel) linkUrlTable.getModel())
1589 .isRowDeletable(modelIndex))
1591 deleteLink.setEnabled(true);
1595 deleteLink.setEnabled(false);
1598 if (((UrlLinkTableModel) linkUrlTable.getModel())
1599 .isRowEditable(modelIndex))
1601 editLink.setEnabled(true);
1605 editLink.setEnabled(false);