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 edu.stanford.ejalbert.launching.IBrowserLaunching;
55 import ext.edu.ucsf.rbvi.strucviz2.StructureManager;
56 import jalview.analysis.AnnotationSorter.SequenceAnnotationOrder;
57 import jalview.bin.Cache;
58 import jalview.bin.Console;
59 import jalview.bin.MemorySetting;
60 import jalview.ext.pymol.PymolManager;
61 import jalview.gui.Help.HelpId;
62 import jalview.gui.StructureViewer.ViewerType;
63 import jalview.io.BackupFiles;
64 import jalview.io.BackupFilesPresetEntry;
65 import jalview.io.FileFormatI;
66 import jalview.io.JalviewFileChooser;
67 import jalview.io.JalviewFileView;
68 import jalview.jbgui.GPreferences;
69 import jalview.jbgui.GSequenceLink;
70 import jalview.schemes.ColourSchemeI;
71 import jalview.schemes.ColourSchemes;
72 import jalview.schemes.ResidueColourScheme;
73 import jalview.urls.UrlLinkTableModel;
74 import jalview.urls.api.UrlProviderFactoryI;
75 import jalview.urls.api.UrlProviderI;
76 import jalview.urls.desktop.DesktopUrlProviderFactory;
77 import jalview.util.BrowserLauncher;
78 import jalview.util.MessageManager;
79 import jalview.util.Platform;
80 import jalview.util.UrlConstants;
81 import jalview.ws.sifts.SiftsSettings;
90 * for merge with Jalview-JS
91 public class Preferences extends GPreferences implements ApplicationSingletonI
93 public class Preferences extends GPreferences
95 public static final String ENABLE_SPLIT_FRAME = "ENABLE_SPLIT_FRAME";
97 public static final String SCALE_PROTEIN_TO_CDNA = "SCALE_PROTEIN_TO_CDNA";
99 public static final String DEFAULT_COLOUR = "DEFAULT_COLOUR";
101 public static final String DEFAULT_COLOUR_PROT = "DEFAULT_COLOUR_PROT";
103 public static final String DEFAULT_COLOUR_NUC = "DEFAULT_COLOUR_NUC";
105 public static final String ADD_TEMPFACT_ANN = "ADD_TEMPFACT_ANN";
107 public static final String ADD_SS_ANN = "ADD_SS_ANN";
109 public static final String USE_RNAVIEW = "USE_RNAVIEW";
111 public static final String STRUCT_FROM_PDB = "STRUCT_FROM_PDB";
113 public static final String STRUCTURE_DISPLAY = "STRUCTURE_DISPLAY";
115 public static final String CHIMERA_PATH = "CHIMERA_PATH";
117 public static final String CHIMERAX_PATH = "CHIMERAX_PATH";
119 public static final String PYMOL_PATH = "PYMOL_PATH";
121 public static final String SORT_ANNOTATIONS = "SORT_ANNOTATIONS";
123 public static final String SHOW_AUTOCALC_ABOVE = "SHOW_AUTOCALC_ABOVE";
125 public static final String SHOW_OCCUPANCY = "SHOW_OCCUPANCY";
127 public static final String SHOW_OV_HIDDEN_AT_START = "SHOW_OV_HIDDEN_AT_START";
129 public static final String USE_LEGACY_GAP = "USE_LEGACY_GAP";
131 public static final String GAP_COLOUR = "GAP_COLOUR";
133 public static final String HIDDEN_COLOUR = "HIDDEN_COLOUR";
135 private static final int MIN_FONT_SIZE = 1;
137 private static final int MAX_FONT_SIZE = 30;
139 private String previousProxyType;
141 private static Preferences INSTANCE = null; // add "final"
144 * Holds name and link separated with | character. Sequence ID must be
145 * $SEQUENCE_ID$ or $SEQUENCE_ID=/.possible | chars ./=$
147 public static UrlProviderI sequenceUrlLinks;
149 public static UrlLinkTableModel dataModel;
152 * Holds name and link separated with | character. Sequence IDS and Sequences
153 * must be $SEQUENCEIDS$ or $SEQUENCEIDS=/.possible | chars ./=$ and
154 * $SEQUENCES$ or $SEQUENCES=/.possible | chars ./=$ and separation character
155 * for first and second token specified after a pipe character at end |,|.
156 * (TODO: proper escape for using | to separate ids or sequences
159 public static List<String> groupURLLinks;
162 // get links selected to be in the menu (SEQUENCE_LINKS)
163 // and links entered by the user but not selected (STORED_LINKS)
164 String inMenuString = Cache.getDefault("SEQUENCE_LINKS", "");
165 String notInMenuString = Cache.getDefault("STORED_LINKS", "");
166 String defaultUrl = Cache.getDefault("DEFAULT_URL",
167 UrlConstants.DEFAULT_LABEL);
169 // if both links lists are empty, add the DEFAULT_URL link
170 // otherwise we assume the default link is in one of the lists
171 if (inMenuString.isEmpty() && notInMenuString.isEmpty())
173 inMenuString = UrlConstants.DEFAULT_STRING;
175 UrlProviderFactoryI factory = new DesktopUrlProviderFactory(defaultUrl,
176 inMenuString, notInMenuString);
177 sequenceUrlLinks = factory.createUrlProvider();
178 dataModel = new UrlLinkTableModel(sequenceUrlLinks);
181 * TODO: reformulate groupURL encoding so two or more can be stored in the
182 * .properties file as '|' separated strings
185 groupURLLinks = new ArrayList<>();
188 JInternalFrame frame;
190 private WsPreferences wsPrefs;
192 private OptionsParam promptEachTimeOpt = new OptionsParam(
193 MessageManager.getString("label.prompt_each_time"),
196 private OptionsParam lineArtOpt = new OptionsParam(
197 MessageManager.getString("label.lineart"), "Lineart");
199 private OptionsParam textOpt = new OptionsParam(
200 MessageManager.getString("action.text"), "Text");
202 // get singleton Preferences instance
203 public static Preferences getInstance()
205 if (INSTANCE == null || INSTANCE.frame == null
206 || INSTANCE.frame.isClosed())
208 INSTANCE = new Preferences();
213 * Replace code with the following for Jalvew-JS
214 Preferences INSTANCE = ApplicationSingletonProvider.getInstance(Preferences.class);
215 if (INSTANCE == null || INSTANCE.frame == null
216 || INSTANCE.frame.isClosed())
218 ApplicationSingletonProvider.remove(Preferences.class);
219 INSTANCE = ApplicationSingletonProvider.getInstance(Preferences.class);
225 public static void openPreferences()
227 openPreferences(null, null);
230 public static void openPreferences(TabRef selectTab, String message)
232 Preferences p = getInstance();
233 if (selectTab != null)
234 p.selectTab(selectTab, message);
236 p.frame.moveToFront();
240 public void selectTab(TabRef selectTab, String message)
242 this.selectTab(selectTab);
244 this.setMessage(message);
249 * Creates a new Preferences object.
251 private Preferences()
254 frame = new JInternalFrame();
255 frame.setContentPane(this);
256 if (!Platform.isJS())
263 wsPrefs = new WsPreferences();
264 wsTab.add(wsPrefs, BorderLayout.CENTER);
266 int width = 500, height = 450;
267 if (Platform.isAMacAndNotJS())
273 Desktop.addInternalFrame(frame,
274 MessageManager.getString("label.preferences"), width, height);
275 frame.setMinimumSize(new Dimension(width, height));
278 * Set Visual tab defaults
280 seqLimit.setSelected(Cache.getDefault("SHOW_JVSUFFIX", true));
281 rightAlign.setSelected(Cache.getDefault("RIGHT_ALIGN_IDS", false));
282 fullScreen.setSelected(Cache.getDefault("SHOW_FULLSCREEN", false));
283 annotations.setSelected(Cache.getDefault("SHOW_ANNOTATIONS", true));
285 conservation.setSelected(Cache.getDefault("SHOW_CONSERVATION", true));
286 quality.setSelected(Cache.getDefault("SHOW_QUALITY", true));
287 identity.setSelected(Cache.getDefault("SHOW_IDENTITY", true));
288 openoverv.setSelected(Cache.getDefault("SHOW_OVERVIEW", false));
290 .setSelected(Cache.getDefault("SHOW_UNCONSERVED", false));
291 showOccupancy.setSelected(Cache.getDefault(SHOW_OCCUPANCY, false));
293 .setSelected(Cache.getDefault("SHOW_GROUP_CONSENSUS", false));
294 showGroupConservation.setSelected(
295 Cache.getDefault("SHOW_GROUP_CONSERVATION", false));
296 showConsensHistogram.setSelected(
297 Cache.getDefault("SHOW_CONSENSUS_HISTOGRAM", true));
299 .setSelected(Cache.getDefault("SHOW_CONSENSUS_LOGO", false));
301 .setSelected(Cache.getDefault("SHOW_NPFEATS_TOOLTIP", true));
303 .setSelected(Cache.getDefault("SHOW_DBREFS_TOOLTIP", true));
305 String[] fonts = java.awt.GraphicsEnvironment
306 .getLocalGraphicsEnvironment().getAvailableFontFamilyNames();
307 for (int i = 0; i < fonts.length; i++)
309 fontNameCB.addItem(fonts[i]);
312 for (int i = MIN_FONT_SIZE; i <= MAX_FONT_SIZE; i++)
314 fontSizeCB.addItem(i + "");
317 fontStyleCB.addItem("plain");
318 fontStyleCB.addItem("bold");
319 fontStyleCB.addItem("italic");
321 fontNameCB.setSelectedItem(Cache.getDefault("FONT_NAME", "SansSerif"));
322 fontSizeCB.setSelectedItem(Cache.getDefault("FONT_SIZE", "10"));
323 fontStyleCB.setSelectedItem(
324 Cache.getDefault("FONT_STYLE", Font.PLAIN + ""));
326 smoothFont.setSelected(Cache.getDefault("ANTI_ALIAS", true));
328 .setSelected(Cache.getDefault(SCALE_PROTEIN_TO_CDNA, false));
330 idItalics.setSelected(Cache.getDefault("ID_ITALICS", true));
332 wrap.setSelected(Cache.getDefault("WRAP_ALIGNMENT", false));
334 gapSymbolCB.addItem("-");
335 gapSymbolCB.addItem(".");
337 gapSymbolCB.setSelectedItem(Cache.getDefault("GAP_SYMBOL", "-"));
339 sortby.addItem("No sort");
340 sortby.addItem("Id");
341 sortby.addItem("Pairwise Identity");
342 sortby.setSelectedItem(Cache.getDefault("SORT_ALIGNMENT", "No sort"));
344 sortAnnBy.addItem(SequenceAnnotationOrder.NONE.toString());
346 .addItem(SequenceAnnotationOrder.SEQUENCE_AND_LABEL.toString());
348 .addItem(SequenceAnnotationOrder.LABEL_AND_SEQUENCE.toString());
349 SequenceAnnotationOrder savedSort = SequenceAnnotationOrder
350 .valueOf(Cache.getDefault(SORT_ANNOTATIONS,
351 SequenceAnnotationOrder.NONE.name()));
352 sortAnnBy.setSelectedItem(savedSort.toString());
354 sortAutocalc.addItem("Autocalculated first");
355 sortAutocalc.addItem("Autocalculated last");
356 final boolean showAbove = Cache.getDefault(SHOW_AUTOCALC_ABOVE, true);
357 sortAutocalc.setSelectedItem(showAbove ? sortAutocalc.getItemAt(0)
358 : sortAutocalc.getItemAt(1));
360 .setSelected(Cache.getDefault("SHOW_STARTUP_FILE", true));
361 startupFileTextfield.setText(Cache.getDefault("STARTUP_FILE",
362 Cache.getDefault("www.jalview.org", "https://www.jalview.org")
363 + "/examples/exampleFile_2_7.jvp"));
366 * Set Colours tab defaults
368 protColour.addItem(ResidueColourScheme.NONE);
369 nucColour.addItem(ResidueColourScheme.NONE);
370 for (ColourSchemeI cs : ColourSchemes.getInstance().getColourSchemes())
372 String name = cs.getSchemeName();
373 protColour.addItem(name);
374 nucColour.addItem(name);
376 String oldProp = Cache.getDefault(DEFAULT_COLOUR,
377 ResidueColourScheme.NONE);
378 String newProp = Cache.getDefault(DEFAULT_COLOUR_PROT, null);
379 protColour.setSelectedItem(newProp != null ? newProp : oldProp);
380 newProp = Cache.getDefault(DEFAULT_COLOUR_NUC, null);
381 nucColour.setSelectedItem(newProp != null ? newProp : oldProp);
382 minColour.setBackground(
383 Cache.getDefaultColour("ANNOTATIONCOLOUR_MIN", Color.orange));
384 maxColour.setBackground(
385 Cache.getDefaultColour("ANNOTATIONCOLOUR_MAX", Color.red));
388 * Set overview panel defaults
390 gapColour.setBackground(Cache.getDefaultColour(GAP_COLOUR,
391 jalview.renderer.OverviewResColourFinder.OVERVIEW_DEFAULT_GAP));
392 hiddenColour.setBackground(Cache.getDefaultColour(HIDDEN_COLOUR,
393 jalview.renderer.OverviewResColourFinder.OVERVIEW_DEFAULT_HIDDEN));
394 useLegacyGap.setSelected(Cache.getDefault(USE_LEGACY_GAP, false));
395 gapLabel.setEnabled(!useLegacyGap.isSelected());
396 gapColour.setEnabled(!useLegacyGap.isSelected());
398 .setSelected(Cache.getDefault(SHOW_OV_HIDDEN_AT_START, false));
401 * Set Structure tab defaults
403 final boolean structSelected = Cache.getDefault(STRUCT_FROM_PDB, true);
404 structFromPdb.setSelected(structSelected);
405 addSecondaryStructure.setSelected(Cache.getDefault(ADD_SS_ANN, true));
406 addSecondaryStructure.setEnabled(structSelected);
407 addTempFactor.setSelected(Cache.getDefault(ADD_TEMPFACT_ANN, true));
408 addTempFactor.setEnabled(structSelected);
411 * set choice of structure viewer, and path if saved as a preference;
412 * default to Jmol (first choice) if an unexpected value is found
414 String viewerType = Cache.getDefault(STRUCTURE_DISPLAY,
415 ViewerType.JMOL.name());
416 structViewer.setSelectedItem(viewerType);
417 String viewerPath = "";
418 ViewerType type = null;
421 type = ViewerType.valueOf(viewerType);
427 viewerPath = Cache.getDefault(CHIMERA_PATH, "");
430 viewerPath = Cache.getDefault(CHIMERAX_PATH, "");
433 viewerPath = Cache.getDefault(PYMOL_PATH, "");
436 } catch (IllegalArgumentException e)
438 Console.error("Unknown structure viewer type: " + viewerType
439 + ", defaulting to Jmol");
440 type = ViewerType.JMOL;
442 structureViewerPath.setText(viewerPath);
444 structureViewerPath.addActionListener(new ActionListener()
447 public void actionPerformed(ActionEvent e)
449 if (validateViewerPath())
451 String path = structureViewerPath.getText();
454 ViewerType type = ViewerType.valueOf(viewerType);
460 Cache.setProperty(CHIMERA_PATH, path);
463 Cache.setProperty(CHIMERAX_PATH, path);
466 Cache.setProperty(PYMOL_PATH, path);
469 } catch (IllegalArgumentException x)
471 Console.error("Failed to set path - unknown viewer type", x);
477 if (Cache.getDefault("MAP_WITH_SIFTS", false))
479 siftsMapping.setSelected(true);
483 nwMapping.setSelected(true);
487 .setMapWithSifts(Cache.getDefault("MAP_WITH_SIFTS", false));
490 * Set Connections tab defaults
494 linkUrlTable.setModel(dataModel);
495 final TableRowSorter<TableModel> sorter = new TableRowSorter<>(
496 linkUrlTable.getModel());
497 linkUrlTable.setRowSorter(sorter);
498 List<RowSorter.SortKey> sortKeys = new ArrayList<>();
500 UrlLinkTableModel m = (UrlLinkTableModel) linkUrlTable.getModel();
501 sortKeys.add(new RowSorter.SortKey(m.getPrimaryColumn(),
502 SortOrder.DESCENDING));
503 sortKeys.add(new RowSorter.SortKey(m.getSelectedColumn(),
504 SortOrder.DESCENDING));
506 new RowSorter.SortKey(m.getNameColumn(), SortOrder.ASCENDING));
508 sorter.setSortKeys(sortKeys);
509 // BH 2018 setSortKeys will do the sort
513 ActionListener onReset;
514 onReset = new ActionListener()
517 public void actionPerformed(ActionEvent e)
519 filterTB.setText("");
520 sorter.setRowFilter(RowFilter.regexFilter(""));
524 doReset.addActionListener(onReset);
526 // filter to display only custom urls
527 final RowFilter<TableModel, Object> customUrlFilter = new RowFilter<TableModel, Object>()
530 public boolean include(
531 Entry<? extends TableModel, ? extends Object> entry)
533 return ((UrlLinkTableModel) entry.getModel()).isUserEntry(entry);
537 final TableRowSorter<TableModel> customSorter = new TableRowSorter<>(
538 linkUrlTable.getModel());
539 customSorter.setRowFilter(customUrlFilter);
541 ActionListener onCustomOnly;
542 onCustomOnly = new ActionListener()
545 public void actionPerformed(ActionEvent e)
547 filterTB.setText("");
548 sorter.setRowFilter(customUrlFilter);
551 userOnly.addActionListener(onCustomOnly);
553 filterTB.getDocument().addDocumentListener(new DocumentListener()
555 String caseInsensitiveFlag = "(?i)";
558 public void changedUpdate(DocumentEvent e)
560 sorter.setRowFilter(RowFilter
561 .regexFilter(caseInsensitiveFlag + filterTB.getText()));
565 public void removeUpdate(DocumentEvent e)
567 sorter.setRowFilter(RowFilter
568 .regexFilter(caseInsensitiveFlag + filterTB.getText()));
572 public void insertUpdate(DocumentEvent e)
574 sorter.setRowFilter(RowFilter
575 .regexFilter(caseInsensitiveFlag + filterTB.getText()));
579 // set up list selection functionality
580 linkUrlTable.getSelectionModel()
581 .addListSelectionListener(new UrlListSelectionHandler());
583 // set up radio buttons
584 int onClickCol = ((UrlLinkTableModel) linkUrlTable.getModel())
586 String onClickName = linkUrlTable.getColumnName(onClickCol);
587 linkUrlTable.getColumn(onClickName)
588 .setCellRenderer(new RadioButtonRenderer());
589 linkUrlTable.getColumn(onClickName)
590 .setCellEditor(new RadioButtonEditor());
592 // get boolean columns and resize those to min possible
593 for (int column = 0; column < linkUrlTable.getColumnCount(); column++)
595 if (linkUrlTable.getModel().getColumnClass(column)
596 .equals(Boolean.class))
598 TableColumn tableColumn = linkUrlTable.getColumnModel()
600 int preferredWidth = tableColumn.getMinWidth();
602 TableCellRenderer cellRenderer = linkUrlTable.getCellRenderer(0,
604 Component c = linkUrlTable.prepareRenderer(cellRenderer, 0, column);
605 int cwidth = c.getPreferredSize().width
606 + linkUrlTable.getIntercellSpacing().width;
607 preferredWidth = Math.max(preferredWidth, cwidth);
609 tableColumn.setPreferredWidth(preferredWidth);
613 String proxyTypeString = Cache.getDefault("USE_PROXY", "false");
614 previousProxyType = proxyTypeString;
615 switch (proxyTypeString)
617 case Cache.PROXYTYPE_NONE:
618 proxyType.setSelected(noProxy.getModel(), true);
620 case Cache.PROXYTYPE_SYSTEM:
621 proxyType.setSelected(systemProxy.getModel(), true);
623 case Cache.PROXYTYPE_CUSTOM:
624 proxyType.setSelected(customProxy.getModel(), true);
628 "Incorrect PROXY_TYPE - should be 'none' (clear proxy properties), 'false' (system settings), 'true' (custom settings): "
631 proxyServerHttpTB.setText(Cache.getDefault("PROXY_SERVER", ""));
632 proxyPortHttpTB.setText(Cache.getDefault("PROXY_PORT", ""));
633 proxyServerHttpsTB.setText(Cache.getDefault("PROXY_SERVER_HTTPS", ""));
634 proxyPortHttpsTB.setText(Cache.getDefault("PROXY_PORT_HTTPS", ""));
635 proxyAuth.setSelected(Cache.getDefault("PROXY_AUTH", false));
637 .setText(Cache.getDefault("PROXY_AUTH_USERNAME", ""));
638 // we are not storing or retrieving proxy password from .jalview_properties
639 proxyAuthPasswordPB.setText(Cache.proxyAuthPassword == null ? ""
640 : new String(Cache.proxyAuthPassword));
641 setCustomProxyEnabled();
642 applyProxyButtonEnabled(false);
644 String browserPref = Cache.getDefault("DEFAULT_BROWSER", "");
645 if (browserPref != null)
647 defaultBrowser.getModel().setSelectedItem(browserPref);
650 usagestats.setSelected(Cache.getDefault("USAGESTATS", false));
651 // note antisense here: default is true
653 .setSelected(Cache.getProperty("NOQUESTIONNAIRES") == null);
654 versioncheck.setSelected(Cache.getDefault("VERSION_CHECK", true));
657 * Set Output tab defaults
659 setupOutputCombo(epsRendering, "EPS_RENDERING");
660 setupOutputCombo(htmlRendering, "HTML_RENDERING");
661 setupOutputCombo(svgRendering, "SVG_RENDERING");
662 autoIdWidth.setSelected(Cache.getDefault("FIGURE_AUTOIDWIDTH", false));
663 userIdWidth.setEnabled(!autoIdWidth.isSelected());
664 userIdWidthlabel.setEnabled(!autoIdWidth.isSelected());
665 Integer wi = Cache.getIntegerProperty("FIGURE_FIXEDIDWIDTH");
666 userIdWidth.setText(wi == null ? "" : wi.toString());
667 // TODO: refactor to use common enum via FormatAdapter and allow extension
668 // for new flat file formats
669 blcjv.setSelected(Cache.getDefault("BLC_JVSUFFIX", true));
670 clustaljv.setSelected(Cache.getDefault("CLUSTAL_JVSUFFIX", true));
671 fastajv.setSelected(Cache.getDefault("FASTA_JVSUFFIX", true));
672 msfjv.setSelected(Cache.getDefault("MSF_JVSUFFIX", true));
673 pfamjv.setSelected(Cache.getDefault("PFAM_JVSUFFIX", true));
674 pileupjv.setSelected(Cache.getDefault("PILEUP_JVSUFFIX", true));
675 pirjv.setSelected(Cache.getDefault("PIR_JVSUFFIX", true));
676 modellerOutput.setSelected(Cache.getDefault("PIR_MODELLER", false));
678 .setSelected(Cache.getDefault("EXPORT_EMBBED_BIOJSON", true));
681 * Set Editing tab defaults
683 autoCalculateConsCheck
684 .setSelected(Cache.getDefault("AUTO_CALC_CONSENSUS", true));
685 padGaps.setSelected(Cache.getDefault("PAD_GAPS", false));
686 sortByTree.setSelected(Cache.getDefault("SORT_BY_TREE", false));
688 annotations_actionPerformed(null); // update the display of the annotation
692 * Set Backups tab defaults
694 loadLastSavedBackupsOptions();
697 * Set Startup tab defaults
703 * A helper method that sets the items and initial selection in a character
704 * rendering option list (Prompt each time/Lineart/Text)
709 protected void setupOutputCombo(JComboBox<Object> comboBox,
712 comboBox.addItem(promptEachTimeOpt);
713 comboBox.addItem(lineArtOpt);
714 comboBox.addItem(textOpt);
717 * JalviewJS doesn't support Lineart so force it to Text
719 String defaultOption = Platform.isJS() ? "Text"
720 : Cache.getDefault(propertyKey, "Prompt each time");
721 if (defaultOption.equalsIgnoreCase("Text"))
723 comboBox.setSelectedItem(textOpt);
725 else if (defaultOption.equalsIgnoreCase("Lineart"))
727 comboBox.setSelectedItem(lineArtOpt);
731 comboBox.setSelectedItem(promptEachTimeOpt);
736 * Save user selections on the Preferences tabs to the Cache and write out to
742 public void ok_actionPerformed(ActionEvent e)
744 if (!validateSettings())
750 * Set proxy settings first (to be before web services refresh)
755 * Save Visual settings
757 Cache.applicationProperties.setProperty("SHOW_JVSUFFIX",
758 Boolean.toString(seqLimit.isSelected()));
759 Cache.applicationProperties.setProperty("RIGHT_ALIGN_IDS",
760 Boolean.toString(rightAlign.isSelected()));
761 Cache.applicationProperties.setProperty("SHOW_FULLSCREEN",
762 Boolean.toString(fullScreen.isSelected()));
763 Cache.applicationProperties.setProperty("SHOW_OVERVIEW",
764 Boolean.toString(openoverv.isSelected()));
765 Cache.applicationProperties.setProperty("SHOW_ANNOTATIONS",
766 Boolean.toString(annotations.isSelected()));
767 Cache.applicationProperties.setProperty("SHOW_CONSERVATION",
768 Boolean.toString(conservation.isSelected()));
769 Cache.applicationProperties.setProperty("SHOW_QUALITY",
770 Boolean.toString(quality.isSelected()));
771 Cache.applicationProperties.setProperty("SHOW_IDENTITY",
772 Boolean.toString(identity.isSelected()));
774 Cache.applicationProperties.setProperty("GAP_SYMBOL",
775 gapSymbolCB.getSelectedItem().toString());
777 Cache.applicationProperties.setProperty("FONT_NAME",
778 fontNameCB.getSelectedItem().toString());
779 Cache.applicationProperties.setProperty("FONT_STYLE",
780 fontStyleCB.getSelectedItem().toString());
781 Cache.applicationProperties.setProperty("FONT_SIZE",
782 fontSizeCB.getSelectedItem().toString());
784 Cache.applicationProperties.setProperty("ID_ITALICS",
785 Boolean.toString(idItalics.isSelected()));
786 Cache.applicationProperties.setProperty("SHOW_UNCONSERVED",
787 Boolean.toString(showUnconserved.isSelected()));
788 Cache.applicationProperties.setProperty(SHOW_OCCUPANCY,
789 Boolean.toString(showOccupancy.isSelected()));
790 Cache.applicationProperties.setProperty("SHOW_GROUP_CONSENSUS",
791 Boolean.toString(showGroupConsensus.isSelected()));
792 Cache.applicationProperties.setProperty("SHOW_GROUP_CONSERVATION",
793 Boolean.toString(showGroupConservation.isSelected()));
794 Cache.applicationProperties.setProperty("SHOW_CONSENSUS_HISTOGRAM",
795 Boolean.toString(showConsensHistogram.isSelected()));
796 Cache.applicationProperties.setProperty("SHOW_CONSENSUS_LOGO",
797 Boolean.toString(showConsensLogo.isSelected()));
798 Cache.applicationProperties.setProperty("ANTI_ALIAS",
799 Boolean.toString(smoothFont.isSelected()));
800 Cache.applicationProperties.setProperty(SCALE_PROTEIN_TO_CDNA,
801 Boolean.toString(scaleProteinToCdna.isSelected()));
802 Cache.applicationProperties.setProperty("SHOW_NPFEATS_TOOLTIP",
803 Boolean.toString(showNpTooltip.isSelected()));
804 Cache.applicationProperties.setProperty("SHOW_DBREFS_TOOLTIP",
805 Boolean.toString(showDbRefTooltip.isSelected()));
807 Cache.applicationProperties.setProperty("WRAP_ALIGNMENT",
808 Boolean.toString(wrap.isSelected()));
810 Cache.applicationProperties.setProperty("STARTUP_FILE",
811 startupFileTextfield.getText());
812 Cache.applicationProperties.setProperty("SHOW_STARTUP_FILE",
813 Boolean.toString(startupCheckbox.isSelected()));
815 Cache.applicationProperties.setProperty("SORT_ALIGNMENT",
816 sortby.getSelectedItem().toString());
818 // convert description of sort order to enum name for save
819 SequenceAnnotationOrder annSortOrder = SequenceAnnotationOrder
820 .forDescription(sortAnnBy.getSelectedItem().toString());
821 if (annSortOrder != null)
823 Cache.applicationProperties.setProperty(SORT_ANNOTATIONS,
824 annSortOrder.name());
827 final boolean showAutocalcFirst = sortAutocalc.getSelectedIndex() == 0;
828 Cache.applicationProperties.setProperty(SHOW_AUTOCALC_ABOVE,
829 Boolean.valueOf(showAutocalcFirst).toString());
832 * Save Colours settings
834 Cache.applicationProperties.setProperty(DEFAULT_COLOUR_PROT,
835 protColour.getSelectedItem().toString());
836 Cache.applicationProperties.setProperty(DEFAULT_COLOUR_NUC,
837 nucColour.getSelectedItem().toString());
838 Cache.setColourProperty("ANNOTATIONCOLOUR_MIN",
839 minColour.getBackground());
840 Cache.setColourProperty("ANNOTATIONCOLOUR_MAX",
841 maxColour.getBackground());
844 * Save Overview settings
846 Cache.setColourProperty(GAP_COLOUR, gapColour.getBackground());
847 Cache.setColourProperty(HIDDEN_COLOUR, hiddenColour.getBackground());
848 Cache.applicationProperties.setProperty(USE_LEGACY_GAP,
849 Boolean.toString(useLegacyGap.isSelected()));
850 Cache.applicationProperties.setProperty(SHOW_OV_HIDDEN_AT_START,
851 Boolean.toString(showHiddenAtStart.isSelected()));
854 * Save Structure settings
856 Cache.applicationProperties.setProperty(ADD_TEMPFACT_ANN,
857 Boolean.toString(addTempFactor.isSelected()));
858 Cache.applicationProperties.setProperty(ADD_SS_ANN,
859 Boolean.toString(addSecondaryStructure.isSelected()));
860 Cache.applicationProperties.setProperty(STRUCT_FROM_PDB,
861 Boolean.toString(structFromPdb.isSelected()));
862 String viewer = structViewer.getSelectedItem().toString();
863 String viewerPath = structureViewerPath.getText();
864 Cache.applicationProperties.setProperty(STRUCTURE_DISPLAY, viewer);
865 if (viewer.equals(ViewerType.CHIMERA.name()))
867 Cache.setOrRemove(CHIMERA_PATH, viewerPath);
869 else if (viewer.equals(ViewerType.CHIMERAX.name()))
871 Cache.setOrRemove(CHIMERAX_PATH, viewerPath);
873 else if (viewer.equals(ViewerType.PYMOL.name()))
875 Cache.setOrRemove(PYMOL_PATH, viewerPath);
877 Cache.applicationProperties.setProperty("MAP_WITH_SIFTS",
878 Boolean.toString(siftsMapping.isSelected()));
879 SiftsSettings.setMapWithSifts(siftsMapping.isSelected());
882 * Save Output settings
884 Cache.applicationProperties.setProperty("EPS_RENDERING",
885 ((OptionsParam) epsRendering.getSelectedItem()).getCode());
886 Cache.applicationProperties.setProperty("HTML_RENDERING",
887 ((OptionsParam) htmlRendering.getSelectedItem()).getCode());
888 Cache.applicationProperties.setProperty("SVG_RENDERING",
889 ((OptionsParam) svgRendering.getSelectedItem()).getCode());
892 * Save Connections settings
894 // Proxy settings set first (to catch web services)
896 Cache.setOrRemove("DEFAULT_BROWSER",
897 (String) defaultBrowser.getSelectedItem());
898 BrowserLauncher.resetBrowser(true);
900 // save user-defined and selected links
901 String menuLinks = sequenceUrlLinks.writeUrlsAsString(true);
902 if (menuLinks.isEmpty())
904 Cache.applicationProperties.remove("SEQUENCE_LINKS");
908 Cache.applicationProperties.setProperty("SEQUENCE_LINKS",
909 menuLinks.toString());
912 String nonMenuLinks = sequenceUrlLinks.writeUrlsAsString(false);
913 if (nonMenuLinks.isEmpty())
915 Cache.applicationProperties.remove("STORED_LINKS");
919 Cache.applicationProperties.setProperty("STORED_LINKS",
920 nonMenuLinks.toString());
923 Cache.applicationProperties.setProperty("DEFAULT_URL",
924 sequenceUrlLinks.getPrimaryUrlId());
926 Cache.setProperty("VERSION_CHECK",
927 Boolean.toString(versioncheck.isSelected()));
928 if (Cache.getProperty("USAGESTATS") != null || usagestats.isSelected())
930 // default is false - we only set this if the user has actively agreed
931 Cache.setProperty("USAGESTATS",
932 Boolean.toString(usagestats.isSelected()));
934 if (!questionnaire.isSelected())
936 Cache.setProperty("NOQUESTIONNAIRES", "true");
940 // special - made easy to edit a property file to disable questionnaires
941 // by just adding the given line
942 Cache.removeProperty("NOQUESTIONNAIRES");
946 * Save Output settings
948 Cache.applicationProperties.setProperty("BLC_JVSUFFIX",
949 Boolean.toString(blcjv.isSelected()));
950 Cache.applicationProperties.setProperty("CLUSTAL_JVSUFFIX",
951 Boolean.toString(clustaljv.isSelected()));
952 Cache.applicationProperties.setProperty("FASTA_JVSUFFIX",
953 Boolean.toString(fastajv.isSelected()));
954 Cache.applicationProperties.setProperty("MSF_JVSUFFIX",
955 Boolean.toString(msfjv.isSelected()));
956 Cache.applicationProperties.setProperty("PFAM_JVSUFFIX",
957 Boolean.toString(pfamjv.isSelected()));
958 Cache.applicationProperties.setProperty("PILEUP_JVSUFFIX",
959 Boolean.toString(pileupjv.isSelected()));
960 Cache.applicationProperties.setProperty("PIR_JVSUFFIX",
961 Boolean.toString(pirjv.isSelected()));
962 Cache.applicationProperties.setProperty("PIR_MODELLER",
963 Boolean.toString(modellerOutput.isSelected()));
964 Cache.applicationProperties.setProperty("EXPORT_EMBBED_BIOJSON",
965 Boolean.toString(embbedBioJSON.isSelected()));
966 jalview.io.PIRFile.useModellerOutput = modellerOutput.isSelected();
968 Cache.applicationProperties.setProperty("FIGURE_AUTOIDWIDTH",
969 Boolean.toString(autoIdWidth.isSelected()));
970 userIdWidth_actionPerformed();
971 Cache.applicationProperties.setProperty("FIGURE_FIXEDIDWIDTH",
972 userIdWidth.getText());
975 * Save Editing settings
977 Cache.applicationProperties.setProperty("AUTO_CALC_CONSENSUS",
978 Boolean.toString(autoCalculateConsCheck.isSelected()));
979 Cache.applicationProperties.setProperty("SORT_BY_TREE",
980 Boolean.toString(sortByTree.isSelected()));
981 Cache.applicationProperties.setProperty("PAD_GAPS",
982 Boolean.toString(padGaps.isSelected()));
984 if (!Platform.isJS())
986 wsPrefs.updateAndRefreshWsMenuConfig(false);
990 * Save Backups settings
992 Cache.applicationProperties.setProperty(BackupFiles.ENABLED,
993 Boolean.toString(enableBackupFiles.isSelected()));
994 int preset = getComboIntStringKey(backupfilesPresetsCombo);
995 Cache.applicationProperties.setProperty(BackupFiles.NS + "_PRESET",
996 Integer.toString(preset));
998 if (preset == BackupFilesPresetEntry.BACKUPFILESSCHEMECUSTOM)
1000 BackupFilesPresetEntry customBFPE = getBackupfilesCurrentEntry();
1001 BackupFilesPresetEntry.backupfilesPresetEntriesValues.put(
1002 BackupFilesPresetEntry.BACKUPFILESSCHEMECUSTOM, customBFPE);
1003 Cache.applicationProperties.setProperty(
1004 BackupFilesPresetEntry.CUSTOMCONFIG, customBFPE.toString());
1007 BackupFilesPresetEntry savedBFPE = BackupFilesPresetEntry.backupfilesPresetEntriesValues
1009 Cache.applicationProperties.setProperty(
1010 BackupFilesPresetEntry.SAVEDCONFIG, savedBFPE.toString());
1013 * Save Memory Settings
1015 Cache.applicationProperties.setProperty(
1016 MemorySetting.CUSTOMISED_SETTINGS,
1017 Boolean.toString(customiseMemorySetting.isSelected()));
1018 Cache.applicationProperties.setProperty(MemorySetting.MEMORY_JVMMEMPC,
1019 Integer.toString(jvmMemoryPercentSlider.getValue()));
1020 Cache.applicationProperties.setProperty(MemorySetting.MEMORY_JVMMEMMAX,
1021 jvmMemoryMaxTextField.getText());
1024 * save and close Preferences
1027 Cache.saveProperties();
1028 Desktop.instance.doConfigureStructurePrefs();
1031 frame.setClosed(true);
1032 } catch (Exception ex)
1037 public void saveProxySettings()
1039 String newProxyType = customProxy.isSelected() ? Cache.PROXYTYPE_CUSTOM
1040 : noProxy.isSelected() ? Cache.PROXYTYPE_NONE
1041 : Cache.PROXYTYPE_SYSTEM;
1042 Cache.applicationProperties.setProperty("USE_PROXY", newProxyType);
1043 Cache.setOrRemove("PROXY_SERVER", proxyServerHttpTB.getText());
1044 Cache.setOrRemove("PROXY_PORT", proxyPortHttpTB.getText());
1045 Cache.setOrRemove("PROXY_SERVER_HTTPS", proxyServerHttpsTB.getText());
1046 Cache.setOrRemove("PROXY_PORT_HTTPS", proxyPortHttpsTB.getText());
1047 Cache.setOrRemove("PROXY_AUTH",
1048 Boolean.toString(proxyAuth.isSelected()));
1049 Cache.setOrRemove("PROXY_AUTH_USERNAME", proxyAuthUsernameTB.getText());
1050 Cache.proxyAuthPassword = proxyAuthPasswordPB.getPassword();
1051 Cache.setProxyPropertiesFromPreferences(previousProxyType);
1052 if (newProxyType.equals(Cache.PROXYTYPE_CUSTOM)
1053 || !newProxyType.equals(previousProxyType))
1055 // force a re-lookup of ws if proxytype is custom or has changed
1058 previousProxyType = newProxyType;
1062 * Do any necessary validation before saving settings. Return focus to the
1063 * first tab which fails validation.
1067 private boolean validateSettings()
1069 if (!validateStructure())
1071 structureTab.requestFocusInWindow();
1078 protected boolean validateStructure()
1080 return validateViewerPath();
1088 public void startupFileTextfield_mouseClicked()
1090 // TODO: JAL-3048 not needed for Jalview-JS
1091 String fileFormat = Cache.getProperty("DEFAULT_FILE_FORMAT");
1092 JalviewFileChooser chooser = JalviewFileChooser
1093 .forRead(Cache.getProperty("LAST_DIRECTORY"), fileFormat);
1094 chooser.setFileView(new JalviewFileView());
1095 chooser.setDialogTitle(
1096 MessageManager.getString("label.select_startup_file"));
1098 int value = chooser.showOpenDialog(this);
1100 if (value == JalviewFileChooser.APPROVE_OPTION)
1102 FileFormatI format = chooser.getSelectedFormat();
1105 Cache.applicationProperties.setProperty("DEFAULT_FILE_FORMAT",
1108 startupFileTextfield
1109 .setText(chooser.getSelectedFile().getAbsolutePath());
1120 public void cancel_actionPerformed(ActionEvent e)
1124 if (!Platform.isJS())
1126 wsPrefs.updateWsMenuConfig(true);
1127 wsPrefs.refreshWs_actionPerformed(e);
1129 frame.setClosed(true);
1130 } catch (Exception ex)
1142 public void annotations_actionPerformed(ActionEvent e)
1144 conservation.setEnabled(annotations.isSelected());
1145 quality.setEnabled(annotations.isSelected());
1146 identity.setEnabled(annotations.isSelected());
1147 showOccupancy.setEnabled(annotations.isSelected());
1148 showGroupConsensus.setEnabled(annotations.isSelected());
1149 showGroupConservation.setEnabled(annotations.isSelected());
1150 showConsensHistogram.setEnabled(annotations.isSelected()
1151 && (identity.isSelected() || showGroupConsensus.isSelected()));
1152 showConsensLogo.setEnabled(annotations.isSelected()
1153 && (identity.isSelected() || showGroupConsensus.isSelected()));
1157 public void newLink_actionPerformed(ActionEvent e)
1159 GSequenceLink link = new GSequenceLink();
1160 boolean valid = false;
1163 if (JvOptionPane.showInternalConfirmDialog(Desktop.desktop, link,
1164 MessageManager.getString("label.new_sequence_url_link"),
1165 JvOptionPane.OK_CANCEL_OPTION, -1,
1166 null) == JvOptionPane.OK_OPTION)
1168 if (link.checkValid())
1170 if (((UrlLinkTableModel) linkUrlTable.getModel())
1171 .isUniqueName(link.getName()))
1173 ((UrlLinkTableModel) linkUrlTable.getModel())
1174 .insertRow(link.getName(), link.getURL());
1179 link.notifyDuplicate();
1192 public void editLink_actionPerformed(ActionEvent e)
1194 GSequenceLink link = new GSequenceLink();
1196 int index = linkUrlTable.getSelectedRow();
1199 // button no longer enabled if row is not selected
1200 Console.debug("Edit with no row selected in linkUrlTable");
1204 int nameCol = ((UrlLinkTableModel) linkUrlTable.getModel())
1206 int urlCol = ((UrlLinkTableModel) linkUrlTable.getModel())
1208 String oldName = linkUrlTable.getValueAt(index, nameCol).toString();
1209 link.setName(oldName);
1210 link.setURL(linkUrlTable.getValueAt(index, urlCol).toString());
1212 boolean valid = false;
1215 if (JvOptionPane.showInternalConfirmDialog(Desktop.desktop, link,
1216 MessageManager.getString("label.edit_sequence_url_link"),
1217 JvOptionPane.OK_CANCEL_OPTION, -1,
1218 null) == JvOptionPane.OK_OPTION)
1220 if (link.checkValid())
1222 if ((oldName.equals(link.getName()))
1223 || (((UrlLinkTableModel) linkUrlTable.getModel())
1224 .isUniqueName(link.getName())))
1226 linkUrlTable.setValueAt(link.getName(), index, nameCol);
1227 linkUrlTable.setValueAt(link.getURL(), index, urlCol);
1232 link.notifyDuplicate();
1245 public void deleteLink_actionPerformed(ActionEvent e)
1247 int index = linkUrlTable.getSelectedRow();
1248 int modelIndex = -1;
1251 // button no longer enabled if row is not selected
1252 Console.debug("Delete with no row selected in linkUrlTable");
1257 modelIndex = linkUrlTable.convertRowIndexToModel(index);
1260 // make sure we use the model index to delete, and not the table index
1261 ((UrlLinkTableModel) linkUrlTable.getModel()).removeRow(modelIndex);
1265 public void defaultBrowser_mouseClicked(MouseEvent e)
1267 // TODO: JAL-3048 not needed for j2s
1268 if (!Platform.isJS()) // BH 2019
1275 JFileChooser chooser = new JFileChooser(".");
1276 chooser.setDialogTitle(
1277 MessageManager.getString("label.select_default_browser"));
1279 int value = chooser.showOpenDialog(this);
1281 if (value == JFileChooser.APPROVE_OPTION)
1283 defaultBrowser.getModel().setSelectedItem(
1284 chooser.getSelectedFile().getAbsolutePath());
1293 * jalview.jbgui.GPreferences#showunconserved_actionPerformed(java.awt.event
1297 protected void showunconserved_actionPerformed(ActionEvent e)
1299 // TODO Auto-generated method stub
1300 super.showunconserved_actionPerformed(e);
1303 public static List<String> getGroupURLLinks()
1305 return groupURLLinks;
1309 public void minColour_actionPerformed(JPanel panel)
1311 JalviewColourChooser.showColourChooser(this,
1312 MessageManager.getString("label.select_colour_minimum_value"),
1317 public void maxColour_actionPerformed(JPanel panel)
1319 JalviewColourChooser.showColourChooser(this,
1320 MessageManager.getString("label.select_colour_maximum_value"),
1325 public void gapColour_actionPerformed(JPanel gap)
1327 if (!useLegacyGap.isSelected())
1329 JalviewColourChooser.showColourChooser(this,
1330 MessageManager.getString("label.select_gap_colour"), gap);
1335 public void hiddenColour_actionPerformed(JPanel hidden)
1337 JalviewColourChooser.showColourChooser(this,
1338 MessageManager.getString("label.select_hidden_colour"), hidden);
1342 protected void useLegacyGaps_actionPerformed(ActionEvent e)
1344 boolean enabled = useLegacyGap.isSelected();
1347 gapColour.setBackground(
1348 jalview.renderer.OverviewResColourFinder.OVERVIEW_DEFAULT_LEGACY_GAP);
1352 gapColour.setBackground(
1353 jalview.renderer.OverviewResColourFinder.OVERVIEW_DEFAULT_GAP);
1355 gapColour.setEnabled(!enabled);
1356 gapLabel.setEnabled(!enabled);
1360 protected void resetOvDefaults_actionPerformed(ActionEvent e)
1362 useLegacyGap.setSelected(false);
1363 useLegacyGaps_actionPerformed(null);
1364 showHiddenAtStart.setSelected(false);
1365 hiddenColour.setBackground(
1366 jalview.renderer.OverviewResColourFinder.OVERVIEW_DEFAULT_HIDDEN);
1370 protected void userIdWidth_actionPerformed()
1374 String val = userIdWidth.getText().trim();
1375 if (val.length() > 0)
1377 Integer iw = Integer.parseInt(val);
1378 if (iw.intValue() < 12)
1380 throw new NumberFormatException();
1382 userIdWidth.setText(iw.toString());
1384 } catch (NumberFormatException x)
1386 userIdWidth.setText("");
1387 JvOptionPane.showInternalMessageDialog(Desktop.desktop,
1389 .getString("warn.user_defined_width_requirements"),
1390 MessageManager.getString("label.invalid_id_column_width"),
1391 JvOptionPane.WARNING_MESSAGE);
1396 protected void autoIdWidth_actionPerformed()
1398 userIdWidth.setEnabled(!autoIdWidth.isSelected());
1399 userIdWidthlabel.setEnabled(!autoIdWidth.isSelected());
1403 * Returns true if structure viewer path is to a valid executable, else shows
1404 * an error dialog. Does nothing if the path is empty, as is the case for Jmol
1405 * (built in to Jalview) or when Jalview is left to try default paths.
1407 private boolean validateViewerPath()
1409 if (structureViewerPath.getText().trim().length() > 0)
1411 File f = new File(structureViewerPath.getText());
1412 if (!f.canExecute())
1414 JvOptionPane.showInternalMessageDialog(Desktop.desktop,
1415 MessageManager.getString("label.invalid_viewer_path"),
1416 MessageManager.getString("label.invalid_viewer_path"),
1417 JvOptionPane.ERROR_MESSAGE);
1425 * If Chimera or ChimeraX or Pymol is selected, check it can be found on
1426 * default or user-specified path, if not show a warning/help dialog
1429 protected void structureViewer_actionPerformed(String selectedItem)
1431 if (selectedItem.equals(ViewerType.JMOL.name()))
1433 structureViewerPath.setEnabled(false);
1434 structureViewerPathLabel.setEnabled(false);
1437 boolean found = false;
1438 structureViewerPath.setEnabled(true);
1439 structureViewerPathLabel.setEnabled(true);
1440 structureViewerPathLabel.setText(MessageManager
1441 .formatMessage("label.viewer_path", selectedItem));
1444 * Try user-specified and standard paths for structure viewer executable
1446 String viewerPath = "";
1447 List<String> paths = null;
1450 ViewerType viewerType = ViewerType.valueOf(selectedItem);
1457 viewerPath = Cache.getDefault(CHIMERA_PATH, "");
1458 paths = StructureManager.getChimeraPaths(false);
1461 viewerPath = Cache.getDefault(CHIMERAX_PATH, "");
1462 paths = StructureManager.getChimeraPaths(true);
1465 viewerPath = Cache.getDefault(PYMOL_PATH, "");
1466 paths = PymolManager.getPymolPaths();
1469 } catch (IllegalArgumentException e)
1471 // only valid entries should be in the drop-down
1473 structureViewerPath.setText(viewerPath);
1475 paths.add(0, structureViewerPath.getText());
1476 for (String path : paths)
1478 if (new File(path.trim()).canExecute())
1487 String[] options = { "OK", "Help" };
1488 int showHelp = JvOptionPane.showInternalOptionDialog(Desktop.desktop,
1489 JvSwingUtils.wrapTooltip(true,
1490 MessageManager.getString("label.viewer_missing")),
1491 "", JvOptionPane.YES_NO_OPTION, JvOptionPane.WARNING_MESSAGE,
1492 null, options, options[0]);
1494 if (showHelp == JvOptionPane.NO_OPTION)
1496 this.selectTab(Preferences.TabRef.STRUCTURE_TAB, null);
1499 Help.showHelpWindow(HelpId.StructureViewer);
1500 } catch (HelpSetException e)
1502 e.printStackTrace();
1505 else if (showHelp == JvOptionPane.OK_OPTION)
1507 this.selectTab(Preferences.TabRef.STRUCTURE_TAB, null);
1508 CompletableFuture<Void> cf = CompletableFuture.runAsync(() -> {
1511 for (int i = 0; i < 3; i++)
1513 structureViewerPath.setBackground(Color.PINK);
1515 structureViewerPath.setBackground(Color.WHITE);
1518 } catch (InterruptedException e)
1526 public class OptionsParam
1528 private String name;
1530 private String code;
1532 public OptionsParam(String name, String code)
1538 public String getName()
1543 public void setName(String name)
1548 public String getCode()
1553 public void setCode(String code)
1559 public String toString()
1565 public boolean equals(Object that)
1567 if (!(that instanceof OptionsParam))
1571 return this.code.equalsIgnoreCase(((OptionsParam) that).code);
1575 public int hashCode()
1577 return name.hashCode() + code.hashCode();
1581 private class UrlListSelectionHandler implements ListSelectionListener
1585 public void valueChanged(ListSelectionEvent e)
1587 ListSelectionModel lsm = (ListSelectionModel) e.getSource();
1589 int index = lsm.getMinSelectionIndex();
1592 // no selection, so disable delete/edit buttons
1593 editLink.setEnabled(false);
1594 deleteLink.setEnabled(false);
1597 int modelIndex = linkUrlTable.convertRowIndexToModel(index);
1599 // enable/disable edit and delete link buttons
1600 if (((UrlLinkTableModel) linkUrlTable.getModel())
1601 .isRowDeletable(modelIndex))
1603 deleteLink.setEnabled(true);
1607 deleteLink.setEnabled(false);
1610 if (((UrlLinkTableModel) linkUrlTable.getModel())
1611 .isRowEditable(modelIndex))
1613 editLink.setEnabled(true);
1617 editLink.setEnabled(false);