X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;f=src%2Fjalview%2Fjbgui%2FGPreferences.java;h=87cc87b3dab038c031763bc1414a2a61461eb463;hb=961e285f3c6769a3d68152a7784d85f6e814cafb;hp=a58569a57258fec0a266d1bb4eeba308091137d6;hpb=75d0279984e769ace9e422376b4104a4522cf0c3;p=jalview.git diff --git a/src/jalview/jbgui/GPreferences.java b/src/jalview/jbgui/GPreferences.java index a58569a..87cc87b 100755 --- a/src/jalview/jbgui/GPreferences.java +++ b/src/jalview/jbgui/GPreferences.java @@ -20,11 +20,17 @@ */ package jalview.jbgui; +import jalview.bin.Cache; import jalview.fts.core.FTSDataColumnPreferences; import jalview.fts.core.FTSDataColumnPreferences.PreferenceSource; import jalview.fts.service.pdb.PDBFTSRestClient; +import jalview.gui.Desktop; +import jalview.gui.JalviewBooleanRadioButtons; +import jalview.gui.JvOptionPane; import jalview.gui.JvSwingUtils; import jalview.gui.StructureViewer.ViewerType; +import jalview.io.BackupFilenameParts; +import jalview.io.BackupFiles; import jalview.util.MessageManager; import java.awt.BorderLayout; @@ -42,8 +48,11 @@ import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.FocusEvent; import java.awt.event.KeyEvent; +import java.awt.event.KeyListener; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; +import java.util.HashMap; +import java.util.Map; import javax.swing.AbstractCellEditor; import javax.swing.BorderFactory; @@ -54,13 +63,18 @@ import javax.swing.JCheckBox; import javax.swing.JComboBox; import javax.swing.JFileChooser; import javax.swing.JLabel; +import javax.swing.JList; import javax.swing.JPanel; import javax.swing.JRadioButton; import javax.swing.JScrollPane; +import javax.swing.JSpinner; import javax.swing.JTabbedPane; import javax.swing.JTable; +import javax.swing.JTextArea; import javax.swing.JTextField; import javax.swing.ListSelectionModel; +import javax.swing.SpinnerModel; +import javax.swing.SpinnerNumberModel; import javax.swing.SwingConstants; import javax.swing.border.Border; import javax.swing.border.EmptyBorder; @@ -84,6 +98,9 @@ public class GPreferences extends JPanel private static final Font LABEL_FONT_ITALIC = JvSwingUtils .getLabelFont(false, true); + private static final Font LABEL_FONT_BOLD = JvSwingUtils + .getLabelFont(true, false); + /* * Visual tab components */ @@ -180,9 +197,18 @@ public class GPreferences extends JPanel protected JComboBox nucColour = new JComboBox<>(); - protected JButton gapColour = new JButton(); + /* + * Overview tab components + */ + protected JPanel gapColour = new JPanel(); + + protected JPanel hiddenColour = new JPanel(); - protected JButton hiddenColour = new JButton(); + protected JCheckBox useLegacyGap; + + protected JCheckBox showHiddenAtStart; + + protected JLabel gapLabel; /* * Connections tab components @@ -256,14 +282,49 @@ public class GPreferences extends JPanel protected JCheckBox sortByTree = new JCheckBox(); /* - * DAS Settings tab + * Web Services tab */ - protected JPanel dasTab = new JPanel(); + protected JPanel wsTab = new JPanel(); /* - * Web Services tab + * Backups tab components + * a lot of these are member variables instead of local variables only so that they + * can be enabled/disabled easily in one go */ - protected JPanel wsTab = new JPanel(); + + protected JCheckBox enableBackupFiles = new JCheckBox(); + + protected JPanel presetsPanel = new JPanel(); + + protected JButton revertButton = new JButton(); + + protected JComboBox backupfilesPresetsCombo = new JComboBox<>(); + + protected JPanel suffixPanel = new JPanel(); + + protected JPanel keepfilesPanel = new JPanel(); + + protected JPanel exampleFilesPanel = new JPanel(); + + protected JTextField suffixTemplate = new JTextField(null, 8); + + protected JLabel suffixTemplateLabel = new JLabel(); + + protected JLabel suffixDigitsLabel = new JLabel(); + + protected JSpinner suffixDigitsSpinner = new JSpinner(); + + protected JalviewBooleanRadioButtons suffixReverse = new JalviewBooleanRadioButtons(); + + protected JalviewBooleanRadioButtons backupfilesKeepAll = new JalviewBooleanRadioButtons(); + + public JSpinner backupfilesRollMaxSpinner = new JSpinner(); + + protected JLabel oldBackupFilesLabel = new JLabel(); + + protected JalviewBooleanRadioButtons backupfilesConfirmDelete = new JalviewBooleanRadioButtons(); + + protected JTextArea backupfilesExampleLabel = new JTextArea(); /** * Creates a new GPreferences object. @@ -298,12 +359,18 @@ public class GPreferences extends JPanel tabbedPane.add(initColoursTab(), MessageManager.getString("label.colours")); + tabbedPane.add(initOverviewTab(), + MessageManager.getString("label.overview")); + tabbedPane.add(initStructureTab(), MessageManager.getString("label.structure")); tabbedPane.add(initConnectionsTab(), MessageManager.getString("label.connections")); + tabbedPane.add(initBackupsTab(), + MessageManager.getString("label.backups")); + tabbedPane.add(initLinksTab(), MessageManager.getString("label.urllinks")); @@ -314,12 +381,6 @@ public class GPreferences extends JPanel MessageManager.getString("label.editing")); /* - * See DasSourceBrowser for the real work of configuring this tab. - */ - dasTab.setLayout(new BorderLayout()); - tabbedPane.add(dasTab, MessageManager.getString("label.das_settings")); - - /* * See WsPreferences for the real work of configuring this tab. */ wsTab.setLayout(new BorderLayout()); @@ -512,7 +573,9 @@ public class GPreferences extends JPanel MessageManager.getString("label.default_browser_unix")); defaultBrowser.setFont(LABEL_FONT); defaultBrowser.setText(""); - + final String tooltip = JvSwingUtils.wrapTooltip(true, + MessageManager.getString("label.double_click_to_browse")); + defaultBrowser.setToolTipText(tooltip); defaultBrowser.addMouseListener(new MouseAdapter() { @Override @@ -580,6 +643,7 @@ public class GPreferences extends JPanel linkTab.setLayout(new GridBagLayout()); // Set up table for Url links + linkUrlTable.getTableHeader().setReorderingAllowed(false); linkUrlTable.setFillsViewportHeight(true); linkUrlTable.setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS); linkUrlTable.setAutoCreateRowSorter(true); @@ -892,10 +956,9 @@ public class GPreferences extends JPanel private JPanel initColoursTab() { JPanel coloursTab = new JPanel(); - JPanel alignmentPanel = new JPanel(); - alignmentPanel.setBorder(new TitledBorder( + coloursTab.setBorder(new TitledBorder( MessageManager.getString("action.open_new_alignment"))); - alignmentPanel.setLayout(new FlowLayout()); + coloursTab.setLayout(new FlowLayout()); JLabel mincolourLabel = new JLabel(); mincolourLabel.setFont(LABEL_FONT); mincolourLabel.setHorizontalAlignment(SwingConstants.RIGHT); @@ -934,7 +997,7 @@ public class GPreferences extends JPanel protColourLabel.setHorizontalAlignment(SwingConstants.LEFT); protColourLabel.setText( MessageManager.getString("label.prot_alignment_colour") + " "); - JvSwingUtils.addtoLayout(alignmentPanel, + JvSwingUtils.addtoLayout(coloursTab, MessageManager .getString("label.default_colour_scheme_for_alignment"), protColourLabel, protColour); @@ -946,7 +1009,7 @@ public class GPreferences extends JPanel nucColourLabel.setHorizontalAlignment(SwingConstants.LEFT); nucColourLabel.setText( MessageManager.getString("label.nuc_alignment_colour") + " "); - JvSwingUtils.addtoLayout(alignmentPanel, + JvSwingUtils.addtoLayout(coloursTab, MessageManager .getString("label.default_colour_scheme_for_alignment"), nucColourLabel, nucColour); @@ -963,15 +1026,25 @@ public class GPreferences extends JPanel MessageManager.getString( "label.default_maximum_colour_annotation_shading"), maxcolourLabel, maxColour); - alignmentPanel.add(annotationShding); // , FlowLayout.LEFT); + coloursTab.add(annotationShding); // , FlowLayout.LEFT); + return coloursTab; + } + /** + * Initialises the Overview tabbed panel. + * + * @return + */ + private JPanel initOverviewTab() + { JPanel overviewPanel = new JPanel(); overviewPanel.setBorder(new TitledBorder( MessageManager.getString("label.overview_settings"))); - overviewPanel.setLayout(new FlowLayout()); gapColour.setFont(LABEL_FONT); - gapColour.setBorder(BorderFactory.createEtchedBorder()); + // fixing the border colours stops apparent colour bleed from the panel + gapColour.setBorder( + BorderFactory.createEtchedBorder(Color.white, Color.lightGray)); gapColour.setPreferredSize(new Dimension(40, 20)); gapColour.addMouseListener(new MouseAdapter() { @@ -983,7 +1056,9 @@ public class GPreferences extends JPanel }); hiddenColour.setFont(LABEL_FONT); - hiddenColour.setBorder(BorderFactory.createEtchedBorder()); + // fixing the border colours stops apparent colour bleed from the panel + hiddenColour.setBorder( + BorderFactory.createEtchedBorder(Color.white, Color.lightGray)); hiddenColour.setPreferredSize(new Dimension(40, 20)); hiddenColour.addMouseListener(new MouseAdapter() { @@ -993,23 +1068,35 @@ public class GPreferences extends JPanel hiddenColour_actionPerformed(hiddenColour); } }); - - JCheckBox gapSetting = new JCheckBox( + + useLegacyGap = new JCheckBox( MessageManager.getString("label.ov_legacy_gap")); - gapSetting.setFont(LABEL_FONT); - gapSetting.setHorizontalAlignment(SwingConstants.LEFT); - JLabel gapLabel = new JLabel( - MessageManager.getString("label.gap_colour")); + useLegacyGap.setFont(LABEL_FONT); + useLegacyGap.setHorizontalAlignment(SwingConstants.LEFT); + useLegacyGap.setVerticalTextPosition(SwingConstants.TOP); + gapLabel = new JLabel(MessageManager.getString("label.gap_colour")); gapLabel.setFont(LABEL_FONT); gapLabel.setHorizontalAlignment(SwingConstants.LEFT); - JCheckBox hiddenSetting = new JCheckBox( + gapLabel.setVerticalTextPosition(SwingConstants.TOP); + showHiddenAtStart = new JCheckBox( MessageManager.getString("label.ov_show_hide_default")); - hiddenSetting.setFont(LABEL_FONT); - hiddenSetting.setHorizontalAlignment(SwingConstants.LEFT); + showHiddenAtStart.setFont(LABEL_FONT); + showHiddenAtStart.setHorizontalAlignment(SwingConstants.LEFT); + showHiddenAtStart.setVerticalTextPosition(SwingConstants.TOP); JLabel hiddenLabel = new JLabel( MessageManager.getString("label.hidden_colour")); hiddenLabel.setFont(LABEL_FONT); hiddenLabel.setHorizontalAlignment(SwingConstants.LEFT); + hiddenLabel.setVerticalTextPosition(SwingConstants.TOP); + + useLegacyGap.addActionListener(new ActionListener() + { + @Override + public void actionPerformed(ActionEvent e) + { + useLegacyGaps_actionPerformed(e); + } + }); overviewPanel.setLayout(new GridBagLayout()); GridBagConstraints c1 = new GridBagConstraints(); @@ -1018,20 +1105,22 @@ public class GPreferences extends JPanel c1.gridx = 0; c1.gridy = 0; c1.weightx = 1; + c1.ipady = 20; c1.anchor = GridBagConstraints.FIRST_LINE_START; - overviewPanel.add(gapSetting, c1); + overviewPanel.add(useLegacyGap, c1); GridBagConstraints c2 = new GridBagConstraints(); c2.fill = GridBagConstraints.HORIZONTAL; c2.gridx = 1; c2.gridy = 0; - c2.insets = new Insets(0, 5, 0, 5); + c2.insets = new Insets(0, 15, 0, 10); overviewPanel.add(gapLabel, c2); GridBagConstraints c3 = new GridBagConstraints(); c3.fill = GridBagConstraints.HORIZONTAL; c3.gridx = 2; c3.gridy = 0; + c3.insets = new Insets(0, 0, 0, 15); overviewPanel.add(gapColour, c3); GridBagConstraints c4 = new GridBagConstraints(); @@ -1039,32 +1128,50 @@ public class GPreferences extends JPanel c4.gridx = 0; c4.gridy = 1; c4.weightx = 1; - overviewPanel.add(hiddenSetting, c4); + overviewPanel.add(showHiddenAtStart, c4); GridBagConstraints c5 = new GridBagConstraints(); c5.fill = GridBagConstraints.HORIZONTAL; c5.gridx = 1; c5.gridy = 1; - c5.insets = new Insets(0, 5, 0, 5); + c5.insets = new Insets(0, 15, 0, 10); overviewPanel.add(hiddenLabel, c5); GridBagConstraints c6 = new GridBagConstraints(); c6.fill = GridBagConstraints.HORIZONTAL; c6.gridx = 2; c6.gridy = 1; + c6.insets = new Insets(0, 0, 0, 15); overviewPanel.add(hiddenColour, c6); + JButton resetButton = new JButton( + MessageManager.getString("label.reset_to_defaults")); + + resetButton.addActionListener(new ActionListener() + { + @Override + public void actionPerformed(ActionEvent e) + { + resetOvDefaults_actionPerformed(e); + } + }); + + GridBagConstraints c7 = new GridBagConstraints(); + c7.fill = GridBagConstraints.NONE; + c7.gridx = 0; + c7.gridy = 2; + c7.insets = new Insets(10, 0, 0, 0); + c7.anchor = GridBagConstraints.WEST; + overviewPanel.add(resetButton, c7); + // Add padding so the panel doesn't look ridiculous JPanel spacePanel = new JPanel(); overviewPanel.add(spacePanel, - new GridBagConstraints(0, 2, 1, 1, 1.0, 1.0, + new GridBagConstraints(0, 3, 1, 1, 1.0, 1.0, GridBagConstraints.WEST, GridBagConstraints.BOTH, new Insets(0, 0, 0, 5), 0, 0)); - coloursTab.setLayout(new GridLayout(2, 1)); - coloursTab.add(alignmentPanel); - coloursTab.add(overviewPanel); - return coloursTab; + return overviewPanel; } /** @@ -1150,14 +1257,14 @@ public class GPreferences extends JPanel pathLabel.setFont(new java.awt.Font("SansSerif", 0, 11)); pathLabel.setHorizontalAlignment(SwingConstants.LEFT); pathLabel.setText(MessageManager.getString("label.chimera_path")); - final String tooltip = JvSwingUtils.wrapTooltip(true, - MessageManager.getString("label.chimera_path_tip")); - pathLabel.setToolTipText(tooltip); pathLabel.setBounds(new Rectangle(10, ypos, 140, height)); structureTab.add(pathLabel); chimeraPath.setFont(LABEL_FONT); chimeraPath.setText(""); + final String tooltip = JvSwingUtils.wrapTooltip(true, + MessageManager.getString("label.chimera_path_tip")); + chimeraPath.setToolTipText(tooltip); chimeraPath.setBounds(new Rectangle(160, ypos, 300, height)); chimeraPath.addMouseListener(new MouseAdapter() { @@ -1456,6 +1563,9 @@ public class GPreferences extends JPanel startupCheckbox.setSelected(true); startupFileTextfield.setFont(LABEL_FONT); startupFileTextfield.setBounds(new Rectangle(172, 310, 330, 20)); + final String tooltip = JvSwingUtils.wrapTooltip(true, + MessageManager.getString("label.double_click_to_browse")); + startupFileTextfield.setToolTipText(tooltip); startupFileTextfield.addMouseListener(new MouseAdapter() { @Override @@ -1579,6 +1689,846 @@ public class GPreferences extends JPanel return visualTab; } + /** + * Load the saved Backups options EXCEPT "Enabled" and "Scheme" + */ + + protected void loadLastSavedBackupsOptions() + { + enableBackupFiles + .setSelected(Cache.getDefault(BackupFiles.ENABLED, true)); + setComboIntStringKey(backupfilesPresetsCombo, + Cache.getDefault(BackupFiles.NS + "_PRESET", 1)); + suffixTemplate.setText(Cache.getDefault(BackupFiles.SUFFIX, + ".bak" + BackupFiles.NUM_PLACEHOLDER)); + suffixDigitsSpinner + .setValue(Cache.getDefault(BackupFiles.SUFFIX_DIGITS, 3)); + suffixReverse.setSelected( + Cache.getDefault(BackupFiles.REVERSE_ORDER, false)); + backupfilesKeepAll + .setSelected(Cache.getDefault(BackupFiles.NO_MAX, false)); + backupfilesRollMaxSpinner + .setValue(Cache.getDefault(BackupFiles.ROLL_MAX, 3)); + backupfilesConfirmDelete.setSelected( + Cache.getDefault(BackupFiles.CONFIRM_DELETE_OLD, true)); + + backupsOptionsSetEnabled(); + updateBackupFilesExampleLabel(); + } + + private boolean warnAboutSuffixReverseChange() + { + boolean savedSuffixReverse = Cache.getDefault(BackupFiles.REVERSE_ORDER, + false); + int savedSuffixDigits = Cache.getDefault(BackupFiles.SUFFIX_DIGITS, 3); + String savedSuffixTemplate = Cache.getDefault(BackupFiles.SUFFIX, + ".bak" + BackupFiles.NUM_PLACEHOLDER); + + boolean nowSuffixReverse = suffixReverse.isSelected(); + int nowSuffixDigits = getSpinnerInt(suffixDigitsSpinner, 3); + String nowSuffixTemplate = suffixTemplate.getText(); + return nowSuffixReverse != savedSuffixReverse + && nowSuffixDigits == savedSuffixDigits + && nowSuffixTemplate != null + && nowSuffixTemplate.equals(savedSuffixTemplate); + } + + /** + * Initialises the Backups tabbed panel. + * + * @return + */ + private JPanel initBackupsTab() + { + JPanel backupsTab = new JPanel(); + backupsTab.setBorder(new TitledBorder( + MessageManager.getString("label.backup_files"))); + backupsTab.setLayout(new GridBagLayout()); + + GridBagConstraints gbc = new GridBagConstraints(); + gbc.weightx = 0.0; + gbc.weighty = 0.0; + gbc.anchor = GridBagConstraints.FIRST_LINE_START; + gbc.fill = GridBagConstraints.NONE; + + initBackupsTabPresetsPanel(); + initBackupsTabSuffixPanel(); + initBackupsTabKeepFilesPanel(); + initBackupsTabFilenameExamplesPanel(); + + enableBackupFiles.setFont(LABEL_FONT_BOLD); + enableBackupFiles + .setText(MessageManager.getString("label.enable_backupfiles")); + enableBackupFiles.addActionListener(new ActionListener() + { + @Override + public void actionPerformed(ActionEvent e) + { + // enable other options only when the first is checked + backupsOptionsSetEnabled(); + } + }); + + + // enable checkbox 1 col + gbc.gridwidth = 1; + gbc.gridheight = 1; + gbc.gridx = 0; + gbc.gridy = 0; // row 0 + backupsTab.add(enableBackupFiles, gbc); + + // summary of scheme box (over two rows) + gbc.gridx = 1; + gbc.weightx = 0.0; + gbc.gridheight = 2; + gbc.anchor = GridBagConstraints.FIRST_LINE_END; + gbc.fill = GridBagConstraints.BOTH; + backupsTab.add(exampleFilesPanel, gbc); + gbc.gridheight = 1; + gbc.anchor = GridBagConstraints.FIRST_LINE_START; + gbc.fill = GridBagConstraints.NONE; + + // fill empty space on right + gbc.gridx++; + gbc.weightx = 1.0; + backupsTab.add(new JPanel(), gbc); + + // schemes box + gbc.weightx = 0.0; + gbc.gridx = 0; + gbc.gridy++; // row 1 + backupsTab.add(presetsPanel, gbc); + + // gbc.anchor = GridBagConstraints.NORTHWEST; + // now using whole row + gbc.gridwidth = 2; + gbc.gridheight = 1; + // keep files box + gbc.gridx = 0; + gbc.gridy++; // row 2 + backupsTab.add(keepfilesPanel, gbc); + + // filename strategy box + gbc.gridy++; // row 3 + backupsTab.add(suffixPanel, gbc); + + // fill empty space + gbc.gridy++; // row 4 + gbc.weighty = 1.0; + backupsTab.add(new JPanel(), gbc); + + backupsOptionsSetEnabled(); + return backupsTab; + } + + protected static final int BACKUPFILESSCHEMECUSTOMISE = 0; + + private static final IntKeyStringValueEntry[] backupfilesPresetEntries = { + new IntKeyStringValueEntry(1, + MessageManager.getString("label.default")), + new IntKeyStringValueEntry(2, + MessageManager.getString("label.single_file")), + new IntKeyStringValueEntry(3, + MessageManager.getString("label.keep_all_versions")), + new IntKeyStringValueEntry(4, + MessageManager.getString("label.rolled_backups")), + // ... + // IMPORTANT, keep "Custom" entry with key 0 (even though it appears last) + new IntKeyStringValueEntry(BACKUPFILESSCHEMECUSTOMISE, + MessageManager.getString("label.customise")) }; + + private static final Map backupfilesPresetEntriesValues = new HashMap() + { + /** + * + */ + private static final long serialVersionUID = 125L; + + { + put(1, new BackupFilesPresetEntry( + ".bak" + BackupFiles.NUM_PLACEHOLDER, 3, false, false, 3, + false)); + put(2, new BackupFilesPresetEntry("~", 1, false, false, 1, false)); + put(3, new BackupFilesPresetEntry(".v" + BackupFiles.NUM_PLACEHOLDER, + 3, false, true, 10, true)); + put(4, new BackupFilesPresetEntry( + "_bak." + BackupFiles.NUM_PLACEHOLDER, 1, true, false, 9, + false)); + } + }; + + private JPanel initBackupsTabPresetsPanel() + { + + String title = MessageManager.getString("label.schemes"); + // TitledBorder tb = new TitledBorder(new EmptyBorder(0, 0, 0, 0), title); + // TitledBorder tb = new TitledBorder(title); + // tb.setTitleFont(LABEL_FONT); + // presetsPanel.setBorder(tb); + + presetsPanel.setLayout(new GridBagLayout()); + + GridBagConstraints gbc = new GridBagConstraints(); + gbc.weightx = 0.0; + gbc.weighty = 0.0; + gbc.anchor = GridBagConstraints.BASELINE_LEADING; + gbc.fill = GridBagConstraints.NONE; + gbc.gridwidth = 1; + gbc.gridheight = 1; + + // "Scheme: " + gbc.gridx = 0; + gbc.gridy = 0; + presetsPanel.add(new JLabel(title + ":"), gbc); + + for (int i = 0; i < backupfilesPresetEntries.length; i++) + { + backupfilesPresetsCombo.addItem(backupfilesPresetEntries[i]); + } + + // put "Previously saved scheme" item in italics (it's not really + // selectable, as such -- it deselects itself when selected) and + // "Customise" in bold + backupfilesPresetsCombo + .setRenderer(new BackupFilesPresetsComboBoxRenderer()); + backupfilesPresetsCombo.addActionListener(new ActionListener() + { + @Override + public void actionPerformed(ActionEvent e) + { + backupsTabUpdatePresets(); + } + }); + + // dropdown list of preset schemes + gbc.gridx = 1; + presetsPanel.add(backupfilesPresetsCombo, gbc); + + revertButton.setText(MessageManager.getString("label.cancel_changes")); + revertButton.addActionListener(new ActionListener() + { + @Override + public void actionPerformed(ActionEvent e) + { + loadLastSavedBackupsOptions(); + } + + }); + revertButton.setFont(LABEL_FONT); + + // "Cancel changes" button (aligned with combo box above) + gbc.gridx = 1; + gbc.gridy++; + presetsPanel.add(revertButton, gbc); + + return presetsPanel; + } + + private JPanel initBackupsTabFilenameExamplesPanel() + { + String title = MessageManager + .getString("label.summary_of_backups_scheme"); + TitledBorder tb = new TitledBorder(title); + exampleFilesPanel.setBorder(tb); + exampleFilesPanel.setLayout(new GridBagLayout()); + + + backupfilesExampleLabel.setEditable(false); + backupfilesExampleLabel + .setBackground(exampleFilesPanel.getBackground()); + + updateBackupFilesExampleLabel(); + + GridBagConstraints gbc = new GridBagConstraints(); + gbc.weightx = 1.0; + gbc.weighty = 1.0; + gbc.fill = GridBagConstraints.NONE; + gbc.anchor = GridBagConstraints.FIRST_LINE_START; + + exampleFilesPanel.add(backupfilesExampleLabel, gbc); + return exampleFilesPanel; + } + + private void backupsTabUpdatePresets() + { + IntKeyStringValueEntry entry = (IntKeyStringValueEntry) backupfilesPresetsCombo + .getSelectedItem(); + int key = entry.getKey(); + String value = entry.getValue(); + + // BACKUPFILESSCHEMECUSTOMISE (==0) reserved for "Custom" + if (key != BACKUPFILESSCHEMECUSTOMISE) + { + if (backupfilesPresetEntriesValues.containsKey(key)) + { + backupsSetOptions(backupfilesPresetEntriesValues.get(key)); + } + else + { + System.out.println("Preset '" + value + "' not implemented"); + } + } + + backupfilesCustomOptionsSetEnabled(); + updateBackupFilesExampleLabel(); + } + + protected int getComboIntStringKey(JComboBox c) + { + IntKeyStringValueEntry e = (IntKeyStringValueEntry) c.getSelectedItem(); + return e != null ? e.getKey() : 0; + } + + protected void setComboIntStringKey(JComboBox c, + int key) + { + for (int i = 0; i < c.getItemCount(); i++) + { + IntKeyStringValueEntry e = c.getItemAt(i); + if (e.getKey() == key) + { + c.setSelectedIndex(i); + break; + } + } + backupsTabUpdatePresets(); + } + + private JPanel initBackupsTabSuffixPanel() + { + suffixPanel.setBorder(new TitledBorder( + MessageManager.getString("label.backup_filename_strategy"))); + suffixPanel.setLayout(new GridBagLayout()); + + suffixTemplateLabel + .setText(MessageManager.getString("label.append_to_filename")); + suffixTemplateLabel.setHorizontalAlignment(SwingConstants.LEFT); + suffixTemplateLabel.setFont(LABEL_FONT); + + final String tooltip = JvSwingUtils.wrapTooltip(true, + MessageManager.getString("label.append_to_filename_tooltip")); + suffixTemplate.setToolTipText(tooltip); + suffixTemplate.addActionListener(new ActionListener() + { + @Override + public void actionPerformed(ActionEvent e) + { + updateBackupFilesExampleLabel(); + backupfilesCustomOptionsSetEnabled(); + } + + }); + KeyListener kl = new KeyListener() + { + @Override + public void keyReleased(KeyEvent e) + { + updateBackupFilesExampleLabel(); + backupfilesCustomOptionsSetEnabled(); + } + + @Override + public void keyPressed(KeyEvent e) + { + } + + // disable use of ':' or '/' or '\' + @Override + public void keyTyped(KeyEvent e) + { + char c = e.getKeyChar(); + if (c == ':' || c == '/' || c == '\\') + { + // don't process ':' or '/' or '\' + e.consume(); + } + } + + }; + suffixTemplate.addKeyListener(kl); + + // digits spinner + suffixDigitsLabel + .setText(MessageManager.getString("label.index_digits")); + suffixDigitsLabel.setHorizontalAlignment(SwingConstants.LEFT); + suffixDigitsLabel.setFont(LABEL_FONT); + int defaultmin = 1; + int defaultmax = 6; + ChangeListener c = new ChangeListener() + { + @Override + public void stateChanged(ChangeEvent e) + { + updateBackupFilesExampleLabel(); + } + + }; + setIntegerSpinner(suffixDigitsSpinner, defaultmin, defaultmax, 3, c); + + suffixReverse.setLabels(MessageManager.getString("label.reverse_roll"), + MessageManager.getString("label.increment_index")); + suffixReverse.addActionListener(new ActionListener() + { + @Override + public void actionPerformed(ActionEvent e) + { + boolean okay = true; + if (warnAboutSuffixReverseChange()) + { + // Warning popup + okay = confirmSuffixReverseChange(); + } + if (okay) + { + updateBackupFilesExampleLabel(); + } + else + { + boolean savedSuffixReverse = Cache + .getDefault(BackupFiles.REVERSE_ORDER, false); + suffixReverse.setSelected(savedSuffixReverse); + } + } + }); + + GridBagConstraints sgbc = new GridBagConstraints(); + + // first row (template text box) + sgbc.anchor = GridBagConstraints.WEST; + sgbc.gridx = 0; + sgbc.gridy = 0; + sgbc.gridwidth = 1; + sgbc.gridheight = 1; + sgbc.weightx = 1.0; + sgbc.weighty = 0.0; + sgbc.fill = GridBagConstraints.NONE; + suffixPanel.add(suffixTemplateLabel, sgbc); + + sgbc.gridx = 1; + sgbc.fill = GridBagConstraints.HORIZONTAL; + suffixPanel.add(suffixTemplate, sgbc); + + // second row (number of digits spinner) + sgbc.gridy = 1; + + sgbc.gridx = 0; + sgbc.fill = GridBagConstraints.NONE; + suffixPanel.add(suffixDigitsLabel, sgbc); + + sgbc.gridx = 1; + sgbc.fill = GridBagConstraints.HORIZONTAL; + suffixPanel.add(suffixDigitsSpinner, sgbc); + + // third row (forward order radio selection) + sgbc.gridx = 0; + sgbc.gridy = 2; + sgbc.gridwidth = GridBagConstraints.REMAINDER; + sgbc.fill = GridBagConstraints.HORIZONTAL; + suffixPanel.add(suffixReverse.getFalseButton(), sgbc); + + // fourth row (reverse order radio selection) + sgbc.gridy = 3; + suffixPanel.add(suffixReverse.getTrueButton(), sgbc); + return suffixPanel; + } + + private boolean confirmSuffixReverseChange() + { + boolean ret = false; + String warningMessage = MessageManager + .getString("label.warning_confirm_change_reverse"); + int confirm = JvOptionPane.showConfirmDialog(Desktop.desktop, + warningMessage, + MessageManager.getString("label.change_increment_decrement"), + JvOptionPane.YES_NO_OPTION, JvOptionPane.WARNING_MESSAGE); + + ret = (confirm == JvOptionPane.YES_OPTION); + return ret; + } + + private JPanel initBackupsTabKeepFilesPanel() + { + keepfilesPanel.setBorder( + new TitledBorder(MessageManager.getString("label.keep_files"))); + keepfilesPanel.setLayout(new GridBagLayout()); + + backupfilesKeepAll.setLabels( + MessageManager.getString("label.keep_all_backup_files"), + MessageManager.getString( + "label.keep_only_this_number_of_backup_files")); + backupfilesKeepAll.addTrueActionListener(new ActionListener() + { + @Override + public void actionPerformed(ActionEvent e) + { + updateBackupFilesExampleLabel(); + } + }); + backupfilesKeepAll.addActionListener(new ActionListener() + { + @Override + public void actionPerformed(ActionEvent e) + { + keepRollMaxOptionsEnabled(); + updateBackupFilesExampleLabel(); + } + }); + + ChangeListener c = new ChangeListener() + { + @Override + public void stateChanged(ChangeEvent e) + { + updateBackupFilesExampleLabel(); + } + + }; + setIntegerSpinner(backupfilesRollMaxSpinner, 1, 999, 4, true, c); + + backupfilesConfirmDelete.setLabels( + MessageManager.getString("label.always_ask"), + MessageManager.getString("label.auto_delete")); + // update the enabled section + keepRollMaxOptionsEnabled(); + + GridBagConstraints kgbc = new GridBagConstraints(); + + // first row (template text box) + kgbc.anchor = GridBagConstraints.WEST; + kgbc.gridx = 0; + kgbc.gridy = 0; + kgbc.gridwidth = GridBagConstraints.REMAINDER; + kgbc.gridheight = 1; + kgbc.weightx = 1.0; + kgbc.weighty = 0.0; + kgbc.fill = GridBagConstraints.HORIZONTAL; + keepfilesPanel.add(backupfilesKeepAll.getTrueButton(), kgbc); + + // second row + kgbc.gridy = 1; + + kgbc.gridx = 0; + kgbc.gridwidth = GridBagConstraints.RELATIVE; + keepfilesPanel.add(backupfilesKeepAll.getFalseButton(), kgbc); + + kgbc.gridx = 1; + kgbc.gridwidth = GridBagConstraints.REMAINDER; + keepfilesPanel.add(backupfilesRollMaxSpinner, kgbc); + + // third row (indented) + kgbc.gridy = 2; + kgbc.insets = new Insets(0, 20, 0, 0); + + kgbc.gridx = 0; + kgbc.gridwidth = GridBagConstraints.REMAINDER; + kgbc.fill = GridBagConstraints.HORIZONTAL; + kgbc.weightx = 1.0; + /* + keepfilesPanel.add(backupfilesConfirmDelete.getTrueButton(), kgbc); + + // fourth row (indented) + kgbc.gridy = 3; + keepfilesPanel.add(backupfilesConfirmDelete.getFalseButton(), kgbc); + */ + + JPanel jp = new JPanel(); + jp.setLayout(new FlowLayout()); + oldBackupFilesLabel + .setText(MessageManager + .getString("label.autodelete_old_backup_files")); + oldBackupFilesLabel.setFont(LABEL_FONT); + oldBackupFilesLabel.setHorizontalAlignment(SwingConstants.LEFT); + jp.add(oldBackupFilesLabel); + jp.add(backupfilesConfirmDelete.getTrueButton()); + jp.add(backupfilesConfirmDelete.getFalseButton()); + keepfilesPanel.add(jp, kgbc); + + return keepfilesPanel; + } + + protected void updateBackupFilesExampleLabel() + { + int exampleindex = 12; + String base = MessageManager.getString("label.filename") + ".fa"; + if (base == null || base.length() == 0) + { + base = "file_name.fa"; + } + + boolean reverse = suffixReverse.isSelected(); + boolean keepAll = backupfilesKeepAll.isSelected(); + int rollMax = 4; + String suffix = suffixTemplate.getText(); + int digits = 3; + + backupfilesExampleLabel.setFont(LABEL_FONT_ITALIC); + if (suffix == null || suffix.length() == 0) + { + backupfilesExampleLabel + .setText(MessageManager.getString("label.no_backup_files")); + backupfilesExampleLabel.setFont(LABEL_FONT_BOLD); + return; + } + + rollMax = getSpinnerInt(backupfilesRollMaxSpinner, 4); + rollMax = rollMax < 1 ? 1 : rollMax; + + if (suffix.indexOf(BackupFiles.NUM_PLACEHOLDER) == -1) + { + rollMax = 1; + } + + digits = getSpinnerInt(suffixDigitsSpinner, 3); + digits = digits < 1 ? 1 : digits; + + int lowersurround = 2; + int uppersurround = 0; + StringBuilder exampleSB = new StringBuilder(); + boolean firstLine = true; + if (reverse) + { + + int min = 1; + int max = keepAll ? exampleindex : rollMax; + for (int index = min; index <= max; index++) + { + if (index == min + lowersurround && index < max - uppersurround - 1) + { + exampleSB.append("\n..."); + } + else if (index > min + lowersurround && index < max - uppersurround) + { + // nothing + } + else + { + if (firstLine) + { + firstLine = false; + } + else + { + exampleSB.append("\n"); + } + exampleSB.append(BackupFilenameParts.getBackupFilename(index, + base, suffix, digits)); + if (min == max) + { + // no extra text needed + } + else if (index == min) + { + String newest = MessageManager.getString("label.braced_newest"); + if (newest != null && newest.length() > 0) + { + exampleSB.append(" " + newest); + } + } + else if (index == max) + { + String oldest = MessageManager.getString("label.braced_oldest"); + if (oldest != null && oldest.length() > 0) + { + exampleSB.append(" " + oldest); + } + } + } + } + } + else + { + + int min = (keepAll || exampleindex - rollMax < 0) ? 1 + : exampleindex - rollMax + 1; + int max = exampleindex; + + for (int index = min; index <= max; index++) + { + + if (index == min + lowersurround && index < max - uppersurround - 1) + { + exampleSB.append("\n..."); + } + else if (index > min + lowersurround && index < max - uppersurround) + { + // nothing + } + else + { + if (firstLine) + { + firstLine = false; + } + else + { + exampleSB.append("\n"); + } + exampleSB.append(BackupFilenameParts.getBackupFilename(index, + base, suffix, digits)); + if (min == max) + { + // no extra text needed + } + else if (index == min) + { + String oldest = MessageManager.getString("label.braced_oldest"); + if (oldest != null && oldest.length() > 0) + { + exampleSB.append(" " + oldest); + } + } + else if (index == max) + { + String newest = MessageManager.getString("label.braced_newest"); + if (newest != null && newest.length() > 0) + { + exampleSB.append(" " + newest); + } + } + } + } + + } + + backupfilesExampleLabel.setText(exampleSB.toString()); + } + + protected void setIntegerSpinner(JSpinner s, int min, int max, int def, + boolean useExistingVal, ChangeListener c) + { + int i = def; + if (useExistingVal) + { + try + { + i = Integer.parseInt((String) s.getValue()); + } catch (Exception e) + { + System.out.println( + "Exception casting the initial value of s.getValue()"); + } + } + + setIntegerSpinner(s, min, max, i, c); + } + + protected void setIntegerSpinner(JSpinner s, int min, int max, int def, + ChangeListener c) + { + // integer spinner for number of digits + if (def > max) + { + max = def; + } + SpinnerModel sModel = new SpinnerNumberModel(def, min, max, 1); + s.setModel(sModel); + + s.addChangeListener(c); + + } + + protected static int getSpinnerInt(JSpinner s, int def) + { + int i = def; + try + { + s.commitEdit(); + i = (Integer) s.getValue(); + } catch (Exception e) + { + System.out.println("Failed casting (Integer) JSpinner s.getValue()"); + } + return i; + } + + private void keepRollMaxOptionsEnabled() + { + boolean enabled = backupfilesKeepAll.isEnabled() + && !backupfilesKeepAll.isSelected(); + oldBackupFilesLabel.setEnabled(enabled); + backupfilesRollMaxSpinner.setEnabled(enabled); + backupfilesConfirmDelete.setEnabled(enabled); + } + + private void backupfilesKeepAllSetEnabled(boolean tryEnabled) + { + boolean enabled = tryEnabled && enableBackupFiles.isSelected() + && getComboIntStringKey(backupfilesPresetsCombo) == 0 + && suffixTemplate.getText() + .indexOf(BackupFiles.NUM_PLACEHOLDER) > -1; + keepfilesPanel.setEnabled(enabled); + backupfilesKeepAll.setEnabled(enabled); + oldBackupFilesLabel.setEnabled(enabled); + keepRollMaxOptionsEnabled(); + } + + private void backupfilesSuffixTemplateDigitsSetEnabled() + { + boolean enabled = suffixTemplate.isEnabled() && suffixTemplate.getText() + .indexOf(BackupFiles.NUM_PLACEHOLDER) > -1; + suffixDigitsLabel.setEnabled(enabled); + suffixDigitsSpinner.setEnabled(enabled); + suffixReverse.setEnabled(enabled); + } + + private void backupfilesSuffixTemplateSetEnabled(boolean tryEnabled) + { + boolean enabled = tryEnabled && enableBackupFiles.isSelected() + && getComboIntStringKey(backupfilesPresetsCombo) == 0; + suffixPanel.setEnabled(enabled); + suffixTemplateLabel.setEnabled(enabled); + suffixTemplate.setEnabled(enabled); + backupfilesSuffixTemplateDigitsSetEnabled(); + } + + protected void backupfilesCustomOptionsSetEnabled() + { + int scheme = getComboIntStringKey(backupfilesPresetsCombo); + boolean enabled = scheme == 0 && enableBackupFiles.isSelected(); + + backupfilesSuffixTemplateSetEnabled(enabled); + backupfilesKeepAllSetEnabled(enabled); + } + + private void backupfilesSummarySetEnabled() + { + boolean enabled = enableBackupFiles.isSelected(); + backupfilesExampleLabel.setEnabled(enabled); + exampleFilesPanel.setEnabled(enabled); + } + + private void backupfilesPresetsSetEnabled() + { + boolean enabled = enableBackupFiles.isSelected(); + presetsPanel.setEnabled(enabled); + backupfilesPresetsCombo.setEnabled(enabled); + } + + protected void backupsOptionsSetEnabled() + { + backupfilesPresetsSetEnabled(); + backupfilesSummarySetEnabled(); + backupfilesCustomOptionsSetEnabled(); + } + + protected void backupsSetOptions(String suffix, int digits, + boolean reverse, boolean keepAll, int rollMax, + boolean confirmDelete) + { + suffixTemplate.setText(suffix); + suffixDigitsSpinner.setValue(digits); + suffixReverse.setSelected(reverse); + backupfilesKeepAll.setSelected(keepAll); + backupfilesRollMaxSpinner.setValue(rollMax); + backupfilesConfirmDelete.setSelected(confirmDelete); + } + + protected void backupsSetOptions(BackupFilesPresetEntry p) + { + backupsSetOptions(p.suffix, p.digits, p.reverse, p.keepAll, p.rollMax, + p.confirmDelete); + } + protected void autoIdWidth_actionPerformed() { // TODO Auto-generated method stub @@ -1599,11 +2549,11 @@ public class GPreferences extends JPanel { } - protected void gapColour_actionPerformed(JButton btn) + protected void gapColour_actionPerformed(JPanel panel) { } - protected void hiddenColour_actionPerformed(JButton btn) + protected void hiddenColour_actionPerformed(JPanel panel) { } @@ -1613,6 +2563,14 @@ public class GPreferences extends JPanel } + protected void useLegacyGaps_actionPerformed(ActionEvent e) + { + } + + protected void resetOvDefaults_actionPerformed(ActionEvent e) + { + } + /** * DOCUMENT ME! * @@ -1756,3 +2714,86 @@ public class GPreferences extends JPanel } } + +class IntKeyStringValueEntry +{ + int k; + + String v; + + public IntKeyStringValueEntry(int k, String v) + { + this.k = k; + this.v = v; + } + + @Override + public String toString() + { + return this.getValue(); + } + + public int getKey() + { + return k; + } + + public String getValue() + { + return v; + } +} + +class BackupFilesPresetEntry +{ + String suffix; + + int digits; + + boolean reverse; + + boolean keepAll; + + int rollMax; + + boolean confirmDelete; + + public BackupFilesPresetEntry(String suffix, int digits, boolean reverse, + boolean keepAll, int rollMax, boolean confirmDelete) + { + this.suffix = suffix; + this.digits = digits; + this.reverse = reverse; + this.keepAll = keepAll; + this.rollMax = rollMax; + this.confirmDelete = confirmDelete; + } +} + +class BackupFilesPresetsComboBoxRenderer extends DefaultListCellRenderer +{ + /** + * + */ + private static final long serialVersionUID = 88L; + + @Override + public Component getListCellRendererComponent(JList list, Object value, + int index, boolean isSelected, boolean cellHasFocus) + { + super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); + + try { + IntKeyStringValueEntry e = (IntKeyStringValueEntry) value; + if (e.getKey() == GPreferences.BACKUPFILESSCHEMECUSTOMISE) + { + // "Customise" item + this.setFont(this.getFont().deriveFont(Font.BOLD)); + } + } catch (Exception e) { + return this; + } + + return this; + } +}