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 jalview.renderer.OverviewResColourFinder.OVERVIEW_DEFAULT_GAP));
389 hiddenColour.setBackground(Cache.getDefaultColour(HIDDEN_COLOUR,
390 jalview.renderer.OverviewResColourFinder.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(
1339 jalview.renderer.OverviewResColourFinder.OVERVIEW_DEFAULT_LEGACY_GAP);
1343 gapColour.setBackground(
1344 jalview.renderer.OverviewResColourFinder.OVERVIEW_DEFAULT_GAP);
1346 gapColour.setEnabled(!enabled);
1347 gapLabel.setEnabled(!enabled);
1351 protected void resetOvDefaults_actionPerformed(ActionEvent e)
1353 useLegacyGap.setSelected(false);
1354 useLegacyGaps_actionPerformed(null);
1355 showHiddenAtStart.setSelected(false);
1356 hiddenColour.setBackground(
1357 jalview.renderer.OverviewResColourFinder.OVERVIEW_DEFAULT_HIDDEN);
1361 protected void userIdWidth_actionPerformed()
1365 String val = userIdWidth.getText().trim();
1366 if (val.length() > 0)
1368 Integer iw = Integer.parseInt(val);
1369 if (iw.intValue() < 12)
1371 throw new NumberFormatException();
1373 userIdWidth.setText(iw.toString());
1375 } catch (NumberFormatException x)
1377 userIdWidth.setText("");
1378 JvOptionPane.showInternalMessageDialog(Desktop.desktop,
1380 .getString("warn.user_defined_width_requirements"),
1381 MessageManager.getString("label.invalid_id_column_width"),
1382 JvOptionPane.WARNING_MESSAGE);
1387 protected void autoIdWidth_actionPerformed()
1389 userIdWidth.setEnabled(!autoIdWidth.isSelected());
1390 userIdWidthlabel.setEnabled(!autoIdWidth.isSelected());
1394 * Returns true if structure viewer path is to a valid executable, else shows an
1395 * error dialog. Does nothing if the path is empty, as is the case for Jmol
1396 * (built in to Jalview) or when Jalview is left to try default paths.
1398 private boolean validateViewerPath()
1400 if (structureViewerPath.getText().trim().length() > 0)
1402 File f = new File(structureViewerPath.getText());
1403 if (!f.canExecute())
1405 JvOptionPane.showInternalMessageDialog(Desktop.desktop,
1406 MessageManager.getString("label.invalid_viewer_path"),
1407 MessageManager.getString("label.invalid_viewer_path"),
1408 JvOptionPane.ERROR_MESSAGE);
1416 * If Chimera or ChimeraX or Pymol is selected, check it can be found on default
1417 * or user-specified path, if not show a warning/help dialog
1420 protected void structureViewer_actionPerformed(String selectedItem)
1422 if (selectedItem.equals(ViewerType.JMOL.name()))
1424 structureViewerPath.setEnabled(false);
1425 structureViewerPathLabel.setEnabled(false);
1428 boolean found = false;
1429 structureViewerPath.setEnabled(true);
1430 structureViewerPathLabel.setEnabled(true);
1431 structureViewerPathLabel.setText(MessageManager
1432 .formatMessage("label.viewer_path", selectedItem));
1435 * Try user-specified and standard paths for structure viewer executable
1437 String viewerPath = "";
1438 List<String> paths = null;
1441 ViewerType viewerType = ViewerType.valueOf(selectedItem);
1448 viewerPath = Cache.getDefault(CHIMERA_PATH, "");
1449 paths = StructureManager.getChimeraPaths(false);
1452 viewerPath = Cache.getDefault(CHIMERAX_PATH, "");
1453 paths = StructureManager.getChimeraPaths(true);
1456 viewerPath = Cache.getDefault(PYMOL_PATH, "");
1457 paths = PymolManager.getPymolPaths();
1460 } catch (IllegalArgumentException e)
1462 // only valid entries should be in the drop-down
1464 structureViewerPath.setText(viewerPath);
1466 paths.add(0, structureViewerPath.getText());
1467 for (String path : paths)
1469 if (new File(path.trim()).canExecute())
1478 String[] options = { "OK", "Help" };
1479 int showHelp = JvOptionPane.showInternalOptionDialog(Desktop.desktop,
1480 JvSwingUtils.wrapTooltip(true,
1481 MessageManager.getString("label.viewer_missing")),
1482 "", JvOptionPane.YES_NO_OPTION, JvOptionPane.WARNING_MESSAGE,
1483 null, options, options[0]);
1485 if (showHelp == JvOptionPane.NO_OPTION)
1487 this.selectTab(Preferences.TabRef.STRUCTURE_TAB, null);
1490 Help.showHelpWindow(HelpId.StructureViewer);
1491 } catch (HelpSetException e)
1493 e.printStackTrace();
1496 else if (showHelp == JvOptionPane.OK_OPTION)
1498 this.selectTab(Preferences.TabRef.STRUCTURE_TAB, null);
1499 CompletableFuture<Void> cf = CompletableFuture.runAsync(() -> {
1502 for (int i = 0; i < 3; i++)
1504 structureViewerPath.setBackground(Color.PINK);
1506 structureViewerPath.setBackground(Color.WHITE);
1509 } catch (InterruptedException e)
1517 public class OptionsParam
1519 private String name;
1521 private String code;
1523 public OptionsParam(String name, String code)
1529 public String getName()
1534 public void setName(String name)
1539 public String getCode()
1544 public void setCode(String code)
1550 public String toString()
1556 public boolean equals(Object that)
1558 if (!(that instanceof OptionsParam))
1562 return this.code.equalsIgnoreCase(((OptionsParam) that).code);
1566 public int hashCode()
1568 return name.hashCode() + code.hashCode();
1572 private class UrlListSelectionHandler implements ListSelectionListener
1576 public void valueChanged(ListSelectionEvent e)
1578 ListSelectionModel lsm = (ListSelectionModel) e.getSource();
1580 int index = lsm.getMinSelectionIndex();
1583 // no selection, so disable delete/edit buttons
1584 editLink.setEnabled(false);
1585 deleteLink.setEnabled(false);
1588 int modelIndex = linkUrlTable.convertRowIndexToModel(index);
1590 // enable/disable edit and delete link buttons
1591 if (((UrlLinkTableModel) linkUrlTable.getModel())
1592 .isRowDeletable(modelIndex))
1594 deleteLink.setEnabled(true);
1598 deleteLink.setEnabled(false);
1601 if (((UrlLinkTableModel) linkUrlTable.getModel())
1602 .isRowEditable(modelIndex))
1604 editLink.setEnabled(true);
1608 editLink.setEnabled(false);