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 // get links selected to be in the menu (SEQUENCE_LINKS)
160 // and links entered by the user but not selected (STORED_LINKS)
161 String inMenuString = Cache.getDefault("SEQUENCE_LINKS", "");
162 String notInMenuString = Cache.getDefault("STORED_LINKS", "");
163 String defaultUrl = Cache.getDefault("DEFAULT_URL",
164 UrlConstants.DEFAULT_LABEL);
166 // if both links lists are empty, add the DEFAULT_URL link
167 // otherwise we assume the default link is in one of the lists
168 if (inMenuString.isEmpty() && notInMenuString.isEmpty())
170 inMenuString = UrlConstants.DEFAULT_STRING;
172 UrlProviderFactoryI factory = new DesktopUrlProviderFactory(defaultUrl,
173 inMenuString, notInMenuString);
174 sequenceUrlLinks = factory.createUrlProvider();
175 dataModel = new UrlLinkTableModel(sequenceUrlLinks);
178 * TODO: reformulate groupURL encoding so two or more can be stored in the
179 * .properties file as '|' separated strings
182 groupURLLinks = new ArrayList<>();
185 JInternalFrame frame;
187 private WsPreferences wsPrefs;
189 private OptionsParam promptEachTimeOpt = new OptionsParam(
190 MessageManager.getString("label.prompt_each_time"),
193 private OptionsParam lineArtOpt = new OptionsParam(
194 MessageManager.getString("label.lineart"), "Lineart");
196 private OptionsParam textOpt = new OptionsParam(
197 MessageManager.getString("action.text"), "Text");
199 // get singleton Preferences instance
200 public static Preferences getInstance()
202 if (INSTANCE == null || INSTANCE.frame == null
203 || INSTANCE.frame.isClosed())
205 INSTANCE = new Preferences();
210 * Replace code with the following for Jalvew-JS
211 Preferences INSTANCE = ApplicationSingletonProvider.getInstance(Preferences.class);
212 if (INSTANCE == null || INSTANCE.frame == null
213 || INSTANCE.frame.isClosed())
215 ApplicationSingletonProvider.remove(Preferences.class);
216 INSTANCE = ApplicationSingletonProvider.getInstance(Preferences.class);
222 public static void openPreferences()
224 openPreferences(null, null);
227 public static void openPreferences(TabRef selectTab, String message)
229 Preferences p = getInstance();
230 if (selectTab != null)
231 p.selectTab(selectTab, message);
233 p.frame.moveToFront();
237 public void selectTab(TabRef selectTab, String message)
239 this.selectTab(selectTab);
241 this.setMessage(message);
246 * Creates a new Preferences object.
248 private Preferences()
251 frame = new JInternalFrame();
252 frame.setContentPane(this);
253 if (!Platform.isJS())
260 wsPrefs = new WsPreferences();
261 wsTab.add(wsPrefs, BorderLayout.CENTER);
263 int width = 500, height = 450;
264 if (Platform.isAMacAndNotJS())
270 Desktop.addInternalFrame(frame,
271 MessageManager.getString("label.preferences"), width, height);
272 frame.setMinimumSize(new Dimension(width, height));
275 * Set Visual tab defaults
277 seqLimit.setSelected(Cache.getDefault("SHOW_JVSUFFIX", true));
278 rightAlign.setSelected(Cache.getDefault("RIGHT_ALIGN_IDS", false));
279 fullScreen.setSelected(Cache.getDefault("SHOW_FULLSCREEN", false));
280 annotations.setSelected(Cache.getDefault("SHOW_ANNOTATIONS", true));
282 conservation.setSelected(Cache.getDefault("SHOW_CONSERVATION", true));
283 quality.setSelected(Cache.getDefault("SHOW_QUALITY", true));
284 identity.setSelected(Cache.getDefault("SHOW_IDENTITY", true));
285 openoverv.setSelected(Cache.getDefault("SHOW_OVERVIEW", false));
287 .setSelected(Cache.getDefault("SHOW_UNCONSERVED", false));
288 showOccupancy.setSelected(Cache.getDefault(SHOW_OCCUPANCY, false));
290 .setSelected(Cache.getDefault("SHOW_GROUP_CONSENSUS", false));
291 showGroupConservation.setSelected(
292 Cache.getDefault("SHOW_GROUP_CONSERVATION", false));
293 showConsensHistogram.setSelected(
294 Cache.getDefault("SHOW_CONSENSUS_HISTOGRAM", true));
296 .setSelected(Cache.getDefault("SHOW_CONSENSUS_LOGO", false));
298 .setSelected(Cache.getDefault("SHOW_NPFEATS_TOOLTIP", true));
300 .setSelected(Cache.getDefault("SHOW_DBREFS_TOOLTIP", true));
302 String[] fonts = java.awt.GraphicsEnvironment
303 .getLocalGraphicsEnvironment().getAvailableFontFamilyNames();
304 for (int i = 0; i < fonts.length; i++)
306 fontNameCB.addItem(fonts[i]);
309 for (int i = MIN_FONT_SIZE; i <= MAX_FONT_SIZE; i++)
311 fontSizeCB.addItem(i + "");
314 fontStyleCB.addItem("plain");
315 fontStyleCB.addItem("bold");
316 fontStyleCB.addItem("italic");
318 fontNameCB.setSelectedItem(Cache.getDefault("FONT_NAME", "SansSerif"));
319 fontSizeCB.setSelectedItem(Cache.getDefault("FONT_SIZE", "10"));
320 fontStyleCB.setSelectedItem(
321 Cache.getDefault("FONT_STYLE", Font.PLAIN + ""));
323 smoothFont.setSelected(Cache.getDefault("ANTI_ALIAS", true));
325 .setSelected(Cache.getDefault(SCALE_PROTEIN_TO_CDNA, false));
327 idItalics.setSelected(Cache.getDefault("ID_ITALICS", true));
329 wrap.setSelected(Cache.getDefault("WRAP_ALIGNMENT", false));
331 gapSymbolCB.addItem("-");
332 gapSymbolCB.addItem(".");
334 gapSymbolCB.setSelectedItem(Cache.getDefault("GAP_SYMBOL", "-"));
336 sortby.addItem("No sort");
337 sortby.addItem("Id");
338 sortby.addItem("Pairwise Identity");
339 sortby.setSelectedItem(Cache.getDefault("SORT_ALIGNMENT", "No sort"));
341 sortAnnBy.addItem(SequenceAnnotationOrder.NONE.toString());
343 .addItem(SequenceAnnotationOrder.SEQUENCE_AND_LABEL.toString());
345 .addItem(SequenceAnnotationOrder.LABEL_AND_SEQUENCE.toString());
346 SequenceAnnotationOrder savedSort = SequenceAnnotationOrder
347 .valueOf(Cache.getDefault(SORT_ANNOTATIONS,
348 SequenceAnnotationOrder.NONE.name()));
349 sortAnnBy.setSelectedItem(savedSort.toString());
351 sortAutocalc.addItem("Autocalculated first");
352 sortAutocalc.addItem("Autocalculated last");
353 final boolean showAbove = Cache.getDefault(SHOW_AUTOCALC_ABOVE, true);
354 sortAutocalc.setSelectedItem(showAbove ? sortAutocalc.getItemAt(0)
355 : sortAutocalc.getItemAt(1));
357 .setSelected(Cache.getDefault("SHOW_STARTUP_FILE", true));
358 startupFileTextfield.setText(Cache.getDefault("STARTUP_FILE",
359 Cache.getDefault("www.jalview.org", "https://www.jalview.org")
360 + "/examples/exampleFile_2_7.jvp"));
363 * Set Colours tab defaults
365 protColour.addItem(ResidueColourScheme.NONE);
366 nucColour.addItem(ResidueColourScheme.NONE);
367 for (ColourSchemeI cs : ColourSchemes.getInstance().getColourSchemes())
369 String name = cs.getSchemeName();
370 protColour.addItem(name);
371 nucColour.addItem(name);
373 String oldProp = Cache.getDefault(DEFAULT_COLOUR,
374 ResidueColourScheme.NONE);
375 String newProp = Cache.getDefault(DEFAULT_COLOUR_PROT, null);
376 protColour.setSelectedItem(newProp != null ? newProp : oldProp);
377 newProp = Cache.getDefault(DEFAULT_COLOUR_NUC, null);
378 nucColour.setSelectedItem(newProp != null ? newProp : oldProp);
379 minColour.setBackground(
380 Cache.getDefaultColour("ANNOTATIONCOLOUR_MIN", Color.orange));
381 maxColour.setBackground(
382 Cache.getDefaultColour("ANNOTATIONCOLOUR_MAX", Color.red));
385 * Set overview panel defaults
387 gapColour.setBackground(Cache.getDefaultColour(GAP_COLOUR,
388 jalview.renderer.OverviewResColourFinder.OVERVIEW_DEFAULT_GAP));
389 hiddenColour.setBackground(Cache.getDefaultColour(HIDDEN_COLOUR,
390 jalview.renderer.OverviewResColourFinder.OVERVIEW_DEFAULT_HIDDEN));
391 useLegacyGap.setSelected(Cache.getDefault(USE_LEGACY_GAP, false));
392 gapLabel.setEnabled(!useLegacyGap.isSelected());
393 gapColour.setEnabled(!useLegacyGap.isSelected());
395 .setSelected(Cache.getDefault(SHOW_OV_HIDDEN_AT_START, false));
398 * Set Structure tab defaults
400 final boolean structSelected = Cache.getDefault(STRUCT_FROM_PDB, true);
401 structFromPdb.setSelected(structSelected);
402 addSecondaryStructure.setSelected(Cache.getDefault(ADD_SS_ANN, true));
403 addSecondaryStructure.setEnabled(structSelected);
404 addTempFactor.setSelected(Cache.getDefault(ADD_TEMPFACT_ANN, true));
405 addTempFactor.setEnabled(structSelected);
408 * set choice of structure viewer, and path if saved as a preference;
409 * default to Jmol (first choice) if an unexpected value is found
411 String viewerType = Cache.getDefault(STRUCTURE_DISPLAY,
412 ViewerType.JMOL.name());
413 structViewer.setSelectedItem(viewerType);
414 String viewerPath = "";
415 ViewerType type = null;
418 type = ViewerType.valueOf(viewerType);
424 viewerPath = Cache.getDefault(CHIMERA_PATH, "");
427 viewerPath = Cache.getDefault(CHIMERAX_PATH, "");
430 viewerPath = Cache.getDefault(PYMOL_PATH, "");
433 } catch (IllegalArgumentException e)
435 Console.error("Unknown structure viewer type: " + viewerType
436 + ", defaulting to Jmol");
437 type = ViewerType.JMOL;
439 structureViewerPath.setText(viewerPath);
441 structureViewerPath.addActionListener(new ActionListener()
444 public void actionPerformed(ActionEvent e)
446 if (validateViewerPath())
448 String path = structureViewerPath.getText();
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 usagestats.setSelected(Cache.getDefault("USAGESTATS", false));
642 // note antisense here: default is true
644 .setSelected(Cache.getProperty("NOQUESTIONNAIRES") == null);
645 versioncheck.setSelected(Cache.getDefault("VERSION_CHECK", true));
648 * Set Output tab defaults
650 setupOutputCombo(epsRendering, "EPS_RENDERING");
651 setupOutputCombo(htmlRendering, "HTML_RENDERING");
652 setupOutputCombo(svgRendering, "SVG_RENDERING");
653 autoIdWidth.setSelected(Cache.getDefault("FIGURE_AUTOIDWIDTH", false));
654 userIdWidth.setEnabled(!autoIdWidth.isSelected());
655 userIdWidthlabel.setEnabled(!autoIdWidth.isSelected());
656 Integer wi = Cache.getIntegerProperty("FIGURE_FIXEDIDWIDTH");
657 userIdWidth.setText(wi == null ? "" : wi.toString());
658 // TODO: refactor to use common enum via FormatAdapter and allow extension
659 // for new flat file formats
660 blcjv.setSelected(Cache.getDefault("BLC_JVSUFFIX", true));
661 clustaljv.setSelected(Cache.getDefault("CLUSTAL_JVSUFFIX", true));
662 fastajv.setSelected(Cache.getDefault("FASTA_JVSUFFIX", true));
663 msfjv.setSelected(Cache.getDefault("MSF_JVSUFFIX", true));
664 pfamjv.setSelected(Cache.getDefault("PFAM_JVSUFFIX", true));
665 pileupjv.setSelected(Cache.getDefault("PILEUP_JVSUFFIX", true));
666 pirjv.setSelected(Cache.getDefault("PIR_JVSUFFIX", true));
667 modellerOutput.setSelected(Cache.getDefault("PIR_MODELLER", false));
669 .setSelected(Cache.getDefault("EXPORT_EMBBED_BIOJSON", true));
672 * Set Editing tab defaults
674 autoCalculateConsCheck
675 .setSelected(Cache.getDefault("AUTO_CALC_CONSENSUS", true));
676 padGaps.setSelected(Cache.getDefault("PAD_GAPS", false));
677 sortByTree.setSelected(Cache.getDefault("SORT_BY_TREE", false));
679 annotations_actionPerformed(null); // update the display of the annotation
683 * Set Backups tab defaults
685 loadLastSavedBackupsOptions();
688 * Set Startup tab defaults
694 * A helper method that sets the items and initial selection in a character
695 * rendering option list (Prompt each time/Lineart/Text)
700 protected void setupOutputCombo(JComboBox<Object> comboBox,
703 comboBox.addItem(promptEachTimeOpt);
704 comboBox.addItem(lineArtOpt);
705 comboBox.addItem(textOpt);
708 * JalviewJS doesn't support Lineart so force it to Text
710 String defaultOption = Platform.isJS() ? "Text"
711 : Cache.getDefault(propertyKey, "Prompt each time");
712 if (defaultOption.equalsIgnoreCase("Text"))
714 comboBox.setSelectedItem(textOpt);
716 else if (defaultOption.equalsIgnoreCase("Lineart"))
718 comboBox.setSelectedItem(lineArtOpt);
722 comboBox.setSelectedItem(promptEachTimeOpt);
727 * Save user selections on the Preferences tabs to the Cache and write out to
733 public void ok_actionPerformed(ActionEvent e)
735 if (!validateSettings())
741 * Set proxy settings first (to be before web services refresh)
746 * Save Visual settings
748 Cache.applicationProperties.setProperty("SHOW_JVSUFFIX",
749 Boolean.toString(seqLimit.isSelected()));
750 Cache.applicationProperties.setProperty("RIGHT_ALIGN_IDS",
751 Boolean.toString(rightAlign.isSelected()));
752 Cache.applicationProperties.setProperty("SHOW_FULLSCREEN",
753 Boolean.toString(fullScreen.isSelected()));
754 Cache.applicationProperties.setProperty("SHOW_OVERVIEW",
755 Boolean.toString(openoverv.isSelected()));
756 Cache.applicationProperties.setProperty("SHOW_ANNOTATIONS",
757 Boolean.toString(annotations.isSelected()));
758 Cache.applicationProperties.setProperty("SHOW_CONSERVATION",
759 Boolean.toString(conservation.isSelected()));
760 Cache.applicationProperties.setProperty("SHOW_QUALITY",
761 Boolean.toString(quality.isSelected()));
762 Cache.applicationProperties.setProperty("SHOW_IDENTITY",
763 Boolean.toString(identity.isSelected()));
765 Cache.applicationProperties.setProperty("GAP_SYMBOL",
766 gapSymbolCB.getSelectedItem().toString());
768 Cache.applicationProperties.setProperty("FONT_NAME",
769 fontNameCB.getSelectedItem().toString());
770 Cache.applicationProperties.setProperty("FONT_STYLE",
771 fontStyleCB.getSelectedItem().toString());
772 Cache.applicationProperties.setProperty("FONT_SIZE",
773 fontSizeCB.getSelectedItem().toString());
775 Cache.applicationProperties.setProperty("ID_ITALICS",
776 Boolean.toString(idItalics.isSelected()));
777 Cache.applicationProperties.setProperty("SHOW_UNCONSERVED",
778 Boolean.toString(showUnconserved.isSelected()));
779 Cache.applicationProperties.setProperty(SHOW_OCCUPANCY,
780 Boolean.toString(showOccupancy.isSelected()));
781 Cache.applicationProperties.setProperty("SHOW_GROUP_CONSENSUS",
782 Boolean.toString(showGroupConsensus.isSelected()));
783 Cache.applicationProperties.setProperty("SHOW_GROUP_CONSERVATION",
784 Boolean.toString(showGroupConservation.isSelected()));
785 Cache.applicationProperties.setProperty("SHOW_CONSENSUS_HISTOGRAM",
786 Boolean.toString(showConsensHistogram.isSelected()));
787 Cache.applicationProperties.setProperty("SHOW_CONSENSUS_LOGO",
788 Boolean.toString(showConsensLogo.isSelected()));
789 Cache.applicationProperties.setProperty("ANTI_ALIAS",
790 Boolean.toString(smoothFont.isSelected()));
791 Cache.applicationProperties.setProperty(SCALE_PROTEIN_TO_CDNA,
792 Boolean.toString(scaleProteinToCdna.isSelected()));
793 Cache.applicationProperties.setProperty("SHOW_NPFEATS_TOOLTIP",
794 Boolean.toString(showNpTooltip.isSelected()));
795 Cache.applicationProperties.setProperty("SHOW_DBREFS_TOOLTIP",
796 Boolean.toString(showDbRefTooltip.isSelected()));
798 Cache.applicationProperties.setProperty("WRAP_ALIGNMENT",
799 Boolean.toString(wrap.isSelected()));
801 Cache.applicationProperties.setProperty("STARTUP_FILE",
802 startupFileTextfield.getText());
803 Cache.applicationProperties.setProperty("SHOW_STARTUP_FILE",
804 Boolean.toString(startupCheckbox.isSelected()));
806 Cache.applicationProperties.setProperty("SORT_ALIGNMENT",
807 sortby.getSelectedItem().toString());
809 // convert description of sort order to enum name for save
810 SequenceAnnotationOrder annSortOrder = SequenceAnnotationOrder
811 .forDescription(sortAnnBy.getSelectedItem().toString());
812 if (annSortOrder != null)
814 Cache.applicationProperties.setProperty(SORT_ANNOTATIONS,
815 annSortOrder.name());
818 final boolean showAutocalcFirst = sortAutocalc.getSelectedIndex() == 0;
819 Cache.applicationProperties.setProperty(SHOW_AUTOCALC_ABOVE,
820 Boolean.valueOf(showAutocalcFirst).toString());
823 * Save Colours settings
825 Cache.applicationProperties.setProperty(DEFAULT_COLOUR_PROT,
826 protColour.getSelectedItem().toString());
827 Cache.applicationProperties.setProperty(DEFAULT_COLOUR_NUC,
828 nucColour.getSelectedItem().toString());
829 Cache.setColourProperty("ANNOTATIONCOLOUR_MIN",
830 minColour.getBackground());
831 Cache.setColourProperty("ANNOTATIONCOLOUR_MAX",
832 maxColour.getBackground());
835 * Save Overview settings
837 Cache.setColourProperty(GAP_COLOUR, gapColour.getBackground());
838 Cache.setColourProperty(HIDDEN_COLOUR, hiddenColour.getBackground());
839 Cache.applicationProperties.setProperty(USE_LEGACY_GAP,
840 Boolean.toString(useLegacyGap.isSelected()));
841 Cache.applicationProperties.setProperty(SHOW_OV_HIDDEN_AT_START,
842 Boolean.toString(showHiddenAtStart.isSelected()));
845 * Save Structure settings
847 Cache.applicationProperties.setProperty(ADD_TEMPFACT_ANN,
848 Boolean.toString(addTempFactor.isSelected()));
849 Cache.applicationProperties.setProperty(ADD_SS_ANN,
850 Boolean.toString(addSecondaryStructure.isSelected()));
851 Cache.applicationProperties.setProperty(STRUCT_FROM_PDB,
852 Boolean.toString(structFromPdb.isSelected()));
853 String viewer = structViewer.getSelectedItem().toString();
854 String viewerPath = structureViewerPath.getText();
855 Cache.applicationProperties.setProperty(STRUCTURE_DISPLAY, viewer);
856 if (viewer.equals(ViewerType.CHIMERA.name()))
858 Cache.setOrRemove(CHIMERA_PATH, viewerPath);
860 else if (viewer.equals(ViewerType.CHIMERAX.name()))
862 Cache.setOrRemove(CHIMERAX_PATH, viewerPath);
864 else if (viewer.equals(ViewerType.PYMOL.name()))
866 Cache.setOrRemove(PYMOL_PATH, viewerPath);
868 Cache.applicationProperties.setProperty("MAP_WITH_SIFTS",
869 Boolean.toString(siftsMapping.isSelected()));
870 SiftsSettings.setMapWithSifts(siftsMapping.isSelected());
873 * Save Output settings
875 Cache.applicationProperties.setProperty("EPS_RENDERING",
876 ((OptionsParam) epsRendering.getSelectedItem()).getCode());
877 Cache.applicationProperties.setProperty("HTML_RENDERING",
878 ((OptionsParam) htmlRendering.getSelectedItem()).getCode());
879 Cache.applicationProperties.setProperty("SVG_RENDERING",
880 ((OptionsParam) svgRendering.getSelectedItem()).getCode());
883 * Save Connections settings
885 // Proxy settings set first (to catch web services)
887 // save user-defined and selected links
888 String menuLinks = sequenceUrlLinks.writeUrlsAsString(true);
889 if (menuLinks.isEmpty())
891 Cache.applicationProperties.remove("SEQUENCE_LINKS");
895 Cache.applicationProperties.setProperty("SEQUENCE_LINKS",
896 menuLinks.toString());
899 String nonMenuLinks = sequenceUrlLinks.writeUrlsAsString(false);
900 if (nonMenuLinks.isEmpty())
902 Cache.applicationProperties.remove("STORED_LINKS");
906 Cache.applicationProperties.setProperty("STORED_LINKS",
907 nonMenuLinks.toString());
910 Cache.applicationProperties.setProperty("DEFAULT_URL",
911 sequenceUrlLinks.getPrimaryUrlId());
913 Cache.setProperty("VERSION_CHECK",
914 Boolean.toString(versioncheck.isSelected()));
915 if (Cache.getProperty("USAGESTATS") != null || usagestats.isSelected())
917 // default is false - we only set this if the user has actively agreed
918 Cache.setProperty("USAGESTATS",
919 Boolean.toString(usagestats.isSelected()));
921 if (!questionnaire.isSelected())
923 Cache.setProperty("NOQUESTIONNAIRES", "true");
927 // special - made easy to edit a property file to disable questionnaires
928 // by just adding the given line
929 Cache.removeProperty("NOQUESTIONNAIRES");
933 * Save Output settings
935 Cache.applicationProperties.setProperty("BLC_JVSUFFIX",
936 Boolean.toString(blcjv.isSelected()));
937 Cache.applicationProperties.setProperty("CLUSTAL_JVSUFFIX",
938 Boolean.toString(clustaljv.isSelected()));
939 Cache.applicationProperties.setProperty("FASTA_JVSUFFIX",
940 Boolean.toString(fastajv.isSelected()));
941 Cache.applicationProperties.setProperty("MSF_JVSUFFIX",
942 Boolean.toString(msfjv.isSelected()));
943 Cache.applicationProperties.setProperty("PFAM_JVSUFFIX",
944 Boolean.toString(pfamjv.isSelected()));
945 Cache.applicationProperties.setProperty("PILEUP_JVSUFFIX",
946 Boolean.toString(pileupjv.isSelected()));
947 Cache.applicationProperties.setProperty("PIR_JVSUFFIX",
948 Boolean.toString(pirjv.isSelected()));
949 Cache.applicationProperties.setProperty("PIR_MODELLER",
950 Boolean.toString(modellerOutput.isSelected()));
951 Cache.applicationProperties.setProperty("EXPORT_EMBBED_BIOJSON",
952 Boolean.toString(embbedBioJSON.isSelected()));
953 jalview.io.PIRFile.useModellerOutput = modellerOutput.isSelected();
955 Cache.applicationProperties.setProperty("FIGURE_AUTOIDWIDTH",
956 Boolean.toString(autoIdWidth.isSelected()));
957 userIdWidth_actionPerformed();
958 Cache.applicationProperties.setProperty("FIGURE_FIXEDIDWIDTH",
959 userIdWidth.getText());
962 * Save Editing settings
964 Cache.applicationProperties.setProperty("AUTO_CALC_CONSENSUS",
965 Boolean.toString(autoCalculateConsCheck.isSelected()));
966 Cache.applicationProperties.setProperty("SORT_BY_TREE",
967 Boolean.toString(sortByTree.isSelected()));
968 Cache.applicationProperties.setProperty("PAD_GAPS",
969 Boolean.toString(padGaps.isSelected()));
971 if (!Platform.isJS())
973 wsPrefs.updateAndRefreshWsMenuConfig(false);
977 * Save Backups settings
979 Cache.applicationProperties.setProperty(BackupFiles.ENABLED,
980 Boolean.toString(enableBackupFiles.isSelected()));
981 int preset = getComboIntStringKey(backupfilesPresetsCombo);
982 Cache.applicationProperties.setProperty(BackupFiles.NS + "_PRESET",
983 Integer.toString(preset));
985 if (preset == BackupFilesPresetEntry.BACKUPFILESSCHEMECUSTOM)
987 BackupFilesPresetEntry customBFPE = getBackupfilesCurrentEntry();
988 BackupFilesPresetEntry.backupfilesPresetEntriesValues.put(
989 BackupFilesPresetEntry.BACKUPFILESSCHEMECUSTOM, customBFPE);
990 Cache.applicationProperties.setProperty(
991 BackupFilesPresetEntry.CUSTOMCONFIG, customBFPE.toString());
994 BackupFilesPresetEntry savedBFPE = BackupFilesPresetEntry.backupfilesPresetEntriesValues
996 Cache.applicationProperties.setProperty(
997 BackupFilesPresetEntry.SAVEDCONFIG, savedBFPE.toString());
1000 * Save Memory Settings
1002 Cache.applicationProperties.setProperty(
1003 MemorySetting.CUSTOMISED_SETTINGS,
1004 Boolean.toString(customiseMemorySetting.isSelected()));
1005 Cache.applicationProperties.setProperty(MemorySetting.MEMORY_JVMMEMPC,
1006 Integer.toString(jvmMemoryPercentSlider.getValue()));
1007 Cache.applicationProperties.setProperty(MemorySetting.MEMORY_JVMMEMMAX,
1008 jvmMemoryMaxTextField.getText());
1011 * save and close Preferences
1014 Cache.saveProperties();
1015 Desktop.instance.doConfigureStructurePrefs();
1018 frame.setClosed(true);
1019 } catch (Exception ex)
1024 public void saveProxySettings()
1026 String newProxyType = customProxy.isSelected() ? Cache.PROXYTYPE_CUSTOM
1027 : noProxy.isSelected() ? Cache.PROXYTYPE_NONE
1028 : Cache.PROXYTYPE_SYSTEM;
1029 Cache.applicationProperties.setProperty("USE_PROXY", newProxyType);
1030 Cache.setOrRemove("PROXY_SERVER", proxyServerHttpTB.getText());
1031 Cache.setOrRemove("PROXY_PORT", proxyPortHttpTB.getText());
1032 Cache.setOrRemove("PROXY_SERVER_HTTPS", proxyServerHttpsTB.getText());
1033 Cache.setOrRemove("PROXY_PORT_HTTPS", proxyPortHttpsTB.getText());
1034 Cache.setOrRemove("PROXY_AUTH",
1035 Boolean.toString(proxyAuth.isSelected()));
1036 Cache.setOrRemove("PROXY_AUTH_USERNAME", proxyAuthUsernameTB.getText());
1037 Cache.proxyAuthPassword = proxyAuthPasswordPB.getPassword();
1038 Cache.setProxyPropertiesFromPreferences(previousProxyType);
1039 if (newProxyType.equals(Cache.PROXYTYPE_CUSTOM)
1040 || !newProxyType.equals(previousProxyType))
1042 // force a re-lookup of ws if proxytype is custom or has changed
1045 previousProxyType = newProxyType;
1049 * Do any necessary validation before saving settings. Return focus to the
1050 * first tab which fails validation.
1054 private boolean validateSettings()
1056 if (!validateStructure())
1058 structureTab.requestFocusInWindow();
1065 protected boolean validateStructure()
1067 return validateViewerPath();
1075 public void startupFileTextfield_mouseClicked()
1077 // TODO: JAL-3048 not needed for Jalview-JS
1078 String fileFormat = Cache.getProperty("DEFAULT_FILE_FORMAT");
1079 JalviewFileChooser chooser = JalviewFileChooser
1080 .forRead(Cache.getProperty("LAST_DIRECTORY"), fileFormat);
1081 chooser.setFileView(new JalviewFileView());
1082 chooser.setDialogTitle(
1083 MessageManager.getString("label.select_startup_file"));
1085 int value = chooser.showOpenDialog(this);
1087 if (value == JalviewFileChooser.APPROVE_OPTION)
1089 FileFormatI format = chooser.getSelectedFormat();
1092 Cache.applicationProperties.setProperty("DEFAULT_FILE_FORMAT",
1095 startupFileTextfield
1096 .setText(chooser.getSelectedFile().getAbsolutePath());
1107 public void cancel_actionPerformed(ActionEvent e)
1111 if (!Platform.isJS())
1113 wsPrefs.updateWsMenuConfig(true);
1114 wsPrefs.refreshWs_actionPerformed(e);
1116 frame.setClosed(true);
1117 } catch (Exception ex)
1129 public void annotations_actionPerformed(ActionEvent e)
1131 conservation.setEnabled(annotations.isSelected());
1132 quality.setEnabled(annotations.isSelected());
1133 identity.setEnabled(annotations.isSelected());
1134 showOccupancy.setEnabled(annotations.isSelected());
1135 showGroupConsensus.setEnabled(annotations.isSelected());
1136 showGroupConservation.setEnabled(annotations.isSelected());
1137 showConsensHistogram.setEnabled(annotations.isSelected()
1138 && (identity.isSelected() || showGroupConsensus.isSelected()));
1139 showConsensLogo.setEnabled(annotations.isSelected()
1140 && (identity.isSelected() || showGroupConsensus.isSelected()));
1144 public void newLink_actionPerformed(ActionEvent e)
1146 GSequenceLink link = new GSequenceLink();
1147 boolean valid = false;
1150 if (JvOptionPane.showInternalConfirmDialog(Desktop.desktop, link,
1151 MessageManager.getString("label.new_sequence_url_link"),
1152 JvOptionPane.OK_CANCEL_OPTION, -1,
1153 null) == JvOptionPane.OK_OPTION)
1155 if (link.checkValid())
1157 if (((UrlLinkTableModel) linkUrlTable.getModel())
1158 .isUniqueName(link.getName()))
1160 ((UrlLinkTableModel) linkUrlTable.getModel())
1161 .insertRow(link.getName(), link.getURL());
1166 link.notifyDuplicate();
1179 public void editLink_actionPerformed(ActionEvent e)
1181 GSequenceLink link = new GSequenceLink();
1183 int index = linkUrlTable.getSelectedRow();
1186 // button no longer enabled if row is not selected
1187 Console.debug("Edit with no row selected in linkUrlTable");
1191 int nameCol = ((UrlLinkTableModel) linkUrlTable.getModel())
1193 int urlCol = ((UrlLinkTableModel) linkUrlTable.getModel())
1195 String oldName = linkUrlTable.getValueAt(index, nameCol).toString();
1196 link.setName(oldName);
1197 link.setURL(linkUrlTable.getValueAt(index, urlCol).toString());
1199 boolean valid = false;
1202 if (JvOptionPane.showInternalConfirmDialog(Desktop.desktop, link,
1203 MessageManager.getString("label.edit_sequence_url_link"),
1204 JvOptionPane.OK_CANCEL_OPTION, -1,
1205 null) == JvOptionPane.OK_OPTION)
1207 if (link.checkValid())
1209 if ((oldName.equals(link.getName()))
1210 || (((UrlLinkTableModel) linkUrlTable.getModel())
1211 .isUniqueName(link.getName())))
1213 linkUrlTable.setValueAt(link.getName(), index, nameCol);
1214 linkUrlTable.setValueAt(link.getURL(), index, urlCol);
1219 link.notifyDuplicate();
1232 public void deleteLink_actionPerformed(ActionEvent e)
1234 int index = linkUrlTable.getSelectedRow();
1235 int modelIndex = -1;
1238 // button no longer enabled if row is not selected
1239 Console.debug("Delete with no row selected in linkUrlTable");
1244 modelIndex = linkUrlTable.convertRowIndexToModel(index);
1247 // make sure we use the model index to delete, and not the table index
1248 ((UrlLinkTableModel) linkUrlTable.getModel()).removeRow(modelIndex);
1255 * jalview.jbgui.GPreferences#showunconserved_actionPerformed(java.awt.event
1259 protected void showunconserved_actionPerformed(ActionEvent e)
1261 // TODO Auto-generated method stub
1262 super.showunconserved_actionPerformed(e);
1265 public static List<String> getGroupURLLinks()
1267 return groupURLLinks;
1271 public void minColour_actionPerformed(JPanel panel)
1273 JalviewColourChooser.showColourChooser(this,
1274 MessageManager.getString("label.select_colour_minimum_value"),
1279 public void maxColour_actionPerformed(JPanel panel)
1281 JalviewColourChooser.showColourChooser(this,
1282 MessageManager.getString("label.select_colour_maximum_value"),
1287 public void gapColour_actionPerformed(JPanel gap)
1289 if (!useLegacyGap.isSelected())
1291 JalviewColourChooser.showColourChooser(this,
1292 MessageManager.getString("label.select_gap_colour"), gap);
1297 public void hiddenColour_actionPerformed(JPanel hidden)
1299 JalviewColourChooser.showColourChooser(this,
1300 MessageManager.getString("label.select_hidden_colour"), hidden);
1304 protected void useLegacyGaps_actionPerformed(ActionEvent e)
1306 boolean enabled = useLegacyGap.isSelected();
1309 gapColour.setBackground(
1310 jalview.renderer.OverviewResColourFinder.OVERVIEW_DEFAULT_LEGACY_GAP);
1314 gapColour.setBackground(
1315 jalview.renderer.OverviewResColourFinder.OVERVIEW_DEFAULT_GAP);
1317 gapColour.setEnabled(!enabled);
1318 gapLabel.setEnabled(!enabled);
1322 protected void resetOvDefaults_actionPerformed(ActionEvent e)
1324 useLegacyGap.setSelected(false);
1325 useLegacyGaps_actionPerformed(null);
1326 showHiddenAtStart.setSelected(false);
1327 hiddenColour.setBackground(
1328 jalview.renderer.OverviewResColourFinder.OVERVIEW_DEFAULT_HIDDEN);
1332 protected void userIdWidth_actionPerformed()
1336 String val = userIdWidth.getText().trim();
1337 if (val.length() > 0)
1339 Integer iw = Integer.parseInt(val);
1340 if (iw.intValue() < 12)
1342 throw new NumberFormatException();
1344 userIdWidth.setText(iw.toString());
1346 } catch (NumberFormatException x)
1348 userIdWidth.setText("");
1349 JvOptionPane.showInternalMessageDialog(Desktop.desktop,
1351 .getString("warn.user_defined_width_requirements"),
1352 MessageManager.getString("label.invalid_id_column_width"),
1353 JvOptionPane.WARNING_MESSAGE);
1358 protected void autoIdWidth_actionPerformed()
1360 userIdWidth.setEnabled(!autoIdWidth.isSelected());
1361 userIdWidthlabel.setEnabled(!autoIdWidth.isSelected());
1365 * Returns true if structure viewer path is to a valid executable, else shows
1366 * an error dialog. Does nothing if the path is empty, as is the case for Jmol
1367 * (built in to Jalview) or when Jalview is left to try default paths.
1369 private boolean validateViewerPath()
1371 if (structureViewerPath.getText().trim().length() > 0)
1373 File f = new File(structureViewerPath.getText());
1374 if (!f.canExecute())
1376 JvOptionPane.showInternalMessageDialog(Desktop.desktop,
1377 MessageManager.getString("label.invalid_viewer_path"),
1378 MessageManager.getString("label.invalid_viewer_path"),
1379 JvOptionPane.ERROR_MESSAGE);
1387 * If Chimera or ChimeraX or Pymol is selected, check it can be found on
1388 * default or user-specified path, if not show a warning/help dialog
1391 protected void structureViewer_actionPerformed(String selectedItem)
1393 if (selectedItem.equals(ViewerType.JMOL.name()))
1395 structureViewerPath.setEnabled(false);
1396 structureViewerPathLabel.setEnabled(false);
1399 boolean found = false;
1400 structureViewerPath.setEnabled(true);
1401 structureViewerPathLabel.setEnabled(true);
1402 structureViewerPathLabel.setText(MessageManager
1403 .formatMessage("label.viewer_path", selectedItem));
1406 * Try user-specified and standard paths for structure viewer executable
1408 String viewerPath = "";
1409 List<String> paths = null;
1412 ViewerType viewerType = ViewerType.valueOf(selectedItem);
1419 viewerPath = Cache.getDefault(CHIMERA_PATH, "");
1420 paths = StructureManager.getChimeraPaths(false);
1423 viewerPath = Cache.getDefault(CHIMERAX_PATH, "");
1424 paths = StructureManager.getChimeraPaths(true);
1427 viewerPath = Cache.getDefault(PYMOL_PATH, "");
1428 paths = PymolManager.getPymolPaths();
1431 } catch (IllegalArgumentException e)
1433 // only valid entries should be in the drop-down
1435 structureViewerPath.setText(viewerPath);
1437 paths.add(0, structureViewerPath.getText());
1438 for (String path : paths)
1440 if (new File(path.trim()).canExecute())
1449 String[] options = { "OK", "Help" };
1450 int showHelp = JvOptionPane.showInternalOptionDialog(Desktop.desktop,
1451 JvSwingUtils.wrapTooltip(true,
1452 MessageManager.getString("label.viewer_missing")),
1453 "", JvOptionPane.YES_NO_OPTION, JvOptionPane.WARNING_MESSAGE,
1454 null, options, options[0]);
1456 if (showHelp == JvOptionPane.NO_OPTION)
1458 this.selectTab(Preferences.TabRef.STRUCTURE_TAB, null);
1461 Help.showHelpWindow(HelpId.StructureViewer);
1462 } catch (HelpSetException e)
1464 e.printStackTrace();
1467 else if (showHelp == JvOptionPane.OK_OPTION)
1469 this.selectTab(Preferences.TabRef.STRUCTURE_TAB, null);
1470 CompletableFuture<Void> cf = CompletableFuture.runAsync(() -> {
1473 for (int i = 0; i < 3; i++)
1475 structureViewerPath.setBackground(Color.PINK);
1477 structureViewerPath.setBackground(Color.WHITE);
1480 } catch (InterruptedException e)
1488 public class OptionsParam
1490 private String name;
1492 private String code;
1494 public OptionsParam(String name, String code)
1500 public String getName()
1505 public void setName(String name)
1510 public String getCode()
1515 public void setCode(String code)
1521 public String toString()
1527 public boolean equals(Object that)
1529 if (!(that instanceof OptionsParam))
1533 return this.code.equalsIgnoreCase(((OptionsParam) that).code);
1537 public int hashCode()
1539 return name.hashCode() + code.hashCode();
1543 private class UrlListSelectionHandler implements ListSelectionListener
1547 public void valueChanged(ListSelectionEvent e)
1549 ListSelectionModel lsm = (ListSelectionModel) e.getSource();
1551 int index = lsm.getMinSelectionIndex();
1554 // no selection, so disable delete/edit buttons
1555 editLink.setEnabled(false);
1556 deleteLink.setEnabled(false);
1559 int modelIndex = linkUrlTable.convertRowIndexToModel(index);
1561 // enable/disable edit and delete link buttons
1562 if (((UrlLinkTableModel) linkUrlTable.getModel())
1563 .isRowDeletable(modelIndex))
1565 deleteLink.setEnabled(true);
1569 deleteLink.setEnabled(false);
1572 if (((UrlLinkTableModel) linkUrlTable.getModel())
1573 .isRowEditable(modelIndex))
1575 editLink.setEnabled(true);
1579 editLink.setEnabled(false);