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.setFrameIcon(null);
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 OverviewCanvas.OVERVIEW_DEFAULT_GAP));
390 hiddenColour.setBackground(Cache.getDefaultColour(HIDDEN_COLOUR,
391 OverviewCanvas.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();
452 ViewerType type = ViewerType.valueOf(viewerType);
458 Cache.setProperty(CHIMERA_PATH, path);
461 Cache.setProperty(CHIMERAX_PATH, path);
464 Cache.setProperty(PYMOL_PATH, path);
467 } catch (IllegalArgumentException x)
469 Console.error("Failed to set path - unknown viewer type", x);
475 if (Cache.getDefault("MAP_WITH_SIFTS", false))
477 siftsMapping.setSelected(true);
481 nwMapping.setSelected(true);
485 .setMapWithSifts(Cache.getDefault("MAP_WITH_SIFTS", false));
488 * Set Connections tab defaults
492 linkUrlTable.setModel(dataModel);
493 final TableRowSorter<TableModel> sorter = new TableRowSorter<>(
494 linkUrlTable.getModel());
495 linkUrlTable.setRowSorter(sorter);
496 List<RowSorter.SortKey> sortKeys = new ArrayList<>();
498 UrlLinkTableModel m = (UrlLinkTableModel) linkUrlTable.getModel();
499 sortKeys.add(new RowSorter.SortKey(m.getPrimaryColumn(),
500 SortOrder.DESCENDING));
501 sortKeys.add(new RowSorter.SortKey(m.getSelectedColumn(),
502 SortOrder.DESCENDING));
504 new RowSorter.SortKey(m.getNameColumn(), SortOrder.ASCENDING));
506 sorter.setSortKeys(sortKeys);
507 // BH 2018 setSortKeys will do the sort
511 ActionListener onReset;
512 onReset = new ActionListener()
515 public void actionPerformed(ActionEvent e)
517 filterTB.setText("");
518 sorter.setRowFilter(RowFilter.regexFilter(""));
522 doReset.addActionListener(onReset);
524 // filter to display only custom urls
525 final RowFilter<TableModel, Object> customUrlFilter = new RowFilter<TableModel, Object>()
528 public boolean include(
529 Entry<? extends TableModel, ? extends Object> entry)
531 return ((UrlLinkTableModel) entry.getModel()).isUserEntry(entry);
535 final TableRowSorter<TableModel> customSorter = new TableRowSorter<>(
536 linkUrlTable.getModel());
537 customSorter.setRowFilter(customUrlFilter);
539 ActionListener onCustomOnly;
540 onCustomOnly = new ActionListener()
543 public void actionPerformed(ActionEvent e)
545 filterTB.setText("");
546 sorter.setRowFilter(customUrlFilter);
549 userOnly.addActionListener(onCustomOnly);
551 filterTB.getDocument().addDocumentListener(new DocumentListener()
553 String caseInsensitiveFlag = "(?i)";
556 public void changedUpdate(DocumentEvent e)
558 sorter.setRowFilter(RowFilter
559 .regexFilter(caseInsensitiveFlag + filterTB.getText()));
563 public void removeUpdate(DocumentEvent e)
565 sorter.setRowFilter(RowFilter
566 .regexFilter(caseInsensitiveFlag + filterTB.getText()));
570 public void insertUpdate(DocumentEvent e)
572 sorter.setRowFilter(RowFilter
573 .regexFilter(caseInsensitiveFlag + filterTB.getText()));
577 // set up list selection functionality
578 linkUrlTable.getSelectionModel()
579 .addListSelectionListener(new UrlListSelectionHandler());
581 // set up radio buttons
582 int onClickCol = ((UrlLinkTableModel) linkUrlTable.getModel())
584 String onClickName = linkUrlTable.getColumnName(onClickCol);
585 linkUrlTable.getColumn(onClickName)
586 .setCellRenderer(new RadioButtonRenderer());
587 linkUrlTable.getColumn(onClickName)
588 .setCellEditor(new RadioButtonEditor());
590 // get boolean columns and resize those to min possible
591 for (int column = 0; column < linkUrlTable.getColumnCount(); column++)
593 if (linkUrlTable.getModel().getColumnClass(column)
594 .equals(Boolean.class))
596 TableColumn tableColumn = linkUrlTable.getColumnModel()
598 int preferredWidth = tableColumn.getMinWidth();
600 TableCellRenderer cellRenderer = linkUrlTable.getCellRenderer(0,
602 Component c = linkUrlTable.prepareRenderer(cellRenderer, 0, column);
603 int cwidth = c.getPreferredSize().width
604 + linkUrlTable.getIntercellSpacing().width;
605 preferredWidth = Math.max(preferredWidth, cwidth);
607 tableColumn.setPreferredWidth(preferredWidth);
611 String proxyTypeString = Cache.getDefault("USE_PROXY", "false");
612 previousProxyType = proxyTypeString;
613 switch (proxyTypeString)
615 case Cache.PROXYTYPE_NONE:
616 proxyType.setSelected(noProxy.getModel(), true);
618 case Cache.PROXYTYPE_SYSTEM:
619 proxyType.setSelected(systemProxy.getModel(), true);
621 case Cache.PROXYTYPE_CUSTOM:
622 proxyType.setSelected(customProxy.getModel(), true);
626 "Incorrect PROXY_TYPE - should be 'none' (clear proxy properties), 'false' (system settings), 'true' (custom settings): "
629 proxyServerHttpTB.setText(Cache.getDefault("PROXY_SERVER", ""));
630 proxyPortHttpTB.setText(Cache.getDefault("PROXY_PORT", ""));
631 proxyServerHttpsTB.setText(Cache.getDefault("PROXY_SERVER_HTTPS", ""));
632 proxyPortHttpsTB.setText(Cache.getDefault("PROXY_PORT_HTTPS", ""));
633 proxyAuth.setSelected(Cache.getDefault("PROXY_AUTH", false));
635 .setText(Cache.getDefault("PROXY_AUTH_USERNAME", ""));
636 // we are not storing or retrieving proxy password from .jalview_properties
637 proxyAuthPasswordPB.setText(Cache.proxyAuthPassword == null ? ""
638 : new String(Cache.proxyAuthPassword));
639 setCustomProxyEnabled();
640 applyProxyButtonEnabled(false);
642 usagestats.setSelected(Cache.getDefault("USAGESTATS", false));
643 // note antisense here: default is true
645 .setSelected(Cache.getProperty("NOQUESTIONNAIRES") == null);
646 versioncheck.setSelected(Cache.getDefault("VERSION_CHECK", true));
649 * Set Output tab defaults
651 setupOutputCombo(epsRendering, "EPS_RENDERING");
652 setupOutputCombo(htmlRendering, "HTML_RENDERING");
653 setupOutputCombo(svgRendering, "SVG_RENDERING");
654 autoIdWidth.setSelected(Cache.getDefault("FIGURE_AUTOIDWIDTH", false));
655 userIdWidth.setEnabled(!autoIdWidth.isSelected());
656 userIdWidthlabel.setEnabled(!autoIdWidth.isSelected());
657 Integer wi = Cache.getIntegerProperty("FIGURE_FIXEDIDWIDTH");
658 userIdWidth.setText(wi == null ? "" : wi.toString());
659 // TODO: refactor to use common enum via FormatAdapter and allow extension
660 // for new flat file formats
661 blcjv.setSelected(Cache.getDefault("BLC_JVSUFFIX", true));
662 clustaljv.setSelected(Cache.getDefault("CLUSTAL_JVSUFFIX", true));
663 fastajv.setSelected(Cache.getDefault("FASTA_JVSUFFIX", true));
664 msfjv.setSelected(Cache.getDefault("MSF_JVSUFFIX", true));
665 pfamjv.setSelected(Cache.getDefault("PFAM_JVSUFFIX", true));
666 pileupjv.setSelected(Cache.getDefault("PILEUP_JVSUFFIX", true));
667 pirjv.setSelected(Cache.getDefault("PIR_JVSUFFIX", true));
668 modellerOutput.setSelected(Cache.getDefault("PIR_MODELLER", false));
670 .setSelected(Cache.getDefault("EXPORT_EMBBED_BIOJSON", true));
673 * Set Editing tab defaults
675 autoCalculateConsCheck
676 .setSelected(Cache.getDefault("AUTO_CALC_CONSENSUS", true));
677 padGaps.setSelected(Cache.getDefault("PAD_GAPS", false));
678 sortByTree.setSelected(Cache.getDefault("SORT_BY_TREE", false));
680 annotations_actionPerformed(null); // update the display of the annotation
684 * Set Backups tab defaults
686 loadLastSavedBackupsOptions();
689 * Set Startup tab defaults
695 * A helper method that sets the items and initial selection in a character
696 * rendering option list (Prompt each time/Lineart/Text)
701 protected void setupOutputCombo(JComboBox<Object> comboBox,
704 comboBox.addItem(promptEachTimeOpt);
705 comboBox.addItem(lineArtOpt);
706 comboBox.addItem(textOpt);
709 * JalviewJS doesn't support Lineart so force it to Text
711 String defaultOption = Platform.isJS() ? "Text"
712 : Cache.getDefault(propertyKey, "Prompt each time");
713 if (defaultOption.equalsIgnoreCase("Text"))
715 comboBox.setSelectedItem(textOpt);
717 else if (defaultOption.equalsIgnoreCase("Lineart"))
719 comboBox.setSelectedItem(lineArtOpt);
723 comboBox.setSelectedItem(promptEachTimeOpt);
728 * Save user selections on the Preferences tabs to the Cache and write out to
734 public void ok_actionPerformed(ActionEvent e)
736 if (!validateSettings())
742 * Set proxy settings first (to be before web services refresh)
747 * Save Visual settings
749 Cache.applicationProperties.setProperty("SHOW_JVSUFFIX",
750 Boolean.toString(seqLimit.isSelected()));
751 Cache.applicationProperties.setProperty("RIGHT_ALIGN_IDS",
752 Boolean.toString(rightAlign.isSelected()));
753 Cache.applicationProperties.setProperty("SHOW_FULLSCREEN",
754 Boolean.toString(fullScreen.isSelected()));
755 Cache.applicationProperties.setProperty("SHOW_OVERVIEW",
756 Boolean.toString(openoverv.isSelected()));
757 Cache.applicationProperties.setProperty("SHOW_ANNOTATIONS",
758 Boolean.toString(annotations.isSelected()));
759 Cache.applicationProperties.setProperty("SHOW_CONSERVATION",
760 Boolean.toString(conservation.isSelected()));
761 Cache.applicationProperties.setProperty("SHOW_QUALITY",
762 Boolean.toString(quality.isSelected()));
763 Cache.applicationProperties.setProperty("SHOW_IDENTITY",
764 Boolean.toString(identity.isSelected()));
766 Cache.applicationProperties.setProperty("GAP_SYMBOL",
767 gapSymbolCB.getSelectedItem().toString());
769 Cache.applicationProperties.setProperty("FONT_NAME",
770 fontNameCB.getSelectedItem().toString());
771 Cache.applicationProperties.setProperty("FONT_STYLE",
772 fontStyleCB.getSelectedItem().toString());
773 Cache.applicationProperties.setProperty("FONT_SIZE",
774 fontSizeCB.getSelectedItem().toString());
776 Cache.applicationProperties.setProperty("ID_ITALICS",
777 Boolean.toString(idItalics.isSelected()));
778 Cache.applicationProperties.setProperty("SHOW_UNCONSERVED",
779 Boolean.toString(showUnconserved.isSelected()));
780 Cache.applicationProperties.setProperty(SHOW_OCCUPANCY,
781 Boolean.toString(showOccupancy.isSelected()));
782 Cache.applicationProperties.setProperty("SHOW_GROUP_CONSENSUS",
783 Boolean.toString(showGroupConsensus.isSelected()));
784 Cache.applicationProperties.setProperty("SHOW_GROUP_CONSERVATION",
785 Boolean.toString(showGroupConservation.isSelected()));
786 Cache.applicationProperties.setProperty("SHOW_CONSENSUS_HISTOGRAM",
787 Boolean.toString(showConsensHistogram.isSelected()));
788 Cache.applicationProperties.setProperty("SHOW_CONSENSUS_LOGO",
789 Boolean.toString(showConsensLogo.isSelected()));
790 Cache.applicationProperties.setProperty("ANTI_ALIAS",
791 Boolean.toString(smoothFont.isSelected()));
792 Cache.applicationProperties.setProperty(SCALE_PROTEIN_TO_CDNA,
793 Boolean.toString(scaleProteinToCdna.isSelected()));
794 Cache.applicationProperties.setProperty("SHOW_NPFEATS_TOOLTIP",
795 Boolean.toString(showNpTooltip.isSelected()));
796 Cache.applicationProperties.setProperty("SHOW_DBREFS_TOOLTIP",
797 Boolean.toString(showDbRefTooltip.isSelected()));
799 Cache.applicationProperties.setProperty("WRAP_ALIGNMENT",
800 Boolean.toString(wrap.isSelected()));
802 Cache.applicationProperties.setProperty("STARTUP_FILE",
803 startupFileTextfield.getText());
804 Cache.applicationProperties.setProperty("SHOW_STARTUP_FILE",
805 Boolean.toString(startupCheckbox.isSelected()));
807 Cache.applicationProperties.setProperty("SORT_ALIGNMENT",
808 sortby.getSelectedItem().toString());
810 // convert description of sort order to enum name for save
811 SequenceAnnotationOrder annSortOrder = SequenceAnnotationOrder
812 .forDescription(sortAnnBy.getSelectedItem().toString());
813 if (annSortOrder != null)
815 Cache.applicationProperties.setProperty(SORT_ANNOTATIONS,
816 annSortOrder.name());
819 final boolean showAutocalcFirst = sortAutocalc.getSelectedIndex() == 0;
820 Cache.applicationProperties.setProperty(SHOW_AUTOCALC_ABOVE,
821 Boolean.valueOf(showAutocalcFirst).toString());
824 * Save Colours settings
826 Cache.applicationProperties.setProperty(DEFAULT_COLOUR_PROT,
827 protColour.getSelectedItem().toString());
828 Cache.applicationProperties.setProperty(DEFAULT_COLOUR_NUC,
829 nucColour.getSelectedItem().toString());
830 Cache.setColourProperty("ANNOTATIONCOLOUR_MIN",
831 minColour.getBackground());
832 Cache.setColourProperty("ANNOTATIONCOLOUR_MAX",
833 maxColour.getBackground());
836 * Save Overview settings
838 Cache.setColourProperty(GAP_COLOUR, gapColour.getBackground());
839 Cache.setColourProperty(HIDDEN_COLOUR, hiddenColour.getBackground());
840 Cache.applicationProperties.setProperty(USE_LEGACY_GAP,
841 Boolean.toString(useLegacyGap.isSelected()));
842 Cache.applicationProperties.setProperty(SHOW_OV_HIDDEN_AT_START,
843 Boolean.toString(showHiddenAtStart.isSelected()));
846 * Save Structure settings
848 Cache.applicationProperties.setProperty(ADD_TEMPFACT_ANN,
849 Boolean.toString(addTempFactor.isSelected()));
850 Cache.applicationProperties.setProperty(ADD_SS_ANN,
851 Boolean.toString(addSecondaryStructure.isSelected()));
852 Cache.applicationProperties.setProperty(STRUCT_FROM_PDB,
853 Boolean.toString(structFromPdb.isSelected()));
854 String viewer = structViewer.getSelectedItem().toString();
855 String viewerPath = structureViewerPath.getText();
856 Cache.applicationProperties.setProperty(STRUCTURE_DISPLAY, viewer);
857 if (viewer.equals(ViewerType.CHIMERA.name()))
859 Cache.setOrRemove(CHIMERA_PATH, viewerPath);
861 else if (viewer.equals(ViewerType.CHIMERAX.name()))
863 Cache.setOrRemove(CHIMERAX_PATH, viewerPath);
865 else if (viewer.equals(ViewerType.PYMOL.name()))
867 Cache.setOrRemove(PYMOL_PATH, viewerPath);
869 Cache.applicationProperties.setProperty("MAP_WITH_SIFTS",
870 Boolean.toString(siftsMapping.isSelected()));
871 SiftsSettings.setMapWithSifts(siftsMapping.isSelected());
874 * Save Output settings
876 Cache.applicationProperties.setProperty("EPS_RENDERING",
877 ((OptionsParam) epsRendering.getSelectedItem()).getCode());
878 Cache.applicationProperties.setProperty("HTML_RENDERING",
879 ((OptionsParam) htmlRendering.getSelectedItem()).getCode());
880 Cache.applicationProperties.setProperty("SVG_RENDERING",
881 ((OptionsParam) svgRendering.getSelectedItem()).getCode());
884 * Save Connections settings
886 // Proxy settings set first (to catch web services)
888 // save user-defined and selected links
889 String menuLinks = sequenceUrlLinks.writeUrlsAsString(true);
890 if (menuLinks.isEmpty())
892 Cache.applicationProperties.remove("SEQUENCE_LINKS");
896 Cache.applicationProperties.setProperty("SEQUENCE_LINKS",
897 menuLinks.toString());
900 String nonMenuLinks = sequenceUrlLinks.writeUrlsAsString(false);
901 if (nonMenuLinks.isEmpty())
903 Cache.applicationProperties.remove("STORED_LINKS");
907 Cache.applicationProperties.setProperty("STORED_LINKS",
908 nonMenuLinks.toString());
911 Cache.applicationProperties.setProperty("DEFAULT_URL",
912 sequenceUrlLinks.getPrimaryUrlId());
914 Cache.setProperty("VERSION_CHECK",
915 Boolean.toString(versioncheck.isSelected()));
916 if (Cache.getProperty("USAGESTATS") != null || usagestats.isSelected())
918 // default is false - we only set this if the user has actively agreed
919 Cache.setProperty("USAGESTATS",
920 Boolean.toString(usagestats.isSelected()));
922 if (!questionnaire.isSelected())
924 Cache.setProperty("NOQUESTIONNAIRES", "true");
928 // special - made easy to edit a property file to disable questionnaires
929 // by just adding the given line
930 Cache.removeProperty("NOQUESTIONNAIRES");
934 * Save Output settings
936 Cache.applicationProperties.setProperty("BLC_JVSUFFIX",
937 Boolean.toString(blcjv.isSelected()));
938 Cache.applicationProperties.setProperty("CLUSTAL_JVSUFFIX",
939 Boolean.toString(clustaljv.isSelected()));
940 Cache.applicationProperties.setProperty("FASTA_JVSUFFIX",
941 Boolean.toString(fastajv.isSelected()));
942 Cache.applicationProperties.setProperty("MSF_JVSUFFIX",
943 Boolean.toString(msfjv.isSelected()));
944 Cache.applicationProperties.setProperty("PFAM_JVSUFFIX",
945 Boolean.toString(pfamjv.isSelected()));
946 Cache.applicationProperties.setProperty("PILEUP_JVSUFFIX",
947 Boolean.toString(pileupjv.isSelected()));
948 Cache.applicationProperties.setProperty("PIR_JVSUFFIX",
949 Boolean.toString(pirjv.isSelected()));
950 Cache.applicationProperties.setProperty("PIR_MODELLER",
951 Boolean.toString(modellerOutput.isSelected()));
952 Cache.applicationProperties.setProperty("EXPORT_EMBBED_BIOJSON",
953 Boolean.toString(embbedBioJSON.isSelected()));
954 jalview.io.PIRFile.useModellerOutput = modellerOutput.isSelected();
956 Cache.applicationProperties.setProperty("FIGURE_AUTOIDWIDTH",
957 Boolean.toString(autoIdWidth.isSelected()));
958 userIdWidth_actionPerformed();
959 Cache.applicationProperties.setProperty("FIGURE_FIXEDIDWIDTH",
960 userIdWidth.getText());
963 * Save Editing settings
965 Cache.applicationProperties.setProperty("AUTO_CALC_CONSENSUS",
966 Boolean.toString(autoCalculateConsCheck.isSelected()));
967 Cache.applicationProperties.setProperty("SORT_BY_TREE",
968 Boolean.toString(sortByTree.isSelected()));
969 Cache.applicationProperties.setProperty("PAD_GAPS",
970 Boolean.toString(padGaps.isSelected()));
972 if (!Platform.isJS())
974 wsPrefs.updateAndRefreshWsMenuConfig(false);
978 * Save Backups settings
980 Cache.applicationProperties.setProperty(BackupFiles.ENABLED,
981 Boolean.toString(enableBackupFiles.isSelected()));
982 int preset = getComboIntStringKey(backupfilesPresetsCombo);
983 Cache.applicationProperties.setProperty(BackupFiles.NS + "_PRESET",
984 Integer.toString(preset));
986 if (preset == BackupFilesPresetEntry.BACKUPFILESSCHEMECUSTOM)
988 BackupFilesPresetEntry customBFPE = getBackupfilesCurrentEntry();
989 BackupFilesPresetEntry.backupfilesPresetEntriesValues.put(
990 BackupFilesPresetEntry.BACKUPFILESSCHEMECUSTOM, customBFPE);
991 Cache.applicationProperties.setProperty(
992 BackupFilesPresetEntry.CUSTOMCONFIG, customBFPE.toString());
995 BackupFilesPresetEntry savedBFPE = BackupFilesPresetEntry.backupfilesPresetEntriesValues
997 Cache.applicationProperties.setProperty(
998 BackupFilesPresetEntry.SAVEDCONFIG, savedBFPE.toString());
1001 * Save Memory Settings
1003 Cache.applicationProperties.setProperty(
1004 MemorySetting.CUSTOMISED_SETTINGS,
1005 Boolean.toString(customiseMemorySetting.isSelected()));
1006 Cache.applicationProperties.setProperty(MemorySetting.MEMORY_JVMMEMPC,
1007 Integer.toString(jvmMemoryPercentSlider.getValue()));
1008 Cache.applicationProperties.setProperty(MemorySetting.MEMORY_JVMMEMMAX,
1009 jvmMemoryMaxTextField.getText());
1012 * save and close Preferences
1015 Cache.saveProperties();
1016 Desktop.instance.doConfigureStructurePrefs();
1019 frame.setClosed(true);
1020 } catch (Exception ex)
1025 public void saveProxySettings()
1027 String newProxyType = customProxy.isSelected() ? Cache.PROXYTYPE_CUSTOM
1028 : noProxy.isSelected() ? Cache.PROXYTYPE_NONE
1029 : Cache.PROXYTYPE_SYSTEM;
1030 Cache.applicationProperties.setProperty("USE_PROXY", newProxyType);
1031 Cache.setOrRemove("PROXY_SERVER", proxyServerHttpTB.getText());
1032 Cache.setOrRemove("PROXY_PORT", proxyPortHttpTB.getText());
1033 Cache.setOrRemove("PROXY_SERVER_HTTPS", proxyServerHttpsTB.getText());
1034 Cache.setOrRemove("PROXY_PORT_HTTPS", proxyPortHttpsTB.getText());
1035 Cache.setOrRemove("PROXY_AUTH",
1036 Boolean.toString(proxyAuth.isSelected()));
1037 Cache.setOrRemove("PROXY_AUTH_USERNAME", proxyAuthUsernameTB.getText());
1038 Cache.proxyAuthPassword = proxyAuthPasswordPB.getPassword();
1039 Cache.setProxyPropertiesFromPreferences(previousProxyType);
1040 if (newProxyType.equals(Cache.PROXYTYPE_CUSTOM)
1041 || !newProxyType.equals(previousProxyType))
1043 // force a re-lookup of ws if proxytype is custom or has changed
1046 previousProxyType = newProxyType;
1050 * Do any necessary validation before saving settings. Return focus to the
1051 * first tab which fails validation.
1055 private boolean validateSettings()
1057 if (!validateStructure())
1059 structureTab.requestFocusInWindow();
1066 protected boolean validateStructure()
1068 return validateViewerPath();
1076 public void startupFileTextfield_mouseClicked()
1078 // TODO: JAL-3048 not needed for Jalview-JS
1079 String fileFormat = Cache.getProperty("DEFAULT_FILE_FORMAT");
1080 JalviewFileChooser chooser = JalviewFileChooser
1081 .forRead(Cache.getProperty("LAST_DIRECTORY"), fileFormat);
1082 chooser.setFileView(new JalviewFileView());
1083 chooser.setDialogTitle(
1084 MessageManager.getString("label.select_startup_file"));
1086 int value = chooser.showOpenDialog(this);
1088 if (value == JalviewFileChooser.APPROVE_OPTION)
1090 FileFormatI format = chooser.getSelectedFormat();
1093 Cache.applicationProperties.setProperty("DEFAULT_FILE_FORMAT",
1096 startupFileTextfield
1097 .setText(chooser.getSelectedFile().getAbsolutePath());
1108 public void cancel_actionPerformed(ActionEvent e)
1112 if (!Platform.isJS())
1114 wsPrefs.updateWsMenuConfig(true);
1115 wsPrefs.refreshWs_actionPerformed(e);
1117 frame.setClosed(true);
1118 } catch (Exception ex)
1130 public void annotations_actionPerformed(ActionEvent e)
1132 conservation.setEnabled(annotations.isSelected());
1133 quality.setEnabled(annotations.isSelected());
1134 identity.setEnabled(annotations.isSelected());
1135 showOccupancy.setEnabled(annotations.isSelected());
1136 showGroupConsensus.setEnabled(annotations.isSelected());
1137 showGroupConservation.setEnabled(annotations.isSelected());
1138 showConsensHistogram.setEnabled(annotations.isSelected()
1139 && (identity.isSelected() || showGroupConsensus.isSelected()));
1140 showConsensLogo.setEnabled(annotations.isSelected()
1141 && (identity.isSelected() || showGroupConsensus.isSelected()));
1145 public void newLink_actionPerformed(ActionEvent e)
1147 GSequenceLink link = new GSequenceLink();
1148 boolean valid = false;
1151 if (JvOptionPane.showInternalConfirmDialog(Desktop.desktop, link,
1152 MessageManager.getString("label.new_sequence_url_link"),
1153 JvOptionPane.OK_CANCEL_OPTION, -1,
1154 null) == JvOptionPane.OK_OPTION)
1156 if (link.checkValid())
1158 if (((UrlLinkTableModel) linkUrlTable.getModel())
1159 .isUniqueName(link.getName()))
1161 ((UrlLinkTableModel) linkUrlTable.getModel())
1162 .insertRow(link.getName(), link.getURL());
1167 link.notifyDuplicate();
1180 public void editLink_actionPerformed(ActionEvent e)
1182 GSequenceLink link = new GSequenceLink();
1184 int index = linkUrlTable.getSelectedRow();
1187 // button no longer enabled if row is not selected
1188 Console.debug("Edit with no row selected in linkUrlTable");
1192 int nameCol = ((UrlLinkTableModel) linkUrlTable.getModel())
1194 int urlCol = ((UrlLinkTableModel) linkUrlTable.getModel())
1196 String oldName = linkUrlTable.getValueAt(index, nameCol).toString();
1197 link.setName(oldName);
1198 link.setURL(linkUrlTable.getValueAt(index, urlCol).toString());
1200 boolean valid = false;
1203 if (JvOptionPane.showInternalConfirmDialog(Desktop.desktop, link,
1204 MessageManager.getString("label.edit_sequence_url_link"),
1205 JvOptionPane.OK_CANCEL_OPTION, -1,
1206 null) == JvOptionPane.OK_OPTION)
1208 if (link.checkValid())
1210 if ((oldName.equals(link.getName()))
1211 || (((UrlLinkTableModel) linkUrlTable.getModel())
1212 .isUniqueName(link.getName())))
1214 linkUrlTable.setValueAt(link.getName(), index, nameCol);
1215 linkUrlTable.setValueAt(link.getURL(), index, urlCol);
1220 link.notifyDuplicate();
1233 public void deleteLink_actionPerformed(ActionEvent e)
1235 int index = linkUrlTable.getSelectedRow();
1236 int modelIndex = -1;
1239 // button no longer enabled if row is not selected
1240 Console.debug("Delete with no row selected in linkUrlTable");
1245 modelIndex = linkUrlTable.convertRowIndexToModel(index);
1248 // make sure we use the model index to delete, and not the table index
1249 ((UrlLinkTableModel) linkUrlTable.getModel()).removeRow(modelIndex);
1256 * jalview.jbgui.GPreferences#showunconserved_actionPerformed(java.awt.event
1260 protected void showunconserved_actionPerformed(ActionEvent e)
1262 // TODO Auto-generated method stub
1263 super.showunconserved_actionPerformed(e);
1266 public static List<String> getGroupURLLinks()
1268 return groupURLLinks;
1272 public void minColour_actionPerformed(JPanel panel)
1274 JalviewColourChooser.showColourChooser(this,
1275 MessageManager.getString("label.select_colour_minimum_value"),
1280 public void maxColour_actionPerformed(JPanel panel)
1282 JalviewColourChooser.showColourChooser(this,
1283 MessageManager.getString("label.select_colour_maximum_value"),
1288 public void gapColour_actionPerformed(JPanel gap)
1290 if (!useLegacyGap.isSelected())
1292 JalviewColourChooser.showColourChooser(this,
1293 MessageManager.getString("label.select_gap_colour"), gap);
1298 public void hiddenColour_actionPerformed(JPanel hidden)
1300 JalviewColourChooser.showColourChooser(this,
1301 MessageManager.getString("label.select_hidden_colour"), hidden);
1305 protected void useLegacyGaps_actionPerformed(ActionEvent e)
1307 boolean enabled = useLegacyGap.isSelected();
1310 gapColour.setBackground(OverviewCanvas.OVERVIEW_DEFAULT_LEGACY_GAP);
1314 gapColour.setBackground(OverviewCanvas.OVERVIEW_DEFAULT_GAP);
1316 gapColour.setEnabled(!enabled);
1317 gapLabel.setEnabled(!enabled);
1321 protected void resetOvDefaults_actionPerformed(ActionEvent e)
1323 useLegacyGap.setSelected(false);
1324 useLegacyGaps_actionPerformed(null);
1325 showHiddenAtStart.setSelected(false);
1326 hiddenColour.setBackground(OverviewCanvas.OVERVIEW_DEFAULT_HIDDEN);
1330 protected void userIdWidth_actionPerformed()
1334 String val = userIdWidth.getText().trim();
1335 if (val.length() > 0)
1337 Integer iw = Integer.parseInt(val);
1338 if (iw.intValue() < 12)
1340 throw new NumberFormatException();
1342 userIdWidth.setText(iw.toString());
1344 } catch (NumberFormatException x)
1346 userIdWidth.setText("");
1347 JvOptionPane.showInternalMessageDialog(Desktop.desktop,
1349 .getString("warn.user_defined_width_requirements"),
1350 MessageManager.getString("label.invalid_id_column_width"),
1351 JvOptionPane.WARNING_MESSAGE);
1356 protected void autoIdWidth_actionPerformed()
1358 userIdWidth.setEnabled(!autoIdWidth.isSelected());
1359 userIdWidthlabel.setEnabled(!autoIdWidth.isSelected());
1363 * Returns true if structure viewer path is to a valid executable, else shows
1364 * an error dialog. Does nothing if the path is empty, as is the case for Jmol
1365 * (built in to Jalview) or when Jalview is left to try default paths.
1367 private boolean validateViewerPath()
1369 if (structureViewerPath.getText().trim().length() > 0)
1371 File f = new File(structureViewerPath.getText());
1372 if (!f.canExecute())
1374 JvOptionPane.showInternalMessageDialog(Desktop.desktop,
1375 MessageManager.getString("label.invalid_viewer_path"),
1376 MessageManager.getString("label.invalid_viewer_path"),
1377 JvOptionPane.ERROR_MESSAGE);
1385 * If Chimera or ChimeraX or Pymol is selected, check it can be found on
1386 * default or user-specified path, if not show a warning/help dialog
1389 protected void structureViewer_actionPerformed(String selectedItem)
1391 if (selectedItem.equals(ViewerType.JMOL.name()))
1393 structureViewerPath.setEnabled(false);
1394 structureViewerPathLabel.setEnabled(false);
1397 boolean found = false;
1398 structureViewerPath.setEnabled(true);
1399 structureViewerPathLabel.setEnabled(true);
1400 structureViewerPathLabel.setText(MessageManager
1401 .formatMessage("label.viewer_path", selectedItem));
1404 * Try user-specified and standard paths for structure viewer executable
1406 String viewerPath = "";
1407 List<String> paths = null;
1410 ViewerType viewerType = ViewerType.valueOf(selectedItem);
1417 viewerPath = Cache.getDefault(CHIMERA_PATH, "");
1418 paths = StructureManager.getChimeraPaths(false);
1421 viewerPath = Cache.getDefault(CHIMERAX_PATH, "");
1422 paths = StructureManager.getChimeraPaths(true);
1425 viewerPath = Cache.getDefault(PYMOL_PATH, "");
1426 paths = PymolManager.getPymolPaths();
1429 } catch (IllegalArgumentException e)
1431 // only valid entries should be in the drop-down
1433 structureViewerPath.setText(viewerPath);
1435 paths.add(0, structureViewerPath.getText());
1436 for (String path : paths)
1438 if (new File(path.trim()).canExecute())
1447 String[] options = { "OK", "Help" };
1448 int showHelp = JvOptionPane.showInternalOptionDialog(Desktop.desktop,
1449 JvSwingUtils.wrapTooltip(true,
1450 MessageManager.getString("label.viewer_missing")),
1451 "", JvOptionPane.YES_NO_OPTION, JvOptionPane.WARNING_MESSAGE,
1452 null, options, options[0]);
1454 if (showHelp == JvOptionPane.NO_OPTION)
1456 this.selectTab(Preferences.TabRef.STRUCTURE_TAB, null);
1459 Help.showHelpWindow(HelpId.StructureViewer);
1460 } catch (HelpSetException e)
1462 e.printStackTrace();
1465 else if (showHelp == JvOptionPane.OK_OPTION)
1467 this.selectTab(Preferences.TabRef.STRUCTURE_TAB, null);
1468 CompletableFuture<Void> cf = CompletableFuture.runAsync(() -> {
1471 for (int i = 0; i < 3; i++)
1473 structureViewerPath.setBackground(Color.PINK);
1475 structureViewerPath.setBackground(Color.WHITE);
1478 } catch (InterruptedException e)
1486 public class OptionsParam
1488 private String name;
1490 private String code;
1492 public OptionsParam(String name, String code)
1498 public String getName()
1503 public void setName(String name)
1508 public String getCode()
1513 public void setCode(String code)
1519 public String toString()
1525 public boolean equals(Object that)
1527 if (!(that instanceof OptionsParam))
1531 return this.code.equalsIgnoreCase(((OptionsParam) that).code);
1535 public int hashCode()
1537 return name.hashCode() + code.hashCode();
1541 private class UrlListSelectionHandler implements ListSelectionListener
1545 public void valueChanged(ListSelectionEvent e)
1547 ListSelectionModel lsm = (ListSelectionModel) e.getSource();
1549 int index = lsm.getMinSelectionIndex();
1552 // no selection, so disable delete/edit buttons
1553 editLink.setEnabled(false);
1554 deleteLink.setEnabled(false);
1557 int modelIndex = linkUrlTable.convertRowIndexToModel(index);
1559 // enable/disable edit and delete link buttons
1560 if (((UrlLinkTableModel) linkUrlTable.getModel())
1561 .isRowDeletable(modelIndex))
1563 deleteLink.setEnabled(true);
1567 deleteLink.setEnabled(false);
1570 if (((UrlLinkTableModel) linkUrlTable.getModel())
1571 .isRowEditable(modelIndex))
1573 editLink.setEnabled(true);
1577 editLink.setEnabled(false);