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;
31 import java.util.ArrayList;
32 import java.util.List;
33 import java.util.concurrent.CompletableFuture;
35 import javax.help.HelpSetException;
36 import javax.swing.JComboBox;
37 import javax.swing.JInternalFrame;
38 import javax.swing.JPanel;
39 import javax.swing.ListSelectionModel;
40 import javax.swing.RowFilter;
41 import javax.swing.RowSorter;
42 import javax.swing.SortOrder;
43 import javax.swing.event.DocumentEvent;
44 import javax.swing.event.DocumentListener;
45 import javax.swing.event.ListSelectionEvent;
46 import javax.swing.event.ListSelectionListener;
47 import javax.swing.table.TableCellRenderer;
48 import javax.swing.table.TableColumn;
49 import javax.swing.table.TableModel;
50 import javax.swing.table.TableRowSorter;
52 //import edu.stanford.ejalbert.launching.IBrowserLaunching;
53 import ext.edu.ucsf.rbvi.strucviz2.StructureManager;
54 import jalview.analysis.AnnotationSorter.SequenceAnnotationOrder;
55 import jalview.bin.Cache;
56 import jalview.bin.Console;
57 import jalview.bin.MemorySetting;
58 import jalview.ext.pymol.PymolManager;
59 import jalview.gui.Help.HelpId;
60 import jalview.gui.StructureViewer.ViewerType;
61 import jalview.io.BackupFiles;
62 import jalview.io.BackupFilesPresetEntry;
63 import jalview.io.FileFormatI;
64 import jalview.io.JalviewFileChooser;
65 import jalview.io.JalviewFileView;
66 import jalview.jbgui.GPreferences;
67 import jalview.jbgui.GSequenceLink;
68 import jalview.schemes.ColourSchemeI;
69 import jalview.schemes.ColourSchemes;
70 import jalview.schemes.ResidueColourScheme;
71 import jalview.urls.UrlLinkTableModel;
72 import jalview.urls.api.UrlProviderFactoryI;
73 import jalview.urls.api.UrlProviderI;
74 import jalview.urls.desktop.DesktopUrlProviderFactory;
75 import jalview.util.MessageManager;
76 import jalview.util.Platform;
77 import jalview.util.UrlConstants;
78 import jalview.ws.sifts.SiftsSettings;
87 * for merge with Jalview-JS
88 public class Preferences extends GPreferences implements ApplicationSingletonI
90 public class Preferences extends GPreferences
92 public static final String ENABLE_SPLIT_FRAME = "ENABLE_SPLIT_FRAME";
94 public static final String SCALE_PROTEIN_TO_CDNA = "SCALE_PROTEIN_TO_CDNA";
96 public static final String DEFAULT_COLOUR = "DEFAULT_COLOUR";
98 public static final String DEFAULT_COLOUR_PROT = "DEFAULT_COLOUR_PROT";
100 public static final String DEFAULT_COLOUR_NUC = "DEFAULT_COLOUR_NUC";
102 public static final String ADD_TEMPFACT_ANN = "ADD_TEMPFACT_ANN";
104 public static final String ADD_SS_ANN = "ADD_SS_ANN";
106 public static final String USE_RNAVIEW = "USE_RNAVIEW";
108 public static final String STRUCT_FROM_PDB = "STRUCT_FROM_PDB";
110 public static final String STRUCTURE_DISPLAY = "STRUCTURE_DISPLAY";
112 public static final String CHIMERA_PATH = "CHIMERA_PATH";
114 public static final String CHIMERAX_PATH = "CHIMERAX_PATH";
116 public static final String PYMOL_PATH = "PYMOL_PATH";
118 public static final String SORT_ANNOTATIONS = "SORT_ANNOTATIONS";
120 public static final String SHOW_AUTOCALC_ABOVE = "SHOW_AUTOCALC_ABOVE";
122 public static final String SHOW_OCCUPANCY = "SHOW_OCCUPANCY";
124 public static final String SHOW_OV_HIDDEN_AT_START = "SHOW_OV_HIDDEN_AT_START";
126 public static final String USE_LEGACY_GAP = "USE_LEGACY_GAP";
128 public static final String GAP_COLOUR = "GAP_COLOUR";
130 public static final String HIDDEN_COLOUR = "HIDDEN_COLOUR";
132 private static final int MIN_FONT_SIZE = 1;
134 private static final int MAX_FONT_SIZE = 30;
136 private String previousProxyType;
138 private static Preferences INSTANCE = null; // add "final"
141 * Holds name and link separated with | character. Sequence ID must be
142 * $SEQUENCE_ID$ or $SEQUENCE_ID=/.possible | chars ./=$
144 public static UrlProviderI sequenceUrlLinks;
146 public static UrlLinkTableModel dataModel;
149 * Holds name and link separated with | character. Sequence IDS and Sequences
150 * must be $SEQUENCEIDS$ or $SEQUENCEIDS=/.possible | chars ./=$ and
151 * $SEQUENCES$ or $SEQUENCES=/.possible | chars ./=$ and separation character
152 * for first and second token specified after a pipe character at end |,|.
153 * (TODO: proper escape for using | to separate ids or sequences
156 public static List<String> groupURLLinks;
159 // don't populate with session properties
160 Cache.disableSessionProperties();
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 Cache.enableSessionProperties();
191 JInternalFrame frame;
193 private WsPreferences wsPrefs;
195 private OptionsParam promptEachTimeOpt = new OptionsParam(
196 MessageManager.getString("label.prompt_each_time"),
197 LineartOptions.PROMPT_EACH_TIME);
199 private OptionsParam lineArtOpt = new OptionsParam(
200 MessageManager.getString("label.lineart"), "Lineart");
202 private OptionsParam textOpt = new OptionsParam(
203 MessageManager.getString("action.text"), "Text");
205 // get singleton Preferences instance
206 public static Preferences getInstance()
208 if (INSTANCE == null || INSTANCE.frame == null
209 || INSTANCE.frame.isClosed())
211 INSTANCE = new Preferences();
216 * Replace code with the following for Jalvew-JS
217 Preferences INSTANCE = ApplicationSingletonProvider.getInstance(Preferences.class);
218 if (INSTANCE == null || INSTANCE.frame == null
219 || INSTANCE.frame.isClosed())
221 ApplicationSingletonProvider.remove(Preferences.class);
222 INSTANCE = ApplicationSingletonProvider.getInstance(Preferences.class);
228 public static void openPreferences()
230 openPreferences(null, null);
233 public static void openPreferences(TabRef selectTab, String message)
235 Preferences p = getInstance();
236 if (selectTab != null)
237 p.selectTab(selectTab, message);
239 p.frame.moveToFront();
243 public void selectTab(TabRef selectTab, String message)
245 this.selectTab(selectTab);
247 this.setMessage(message);
252 * Creates a new Preferences object.
254 private Preferences()
257 // don't populate with session properties
258 Cache.disableSessionProperties();
260 frame = new JInternalFrame();
261 frame.setFrameIcon(null);
262 frame.setContentPane(this);
263 if (!Platform.isJS())
270 wsPrefs = new WsPreferences();
271 wsTab.add(wsPrefs, BorderLayout.CENTER);
273 int width = 500, height = 450;
274 if (Platform.isAMacAndNotJS())
280 Desktop.addInternalFrame(frame,
281 MessageManager.getString("label.preferences"), width, height);
282 frame.setMinimumSize(new Dimension(width, height));
285 * Set Visual tab defaults
287 seqLimit.setSelected(Cache.getDefault("SHOW_JVSUFFIX", true));
288 rightAlign.setSelected(Cache.getDefault("RIGHT_ALIGN_IDS", false));
289 fullScreen.setSelected(Cache.getDefault("SHOW_FULLSCREEN", false));
290 annotations.setSelected(Cache.getDefault("SHOW_ANNOTATIONS", true));
292 conservation.setSelected(Cache.getDefault("SHOW_CONSERVATION", true));
293 quality.setSelected(Cache.getDefault("SHOW_QUALITY", true));
294 identity.setSelected(Cache.getDefault("SHOW_IDENTITY", true));
295 ssConsensus.setSelected(Cache.getDefault("SHOW_SS_CONSENSUS", false));
296 openoverv.setSelected(Cache.getDefault("SHOW_OVERVIEW", false));
298 .setSelected(Cache.getDefault("SHOW_UNCONSERVED", false));
299 showOccupancy.setSelected(Cache.getDefault(SHOW_OCCUPANCY, false));
301 .setSelected(Cache.getDefault("SHOW_GROUP_CONSENSUS", false));
302 showGroupConservation.setSelected(
303 Cache.getDefault("SHOW_GROUP_CONSERVATION", false));
304 showConsensHistogram.setSelected(
305 Cache.getDefault("SHOW_CONSENSUS_HISTOGRAM", true));
307 .setSelected(Cache.getDefault("SHOW_CONSENSUS_LOGO", false));
309 .setSelected(Cache.getDefault("SHOW_NPFEATS_TOOLTIP", true));
311 .setSelected(Cache.getDefault("SHOW_DBREFS_TOOLTIP", true));
313 String[] fonts = java.awt.GraphicsEnvironment
314 .getLocalGraphicsEnvironment().getAvailableFontFamilyNames();
315 for (int i = 0; i < fonts.length; i++)
317 fontNameCB.addItem(fonts[i]);
320 for (int i = MIN_FONT_SIZE; i <= MAX_FONT_SIZE; i++)
322 fontSizeCB.addItem(i + "");
325 fontStyleCB.addItem("plain");
326 fontStyleCB.addItem("bold");
327 fontStyleCB.addItem("italic");
329 fontNameCB.setSelectedItem(Cache.getDefault("FONT_NAME", "SansSerif"));
330 fontSizeCB.setSelectedItem(Cache.getDefault("FONT_SIZE", "10"));
331 fontStyleCB.setSelectedItem(
332 Cache.getDefault("FONT_STYLE", Font.PLAIN + ""));
334 smoothFont.setSelected(Cache.getDefault("ANTI_ALIAS", true));
336 .setSelected(Cache.getDefault(SCALE_PROTEIN_TO_CDNA, false));
338 idItalics.setSelected(Cache.getDefault("ID_ITALICS", true));
340 wrap.setSelected(Cache.getDefault("WRAP_ALIGNMENT", false));
342 gapSymbolCB.addItem("-");
343 gapSymbolCB.addItem(".");
345 gapSymbolCB.setSelectedItem(Cache.getDefault("GAP_SYMBOL", "-"));
347 sortby.addItem("No sort");
348 sortby.addItem("Id");
349 sortby.addItem("Pairwise Identity");
350 sortby.setSelectedItem(Cache.getDefault("SORT_ALIGNMENT", "No sort"));
352 sortAnnBy.addItem(SequenceAnnotationOrder.NONE.toString());
354 .addItem(SequenceAnnotationOrder.SEQUENCE_AND_LABEL.toString());
356 .addItem(SequenceAnnotationOrder.LABEL_AND_SEQUENCE.toString());
357 SequenceAnnotationOrder savedSort = SequenceAnnotationOrder
358 .valueOf(Cache.getDefault(SORT_ANNOTATIONS,
359 SequenceAnnotationOrder.NONE.name()));
360 sortAnnBy.setSelectedItem(savedSort.toString());
362 sortAutocalc.addItem("Autocalculated first");
363 sortAutocalc.addItem("Autocalculated last");
364 final boolean showAbove = Cache.getDefault(SHOW_AUTOCALC_ABOVE, true);
365 sortAutocalc.setSelectedItem(showAbove ? sortAutocalc.getItemAt(0)
366 : sortAutocalc.getItemAt(1));
368 .setSelected(Cache.getDefault("SHOW_STARTUP_FILE", true));
369 startupFileTextfield.setText(Cache.getDefault("STARTUP_FILE",
370 Cache.getDefault("www.jalview.org", "https://www.jalview.org")
371 + "/examples/exampleFile_2_7.jvp"));
374 * Set Colours tab defaults
376 protColour.addItem(ResidueColourScheme.NONE);
377 nucColour.addItem(ResidueColourScheme.NONE);
378 for (ColourSchemeI cs : ColourSchemes.getInstance().getColourSchemes())
380 String name = cs.getSchemeName();
381 protColour.addItem(name);
382 nucColour.addItem(name);
384 String oldProp = Cache.getDefault(DEFAULT_COLOUR,
385 ResidueColourScheme.NONE);
386 String newProp = Cache.getDefault(DEFAULT_COLOUR_PROT, null);
387 protColour.setSelectedItem(newProp != null ? newProp : oldProp);
388 newProp = Cache.getDefault(DEFAULT_COLOUR_NUC, null);
389 nucColour.setSelectedItem(newProp != null ? newProp : oldProp);
390 minColour.setBackground(
391 Cache.getDefaultColour("ANNOTATIONCOLOUR_MIN", Color.orange));
392 maxColour.setBackground(
393 Cache.getDefaultColour("ANNOTATIONCOLOUR_MAX", Color.red));
396 * Set overview panel defaults
398 gapColour.setBackground(Cache.getDefaultColour(GAP_COLOUR,
399 OverviewCanvas.OVERVIEW_DEFAULT_GAP));
400 hiddenColour.setBackground(Cache.getDefaultColour(HIDDEN_COLOUR,
401 OverviewCanvas.OVERVIEW_DEFAULT_HIDDEN));
402 useLegacyGap.setSelected(Cache.getDefault(USE_LEGACY_GAP, false));
403 gapLabel.setEnabled(!useLegacyGap.isSelected());
404 gapColour.setEnabled(!useLegacyGap.isSelected());
406 .setSelected(Cache.getDefault(SHOW_OV_HIDDEN_AT_START, false));
409 * Set Structure tab defaults
411 final boolean structSelected = Cache.getDefault(STRUCT_FROM_PDB, true);
412 structFromPdb.setSelected(structSelected);
413 addSecondaryStructure.setSelected(Cache.getDefault(ADD_SS_ANN, true));
414 addSecondaryStructure.setEnabled(structSelected);
415 addTempFactor.setSelected(Cache.getDefault(ADD_TEMPFACT_ANN, true));
416 addTempFactor.setEnabled(structSelected);
419 * set choice of structure viewer, and path if saved as a preference;
420 * default to Jmol (first choice) if an unexpected value is found
422 String viewerType = Cache.getDefault(STRUCTURE_DISPLAY,
423 ViewerType.JMOL.name());
424 structViewer.setSelectedItem(viewerType);
425 String viewerPath = "";
426 ViewerType type = null;
429 type = ViewerType.valueOf(viewerType);
435 viewerPath = Cache.getDefault(CHIMERA_PATH, "");
438 viewerPath = Cache.getDefault(CHIMERAX_PATH, "");
441 viewerPath = Cache.getDefault(PYMOL_PATH, "");
444 } catch (IllegalArgumentException e)
446 Console.error("Unknown structure viewer type: " + viewerType
447 + ", defaulting to Jmol");
448 type = ViewerType.JMOL;
450 structureViewerPath.setText(viewerPath);
452 structureViewerPath.addActionListener(new ActionListener()
455 public void actionPerformed(ActionEvent e)
457 if (validateViewerPath())
459 String path = structureViewerPath.getText();
462 ViewerType type = ViewerType.valueOf(viewerType);
468 Cache.setProperty(CHIMERA_PATH, path);
471 Cache.setProperty(CHIMERAX_PATH, path);
474 Cache.setProperty(PYMOL_PATH, path);
477 } catch (IllegalArgumentException x)
479 Console.error("Failed to set path - unknown viewer type", x);
485 if (Cache.getDefault("MAP_WITH_SIFTS", false))
487 siftsMapping.setSelected(true);
491 nwMapping.setSelected(true);
495 .setMapWithSifts(Cache.getDefault("MAP_WITH_SIFTS", false));
498 * Set Connections tab defaults
502 linkUrlTable.setModel(dataModel);
503 final TableRowSorter<TableModel> sorter = new TableRowSorter<>(
504 linkUrlTable.getModel());
505 linkUrlTable.setRowSorter(sorter);
506 List<RowSorter.SortKey> sortKeys = new ArrayList<>();
508 UrlLinkTableModel m = (UrlLinkTableModel) linkUrlTable.getModel();
509 sortKeys.add(new RowSorter.SortKey(m.getPrimaryColumn(),
510 SortOrder.DESCENDING));
511 sortKeys.add(new RowSorter.SortKey(m.getSelectedColumn(),
512 SortOrder.DESCENDING));
514 new RowSorter.SortKey(m.getNameColumn(), SortOrder.ASCENDING));
516 sorter.setSortKeys(sortKeys);
517 // BH 2018 setSortKeys will do the sort
521 ActionListener onReset;
522 onReset = new ActionListener()
525 public void actionPerformed(ActionEvent e)
527 filterTB.setText("");
528 sorter.setRowFilter(RowFilter.regexFilter(""));
532 doReset.addActionListener(onReset);
534 // filter to display only custom urls
535 final RowFilter<TableModel, Object> customUrlFilter = new RowFilter<TableModel, Object>()
538 public boolean include(
539 Entry<? extends TableModel, ? extends Object> entry)
541 return ((UrlLinkTableModel) entry.getModel()).isUserEntry(entry);
545 final TableRowSorter<TableModel> customSorter = new TableRowSorter<>(
546 linkUrlTable.getModel());
547 customSorter.setRowFilter(customUrlFilter);
549 ActionListener onCustomOnly;
550 onCustomOnly = new ActionListener()
553 public void actionPerformed(ActionEvent e)
555 filterTB.setText("");
556 sorter.setRowFilter(customUrlFilter);
559 userOnly.addActionListener(onCustomOnly);
561 filterTB.getDocument().addDocumentListener(new DocumentListener()
563 String caseInsensitiveFlag = "(?i)";
566 public void changedUpdate(DocumentEvent e)
568 sorter.setRowFilter(RowFilter
569 .regexFilter(caseInsensitiveFlag + filterTB.getText()));
573 public void removeUpdate(DocumentEvent e)
575 sorter.setRowFilter(RowFilter
576 .regexFilter(caseInsensitiveFlag + filterTB.getText()));
580 public void insertUpdate(DocumentEvent e)
582 sorter.setRowFilter(RowFilter
583 .regexFilter(caseInsensitiveFlag + filterTB.getText()));
587 // set up list selection functionality
588 linkUrlTable.getSelectionModel()
589 .addListSelectionListener(new UrlListSelectionHandler());
591 // set up radio buttons
592 int onClickCol = ((UrlLinkTableModel) linkUrlTable.getModel())
594 String onClickName = linkUrlTable.getColumnName(onClickCol);
595 linkUrlTable.getColumn(onClickName)
596 .setCellRenderer(new RadioButtonRenderer());
597 linkUrlTable.getColumn(onClickName)
598 .setCellEditor(new RadioButtonEditor());
600 // get boolean columns and resize those to min possible
601 for (int column = 0; column < linkUrlTable.getColumnCount(); column++)
603 if (linkUrlTable.getModel().getColumnClass(column)
604 .equals(Boolean.class))
606 TableColumn tableColumn = linkUrlTable.getColumnModel()
608 int preferredWidth = tableColumn.getMinWidth();
610 TableCellRenderer cellRenderer = linkUrlTable.getCellRenderer(0,
612 Component c = linkUrlTable.prepareRenderer(cellRenderer, 0, column);
613 int cwidth = c.getPreferredSize().width
614 + linkUrlTable.getIntercellSpacing().width;
615 preferredWidth = Math.max(preferredWidth, cwidth);
617 tableColumn.setPreferredWidth(preferredWidth);
621 String proxyTypeString = Cache.getDefault("USE_PROXY", "false");
622 previousProxyType = proxyTypeString;
623 switch (proxyTypeString)
625 case Cache.PROXYTYPE_NONE:
626 proxyType.setSelected(noProxy.getModel(), true);
628 case Cache.PROXYTYPE_SYSTEM:
629 proxyType.setSelected(systemProxy.getModel(), true);
631 case Cache.PROXYTYPE_CUSTOM:
632 proxyType.setSelected(customProxy.getModel(), true);
636 "Incorrect PROXY_TYPE - should be 'none' (clear proxy properties), 'false' (system settings), 'true' (custom settings): "
639 proxyServerHttpTB.setText(Cache.getDefault("PROXY_SERVER", ""));
640 proxyPortHttpTB.setText(Cache.getDefault("PROXY_PORT", ""));
641 proxyServerHttpsTB.setText(Cache.getDefault("PROXY_SERVER_HTTPS", ""));
642 proxyPortHttpsTB.setText(Cache.getDefault("PROXY_PORT_HTTPS", ""));
643 proxyAuth.setSelected(Cache.getDefault("PROXY_AUTH", false));
645 .setText(Cache.getDefault("PROXY_AUTH_USERNAME", ""));
646 // we are not storing or retrieving proxy password from .jalview_properties
647 proxyAuthPasswordPB.setText(Cache.proxyAuthPassword == null ? ""
648 : new String(Cache.proxyAuthPassword));
649 setCustomProxyEnabled();
650 applyProxyButtonEnabled(false);
652 usagestats.setSelected(Cache.getDefault("USAGESTATS", false));
653 // note antisense here: default is true
655 .setSelected(Cache.getProperty("NOQUESTIONNAIRES") == null);
656 versioncheck.setSelected(Cache.getDefault("VERSION_CHECK", true));
659 * Set Output tab defaults
661 setupOutputCombo(epsRendering, "EPS_RENDERING");
662 setupOutputCombo(htmlRendering, "HTML_RENDERING");
663 setupOutputCombo(svgRendering, "SVG_RENDERING");
664 autoIdWidth.setSelected(Cache.getDefault("FIGURE_AUTOIDWIDTH", false));
665 userIdWidth.setEnabled(!autoIdWidth.isSelected());
666 userIdWidthlabel.setEnabled(!autoIdWidth.isSelected());
667 Integer wi = Cache.getIntegerProperty("FIGURE_FIXEDIDWIDTH");
668 userIdWidth.setText(wi == null ? "" : wi.toString());
669 // TODO: refactor to use common enum via FormatAdapter and allow extension
670 // for new flat file formats
671 blcjv.setSelected(Cache.getDefault("BLC_JVSUFFIX", true));
672 clustaljv.setSelected(Cache.getDefault("CLUSTAL_JVSUFFIX", true));
673 fastajv.setSelected(Cache.getDefault("FASTA_JVSUFFIX", true));
674 msfjv.setSelected(Cache.getDefault("MSF_JVSUFFIX", true));
675 pfamjv.setSelected(Cache.getDefault("PFAM_JVSUFFIX", true));
676 pileupjv.setSelected(Cache.getDefault("PILEUP_JVSUFFIX", true));
677 pirjv.setSelected(Cache.getDefault("PIR_JVSUFFIX", true));
678 modellerOutput.setSelected(Cache.getDefault("PIR_MODELLER", false));
680 .setSelected(Cache.getDefault("EXPORT_EMBBED_BIOJSON", true));
683 * Set Editing tab defaults
685 autoCalculateConsCheck
686 .setSelected(Cache.getDefault("AUTO_CALC_CONSENSUS", true));
687 padGaps.setSelected(Cache.getDefault("PAD_GAPS", false));
688 sortByTree.setSelected(Cache.getDefault("SORT_BY_TREE", false));
690 annotations_actionPerformed(null); // update the display of the annotation
694 * Set Backups tab defaults
696 loadLastSavedBackupsOptions();
699 * Set Startup tab defaults
703 Cache.enableSessionProperties();
707 * A helper method that sets the items and initial selection in a character
708 * rendering option list (Prompt each time/Lineart/Text)
713 protected void setupOutputCombo(JComboBox<Object> comboBox,
716 Cache.disableSessionProperties();
718 comboBox.addItem(promptEachTimeOpt);
719 comboBox.addItem(lineArtOpt);
720 comboBox.addItem(textOpt);
723 * JalviewJS doesn't support Lineart so force it to Text
725 String defaultOption = Platform.isJS() ? "Text"
726 : Cache.getDefault(propertyKey, "Prompt each time");
727 if (defaultOption.equalsIgnoreCase("Text"))
729 comboBox.setSelectedItem(textOpt);
731 else if (defaultOption.equalsIgnoreCase("Lineart"))
733 comboBox.setSelectedItem(lineArtOpt);
737 comboBox.setSelectedItem(promptEachTimeOpt);
740 Cache.enableSessionProperties();
744 * Save user selections on the Preferences tabs to the Cache and write out to
750 public void ok_actionPerformed(ActionEvent e)
752 Cache.disableSessionProperties();
754 if (!validateSettings())
760 * Set proxy settings first (to be before web services refresh)
765 * Save Visual settings
768 Cache.applicationProperties.setProperty("SHOW_JVSUFFIX",
769 Boolean.toString(seqLimit.isSelected()));
770 Cache.applicationProperties.setProperty("RIGHT_ALIGN_IDS",
771 Boolean.toString(rightAlign.isSelected()));
772 Cache.applicationProperties.setProperty("SHOW_FULLSCREEN",
773 Boolean.toString(fullScreen.isSelected()));
774 Cache.applicationProperties.setProperty("SHOW_OVERVIEW",
775 Boolean.toString(openoverv.isSelected()));
776 Cache.applicationProperties.setProperty("SHOW_ANNOTATIONS",
777 Boolean.toString(annotations.isSelected()));
778 Cache.applicationProperties.setProperty("SHOW_CONSERVATION",
779 Boolean.toString(conservation.isSelected()));
780 Cache.applicationProperties.setProperty("SHOW_QUALITY",
781 Boolean.toString(quality.isSelected()));
782 Cache.applicationProperties.setProperty("SHOW_IDENTITY",
783 Boolean.toString(identity.isSelected()));
785 Cache.applicationProperties.setProperty("SHOW_SS_CONSENSUS",
786 Boolean.toString(ssConsensus.isSelected()));
788 Cache.applicationProperties.setProperty("GAP_SYMBOL",
789 gapSymbolCB.getSelectedItem().toString());
791 Cache.applicationProperties.setProperty("FONT_NAME",
792 fontNameCB.getSelectedItem().toString());
793 Cache.applicationProperties.setProperty("FONT_STYLE",
794 fontStyleCB.getSelectedItem().toString());
795 Cache.applicationProperties.setProperty("FONT_SIZE",
796 fontSizeCB.getSelectedItem().toString());
798 Cache.applicationProperties.setProperty("ID_ITALICS",
799 Boolean.toString(idItalics.isSelected()));
800 Cache.applicationProperties.setProperty("SHOW_UNCONSERVED",
801 Boolean.toString(showUnconserved.isSelected()));
802 Cache.applicationProperties.setProperty(SHOW_OCCUPANCY,
803 Boolean.toString(showOccupancy.isSelected()));
804 Cache.applicationProperties.setProperty("SHOW_GROUP_CONSENSUS",
805 Boolean.toString(showGroupConsensus.isSelected()));
806 Cache.applicationProperties.setProperty("SHOW_GROUP_CONSERVATION",
807 Boolean.toString(showGroupConservation.isSelected()));
808 Cache.applicationProperties.setProperty("SHOW_CONSENSUS_HISTOGRAM",
809 Boolean.toString(showConsensHistogram.isSelected()));
810 Cache.applicationProperties.setProperty("SHOW_CONSENSUS_LOGO",
811 Boolean.toString(showConsensLogo.isSelected()));
812 Cache.applicationProperties.setProperty("ANTI_ALIAS",
813 Boolean.toString(smoothFont.isSelected()));
814 Cache.applicationProperties.setProperty(SCALE_PROTEIN_TO_CDNA,
815 Boolean.toString(scaleProteinToCdna.isSelected()));
816 Cache.applicationProperties.setProperty("SHOW_NPFEATS_TOOLTIP",
817 Boolean.toString(showNpTooltip.isSelected()));
818 Cache.applicationProperties.setProperty("SHOW_DBREFS_TOOLTIP",
819 Boolean.toString(showDbRefTooltip.isSelected()));
821 Cache.applicationProperties.setProperty("WRAP_ALIGNMENT",
822 Boolean.toString(wrap.isSelected()));
824 Cache.applicationProperties.setProperty("STARTUP_FILE",
825 startupFileTextfield.getText());
826 Cache.applicationProperties.setProperty("SHOW_STARTUP_FILE",
827 Boolean.toString(startupCheckbox.isSelected()));
829 Cache.applicationProperties.setProperty("SORT_ALIGNMENT",
830 sortby.getSelectedItem().toString());
832 // convert description of sort order to enum name for save
833 SequenceAnnotationOrder annSortOrder = SequenceAnnotationOrder
834 .forDescription(sortAnnBy.getSelectedItem().toString());
835 if (annSortOrder != null)
837 Cache.applicationProperties.setProperty(SORT_ANNOTATIONS,
838 annSortOrder.name());
841 final boolean showAutocalcFirst = sortAutocalc.getSelectedIndex() == 0;
842 Cache.applicationProperties.setProperty(SHOW_AUTOCALC_ABOVE,
843 Boolean.valueOf(showAutocalcFirst).toString());
846 * Save Colours settings
848 Cache.applicationProperties.setProperty(DEFAULT_COLOUR_PROT,
849 protColour.getSelectedItem().toString());
850 Cache.applicationProperties.setProperty(DEFAULT_COLOUR_NUC,
851 nucColour.getSelectedItem().toString());
852 Cache.setColourProperty("ANNOTATIONCOLOUR_MIN",
853 minColour.getBackground());
854 Cache.setColourProperty("ANNOTATIONCOLOUR_MAX",
855 maxColour.getBackground());
858 * Save Overview settings
860 Cache.setColourProperty(GAP_COLOUR, gapColour.getBackground());
861 Cache.setColourProperty(HIDDEN_COLOUR, hiddenColour.getBackground());
862 Cache.applicationProperties.setProperty(USE_LEGACY_GAP,
863 Boolean.toString(useLegacyGap.isSelected()));
864 Cache.applicationProperties.setProperty(SHOW_OV_HIDDEN_AT_START,
865 Boolean.toString(showHiddenAtStart.isSelected()));
868 * Save Structure settings
870 Cache.applicationProperties.setProperty(ADD_TEMPFACT_ANN,
871 Boolean.toString(addTempFactor.isSelected()));
872 Cache.applicationProperties.setProperty(ADD_SS_ANN,
873 Boolean.toString(addSecondaryStructure.isSelected()));
874 Cache.applicationProperties.setProperty(STRUCT_FROM_PDB,
875 Boolean.toString(structFromPdb.isSelected()));
876 String viewer = structViewer.getSelectedItem().toString();
877 String viewerPath = structureViewerPath.getText();
878 Cache.applicationProperties.setProperty(STRUCTURE_DISPLAY, viewer);
879 if (viewer.equals(ViewerType.CHIMERA.name()))
881 Cache.setOrRemove(CHIMERA_PATH, viewerPath);
883 else if (viewer.equals(ViewerType.CHIMERAX.name()))
885 Cache.setOrRemove(CHIMERAX_PATH, viewerPath);
887 else if (viewer.equals(ViewerType.PYMOL.name()))
889 Cache.setOrRemove(PYMOL_PATH, viewerPath);
891 Cache.applicationProperties.setProperty("MAP_WITH_SIFTS",
892 Boolean.toString(siftsMapping.isSelected()));
893 SiftsSettings.setMapWithSifts(siftsMapping.isSelected());
896 * Save Output settings
898 Cache.applicationProperties.setProperty("EPS_RENDERING",
899 ((OptionsParam) epsRendering.getSelectedItem()).getCode());
900 Cache.applicationProperties.setProperty("HTML_RENDERING",
901 ((OptionsParam) htmlRendering.getSelectedItem()).getCode());
902 Cache.applicationProperties.setProperty("SVG_RENDERING",
903 ((OptionsParam) svgRendering.getSelectedItem()).getCode());
906 * Save Connections settings
908 // Proxy settings set first (to catch web services)
910 // save user-defined and selected links
911 String menuLinks = sequenceUrlLinks.writeUrlsAsString(true);
912 if (menuLinks.isEmpty())
914 Cache.applicationProperties.remove("SEQUENCE_LINKS");
918 Cache.applicationProperties.setProperty("SEQUENCE_LINKS",
919 menuLinks.toString());
922 String nonMenuLinks = sequenceUrlLinks.writeUrlsAsString(false);
923 if (nonMenuLinks.isEmpty())
925 Cache.applicationProperties.remove("STORED_LINKS");
929 Cache.applicationProperties.setProperty("STORED_LINKS",
930 nonMenuLinks.toString());
933 Cache.applicationProperties.setProperty("DEFAULT_URL",
934 sequenceUrlLinks.getPrimaryUrlId());
936 Cache.setProperty("VERSION_CHECK",
937 Boolean.toString(versioncheck.isSelected()));
938 if (Cache.getProperty("USAGESTATS") != null || usagestats.isSelected())
940 // default is false - we only set this if the user has actively agreed
941 Cache.setProperty("USAGESTATS",
942 Boolean.toString(usagestats.isSelected()));
944 if (!questionnaire.isSelected())
946 Cache.setProperty("NOQUESTIONNAIRES", "true");
950 // special - made easy to edit a property file to disable questionnaires
951 // by just adding the given line
952 Cache.removeProperty("NOQUESTIONNAIRES");
956 * Save Output settings
958 Cache.applicationProperties.setProperty("BLC_JVSUFFIX",
959 Boolean.toString(blcjv.isSelected()));
960 Cache.applicationProperties.setProperty("CLUSTAL_JVSUFFIX",
961 Boolean.toString(clustaljv.isSelected()));
962 Cache.applicationProperties.setProperty("FASTA_JVSUFFIX",
963 Boolean.toString(fastajv.isSelected()));
964 Cache.applicationProperties.setProperty("MSF_JVSUFFIX",
965 Boolean.toString(msfjv.isSelected()));
966 Cache.applicationProperties.setProperty("PFAM_JVSUFFIX",
967 Boolean.toString(pfamjv.isSelected()));
968 Cache.applicationProperties.setProperty("PILEUP_JVSUFFIX",
969 Boolean.toString(pileupjv.isSelected()));
970 Cache.applicationProperties.setProperty("PIR_JVSUFFIX",
971 Boolean.toString(pirjv.isSelected()));
972 Cache.applicationProperties.setProperty("PIR_MODELLER",
973 Boolean.toString(modellerOutput.isSelected()));
974 Cache.applicationProperties.setProperty("EXPORT_EMBBED_BIOJSON",
975 Boolean.toString(embbedBioJSON.isSelected()));
976 jalview.io.PIRFile.useModellerOutput = modellerOutput.isSelected();
978 Cache.applicationProperties.setProperty("FIGURE_AUTOIDWIDTH",
979 Boolean.toString(autoIdWidth.isSelected()));
980 userIdWidth_actionPerformed();
981 Cache.applicationProperties.setProperty("FIGURE_FIXEDIDWIDTH",
982 userIdWidth.getText());
985 * Save Editing settings
987 Cache.applicationProperties.setProperty("AUTO_CALC_CONSENSUS",
988 Boolean.toString(autoCalculateConsCheck.isSelected()));
989 Cache.applicationProperties.setProperty("SORT_BY_TREE",
990 Boolean.toString(sortByTree.isSelected()));
991 Cache.applicationProperties.setProperty("PAD_GAPS",
992 Boolean.toString(padGaps.isSelected()));
994 if (!Platform.isJS())
996 wsPrefs.updateAndRefreshWsMenuConfig(false);
1000 * Save Backups settings
1002 Cache.applicationProperties.setProperty(BackupFiles.ENABLED,
1003 Boolean.toString(enableBackupFiles.isSelected()));
1004 int preset = getComboIntStringKey(backupfilesPresetsCombo);
1005 Cache.applicationProperties.setProperty(BackupFiles.NS + "_PRESET",
1006 Integer.toString(preset));
1008 if (preset == BackupFilesPresetEntry.BACKUPFILESSCHEMECUSTOM)
1010 BackupFilesPresetEntry customBFPE = getBackupfilesCurrentEntry();
1011 BackupFilesPresetEntry.backupfilesPresetEntriesValues.put(
1012 BackupFilesPresetEntry.BACKUPFILESSCHEMECUSTOM, customBFPE);
1013 Cache.applicationProperties.setProperty(
1014 BackupFilesPresetEntry.CUSTOMCONFIG, customBFPE.toString());
1017 BackupFilesPresetEntry savedBFPE = BackupFilesPresetEntry.backupfilesPresetEntriesValues
1019 Cache.applicationProperties.setProperty(
1020 BackupFilesPresetEntry.SAVEDCONFIG, savedBFPE.toString());
1023 * Save Memory Settings
1025 Cache.applicationProperties.setProperty(
1026 MemorySetting.CUSTOMISED_SETTINGS,
1027 Boolean.toString(customiseMemorySetting.isSelected()));
1028 Cache.applicationProperties.setProperty(MemorySetting.MEMORY_JVMMEMPC,
1029 Integer.toString(jvmMemoryPercentSlider.getValue()));
1030 Cache.applicationProperties.setProperty(MemorySetting.MEMORY_JVMMEMMAX,
1031 jvmMemoryMaxTextField.getText());
1034 * save and close Preferences
1037 Cache.saveProperties();
1038 Desktop.instance.doConfigureStructurePrefs();
1041 frame.setClosed(true);
1042 } catch (Exception ex)
1046 Cache.enableSessionProperties();
1049 public void saveProxySettings()
1051 Cache.disableSessionProperties();
1053 String newProxyType = customProxy.isSelected() ? Cache.PROXYTYPE_CUSTOM
1054 : noProxy.isSelected() ? Cache.PROXYTYPE_NONE
1055 : Cache.PROXYTYPE_SYSTEM;
1056 Cache.applicationProperties.setProperty("USE_PROXY", newProxyType);
1057 Cache.setOrRemove("PROXY_SERVER", proxyServerHttpTB.getText());
1058 Cache.setOrRemove("PROXY_PORT", proxyPortHttpTB.getText());
1059 Cache.setOrRemove("PROXY_SERVER_HTTPS", proxyServerHttpsTB.getText());
1060 Cache.setOrRemove("PROXY_PORT_HTTPS", proxyPortHttpsTB.getText());
1061 Cache.setOrRemove("PROXY_AUTH",
1062 Boolean.toString(proxyAuth.isSelected()));
1063 Cache.setOrRemove("PROXY_AUTH_USERNAME", proxyAuthUsernameTB.getText());
1064 Cache.proxyAuthPassword = proxyAuthPasswordPB.getPassword();
1065 Cache.setProxyPropertiesFromPreferences(previousProxyType);
1066 if (newProxyType.equals(Cache.PROXYTYPE_CUSTOM)
1067 || !newProxyType.equals(previousProxyType))
1069 // force a re-lookup of ws if proxytype is custom or has changed
1072 previousProxyType = newProxyType;
1074 Cache.enableSessionProperties();
1078 * Do any necessary validation before saving settings. Return focus to the
1079 * first tab which fails validation.
1083 private boolean validateSettings()
1085 if (!validateStructure())
1087 structureTab.requestFocusInWindow();
1094 protected boolean validateStructure()
1096 return validateViewerPath();
1104 public void startupFileTextfield_mouseClicked()
1106 Cache.disableSessionProperties();
1108 // TODO: JAL-3048 not needed for Jalview-JS
1109 String fileFormat = Cache.getProperty("DEFAULT_FILE_FORMAT");
1110 JalviewFileChooser chooser = JalviewFileChooser
1111 .forRead(Cache.getProperty("LAST_DIRECTORY"), fileFormat);
1112 chooser.setFileView(new JalviewFileView());
1113 chooser.setDialogTitle(
1114 MessageManager.getString("label.select_startup_file"));
1116 int value = chooser.showOpenDialog(this);
1118 if (value == JalviewFileChooser.APPROVE_OPTION)
1120 FileFormatI format = chooser.getSelectedFormat();
1123 Cache.applicationProperties.setProperty("DEFAULT_FILE_FORMAT",
1126 startupFileTextfield
1127 .setText(chooser.getSelectedFile().getAbsolutePath());
1130 Cache.enableSessionProperties();
1140 public void cancel_actionPerformed(ActionEvent e)
1144 if (!Platform.isJS())
1146 wsPrefs.updateWsMenuConfig(true);
1147 wsPrefs.refreshWs_actionPerformed(e);
1149 frame.setClosed(true);
1150 } catch (Exception ex)
1162 public void annotations_actionPerformed(ActionEvent e)
1164 conservation.setEnabled(annotations.isSelected());
1165 quality.setEnabled(annotations.isSelected());
1166 identity.setEnabled(annotations.isSelected());
1167 ssConsensus.setEnabled(annotations.isSelected());
1168 showOccupancy.setEnabled(annotations.isSelected());
1169 showGroupConsensus.setEnabled(annotations.isSelected());
1170 showGroupConservation.setEnabled(annotations.isSelected());
1171 showConsensHistogram.setEnabled(annotations.isSelected()
1172 && (identity.isSelected() || showGroupConsensus.isSelected()));
1173 showConsensLogo.setEnabled(annotations.isSelected()
1174 && (identity.isSelected() || showGroupConsensus.isSelected()));
1178 public void newLink_actionPerformed(ActionEvent e)
1180 GSequenceLink link = new GSequenceLink();
1181 boolean valid = false;
1184 if (JvOptionPane.showInternalConfirmDialog(Desktop.desktop, link,
1185 MessageManager.getString("label.new_sequence_url_link"),
1186 JvOptionPane.OK_CANCEL_OPTION, -1,
1187 null) == JvOptionPane.OK_OPTION)
1189 if (link.checkValid())
1191 if (((UrlLinkTableModel) linkUrlTable.getModel())
1192 .isUniqueName(link.getName()))
1194 ((UrlLinkTableModel) linkUrlTable.getModel())
1195 .insertRow(link.getName(), link.getURL());
1200 link.notifyDuplicate();
1213 public void editLink_actionPerformed(ActionEvent e)
1215 GSequenceLink link = new GSequenceLink();
1217 int index = linkUrlTable.getSelectedRow();
1220 // button no longer enabled if row is not selected
1221 Console.debug("Edit with no row selected in linkUrlTable");
1225 int nameCol = ((UrlLinkTableModel) linkUrlTable.getModel())
1227 int urlCol = ((UrlLinkTableModel) linkUrlTable.getModel())
1229 String oldName = linkUrlTable.getValueAt(index, nameCol).toString();
1230 link.setName(oldName);
1231 link.setURL(linkUrlTable.getValueAt(index, urlCol).toString());
1233 boolean valid = false;
1236 if (JvOptionPane.showInternalConfirmDialog(Desktop.desktop, link,
1237 MessageManager.getString("label.edit_sequence_url_link"),
1238 JvOptionPane.OK_CANCEL_OPTION, -1,
1239 null) == JvOptionPane.OK_OPTION)
1241 if (link.checkValid())
1243 if ((oldName.equals(link.getName()))
1244 || (((UrlLinkTableModel) linkUrlTable.getModel())
1245 .isUniqueName(link.getName())))
1247 linkUrlTable.setValueAt(link.getName(), index, nameCol);
1248 linkUrlTable.setValueAt(link.getURL(), index, urlCol);
1253 link.notifyDuplicate();
1266 public void deleteLink_actionPerformed(ActionEvent e)
1268 int index = linkUrlTable.getSelectedRow();
1269 int modelIndex = -1;
1272 // button no longer enabled if row is not selected
1273 Console.debug("Delete with no row selected in linkUrlTable");
1278 modelIndex = linkUrlTable.convertRowIndexToModel(index);
1281 // make sure we use the model index to delete, and not the table index
1282 ((UrlLinkTableModel) linkUrlTable.getModel()).removeRow(modelIndex);
1289 * jalview.jbgui.GPreferences#showunconserved_actionPerformed(java.awt.event
1293 protected void showunconserved_actionPerformed(ActionEvent e)
1295 // TODO Auto-generated method stub
1296 super.showunconserved_actionPerformed(e);
1299 public static List<String> getGroupURLLinks()
1301 return groupURLLinks;
1305 public void minColour_actionPerformed(JPanel panel)
1307 JalviewColourChooser.showColourChooser(this,
1308 MessageManager.getString("label.select_colour_minimum_value"),
1313 public void maxColour_actionPerformed(JPanel panel)
1315 JalviewColourChooser.showColourChooser(this,
1316 MessageManager.getString("label.select_colour_maximum_value"),
1321 public void gapColour_actionPerformed(JPanel gap)
1323 if (!useLegacyGap.isSelected())
1325 JalviewColourChooser.showColourChooser(this,
1326 MessageManager.getString("label.select_gap_colour"), gap);
1331 public void hiddenColour_actionPerformed(JPanel hidden)
1333 JalviewColourChooser.showColourChooser(this,
1334 MessageManager.getString("label.select_hidden_colour"), hidden);
1338 protected void useLegacyGaps_actionPerformed(ActionEvent e)
1340 boolean enabled = useLegacyGap.isSelected();
1343 gapColour.setBackground(OverviewCanvas.OVERVIEW_DEFAULT_LEGACY_GAP);
1347 gapColour.setBackground(OverviewCanvas.OVERVIEW_DEFAULT_GAP);
1349 gapColour.setEnabled(!enabled);
1350 gapLabel.setEnabled(!enabled);
1354 protected void resetOvDefaults_actionPerformed(ActionEvent e)
1356 useLegacyGap.setSelected(false);
1357 useLegacyGaps_actionPerformed(null);
1358 showHiddenAtStart.setSelected(false);
1359 hiddenColour.setBackground(OverviewCanvas.OVERVIEW_DEFAULT_HIDDEN);
1363 protected void userIdWidth_actionPerformed()
1367 String val = userIdWidth.getText().trim();
1368 if (val.length() > 0)
1370 Integer iw = Integer.parseInt(val);
1371 if (iw.intValue() < 12)
1373 throw new NumberFormatException();
1375 userIdWidth.setText(iw.toString());
1377 } catch (NumberFormatException x)
1379 userIdWidth.setText("");
1380 JvOptionPane.showInternalMessageDialog(Desktop.desktop,
1382 .getString("warn.user_defined_width_requirements"),
1383 MessageManager.getString("label.invalid_id_column_width"),
1384 JvOptionPane.WARNING_MESSAGE);
1389 protected void autoIdWidth_actionPerformed()
1391 userIdWidth.setEnabled(!autoIdWidth.isSelected());
1392 userIdWidthlabel.setEnabled(!autoIdWidth.isSelected());
1396 * Returns true if structure viewer path is to a valid executable, else shows
1397 * an error dialog. Does nothing if the path is empty, as is the case for Jmol
1398 * (built in to Jalview) or when Jalview is left to try default paths.
1400 private boolean validateViewerPath()
1402 if (structureViewerPath.getText().trim().length() > 0)
1404 File f = new File(structureViewerPath.getText());
1405 if (!f.canExecute())
1407 JvOptionPane.showInternalMessageDialog(Desktop.desktop,
1408 MessageManager.getString("label.invalid_viewer_path"),
1409 MessageManager.getString("label.invalid_viewer_path"),
1410 JvOptionPane.ERROR_MESSAGE);
1418 * If Chimera or ChimeraX or Pymol is selected, check it can be found on
1419 * default or user-specified path, if not show a warning/help dialog
1422 protected void structureViewer_actionPerformed(String selectedItem)
1424 if (selectedItem.equals(ViewerType.JMOL.name()))
1426 structureViewerPath.setEnabled(false);
1427 structureViewerPathLabel.setEnabled(false);
1430 boolean found = false;
1431 structureViewerPath.setEnabled(true);
1432 structureViewerPathLabel.setEnabled(true);
1433 structureViewerPathLabel.setText(MessageManager
1434 .formatMessage("label.viewer_path", selectedItem));
1437 * Try user-specified and standard paths for structure viewer executable
1439 String viewerPath = "";
1440 List<String> paths = null;
1441 Cache.disableSessionProperties();
1444 ViewerType viewerType = ViewerType.valueOf(selectedItem);
1451 viewerPath = Cache.getDefault(CHIMERA_PATH, "");
1452 paths = StructureManager.getChimeraPaths(false);
1455 viewerPath = Cache.getDefault(CHIMERAX_PATH, "");
1456 paths = StructureManager.getChimeraPaths(true);
1459 viewerPath = Cache.getDefault(PYMOL_PATH, "");
1460 paths = PymolManager.getPymolPaths();
1463 } catch (IllegalArgumentException e)
1465 // only valid entries should be in the drop-down
1467 Cache.enableSessionProperties();
1468 structureViewerPath.setText(viewerPath);
1470 paths.add(0, structureViewerPath.getText());
1471 for (String path : paths)
1473 if (new File(path.trim()).canExecute())
1482 String[] options = { "OK", "Help" };
1483 int showHelp = JvOptionPane.showInternalOptionDialog(Desktop.desktop,
1484 JvSwingUtils.wrapTooltip(true,
1485 MessageManager.getString("label.viewer_missing")),
1486 "", JvOptionPane.YES_NO_OPTION, JvOptionPane.WARNING_MESSAGE,
1487 null, options, options[0]);
1489 if (showHelp == JvOptionPane.NO_OPTION)
1491 this.selectTab(Preferences.TabRef.STRUCTURE_TAB, null);
1494 Help.showHelpWindow(HelpId.StructureViewer);
1495 } catch (HelpSetException e)
1497 e.printStackTrace();
1500 else if (showHelp == JvOptionPane.OK_OPTION)
1502 this.selectTab(Preferences.TabRef.STRUCTURE_TAB, null);
1503 CompletableFuture<Void> cf = CompletableFuture.runAsync(() -> {
1506 for (int i = 0; i < 3; i++)
1508 structureViewerPath.setBackground(Color.PINK);
1510 structureViewerPath.setBackground(Color.WHITE);
1513 } catch (InterruptedException e)
1521 public class OptionsParam
1523 private String name;
1525 private String code;
1527 public OptionsParam(String name, String code)
1533 public String getName()
1538 public void setName(String name)
1543 public String getCode()
1548 public void setCode(String code)
1554 public String toString()
1560 public boolean equals(Object that)
1562 if (!(that instanceof OptionsParam))
1566 return this.code.equalsIgnoreCase(((OptionsParam) that).code);
1570 public int hashCode()
1572 return name.hashCode() + code.hashCode();
1576 private class UrlListSelectionHandler implements ListSelectionListener
1580 public void valueChanged(ListSelectionEvent e)
1582 ListSelectionModel lsm = (ListSelectionModel) e.getSource();
1584 int index = lsm.getMinSelectionIndex();
1587 // no selection, so disable delete/edit buttons
1588 editLink.setEnabled(false);
1589 deleteLink.setEnabled(false);
1592 int modelIndex = linkUrlTable.convertRowIndexToModel(index);
1594 // enable/disable edit and delete link buttons
1595 if (((UrlLinkTableModel) linkUrlTable.getModel())
1596 .isRowDeletable(modelIndex))
1598 deleteLink.setEnabled(true);
1602 deleteLink.setEnabled(false);
1605 if (((UrlLinkTableModel) linkUrlTable.getModel())
1606 .isRowEditable(modelIndex))
1608 editLink.setEnabled(true);
1612 editLink.setEnabled(false);