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 if (Cache.getProperty("DEFAULT_BROWSER") != null)
900 System.setProperty(IBrowserLaunching.BROWSER_SYSTEM_PROPERTY,
901 Cache.getProperty("DEFAULT_BROWSER"));
905 System.clearProperty(IBrowserLaunching.BROWSER_SYSTEM_PROPERTY);
907 BrowserLauncher.resetBrowser();
909 // save user-defined and selected links
910 String menuLinks = sequenceUrlLinks.writeUrlsAsString(true);
911 if (menuLinks.isEmpty())
913 Cache.applicationProperties.remove("SEQUENCE_LINKS");
917 Cache.applicationProperties.setProperty("SEQUENCE_LINKS",
918 menuLinks.toString());
921 String nonMenuLinks = sequenceUrlLinks.writeUrlsAsString(false);
922 if (nonMenuLinks.isEmpty())
924 Cache.applicationProperties.remove("STORED_LINKS");
928 Cache.applicationProperties.setProperty("STORED_LINKS",
929 nonMenuLinks.toString());
932 Cache.applicationProperties.setProperty("DEFAULT_URL",
933 sequenceUrlLinks.getPrimaryUrlId());
935 Cache.setProperty("VERSION_CHECK",
936 Boolean.toString(versioncheck.isSelected()));
937 if (Cache.getProperty("USAGESTATS") != null || usagestats.isSelected())
939 // default is false - we only set this if the user has actively agreed
940 Cache.setProperty("USAGESTATS",
941 Boolean.toString(usagestats.isSelected()));
943 if (!questionnaire.isSelected())
945 Cache.setProperty("NOQUESTIONNAIRES", "true");
949 // special - made easy to edit a property file to disable questionnaires
950 // by just adding the given line
951 Cache.removeProperty("NOQUESTIONNAIRES");
955 * Save Output settings
957 Cache.applicationProperties.setProperty("BLC_JVSUFFIX",
958 Boolean.toString(blcjv.isSelected()));
959 Cache.applicationProperties.setProperty("CLUSTAL_JVSUFFIX",
960 Boolean.toString(clustaljv.isSelected()));
961 Cache.applicationProperties.setProperty("FASTA_JVSUFFIX",
962 Boolean.toString(fastajv.isSelected()));
963 Cache.applicationProperties.setProperty("MSF_JVSUFFIX",
964 Boolean.toString(msfjv.isSelected()));
965 Cache.applicationProperties.setProperty("PFAM_JVSUFFIX",
966 Boolean.toString(pfamjv.isSelected()));
967 Cache.applicationProperties.setProperty("PILEUP_JVSUFFIX",
968 Boolean.toString(pileupjv.isSelected()));
969 Cache.applicationProperties.setProperty("PIR_JVSUFFIX",
970 Boolean.toString(pirjv.isSelected()));
971 Cache.applicationProperties.setProperty("PIR_MODELLER",
972 Boolean.toString(modellerOutput.isSelected()));
973 Cache.applicationProperties.setProperty("EXPORT_EMBBED_BIOJSON",
974 Boolean.toString(embbedBioJSON.isSelected()));
975 jalview.io.PIRFile.useModellerOutput = modellerOutput.isSelected();
977 Cache.applicationProperties.setProperty("FIGURE_AUTOIDWIDTH",
978 Boolean.toString(autoIdWidth.isSelected()));
979 userIdWidth_actionPerformed();
980 Cache.applicationProperties.setProperty("FIGURE_FIXEDIDWIDTH",
981 userIdWidth.getText());
984 * Save Editing settings
986 Cache.applicationProperties.setProperty("AUTO_CALC_CONSENSUS",
987 Boolean.toString(autoCalculateConsCheck.isSelected()));
988 Cache.applicationProperties.setProperty("SORT_BY_TREE",
989 Boolean.toString(sortByTree.isSelected()));
990 Cache.applicationProperties.setProperty("PAD_GAPS",
991 Boolean.toString(padGaps.isSelected()));
993 if (!Platform.isJS())
995 wsPrefs.updateAndRefreshWsMenuConfig(false);
999 * Save Backups settings
1001 Cache.applicationProperties.setProperty(BackupFiles.ENABLED,
1002 Boolean.toString(enableBackupFiles.isSelected()));
1003 int preset = getComboIntStringKey(backupfilesPresetsCombo);
1004 Cache.applicationProperties.setProperty(BackupFiles.NS + "_PRESET",
1005 Integer.toString(preset));
1007 if (preset == BackupFilesPresetEntry.BACKUPFILESSCHEMECUSTOM)
1009 BackupFilesPresetEntry customBFPE = getBackupfilesCurrentEntry();
1010 BackupFilesPresetEntry.backupfilesPresetEntriesValues.put(
1011 BackupFilesPresetEntry.BACKUPFILESSCHEMECUSTOM, customBFPE);
1012 Cache.applicationProperties.setProperty(
1013 BackupFilesPresetEntry.CUSTOMCONFIG, customBFPE.toString());
1016 BackupFilesPresetEntry savedBFPE = BackupFilesPresetEntry.backupfilesPresetEntriesValues
1018 Cache.applicationProperties.setProperty(
1019 BackupFilesPresetEntry.SAVEDCONFIG, savedBFPE.toString());
1022 * Save Memory Settings
1024 Cache.applicationProperties.setProperty(
1025 MemorySetting.CUSTOMISED_SETTINGS,
1026 Boolean.toString(customiseMemorySetting.isSelected()));
1027 Cache.applicationProperties.setProperty(MemorySetting.MEMORY_JVMMEMPC,
1028 Integer.toString(jvmMemoryPercentSlider.getValue()));
1029 Cache.applicationProperties.setProperty(MemorySetting.MEMORY_JVMMEMMAX,
1030 jvmMemoryMaxTextField.getText());
1033 * save and close Preferences
1036 Cache.saveProperties();
1037 Desktop.instance.doConfigureStructurePrefs();
1040 frame.setClosed(true);
1041 } catch (Exception ex)
1046 public void saveProxySettings()
1048 String newProxyType = customProxy.isSelected() ? Cache.PROXYTYPE_CUSTOM
1049 : noProxy.isSelected() ? Cache.PROXYTYPE_NONE
1050 : Cache.PROXYTYPE_SYSTEM;
1051 Cache.applicationProperties.setProperty("USE_PROXY", newProxyType);
1052 Cache.setOrRemove("PROXY_SERVER", proxyServerHttpTB.getText());
1053 Cache.setOrRemove("PROXY_PORT", proxyPortHttpTB.getText());
1054 Cache.setOrRemove("PROXY_SERVER_HTTPS", proxyServerHttpsTB.getText());
1055 Cache.setOrRemove("PROXY_PORT_HTTPS", proxyPortHttpsTB.getText());
1056 Cache.setOrRemove("PROXY_AUTH",
1057 Boolean.toString(proxyAuth.isSelected()));
1058 Cache.setOrRemove("PROXY_AUTH_USERNAME", proxyAuthUsernameTB.getText());
1059 Cache.proxyAuthPassword = proxyAuthPasswordPB.getPassword();
1060 Cache.setProxyPropertiesFromPreferences(previousProxyType);
1061 if (newProxyType.equals(Cache.PROXYTYPE_CUSTOM)
1062 || !newProxyType.equals(previousProxyType))
1064 // force a re-lookup of ws if proxytype is custom or has changed
1067 previousProxyType = newProxyType;
1071 * Do any necessary validation before saving settings. Return focus to the
1072 * first tab which fails validation.
1076 private boolean validateSettings()
1078 if (!validateStructure())
1080 structureTab.requestFocusInWindow();
1087 protected boolean validateStructure()
1089 return validateViewerPath();
1097 public void startupFileTextfield_mouseClicked()
1099 // TODO: JAL-3048 not needed for Jalview-JS
1100 String fileFormat = Cache.getProperty("DEFAULT_FILE_FORMAT");
1101 JalviewFileChooser chooser = JalviewFileChooser
1102 .forRead(Cache.getProperty("LAST_DIRECTORY"), fileFormat);
1103 chooser.setFileView(new JalviewFileView());
1104 chooser.setDialogTitle(
1105 MessageManager.getString("label.select_startup_file"));
1107 int value = chooser.showOpenDialog(this);
1109 if (value == JalviewFileChooser.APPROVE_OPTION)
1111 FileFormatI format = chooser.getSelectedFormat();
1114 Cache.applicationProperties.setProperty("DEFAULT_FILE_FORMAT",
1117 startupFileTextfield
1118 .setText(chooser.getSelectedFile().getAbsolutePath());
1129 public void cancel_actionPerformed(ActionEvent e)
1133 if (!Platform.isJS())
1135 wsPrefs.updateWsMenuConfig(true);
1136 wsPrefs.refreshWs_actionPerformed(e);
1138 frame.setClosed(true);
1139 } catch (Exception ex)
1151 public void annotations_actionPerformed(ActionEvent e)
1153 conservation.setEnabled(annotations.isSelected());
1154 quality.setEnabled(annotations.isSelected());
1155 identity.setEnabled(annotations.isSelected());
1156 showOccupancy.setEnabled(annotations.isSelected());
1157 showGroupConsensus.setEnabled(annotations.isSelected());
1158 showGroupConservation.setEnabled(annotations.isSelected());
1159 showConsensHistogram.setEnabled(annotations.isSelected()
1160 && (identity.isSelected() || showGroupConsensus.isSelected()));
1161 showConsensLogo.setEnabled(annotations.isSelected()
1162 && (identity.isSelected() || showGroupConsensus.isSelected()));
1166 public void newLink_actionPerformed(ActionEvent e)
1168 GSequenceLink link = new GSequenceLink();
1169 boolean valid = false;
1172 if (JvOptionPane.showInternalConfirmDialog(Desktop.desktop, link,
1173 MessageManager.getString("label.new_sequence_url_link"),
1174 JvOptionPane.OK_CANCEL_OPTION, -1,
1175 null) == JvOptionPane.OK_OPTION)
1177 if (link.checkValid())
1179 if (((UrlLinkTableModel) linkUrlTable.getModel())
1180 .isUniqueName(link.getName()))
1182 ((UrlLinkTableModel) linkUrlTable.getModel())
1183 .insertRow(link.getName(), link.getURL());
1188 link.notifyDuplicate();
1201 public void editLink_actionPerformed(ActionEvent e)
1203 GSequenceLink link = new GSequenceLink();
1205 int index = linkUrlTable.getSelectedRow();
1208 // button no longer enabled if row is not selected
1209 Console.debug("Edit with no row selected in linkUrlTable");
1213 int nameCol = ((UrlLinkTableModel) linkUrlTable.getModel())
1215 int urlCol = ((UrlLinkTableModel) linkUrlTable.getModel())
1217 String oldName = linkUrlTable.getValueAt(index, nameCol).toString();
1218 link.setName(oldName);
1219 link.setURL(linkUrlTable.getValueAt(index, urlCol).toString());
1221 boolean valid = false;
1224 if (JvOptionPane.showInternalConfirmDialog(Desktop.desktop, link,
1225 MessageManager.getString("label.edit_sequence_url_link"),
1226 JvOptionPane.OK_CANCEL_OPTION, -1,
1227 null) == JvOptionPane.OK_OPTION)
1229 if (link.checkValid())
1231 if ((oldName.equals(link.getName()))
1232 || (((UrlLinkTableModel) linkUrlTable.getModel())
1233 .isUniqueName(link.getName())))
1235 linkUrlTable.setValueAt(link.getName(), index, nameCol);
1236 linkUrlTable.setValueAt(link.getURL(), index, urlCol);
1241 link.notifyDuplicate();
1254 public void deleteLink_actionPerformed(ActionEvent e)
1256 int index = linkUrlTable.getSelectedRow();
1257 int modelIndex = -1;
1260 // button no longer enabled if row is not selected
1261 Console.debug("Delete with no row selected in linkUrlTable");
1266 modelIndex = linkUrlTable.convertRowIndexToModel(index);
1269 // make sure we use the model index to delete, and not the table index
1270 ((UrlLinkTableModel) linkUrlTable.getModel()).removeRow(modelIndex);
1274 public void defaultBrowser_mouseClicked(MouseEvent e)
1276 // TODO: JAL-3048 not needed for j2s
1277 if (!Platform.isJS()) // BH 2019
1284 JFileChooser chooser = new JFileChooser(".");
1285 chooser.setDialogTitle(
1286 MessageManager.getString("label.select_default_browser"));
1288 int value = chooser.showOpenDialog(this);
1290 if (value == JFileChooser.APPROVE_OPTION)
1292 defaultBrowser.getModel().setSelectedItem(
1293 chooser.getSelectedFile().getAbsolutePath());
1302 * jalview.jbgui.GPreferences#showunconserved_actionPerformed(java.awt.event
1306 protected void showunconserved_actionPerformed(ActionEvent e)
1308 // TODO Auto-generated method stub
1309 super.showunconserved_actionPerformed(e);
1312 public static List<String> getGroupURLLinks()
1314 return groupURLLinks;
1318 public void minColour_actionPerformed(JPanel panel)
1320 JalviewColourChooser.showColourChooser(this,
1321 MessageManager.getString("label.select_colour_minimum_value"),
1326 public void maxColour_actionPerformed(JPanel panel)
1328 JalviewColourChooser.showColourChooser(this,
1329 MessageManager.getString("label.select_colour_maximum_value"),
1334 public void gapColour_actionPerformed(JPanel gap)
1336 if (!useLegacyGap.isSelected())
1338 JalviewColourChooser.showColourChooser(this,
1339 MessageManager.getString("label.select_gap_colour"), gap);
1344 public void hiddenColour_actionPerformed(JPanel hidden)
1346 JalviewColourChooser.showColourChooser(this,
1347 MessageManager.getString("label.select_hidden_colour"), hidden);
1351 protected void useLegacyGaps_actionPerformed(ActionEvent e)
1353 boolean enabled = useLegacyGap.isSelected();
1356 gapColour.setBackground(
1357 jalview.renderer.OverviewResColourFinder.OVERVIEW_DEFAULT_LEGACY_GAP);
1361 gapColour.setBackground(
1362 jalview.renderer.OverviewResColourFinder.OVERVIEW_DEFAULT_GAP);
1364 gapColour.setEnabled(!enabled);
1365 gapLabel.setEnabled(!enabled);
1369 protected void resetOvDefaults_actionPerformed(ActionEvent e)
1371 useLegacyGap.setSelected(false);
1372 useLegacyGaps_actionPerformed(null);
1373 showHiddenAtStart.setSelected(false);
1374 hiddenColour.setBackground(
1375 jalview.renderer.OverviewResColourFinder.OVERVIEW_DEFAULT_HIDDEN);
1379 protected void userIdWidth_actionPerformed()
1383 String val = userIdWidth.getText().trim();
1384 if (val.length() > 0)
1386 Integer iw = Integer.parseInt(val);
1387 if (iw.intValue() < 12)
1389 throw new NumberFormatException();
1391 userIdWidth.setText(iw.toString());
1393 } catch (NumberFormatException x)
1395 userIdWidth.setText("");
1396 JvOptionPane.showInternalMessageDialog(Desktop.desktop,
1398 .getString("warn.user_defined_width_requirements"),
1399 MessageManager.getString("label.invalid_id_column_width"),
1400 JvOptionPane.WARNING_MESSAGE);
1405 protected void autoIdWidth_actionPerformed()
1407 userIdWidth.setEnabled(!autoIdWidth.isSelected());
1408 userIdWidthlabel.setEnabled(!autoIdWidth.isSelected());
1412 * Returns true if structure viewer path is to a valid executable, else shows
1413 * an error dialog. Does nothing if the path is empty, as is the case for Jmol
1414 * (built in to Jalview) or when Jalview is left to try default paths.
1416 private boolean validateViewerPath()
1418 if (structureViewerPath.getText().trim().length() > 0)
1420 File f = new File(structureViewerPath.getText());
1421 if (!f.canExecute())
1423 JvOptionPane.showInternalMessageDialog(Desktop.desktop,
1424 MessageManager.getString("label.invalid_viewer_path"),
1425 MessageManager.getString("label.invalid_viewer_path"),
1426 JvOptionPane.ERROR_MESSAGE);
1434 * If Chimera or ChimeraX or Pymol is selected, check it can be found on
1435 * default or user-specified path, if not show a warning/help dialog
1438 protected void structureViewer_actionPerformed(String selectedItem)
1440 if (selectedItem.equals(ViewerType.JMOL.name()))
1442 structureViewerPath.setEnabled(false);
1443 structureViewerPathLabel.setEnabled(false);
1446 boolean found = false;
1447 structureViewerPath.setEnabled(true);
1448 structureViewerPathLabel.setEnabled(true);
1449 structureViewerPathLabel.setText(MessageManager
1450 .formatMessage("label.viewer_path", selectedItem));
1453 * Try user-specified and standard paths for structure viewer executable
1455 String viewerPath = "";
1456 List<String> paths = null;
1459 ViewerType viewerType = ViewerType.valueOf(selectedItem);
1466 viewerPath = Cache.getDefault(CHIMERA_PATH, "");
1467 paths = StructureManager.getChimeraPaths(false);
1470 viewerPath = Cache.getDefault(CHIMERAX_PATH, "");
1471 paths = StructureManager.getChimeraPaths(true);
1474 viewerPath = Cache.getDefault(PYMOL_PATH, "");
1475 paths = PymolManager.getPymolPaths();
1478 } catch (IllegalArgumentException e)
1480 // only valid entries should be in the drop-down
1482 structureViewerPath.setText(viewerPath);
1484 paths.add(0, structureViewerPath.getText());
1485 for (String path : paths)
1487 if (new File(path.trim()).canExecute())
1496 String[] options = { "OK", "Help" };
1497 int showHelp = JvOptionPane.showInternalOptionDialog(Desktop.desktop,
1498 JvSwingUtils.wrapTooltip(true,
1499 MessageManager.getString("label.viewer_missing")),
1500 "", JvOptionPane.YES_NO_OPTION, JvOptionPane.WARNING_MESSAGE,
1501 null, options, options[0]);
1503 if (showHelp == JvOptionPane.NO_OPTION)
1505 this.selectTab(Preferences.TabRef.STRUCTURE_TAB, null);
1508 Help.showHelpWindow(HelpId.StructureViewer);
1509 } catch (HelpSetException e)
1511 e.printStackTrace();
1514 else if (showHelp == JvOptionPane.OK_OPTION)
1516 this.selectTab(Preferences.TabRef.STRUCTURE_TAB, null);
1517 CompletableFuture<Void> cf = CompletableFuture.runAsync(() -> {
1520 for (int i = 0; i < 3; i++)
1522 structureViewerPath.setBackground(Color.PINK);
1524 structureViewerPath.setBackground(Color.WHITE);
1527 } catch (InterruptedException e)
1535 public class OptionsParam
1537 private String name;
1539 private String code;
1541 public OptionsParam(String name, String code)
1547 public String getName()
1552 public void setName(String name)
1557 public String getCode()
1562 public void setCode(String code)
1568 public String toString()
1574 public boolean equals(Object that)
1576 if (!(that instanceof OptionsParam))
1580 return this.code.equalsIgnoreCase(((OptionsParam) that).code);
1584 public int hashCode()
1586 return name.hashCode() + code.hashCode();
1590 private class UrlListSelectionHandler implements ListSelectionListener
1594 public void valueChanged(ListSelectionEvent e)
1596 ListSelectionModel lsm = (ListSelectionModel) e.getSource();
1598 int index = lsm.getMinSelectionIndex();
1601 // no selection, so disable delete/edit buttons
1602 editLink.setEnabled(false);
1603 deleteLink.setEnabled(false);
1606 int modelIndex = linkUrlTable.convertRowIndexToModel(index);
1608 // enable/disable edit and delete link buttons
1609 if (((UrlLinkTableModel) linkUrlTable.getModel())
1610 .isRowDeletable(modelIndex))
1612 deleteLink.setEnabled(true);
1616 deleteLink.setEnabled(false);
1619 if (((UrlLinkTableModel) linkUrlTable.getModel())
1620 .isRowEditable(modelIndex))
1622 editLink.setEnabled(true);
1626 editLink.setEnabled(false);