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.Console;
58 import jalview.bin.MemorySetting;
59 import jalview.ext.pymol.PymolManager;
60 import jalview.gui.Help.HelpId;
61 import jalview.gui.StructureViewer.ViewerType;
62 import jalview.io.BackupFiles;
63 import jalview.io.BackupFilesPresetEntry;
64 import jalview.io.FileFormatI;
65 import jalview.io.JalviewFileChooser;
66 import jalview.io.JalviewFileView;
67 import jalview.jbgui.GPreferences;
68 import jalview.jbgui.GSequenceLink;
69 import jalview.schemes.ColourSchemeI;
70 import jalview.schemes.ColourSchemes;
71 import jalview.schemes.ResidueColourScheme;
72 import jalview.urls.UrlLinkTableModel;
73 import jalview.urls.api.UrlProviderFactoryI;
74 import jalview.urls.api.UrlProviderI;
75 import jalview.urls.desktop.DesktopUrlProviderFactory;
76 import jalview.util.MessageManager;
77 import jalview.util.Platform;
78 import jalview.util.UrlConstants;
79 import jalview.ws.sifts.SiftsSettings;
88 * for merge with Jalview-JS
89 public class Preferences extends GPreferences implements ApplicationSingletonI
91 public class Preferences extends GPreferences
93 public static final String ENABLE_SPLIT_FRAME = "ENABLE_SPLIT_FRAME";
95 public static final String SCALE_PROTEIN_TO_CDNA = "SCALE_PROTEIN_TO_CDNA";
97 public static final String DEFAULT_COLOUR = "DEFAULT_COLOUR";
99 public static final String DEFAULT_COLOUR_PROT = "DEFAULT_COLOUR_PROT";
101 public static final String DEFAULT_COLOUR_NUC = "DEFAULT_COLOUR_NUC";
103 public static final String ADD_TEMPFACT_ANN = "ADD_TEMPFACT_ANN";
105 public static final String ADD_SS_ANN = "ADD_SS_ANN";
107 public static final String USE_RNAVIEW = "USE_RNAVIEW";
109 public static final String STRUCT_FROM_PDB = "STRUCT_FROM_PDB";
111 public static final String STRUCTURE_DISPLAY = "STRUCTURE_DISPLAY";
113 public static final String CHIMERA_PATH = "CHIMERA_PATH";
115 public static final String CHIMERAX_PATH = "CHIMERAX_PATH";
117 public static final String PYMOL_PATH = "PYMOL_PATH";
119 public static final String SORT_ANNOTATIONS = "SORT_ANNOTATIONS";
121 public static final String SHOW_AUTOCALC_ABOVE = "SHOW_AUTOCALC_ABOVE";
123 public static final String SHOW_OCCUPANCY = "SHOW_OCCUPANCY";
125 public static final String SHOW_OV_HIDDEN_AT_START = "SHOW_OV_HIDDEN_AT_START";
127 public static final String USE_LEGACY_GAP = "USE_LEGACY_GAP";
129 public static final String GAP_COLOUR = "GAP_COLOUR";
131 public static final String HIDDEN_COLOUR = "HIDDEN_COLOUR";
133 private static final int MIN_FONT_SIZE = 1;
135 private static final int MAX_FONT_SIZE = 30;
137 private String previousProxyType;
139 private static Preferences INSTANCE = null; // add "final"
142 * Holds name and link separated with | character. Sequence ID must be
143 * $SEQUENCE_ID$ or $SEQUENCE_ID=/.possible | chars ./=$
145 public static UrlProviderI sequenceUrlLinks;
147 public static UrlLinkTableModel dataModel;
150 * Holds name and link separated with | character. Sequence IDS and Sequences
151 * must be $SEQUENCEIDS$ or $SEQUENCEIDS=/.possible | chars ./=$ and $SEQUENCES$
152 * or $SEQUENCES=/.possible | chars ./=$ and separation character for first and
153 * second token specified after a pipe character at end |,|. (TODO: proper
154 * escape for using | to separate ids or sequences
157 public static List<String> groupURLLinks;
160 // get links selected to be in the menu (SEQUENCE_LINKS)
161 // and links entered by the user but not selected (STORED_LINKS)
162 String inMenuString = Cache.getDefault("SEQUENCE_LINKS", "");
163 String notInMenuString = Cache.getDefault("STORED_LINKS", "");
164 String defaultUrl = Cache.getDefault("DEFAULT_URL",
165 UrlConstants.DEFAULT_LABEL);
167 // if both links lists are empty, add the DEFAULT_URL link
168 // otherwise we assume the default link is in one of the lists
169 if (inMenuString.isEmpty() && notInMenuString.isEmpty())
171 inMenuString = UrlConstants.DEFAULT_STRING;
173 UrlProviderFactoryI factory = new DesktopUrlProviderFactory(defaultUrl,
174 inMenuString, notInMenuString);
175 sequenceUrlLinks = factory.createUrlProvider();
176 dataModel = new UrlLinkTableModel(sequenceUrlLinks);
179 * TODO: reformulate groupURL encoding so two or more can be stored in the
180 * .properties file as '|' separated strings
183 groupURLLinks = new ArrayList<>();
186 JInternalFrame frame;
188 private WsPreferences wsPrefs;
190 private OptionsParam promptEachTimeOpt = new OptionsParam(
191 MessageManager.getString("label.prompt_each_time"),
194 private OptionsParam lineArtOpt = new OptionsParam(
195 MessageManager.getString("label.lineart"), "Lineart");
197 private OptionsParam textOpt = new OptionsParam(
198 MessageManager.getString("action.text"), "Text");
200 // get singleton Preferences instance
201 public static Preferences getInstance()
203 if (INSTANCE == null || INSTANCE.frame == null
204 || INSTANCE.frame.isClosed())
206 INSTANCE = new Preferences();
211 * Replace code with the following for Jalvew-JS
212 Preferences INSTANCE = ApplicationSingletonProvider.getInstance(Preferences.class);
213 if (INSTANCE == null || INSTANCE.frame == null
214 || INSTANCE.frame.isClosed())
216 ApplicationSingletonProvider.remove(Preferences.class);
217 INSTANCE = ApplicationSingletonProvider.getInstance(Preferences.class);
223 public static void openPreferences()
225 openPreferences(null, null);
228 public static void openPreferences(TabRef selectTab, String message)
230 Preferences p = getInstance();
231 if (selectTab != null)
232 p.selectTab(selectTab, message);
234 p.frame.moveToFront();
238 public void selectTab(TabRef selectTab, String message)
240 this.selectTab(selectTab);
242 this.setMessage(message);
247 * Creates a new Preferences object.
249 private Preferences()
252 frame = new JInternalFrame();
253 frame.setContentPane(this);
254 if (!Platform.isJS())
261 wsPrefs = new WsPreferences();
262 wsTab.add(wsPrefs, BorderLayout.CENTER);
264 int width = 500, height = 450;
265 if (Platform.isAMacAndNotJS())
271 Desktop.addInternalFrame(frame,
272 MessageManager.getString("label.preferences"), width, height);
273 frame.setMinimumSize(new Dimension(width, height));
276 * Set Visual tab defaults
278 seqLimit.setSelected(Cache.getDefault("SHOW_JVSUFFIX", true));
279 rightAlign.setSelected(Cache.getDefault("RIGHT_ALIGN_IDS", false));
280 fullScreen.setSelected(Cache.getDefault("SHOW_FULLSCREEN", false));
281 annotations.setSelected(Cache.getDefault("SHOW_ANNOTATIONS", true));
283 conservation.setSelected(Cache.getDefault("SHOW_CONSERVATION", true));
284 quality.setSelected(Cache.getDefault("SHOW_QUALITY", true));
285 identity.setSelected(Cache.getDefault("SHOW_IDENTITY", true));
286 openoverv.setSelected(Cache.getDefault("SHOW_OVERVIEW", false));
288 .setSelected(Cache.getDefault("SHOW_UNCONSERVED", false));
289 showOccupancy.setSelected(Cache.getDefault(SHOW_OCCUPANCY, false));
291 .setSelected(Cache.getDefault("SHOW_GROUP_CONSENSUS", false));
292 showGroupConservation.setSelected(
293 Cache.getDefault("SHOW_GROUP_CONSERVATION", false));
294 showConsensHistogram.setSelected(
295 Cache.getDefault("SHOW_CONSENSUS_HISTOGRAM", true));
297 .setSelected(Cache.getDefault("SHOW_CONSENSUS_LOGO", false));
299 .setSelected(Cache.getDefault("SHOW_NPFEATS_TOOLTIP", true));
301 .setSelected(Cache.getDefault("SHOW_DBREFS_TOOLTIP", true));
303 String[] fonts = java.awt.GraphicsEnvironment
304 .getLocalGraphicsEnvironment().getAvailableFontFamilyNames();
305 for (int i = 0; i < fonts.length; i++)
307 fontNameCB.addItem(fonts[i]);
310 for (int i = MIN_FONT_SIZE; i <= MAX_FONT_SIZE; i++)
312 fontSizeCB.addItem(i + "");
315 fontStyleCB.addItem("plain");
316 fontStyleCB.addItem("bold");
317 fontStyleCB.addItem("italic");
319 fontNameCB.setSelectedItem(Cache.getDefault("FONT_NAME", "SansSerif"));
320 fontSizeCB.setSelectedItem(Cache.getDefault("FONT_SIZE", "10"));
321 fontStyleCB.setSelectedItem(
322 Cache.getDefault("FONT_STYLE", Font.PLAIN + ""));
324 smoothFont.setSelected(Cache.getDefault("ANTI_ALIAS", true));
326 .setSelected(Cache.getDefault(SCALE_PROTEIN_TO_CDNA, false));
328 idItalics.setSelected(Cache.getDefault("ID_ITALICS", true));
330 wrap.setSelected(Cache.getDefault("WRAP_ALIGNMENT", false));
332 gapSymbolCB.addItem("-");
333 gapSymbolCB.addItem(".");
335 gapSymbolCB.setSelectedItem(Cache.getDefault("GAP_SYMBOL", "-"));
337 sortby.addItem("No sort");
338 sortby.addItem("Id");
339 sortby.addItem("Pairwise Identity");
340 sortby.setSelectedItem(Cache.getDefault("SORT_ALIGNMENT", "No sort"));
342 sortAnnBy.addItem(SequenceAnnotationOrder.NONE.toString());
344 .addItem(SequenceAnnotationOrder.SEQUENCE_AND_LABEL.toString());
346 .addItem(SequenceAnnotationOrder.LABEL_AND_SEQUENCE.toString());
347 SequenceAnnotationOrder savedSort = SequenceAnnotationOrder
348 .valueOf(Cache.getDefault(SORT_ANNOTATIONS,
349 SequenceAnnotationOrder.NONE.name()));
350 sortAnnBy.setSelectedItem(savedSort.toString());
352 sortAutocalc.addItem("Autocalculated first");
353 sortAutocalc.addItem("Autocalculated last");
354 final boolean showAbove = Cache.getDefault(SHOW_AUTOCALC_ABOVE, true);
355 sortAutocalc.setSelectedItem(showAbove ? sortAutocalc.getItemAt(0)
356 : sortAutocalc.getItemAt(1));
358 .setSelected(Cache.getDefault("SHOW_STARTUP_FILE", true));
359 startupFileTextfield.setText(Cache.getDefault("STARTUP_FILE",
360 Cache.getDefault("www.jalview.org", "https://www.jalview.org")
361 + "/examples/exampleFile_2_7.jvp"));
364 * Set Colours tab defaults
366 protColour.addItem(ResidueColourScheme.NONE);
367 nucColour.addItem(ResidueColourScheme.NONE);
368 for (ColourSchemeI cs : ColourSchemes.getInstance().getColourSchemes())
370 String name = cs.getSchemeName();
371 protColour.addItem(name);
372 nucColour.addItem(name);
374 String oldProp = Cache.getDefault(DEFAULT_COLOUR,
375 ResidueColourScheme.NONE);
376 String newProp = Cache.getDefault(DEFAULT_COLOUR_PROT, null);
377 protColour.setSelectedItem(newProp != null ? newProp : oldProp);
378 newProp = Cache.getDefault(DEFAULT_COLOUR_NUC, null);
379 nucColour.setSelectedItem(newProp != null ? newProp : oldProp);
380 minColour.setBackground(
381 Cache.getDefaultColour("ANNOTATIONCOLOUR_MIN", Color.orange));
382 maxColour.setBackground(
383 Cache.getDefaultColour("ANNOTATIONCOLOUR_MAX", Color.red));
386 * Set overview panel defaults
388 gapColour.setBackground(Cache.getDefaultColour(GAP_COLOUR,
389 jalview.renderer.OverviewResColourFinder.OVERVIEW_DEFAULT_GAP));
390 hiddenColour.setBackground(Cache.getDefaultColour(HIDDEN_COLOUR,
391 jalview.renderer.OverviewResColourFinder.OVERVIEW_DEFAULT_HIDDEN));
392 useLegacyGap.setSelected(Cache.getDefault(USE_LEGACY_GAP, false));
393 gapLabel.setEnabled(!useLegacyGap.isSelected());
394 gapColour.setEnabled(!useLegacyGap.isSelected());
396 .setSelected(Cache.getDefault(SHOW_OV_HIDDEN_AT_START, false));
399 * Set Structure tab defaults
401 final boolean structSelected = Cache.getDefault(STRUCT_FROM_PDB, true);
402 structFromPdb.setSelected(structSelected);
403 addSecondaryStructure.setSelected(Cache.getDefault(ADD_SS_ANN, true));
404 addSecondaryStructure.setEnabled(structSelected);
405 addTempFactor.setSelected(Cache.getDefault(ADD_TEMPFACT_ANN, true));
406 addTempFactor.setEnabled(structSelected);
409 * set choice of structure viewer, and path if saved as a preference;
410 * default to Jmol (first choice) if an unexpected value is found
412 String viewerType = Cache.getDefault(STRUCTURE_DISPLAY,
413 ViewerType.JMOL.name());
414 structViewer.setSelectedItem(viewerType);
415 String viewerPath = "";
416 ViewerType type = null;
419 type = ViewerType.valueOf(viewerType);
425 viewerPath = Cache.getDefault(CHIMERA_PATH, "");
428 viewerPath = Cache.getDefault(CHIMERAX_PATH, "");
431 viewerPath = Cache.getDefault(PYMOL_PATH, "");
434 } catch (IllegalArgumentException e)
436 Console.error("Unknown structure viewer type: " + viewerType
437 + ", defaulting to Jmol");
438 type = ViewerType.JMOL;
440 structureViewerPath.setText(viewerPath);
442 structureViewerPath.addActionListener(new ActionListener()
445 public void actionPerformed(ActionEvent e)
447 if (validateViewerPath())
449 String path = structureViewerPath.getText();
451 ViewerType type = ViewerType.valueOf(viewerType);
457 Cache.setProperty(CHIMERA_PATH, path);
460 Cache.setProperty(CHIMERAX_PATH, path);
463 Cache.setProperty(PYMOL_PATH, path);
466 } catch (IllegalArgumentException x)
468 Console.error("Failed to set path - unknown viewer type",x);
474 if (Cache.getDefault("MAP_WITH_SIFTS", false))
476 siftsMapping.setSelected(true);
480 nwMapping.setSelected(true);
484 .setMapWithSifts(Cache.getDefault("MAP_WITH_SIFTS", false));
487 * Set Connections tab defaults
491 linkUrlTable.setModel(dataModel);
492 final TableRowSorter<TableModel> sorter = new TableRowSorter<>(
493 linkUrlTable.getModel());
494 linkUrlTable.setRowSorter(sorter);
495 List<RowSorter.SortKey> sortKeys = new ArrayList<>();
497 UrlLinkTableModel m = (UrlLinkTableModel) linkUrlTable.getModel();
498 sortKeys.add(new RowSorter.SortKey(m.getPrimaryColumn(),
499 SortOrder.DESCENDING));
500 sortKeys.add(new RowSorter.SortKey(m.getSelectedColumn(),
501 SortOrder.DESCENDING));
503 new RowSorter.SortKey(m.getNameColumn(), SortOrder.ASCENDING));
505 sorter.setSortKeys(sortKeys);
506 // BH 2018 setSortKeys will do the sort
510 ActionListener onReset;
511 onReset = new ActionListener()
514 public void actionPerformed(ActionEvent e)
516 filterTB.setText("");
517 sorter.setRowFilter(RowFilter.regexFilter(""));
521 doReset.addActionListener(onReset);
523 // filter to display only custom urls
524 final RowFilter<TableModel, Object> customUrlFilter = new RowFilter<TableModel, Object>()
527 public boolean include(
528 Entry<? extends TableModel, ? extends Object> entry)
530 return ((UrlLinkTableModel) entry.getModel()).isUserEntry(entry);
534 final TableRowSorter<TableModel> customSorter = new TableRowSorter<>(
535 linkUrlTable.getModel());
536 customSorter.setRowFilter(customUrlFilter);
538 ActionListener onCustomOnly;
539 onCustomOnly = new ActionListener()
542 public void actionPerformed(ActionEvent e)
544 filterTB.setText("");
545 sorter.setRowFilter(customUrlFilter);
548 userOnly.addActionListener(onCustomOnly);
550 filterTB.getDocument().addDocumentListener(new DocumentListener()
552 String caseInsensitiveFlag = "(?i)";
555 public void changedUpdate(DocumentEvent e)
557 sorter.setRowFilter(RowFilter
558 .regexFilter(caseInsensitiveFlag + filterTB.getText()));
562 public void removeUpdate(DocumentEvent e)
564 sorter.setRowFilter(RowFilter
565 .regexFilter(caseInsensitiveFlag + filterTB.getText()));
569 public void insertUpdate(DocumentEvent e)
571 sorter.setRowFilter(RowFilter
572 .regexFilter(caseInsensitiveFlag + filterTB.getText()));
576 // set up list selection functionality
577 linkUrlTable.getSelectionModel()
578 .addListSelectionListener(new UrlListSelectionHandler());
580 // set up radio buttons
581 int onClickCol = ((UrlLinkTableModel) linkUrlTable.getModel())
583 String onClickName = linkUrlTable.getColumnName(onClickCol);
584 linkUrlTable.getColumn(onClickName)
585 .setCellRenderer(new RadioButtonRenderer());
586 linkUrlTable.getColumn(onClickName)
587 .setCellEditor(new RadioButtonEditor());
589 // get boolean columns and resize those to min possible
590 for (int column = 0; column < linkUrlTable.getColumnCount(); column++)
592 if (linkUrlTable.getModel().getColumnClass(column)
593 .equals(Boolean.class))
595 TableColumn tableColumn = linkUrlTable.getColumnModel()
597 int preferredWidth = tableColumn.getMinWidth();
599 TableCellRenderer cellRenderer = linkUrlTable.getCellRenderer(0,
601 Component c = linkUrlTable.prepareRenderer(cellRenderer, 0, column);
602 int cwidth = c.getPreferredSize().width
603 + linkUrlTable.getIntercellSpacing().width;
604 preferredWidth = Math.max(preferredWidth, cwidth);
606 tableColumn.setPreferredWidth(preferredWidth);
610 String proxyTypeString = Cache.getDefault("USE_PROXY", "false");
611 previousProxyType = proxyTypeString;
612 switch (proxyTypeString)
614 case Cache.PROXYTYPE_NONE:
615 proxyType.setSelected(noProxy.getModel(), true);
617 case Cache.PROXYTYPE_SYSTEM:
618 proxyType.setSelected(systemProxy.getModel(), true);
620 case Cache.PROXYTYPE_CUSTOM:
621 proxyType.setSelected(customProxy.getModel(), true);
625 "Incorrect PROXY_TYPE - should be 'none' (clear proxy properties), 'false' (system settings), 'true' (custom settings): "
628 proxyServerHttpTB.setText(Cache.getDefault("PROXY_SERVER", ""));
629 proxyPortHttpTB.setText(Cache.getDefault("PROXY_PORT", ""));
630 proxyServerHttpsTB.setText(Cache.getDefault("PROXY_SERVER_HTTPS", ""));
631 proxyPortHttpsTB.setText(Cache.getDefault("PROXY_PORT_HTTPS", ""));
632 proxyAuth.setSelected(Cache.getDefault("PROXY_AUTH", false));
634 .setText(Cache.getDefault("PROXY_AUTH_USERNAME", ""));
635 // we are not storing or retrieving proxy password from .jalview_properties
636 proxyAuthPasswordPB.setText(Cache.proxyAuthPassword == null ? ""
637 : new String(Cache.proxyAuthPassword));
638 setCustomProxyEnabled();
639 applyProxyButtonEnabled(false);
641 defaultBrowser.setText(Cache.getDefault("DEFAULT_BROWSER", ""));
643 usagestats.setSelected(Cache.getDefault("USAGESTATS", false));
644 // note antisense here: default is true
646 .setSelected(Cache.getProperty("NOQUESTIONNAIRES") == null);
647 versioncheck.setSelected(Cache.getDefault("VERSION_CHECK", true));
650 * Set Output tab defaults
652 setupOutputCombo(epsRendering, "EPS_RENDERING");
653 setupOutputCombo(htmlRendering, "HTML_RENDERING");
654 setupOutputCombo(svgRendering, "SVG_RENDERING");
655 autoIdWidth.setSelected(Cache.getDefault("FIGURE_AUTOIDWIDTH", false));
656 userIdWidth.setEnabled(!autoIdWidth.isSelected());
657 userIdWidthlabel.setEnabled(!autoIdWidth.isSelected());
658 Integer wi = Cache.getIntegerProperty("FIGURE_FIXEDIDWIDTH");
659 userIdWidth.setText(wi == null ? "" : wi.toString());
660 // TODO: refactor to use common enum via FormatAdapter and allow extension
661 // for new flat file formats
662 blcjv.setSelected(Cache.getDefault("BLC_JVSUFFIX", true));
663 clustaljv.setSelected(Cache.getDefault("CLUSTAL_JVSUFFIX", true));
664 fastajv.setSelected(Cache.getDefault("FASTA_JVSUFFIX", true));
665 msfjv.setSelected(Cache.getDefault("MSF_JVSUFFIX", true));
666 pfamjv.setSelected(Cache.getDefault("PFAM_JVSUFFIX", true));
667 pileupjv.setSelected(Cache.getDefault("PILEUP_JVSUFFIX", true));
668 pirjv.setSelected(Cache.getDefault("PIR_JVSUFFIX", true));
669 modellerOutput.setSelected(Cache.getDefault("PIR_MODELLER", false));
671 .setSelected(Cache.getDefault("EXPORT_EMBBED_BIOJSON", true));
674 * Set Editing tab defaults
676 autoCalculateConsCheck
677 .setSelected(Cache.getDefault("AUTO_CALC_CONSENSUS", true));
678 padGaps.setSelected(Cache.getDefault("PAD_GAPS", false));
679 sortByTree.setSelected(Cache.getDefault("SORT_BY_TREE", false));
681 annotations_actionPerformed(null); // update the display of the annotation
685 * Set Backups tab defaults
687 loadLastSavedBackupsOptions();
690 * Set Startup tab defaults
696 * A helper method that sets the items and initial selection in a character
697 * rendering option list (Prompt each time/Lineart/Text)
702 protected void setupOutputCombo(JComboBox<Object> comboBox,
705 comboBox.addItem(promptEachTimeOpt);
706 comboBox.addItem(lineArtOpt);
707 comboBox.addItem(textOpt);
710 * JalviewJS doesn't support Lineart so force it to Text
712 String defaultOption = Platform.isJS() ? "Text"
713 : Cache.getDefault(propertyKey, "Prompt each time");
714 if (defaultOption.equalsIgnoreCase("Text"))
716 comboBox.setSelectedItem(textOpt);
718 else if (defaultOption.equalsIgnoreCase("Lineart"))
720 comboBox.setSelectedItem(lineArtOpt);
724 comboBox.setSelectedItem(promptEachTimeOpt);
729 * Save user selections on the Preferences tabs to the Cache and write out to
735 public void ok_actionPerformed(ActionEvent e)
737 if (!validateSettings())
743 * Set proxy settings first (to be before web services refresh)
748 * Save Visual settings
750 Cache.applicationProperties.setProperty("SHOW_JVSUFFIX",
751 Boolean.toString(seqLimit.isSelected()));
752 Cache.applicationProperties.setProperty("RIGHT_ALIGN_IDS",
753 Boolean.toString(rightAlign.isSelected()));
754 Cache.applicationProperties.setProperty("SHOW_FULLSCREEN",
755 Boolean.toString(fullScreen.isSelected()));
756 Cache.applicationProperties.setProperty("SHOW_OVERVIEW",
757 Boolean.toString(openoverv.isSelected()));
758 Cache.applicationProperties.setProperty("SHOW_ANNOTATIONS",
759 Boolean.toString(annotations.isSelected()));
760 Cache.applicationProperties.setProperty("SHOW_CONSERVATION",
761 Boolean.toString(conservation.isSelected()));
762 Cache.applicationProperties.setProperty("SHOW_QUALITY",
763 Boolean.toString(quality.isSelected()));
764 Cache.applicationProperties.setProperty("SHOW_IDENTITY",
765 Boolean.toString(identity.isSelected()));
767 Cache.applicationProperties.setProperty("GAP_SYMBOL",
768 gapSymbolCB.getSelectedItem().toString());
770 Cache.applicationProperties.setProperty("FONT_NAME",
771 fontNameCB.getSelectedItem().toString());
772 Cache.applicationProperties.setProperty("FONT_STYLE",
773 fontStyleCB.getSelectedItem().toString());
774 Cache.applicationProperties.setProperty("FONT_SIZE",
775 fontSizeCB.getSelectedItem().toString());
777 Cache.applicationProperties.setProperty("ID_ITALICS",
778 Boolean.toString(idItalics.isSelected()));
779 Cache.applicationProperties.setProperty("SHOW_UNCONSERVED",
780 Boolean.toString(showUnconserved.isSelected()));
781 Cache.applicationProperties.setProperty(SHOW_OCCUPANCY,
782 Boolean.toString(showOccupancy.isSelected()));
783 Cache.applicationProperties.setProperty("SHOW_GROUP_CONSENSUS",
784 Boolean.toString(showGroupConsensus.isSelected()));
785 Cache.applicationProperties.setProperty("SHOW_GROUP_CONSERVATION",
786 Boolean.toString(showGroupConservation.isSelected()));
787 Cache.applicationProperties.setProperty("SHOW_CONSENSUS_HISTOGRAM",
788 Boolean.toString(showConsensHistogram.isSelected()));
789 Cache.applicationProperties.setProperty("SHOW_CONSENSUS_LOGO",
790 Boolean.toString(showConsensLogo.isSelected()));
791 Cache.applicationProperties.setProperty("ANTI_ALIAS",
792 Boolean.toString(smoothFont.isSelected()));
793 Cache.applicationProperties.setProperty(SCALE_PROTEIN_TO_CDNA,
794 Boolean.toString(scaleProteinToCdna.isSelected()));
795 Cache.applicationProperties.setProperty("SHOW_NPFEATS_TOOLTIP",
796 Boolean.toString(showNpTooltip.isSelected()));
797 Cache.applicationProperties.setProperty("SHOW_DBREFS_TOOLTIP",
798 Boolean.toString(showDbRefTooltip.isSelected()));
800 Cache.applicationProperties.setProperty("WRAP_ALIGNMENT",
801 Boolean.toString(wrap.isSelected()));
803 Cache.applicationProperties.setProperty("STARTUP_FILE",
804 startupFileTextfield.getText());
805 Cache.applicationProperties.setProperty("SHOW_STARTUP_FILE",
806 Boolean.toString(startupCheckbox.isSelected()));
808 Cache.applicationProperties.setProperty("SORT_ALIGNMENT",
809 sortby.getSelectedItem().toString());
811 // convert description of sort order to enum name for save
812 SequenceAnnotationOrder annSortOrder = SequenceAnnotationOrder
813 .forDescription(sortAnnBy.getSelectedItem().toString());
814 if (annSortOrder != null)
816 Cache.applicationProperties.setProperty(SORT_ANNOTATIONS,
817 annSortOrder.name());
820 final boolean showAutocalcFirst = sortAutocalc.getSelectedIndex() == 0;
821 Cache.applicationProperties.setProperty(SHOW_AUTOCALC_ABOVE,
822 Boolean.valueOf(showAutocalcFirst).toString());
825 * Save Colours settings
827 Cache.applicationProperties.setProperty(DEFAULT_COLOUR_PROT,
828 protColour.getSelectedItem().toString());
829 Cache.applicationProperties.setProperty(DEFAULT_COLOUR_NUC,
830 nucColour.getSelectedItem().toString());
831 Cache.setColourProperty("ANNOTATIONCOLOUR_MIN",
832 minColour.getBackground());
833 Cache.setColourProperty("ANNOTATIONCOLOUR_MAX",
834 maxColour.getBackground());
837 * Save Overview settings
839 Cache.setColourProperty(GAP_COLOUR, gapColour.getBackground());
840 Cache.setColourProperty(HIDDEN_COLOUR, hiddenColour.getBackground());
841 Cache.applicationProperties.setProperty(USE_LEGACY_GAP,
842 Boolean.toString(useLegacyGap.isSelected()));
843 Cache.applicationProperties.setProperty(SHOW_OV_HIDDEN_AT_START,
844 Boolean.toString(showHiddenAtStart.isSelected()));
847 * Save Structure settings
849 Cache.applicationProperties.setProperty(ADD_TEMPFACT_ANN,
850 Boolean.toString(addTempFactor.isSelected()));
851 Cache.applicationProperties.setProperty(ADD_SS_ANN,
852 Boolean.toString(addSecondaryStructure.isSelected()));
853 Cache.applicationProperties.setProperty(STRUCT_FROM_PDB,
854 Boolean.toString(structFromPdb.isSelected()));
855 String viewer = structViewer.getSelectedItem().toString();
856 String viewerPath = structureViewerPath.getText();
857 Cache.applicationProperties.setProperty(STRUCTURE_DISPLAY, viewer);
858 if (viewer.equals(ViewerType.CHIMERA.name()))
860 Cache.setOrRemove(CHIMERA_PATH, viewerPath);
862 else if (viewer.equals(ViewerType.CHIMERAX.name()))
864 Cache.setOrRemove(CHIMERAX_PATH, viewerPath);
866 else if (viewer.equals(ViewerType.PYMOL.name()))
868 Cache.setOrRemove(PYMOL_PATH, viewerPath);
870 Cache.applicationProperties.setProperty("MAP_WITH_SIFTS",
871 Boolean.toString(siftsMapping.isSelected()));
872 SiftsSettings.setMapWithSifts(siftsMapping.isSelected());
875 * Save Output settings
877 Cache.applicationProperties.setProperty("EPS_RENDERING",
878 ((OptionsParam) epsRendering.getSelectedItem()).getCode());
879 Cache.applicationProperties.setProperty("HTML_RENDERING",
880 ((OptionsParam) htmlRendering.getSelectedItem()).getCode());
881 Cache.applicationProperties.setProperty("SVG_RENDERING",
882 ((OptionsParam) svgRendering.getSelectedItem()).getCode());
885 * Save Connections settings
887 // Proxy settings set first (to catch web services)
889 Cache.setOrRemove("DEFAULT_BROWSER", defaultBrowser.getText());
891 jalview.util.BrowserLauncher.resetBrowser();
893 // save user-defined and selected links
894 String menuLinks = sequenceUrlLinks.writeUrlsAsString(true);
895 if (menuLinks.isEmpty())
897 Cache.applicationProperties.remove("SEQUENCE_LINKS");
901 Cache.applicationProperties.setProperty("SEQUENCE_LINKS",
902 menuLinks.toString());
905 String nonMenuLinks = sequenceUrlLinks.writeUrlsAsString(false);
906 if (nonMenuLinks.isEmpty())
908 Cache.applicationProperties.remove("STORED_LINKS");
912 Cache.applicationProperties.setProperty("STORED_LINKS",
913 nonMenuLinks.toString());
916 Cache.applicationProperties.setProperty("DEFAULT_URL",
917 sequenceUrlLinks.getPrimaryUrlId());
919 Cache.setProperty("VERSION_CHECK",
920 Boolean.toString(versioncheck.isSelected()));
921 if (Cache.getProperty("USAGESTATS") != null || usagestats.isSelected())
923 // default is false - we only set this if the user has actively agreed
924 Cache.setProperty("USAGESTATS",
925 Boolean.toString(usagestats.isSelected()));
927 if (!questionnaire.isSelected())
929 Cache.setProperty("NOQUESTIONNAIRES", "true");
933 // special - made easy to edit a property file to disable questionnaires
934 // by just adding the given line
935 Cache.removeProperty("NOQUESTIONNAIRES");
939 * Save Output settings
941 Cache.applicationProperties.setProperty("BLC_JVSUFFIX",
942 Boolean.toString(blcjv.isSelected()));
943 Cache.applicationProperties.setProperty("CLUSTAL_JVSUFFIX",
944 Boolean.toString(clustaljv.isSelected()));
945 Cache.applicationProperties.setProperty("FASTA_JVSUFFIX",
946 Boolean.toString(fastajv.isSelected()));
947 Cache.applicationProperties.setProperty("MSF_JVSUFFIX",
948 Boolean.toString(msfjv.isSelected()));
949 Cache.applicationProperties.setProperty("PFAM_JVSUFFIX",
950 Boolean.toString(pfamjv.isSelected()));
951 Cache.applicationProperties.setProperty("PILEUP_JVSUFFIX",
952 Boolean.toString(pileupjv.isSelected()));
953 Cache.applicationProperties.setProperty("PIR_JVSUFFIX",
954 Boolean.toString(pirjv.isSelected()));
955 Cache.applicationProperties.setProperty("PIR_MODELLER",
956 Boolean.toString(modellerOutput.isSelected()));
957 Cache.applicationProperties.setProperty("EXPORT_EMBBED_BIOJSON",
958 Boolean.toString(embbedBioJSON.isSelected()));
959 jalview.io.PIRFile.useModellerOutput = modellerOutput.isSelected();
961 Cache.applicationProperties.setProperty("FIGURE_AUTOIDWIDTH",
962 Boolean.toString(autoIdWidth.isSelected()));
963 userIdWidth_actionPerformed();
964 Cache.applicationProperties.setProperty("FIGURE_FIXEDIDWIDTH",
965 userIdWidth.getText());
968 * Save Editing settings
970 Cache.applicationProperties.setProperty("AUTO_CALC_CONSENSUS",
971 Boolean.toString(autoCalculateConsCheck.isSelected()));
972 Cache.applicationProperties.setProperty("SORT_BY_TREE",
973 Boolean.toString(sortByTree.isSelected()));
974 Cache.applicationProperties.setProperty("PAD_GAPS",
975 Boolean.toString(padGaps.isSelected()));
977 if (!Platform.isJS())
979 wsPrefs.updateAndRefreshWsMenuConfig(false);
983 * Save Backups settings
985 Cache.applicationProperties.setProperty(BackupFiles.ENABLED,
986 Boolean.toString(enableBackupFiles.isSelected()));
987 int preset = getComboIntStringKey(backupfilesPresetsCombo);
988 Cache.applicationProperties.setProperty(BackupFiles.NS + "_PRESET",
989 Integer.toString(preset));
991 if (preset == BackupFilesPresetEntry.BACKUPFILESSCHEMECUSTOM)
993 BackupFilesPresetEntry customBFPE = getBackupfilesCurrentEntry();
994 BackupFilesPresetEntry.backupfilesPresetEntriesValues.put(
995 BackupFilesPresetEntry.BACKUPFILESSCHEMECUSTOM, customBFPE);
996 Cache.applicationProperties.setProperty(
997 BackupFilesPresetEntry.CUSTOMCONFIG, customBFPE.toString());
1000 BackupFilesPresetEntry savedBFPE = BackupFilesPresetEntry.backupfilesPresetEntriesValues
1002 Cache.applicationProperties.setProperty(
1003 BackupFilesPresetEntry.SAVEDCONFIG, savedBFPE.toString());
1006 * Save Memory Settings
1008 Cache.applicationProperties.setProperty(
1009 MemorySetting.CUSTOMISED_SETTINGS,
1010 Boolean.toString(customiseMemorySetting.isSelected()));
1011 Cache.applicationProperties.setProperty(MemorySetting.MEMORY_JVMMEMPC,
1012 Integer.toString(jvmMemoryPercentSlider.getValue()));
1013 Cache.applicationProperties.setProperty(MemorySetting.MEMORY_JVMMEMMAX,
1014 jvmMemoryMaxTextField.getText());
1017 * save and close Preferences
1020 Cache.saveProperties();
1021 Desktop.instance.doConfigureStructurePrefs();
1024 frame.setClosed(true);
1025 } catch (Exception ex)
1030 public void saveProxySettings()
1032 String newProxyType = customProxy.isSelected() ? Cache.PROXYTYPE_CUSTOM
1033 : noProxy.isSelected() ? Cache.PROXYTYPE_NONE
1034 : Cache.PROXYTYPE_SYSTEM;
1035 Cache.applicationProperties.setProperty("USE_PROXY", newProxyType);
1036 Cache.setOrRemove("PROXY_SERVER", proxyServerHttpTB.getText());
1037 Cache.setOrRemove("PROXY_PORT", proxyPortHttpTB.getText());
1038 Cache.setOrRemove("PROXY_SERVER_HTTPS", proxyServerHttpsTB.getText());
1039 Cache.setOrRemove("PROXY_PORT_HTTPS", proxyPortHttpsTB.getText());
1040 Cache.setOrRemove("PROXY_AUTH",
1041 Boolean.toString(proxyAuth.isSelected()));
1042 Cache.setOrRemove("PROXY_AUTH_USERNAME", proxyAuthUsernameTB.getText());
1043 Cache.proxyAuthPassword = proxyAuthPasswordPB.getPassword();
1044 Cache.setProxyPropertiesFromPreferences(previousProxyType);
1045 if (newProxyType.equals(Cache.PROXYTYPE_CUSTOM)
1046 || !newProxyType.equals(previousProxyType))
1048 // force a re-lookup of ws if proxytype is custom or has changed
1051 previousProxyType = newProxyType;
1055 * Do any necessary validation before saving settings. Return focus to the first
1056 * tab which fails validation.
1060 private boolean validateSettings()
1062 if (!validateStructure())
1064 structureTab.requestFocusInWindow();
1071 protected boolean validateStructure()
1073 return validateViewerPath();
1081 public void startupFileTextfield_mouseClicked()
1083 // TODO: JAL-3048 not needed for Jalview-JS
1084 String fileFormat = Cache.getProperty("DEFAULT_FILE_FORMAT");
1085 JalviewFileChooser chooser = JalviewFileChooser
1086 .forRead(Cache.getProperty("LAST_DIRECTORY"), fileFormat);
1087 chooser.setFileView(new JalviewFileView());
1088 chooser.setDialogTitle(
1089 MessageManager.getString("label.select_startup_file"));
1091 int value = chooser.showOpenDialog(this);
1093 if (value == JalviewFileChooser.APPROVE_OPTION)
1095 FileFormatI format = chooser.getSelectedFormat();
1098 Cache.applicationProperties.setProperty("DEFAULT_FILE_FORMAT",
1101 startupFileTextfield
1102 .setText(chooser.getSelectedFile().getAbsolutePath());
1113 public void cancel_actionPerformed(ActionEvent e)
1117 if (!Platform.isJS())
1119 wsPrefs.updateWsMenuConfig(true);
1120 wsPrefs.refreshWs_actionPerformed(e);
1122 frame.setClosed(true);
1123 } catch (Exception ex)
1135 public void annotations_actionPerformed(ActionEvent e)
1137 conservation.setEnabled(annotations.isSelected());
1138 quality.setEnabled(annotations.isSelected());
1139 identity.setEnabled(annotations.isSelected());
1140 showOccupancy.setEnabled(annotations.isSelected());
1141 showGroupConsensus.setEnabled(annotations.isSelected());
1142 showGroupConservation.setEnabled(annotations.isSelected());
1143 showConsensHistogram.setEnabled(annotations.isSelected()
1144 && (identity.isSelected() || showGroupConsensus.isSelected()));
1145 showConsensLogo.setEnabled(annotations.isSelected()
1146 && (identity.isSelected() || showGroupConsensus.isSelected()));
1150 public void newLink_actionPerformed(ActionEvent e)
1152 GSequenceLink link = new GSequenceLink();
1153 boolean valid = false;
1156 if (JvOptionPane.showInternalConfirmDialog(Desktop.desktop, link,
1157 MessageManager.getString("label.new_sequence_url_link"),
1158 JvOptionPane.OK_CANCEL_OPTION, -1,
1159 null) == JvOptionPane.OK_OPTION)
1161 if (link.checkValid())
1163 if (((UrlLinkTableModel) linkUrlTable.getModel())
1164 .isUniqueName(link.getName()))
1166 ((UrlLinkTableModel) linkUrlTable.getModel())
1167 .insertRow(link.getName(), link.getURL());
1172 link.notifyDuplicate();
1185 public void editLink_actionPerformed(ActionEvent e)
1187 GSequenceLink link = new GSequenceLink();
1189 int index = linkUrlTable.getSelectedRow();
1192 // button no longer enabled if row is not selected
1193 Console.debug("Edit with no row selected in linkUrlTable");
1197 int nameCol = ((UrlLinkTableModel) linkUrlTable.getModel())
1199 int urlCol = ((UrlLinkTableModel) linkUrlTable.getModel())
1201 String oldName = linkUrlTable.getValueAt(index, nameCol).toString();
1202 link.setName(oldName);
1203 link.setURL(linkUrlTable.getValueAt(index, urlCol).toString());
1205 boolean valid = false;
1208 if (JvOptionPane.showInternalConfirmDialog(Desktop.desktop, link,
1209 MessageManager.getString("label.edit_sequence_url_link"),
1210 JvOptionPane.OK_CANCEL_OPTION, -1,
1211 null) == JvOptionPane.OK_OPTION)
1213 if (link.checkValid())
1215 if ((oldName.equals(link.getName()))
1216 || (((UrlLinkTableModel) linkUrlTable.getModel())
1217 .isUniqueName(link.getName())))
1219 linkUrlTable.setValueAt(link.getName(), index, nameCol);
1220 linkUrlTable.setValueAt(link.getURL(), index, urlCol);
1225 link.notifyDuplicate();
1238 public void deleteLink_actionPerformed(ActionEvent e)
1240 int index = linkUrlTable.getSelectedRow();
1241 int modelIndex = -1;
1244 // button no longer enabled if row is not selected
1245 Console.debug("Delete with no row selected in linkUrlTable");
1250 modelIndex = linkUrlTable.convertRowIndexToModel(index);
1253 // make sure we use the model index to delete, and not the table index
1254 ((UrlLinkTableModel) linkUrlTable.getModel()).removeRow(modelIndex);
1258 public void defaultBrowser_mouseClicked(MouseEvent e)
1260 // TODO: JAL-3048 not needed for j2s
1261 if (!Platform.isJS()) // BH 2019
1268 JFileChooser chooser = new JFileChooser(".");
1269 chooser.setDialogTitle(
1270 MessageManager.getString("label.select_default_browser"));
1272 int value = chooser.showOpenDialog(this);
1274 if (value == JFileChooser.APPROVE_OPTION)
1276 defaultBrowser.setText(chooser.getSelectedFile().getAbsolutePath());
1285 * jalview.jbgui.GPreferences#showunconserved_actionPerformed(java.awt.event
1289 protected void showunconserved_actionPerformed(ActionEvent e)
1291 // TODO Auto-generated method stub
1292 super.showunconserved_actionPerformed(e);
1295 public static List<String> getGroupURLLinks()
1297 return groupURLLinks;
1301 public void minColour_actionPerformed(JPanel panel)
1303 JalviewColourChooser.showColourChooser(this,
1304 MessageManager.getString("label.select_colour_minimum_value"),
1309 public void maxColour_actionPerformed(JPanel panel)
1311 JalviewColourChooser.showColourChooser(this,
1312 MessageManager.getString("label.select_colour_maximum_value"),
1317 public void gapColour_actionPerformed(JPanel gap)
1319 if (!useLegacyGap.isSelected())
1321 JalviewColourChooser.showColourChooser(this,
1322 MessageManager.getString("label.select_gap_colour"), gap);
1327 public void hiddenColour_actionPerformed(JPanel hidden)
1329 JalviewColourChooser.showColourChooser(this,
1330 MessageManager.getString("label.select_hidden_colour"), hidden);
1334 protected void useLegacyGaps_actionPerformed(ActionEvent e)
1336 boolean enabled = useLegacyGap.isSelected();
1339 gapColour.setBackground(
1340 jalview.renderer.OverviewResColourFinder.OVERVIEW_DEFAULT_LEGACY_GAP);
1344 gapColour.setBackground(
1345 jalview.renderer.OverviewResColourFinder.OVERVIEW_DEFAULT_GAP);
1347 gapColour.setEnabled(!enabled);
1348 gapLabel.setEnabled(!enabled);
1352 protected void resetOvDefaults_actionPerformed(ActionEvent e)
1354 useLegacyGap.setSelected(false);
1355 useLegacyGaps_actionPerformed(null);
1356 showHiddenAtStart.setSelected(false);
1357 hiddenColour.setBackground(
1358 jalview.renderer.OverviewResColourFinder.OVERVIEW_DEFAULT_HIDDEN);
1362 protected void userIdWidth_actionPerformed()
1366 String val = userIdWidth.getText().trim();
1367 if (val.length() > 0)
1369 Integer iw = Integer.parseInt(val);
1370 if (iw.intValue() < 12)
1372 throw new NumberFormatException();
1374 userIdWidth.setText(iw.toString());
1376 } catch (NumberFormatException x)
1378 userIdWidth.setText("");
1379 JvOptionPane.showInternalMessageDialog(Desktop.desktop,
1381 .getString("warn.user_defined_width_requirements"),
1382 MessageManager.getString("label.invalid_id_column_width"),
1383 JvOptionPane.WARNING_MESSAGE);
1388 protected void autoIdWidth_actionPerformed()
1390 userIdWidth.setEnabled(!autoIdWidth.isSelected());
1391 userIdWidthlabel.setEnabled(!autoIdWidth.isSelected());
1395 * Returns true if structure viewer path is to a valid executable, else shows an
1396 * error dialog. Does nothing if the path is empty, as is the case for Jmol
1397 * (built in to Jalview) or when Jalview is left to try default paths.
1399 private boolean validateViewerPath()
1401 if (structureViewerPath.getText().trim().length() > 0)
1403 File f = new File(structureViewerPath.getText());
1404 if (!f.canExecute())
1406 JvOptionPane.showInternalMessageDialog(Desktop.desktop,
1407 MessageManager.getString("label.invalid_viewer_path"),
1408 MessageManager.getString("label.invalid_viewer_path"),
1409 JvOptionPane.ERROR_MESSAGE);
1417 * If Chimera or ChimeraX or Pymol is selected, check it can be found on default
1418 * or user-specified path, if not show a warning/help dialog
1421 protected void structureViewer_actionPerformed(String selectedItem)
1423 if (selectedItem.equals(ViewerType.JMOL.name()))
1425 structureViewerPath.setEnabled(false);
1426 structureViewerPathLabel.setEnabled(false);
1429 boolean found = false;
1430 structureViewerPath.setEnabled(true);
1431 structureViewerPathLabel.setEnabled(true);
1432 structureViewerPathLabel.setText(MessageManager
1433 .formatMessage("label.viewer_path", selectedItem));
1436 * Try user-specified and standard paths for structure viewer executable
1438 String viewerPath = "";
1439 List<String> paths = null;
1442 ViewerType viewerType = ViewerType.valueOf(selectedItem);
1449 viewerPath = Cache.getDefault(CHIMERA_PATH, "");
1450 paths = StructureManager.getChimeraPaths(false);
1453 viewerPath = Cache.getDefault(CHIMERAX_PATH, "");
1454 paths = StructureManager.getChimeraPaths(true);
1457 viewerPath = Cache.getDefault(PYMOL_PATH, "");
1458 paths = PymolManager.getPymolPaths();
1461 } catch (IllegalArgumentException e)
1463 // only valid entries should be in the drop-down
1465 structureViewerPath.setText(viewerPath);
1467 paths.add(0, structureViewerPath.getText());
1468 for (String path : paths)
1470 if (new File(path.trim()).canExecute())
1479 String[] options = { "OK", "Help" };
1480 int showHelp = JvOptionPane.showInternalOptionDialog(Desktop.desktop,
1481 JvSwingUtils.wrapTooltip(true,
1482 MessageManager.getString("label.viewer_missing")),
1483 "", JvOptionPane.YES_NO_OPTION, JvOptionPane.WARNING_MESSAGE,
1484 null, options, options[0]);
1486 if (showHelp == JvOptionPane.NO_OPTION)
1488 this.selectTab(Preferences.TabRef.STRUCTURE_TAB, null);
1491 Help.showHelpWindow(HelpId.StructureViewer);
1492 } catch (HelpSetException e)
1494 e.printStackTrace();
1497 else if (showHelp == JvOptionPane.OK_OPTION)
1499 this.selectTab(Preferences.TabRef.STRUCTURE_TAB, null);
1500 CompletableFuture<Void> cf = CompletableFuture.runAsync(() -> {
1503 for (int i = 0; i < 3; i++)
1505 structureViewerPath.setBackground(Color.PINK);
1507 structureViewerPath.setBackground(Color.WHITE);
1510 } catch (InterruptedException e)
1518 public class OptionsParam
1520 private String name;
1522 private String code;
1524 public OptionsParam(String name, String code)
1530 public String getName()
1535 public void setName(String name)
1540 public String getCode()
1545 public void setCode(String code)
1551 public String toString()
1557 public boolean equals(Object that)
1559 if (!(that instanceof OptionsParam))
1563 return this.code.equalsIgnoreCase(((OptionsParam) that).code);
1567 public int hashCode()
1569 return name.hashCode() + code.hashCode();
1573 private class UrlListSelectionHandler implements ListSelectionListener
1577 public void valueChanged(ListSelectionEvent e)
1579 ListSelectionModel lsm = (ListSelectionModel) e.getSource();
1581 int index = lsm.getMinSelectionIndex();
1584 // no selection, so disable delete/edit buttons
1585 editLink.setEnabled(false);
1586 deleteLink.setEnabled(false);
1589 int modelIndex = linkUrlTable.convertRowIndexToModel(index);
1591 // enable/disable edit and delete link buttons
1592 if (((UrlLinkTableModel) linkUrlTable.getModel())
1593 .isRowDeletable(modelIndex))
1595 deleteLink.setEnabled(true);
1599 deleteLink.setEnabled(false);
1602 if (((UrlLinkTableModel) linkUrlTable.getModel())
1603 .isRowEditable(modelIndex))
1605 editLink.setEnabled(true);
1609 editLink.setEnabled(false);