JAL-3141 Added Presets options in the Backups Preferences pane, with several presets...
[jalview.git] / src / jalview / jbgui / GPreferences.java
index 904f559..58737ee 100755 (executable)
@@ -20,7 +20,6 @@
  */
 package jalview.jbgui;
 
-import jalview.bin.Cache;
 import jalview.fts.core.FTSDataColumnPreferences;
 import jalview.fts.core.FTSDataColumnPreferences.PreferenceSource;
 import jalview.fts.service.pdb.PDBFTSRestClient;
@@ -37,6 +36,7 @@ import java.awt.Component;
 import java.awt.Dimension;
 import java.awt.FlowLayout;
 import java.awt.Font;
+import java.awt.FontMetrics;
 import java.awt.GridBagConstraints;
 import java.awt.GridBagLayout;
 import java.awt.GridLayout;
@@ -49,6 +49,9 @@ import java.awt.event.KeyEvent;
 import java.awt.event.KeyListener;
 import java.awt.event.MouseAdapter;
 import java.awt.event.MouseEvent;
+import java.util.ArrayList;
+import java.util.Map;
+import java.util.HashMap;
 
 import javax.swing.AbstractCellEditor;
 import javax.swing.BorderFactory;
@@ -93,6 +96,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
    */
@@ -282,11 +288,15 @@ public class GPreferences extends JPanel
   /*
    * Backups tab components
    * a lot of these are member variables instead of local variables only so that they
-   * can be enabled/disabled easily
+   * can be enabled/disabled easily in one go
    */
 
   protected JCheckBox enableBackupFiles = new JCheckBox();
 
+  protected JPanel presetsPanel = new JPanel();
+
+  protected JComboBox<IntKeyStringValueEntry> backupfilesPresetsCombo = new JComboBox<>();
+
   protected JPanel suffixPanel = new JPanel();
 
   protected JPanel keepfilesPanel = new JPanel();
@@ -305,13 +315,11 @@ public class GPreferences extends JPanel
 
   protected JalviewBooleanRadioButtons backupfilesKeepAll = new JalviewBooleanRadioButtons();
 
-  protected JSpinner backupfilesRollMaxSpinner = new JSpinner();
+  public JSpinner backupfilesRollMaxSpinner = new JSpinner();
 
-  protected JalviewBooleanRadioButtons backupfilesConfirmDelete = new JalviewBooleanRadioButtons();
-
-  protected JLabel exampleLabel = new JLabel();
+  protected JLabel oldBackupFilesLabel = new JLabel();
 
-  protected JScrollPane exampleScrollPane = new JScrollPane();
+  protected JalviewBooleanRadioButtons backupfilesConfirmDelete = new JalviewBooleanRadioButtons();
 
   protected JTextArea backupfilesExampleLabel = new JTextArea();
 
@@ -1693,14 +1701,24 @@ public class GPreferences extends JPanel
   {
     JPanel backupsTab = new JPanel();
     backupsTab.setBorder(new TitledBorder(MessageManager
-            .getString("label.backup_files")));
+          .getString("label.backup_files")));
     backupsTab.setLayout(new GridBagLayout());
 
-    enableBackupFiles.setFont(LABEL_FONT);
+    GridBagConstraints gbc = new GridBagConstraints();
+    gbc.weightx = 1.0;
+    gbc.weighty = 0.0;
+    gbc.anchor = GridBagConstraints.NORTHWEST;
+    gbc.fill = GridBagConstraints.NONE;
+
+    initBackupsTabPresetsPanel();
+    initBackupsTabSuffixPanel();
+    initBackupsTabKeepFilesPanel();
+    initBackupsTabFilenameExamplesPanel();
+
+    gbc.weightx = 0.5;
+    enableBackupFiles.setFont(LABEL_FONT_BOLD);
     enableBackupFiles.setText(
             MessageManager.getString("label.enable_backupfiles"));
-    enableBackupFiles
-            .setSelected(Cache.getDefault(BackupFiles.ENABLED, true));
     enableBackupFiles.addActionListener(new ActionListener()
     {
       @Override
@@ -1712,36 +1730,141 @@ public class GPreferences extends JPanel
       }
     });
 
-    GridBagConstraints gbc = new GridBagConstraints();
-    gbc.weightx = 1.0;
-    gbc.weighty = 0.0;
-    gbc.anchor = GridBagConstraints.NORTHWEST;
-
     // enable checkbox 1 row
     gbc.gridwidth = 1;
+    gbc.gridx = 0;
     gbc.gridy = 0;
     backupsTab.add(enableBackupFiles, gbc);
 
-    // whole suffix panel next row
-    initBackupsTabSuffixPanel();
+    gbc.gridx = 1;
+    gbc.weightx = 1.0;
+    gbc.gridheight = 2;
+    //gbc.anchor = GridBagConstraints.NORTHEAST;
+    //gbc.fill = GridBagConstraints.HORIZONTAL;
+    backupsTab.add(exampleFilesPanel, gbc);
+
+    gbc.gridx = 0;
     gbc.gridy = 1;
+    backupsTab.add(presetsPanel, gbc);
+
+    gbc.anchor = GridBagConstraints.NORTHWEST;
+    gbc.fill = GridBagConstraints.NONE;
+    gbc.gridwidth = 2;
+    gbc.gridheight = 1;
+    // whole suffix panel next row
+    gbc.gridx = 0;
+    gbc.gridy = 2;
     backupsTab.add(suffixPanel, gbc);
 
     // keep files panel
-    initBackupsTabKeepFilesPanel();
-    gbc.gridy = 2;
+    gbc.gridy = 3;
     backupsTab.add(keepfilesPanel, gbc);
 
+    /*
     // whole examples panel next row
-    initBackupsTabFilenameExamplesPanel();
     gbc.gridy = 3;
     backupsTab.add(exampleFilesPanel, gbc);
 
+    // fill empty space
+    gbc.gridy = 4;
+    gbc.weighty = 1.0;
+    backupsTab.add(new JPanel(), gbc);
+    */
+
+    backupsOptionsSetEnabled(enableBackupFiles.isSelected());
     return backupsTab;
   }
 
+  private 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_everything")),
+    new IntKeyStringValueEntry(4, MessageManager.getString("label.rolled_backups")),
+    // ...
+    // IMPORTANT, keep "Custom" entry with key 0 (even though it appears last)
+    new IntKeyStringValueEntry(0, MessageManager.getString("label.custom"))
+  };
+
+  private final Map<Integer, BackupFilesPresetEntry> backupfilesPresetEntriesValues = new HashMap<Integer, BackupFilesPresetEntry>()
+  {{
+      put(1, new BackupFilesPresetEntry(".v"+BackupFiles.NUM_PLACEHOLDER, 3, false, false, 4, 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()
+  {
+    presetsPanel.setBorder(new TitledBorder(
+            MessageManager.getString("label.presets")));
+
+    for (int i = 0; i < backupfilesPresetEntries.length; i++)
+    {
+        backupfilesPresetsCombo.addItem(backupfilesPresetEntries[i]);
+    }
+
+    backupfilesPresetsCombo.addActionListener(new ActionListener()
+        {
+            @Override
+            public void actionPerformed(ActionEvent e)
+            {
+              backupsTabUpdatePresets();
+            }
+        }
+    );
+
+    presetsPanel.add(backupfilesPresetsCombo);
+    return presetsPanel;
+  }
+
+  private void backupsTabUpdatePresets()
+  {
+    IntKeyStringValueEntry entry = (IntKeyStringValueEntry) backupfilesPresetsCombo.getSelectedItem();
+    int key = entry.getKey();
+    String value = entry.getValue();
+    boolean custom = key==0;
+
+    if (custom)
+    {
+      //backupsSetCustomOptions();
+    } else
+    {
+      if (backupfilesPresetEntriesValues.containsKey(key))
+      {
+        backupsSetOptions(backupfilesPresetEntriesValues.get(key));
+      } else {
+        System.out.println("Preset '"+value+"' not implemented yet");
+      }
+    }
+
+    updateBackupFilesExampleLabel();
+    backupsCustomOptionsSetEnabled(custom);
+  }
+
+  protected int getComboIntStringKey(JComboBox c)
+  {
+    IntKeyStringValueEntry e = (IntKeyStringValueEntry) c.getSelectedItem();
+    return e!=null?e.getKey():0;
+  }
 
-  public JPanel initBackupsTabSuffixPanel()
+  protected void setComboIntStringKey(JComboBox<IntKeyStringValueEntry> c, int key)
+  {
+      for (int i=0; i < c.getItemCount(); i++)
+      {
+          IntKeyStringValueEntry e = c.getItemAt(i);
+          int k = e.getKey();
+          String v = e.getValue();
+          if (e.getKey() == key)
+          {
+              c.setSelectedIndex(i);
+              break;
+          }
+      }
+      backupsTabUpdatePresets();
+  }
+
+  private JPanel initBackupsTabSuffixPanel()
   {
     suffixPanel.setBorder(new TitledBorder(
             MessageManager.getString("label.suffix_format")));
@@ -1752,8 +1875,6 @@ public class GPreferences extends JPanel
     suffixTemplateLabel.setHorizontalAlignment(SwingConstants.LEFT);
     suffixTemplateLabel.setFont(LABEL_FONT);
 
-    String suffix = Cache.getDefault(BackupFiles.SUFFIX, BackupFiles.getNumPlaceHolder());
-    suffixTemplate.setText(suffix);
     final String tooltip = JvSwingUtils.wrapTooltip(true, MessageManager
             .getString("label.suffix_template_tooltip"));
     suffixTemplate.setToolTipText(tooltip);
@@ -1800,32 +1921,18 @@ public class GPreferences extends JPanel
     suffixDigitsLabel.setHorizontalAlignment(SwingConstants.LEFT);
     suffixDigitsLabel.setFont(LABEL_FONT);
     int defaultmin = 1;
-    try
-    {
-      defaultmin = Integer.parseInt(
-              MessageManager.getString("default.suffix_index_digits_min"));
-    } catch (Exception e)
-    {
-      defaultmin = 1;
-      System.out.println(
-              "Exception setting suffix digits min from default.suffix_index_digits_min label, setting to "
-                      + defaultmin);
-    }
     int defaultmax = 6;
-    try {
-      defaultmax = Integer.parseInt(
-              MessageManager.getString("default.suffix_index_digits_max"));
-    } catch (Exception e) {
-      defaultmax = 6;
-      System.out.println(
-              "Exception setting suffix digits max from default.suffix_index_digits_max label, setting to "
-                      + defaultmax);
-    }
-    setIntegerSpinner(suffixDigitsSpinner, defaultmin, defaultmax,
-            Cache.getDefault(BackupFiles.SUFFIX_DIGITS, 3));
+    ChangeListener c = new ChangeListener()
+    {
+      @Override
+      public void stateChanged(ChangeEvent e)
+      {
+        updateBackupFilesExampleLabel();
+      }
+
+    };
+    setIntegerSpinner(suffixDigitsSpinner, defaultmin, defaultmax, 3, c);
 
-    suffixReverse.setSelected(
-            Cache.getDefault(BackupFiles.REVERSE_ORDER, false));
     suffixReverse.setLabels(
             MessageManager.getString("label.reverse_roll"),
             MessageManager.getString("label.increment_index"));
@@ -1879,14 +1986,18 @@ public class GPreferences extends JPanel
     return suffixPanel;
   }
 
+  private void backupfilesKeepAllEnabled(boolean enabled)
+  {
+    backupfilesKeepAll.setEnabled(enabled);
+    keepRollMaxOptionsEnabled();
+  }
+
   private JPanel initBackupsTabKeepFilesPanel()
   {
     keepfilesPanel.setBorder(
             new TitledBorder(MessageManager.getString("label.keep_files")));
     keepfilesPanel.setLayout(new GridBagLayout());
 
-    backupfilesKeepAll
-            .setSelected(Cache.getDefault(BackupFiles.NO_MAX, true));
     backupfilesKeepAll.setLabels(
             MessageManager.getString("label.keep_all_backup_files"),
             MessageManager.getString(
@@ -1905,21 +2016,27 @@ public class GPreferences extends JPanel
       public void actionPerformed(ActionEvent e)
       {
         boolean selected = backupfilesKeepAll.isSelected();
-        keepRollMaxOptionsEnabled(!selected);
+        keepRollMaxOptionsEnabled();
         updateBackupFilesExampleLabel();
       }
     });
 
-    setIntegerSpinner(backupfilesRollMaxSpinner, 1, 999,
-            Cache.getDefault(BackupFiles.ROLL_MAX, 3));
+    ChangeListener c = new ChangeListener()
+    {
+      @Override
+      public void stateChanged(ChangeEvent e)
+      {
+        updateBackupFilesExampleLabel();
+      }
+
+    };
+    setIntegerSpinner(backupfilesRollMaxSpinner, 1, 999, 4, true, c);
 
-    backupfilesConfirmDelete.setSelected(
-            Cache.getDefault(BackupFiles.CONFIRM_DELETE_OLD, true));
     backupfilesConfirmDelete.setLabels(
             MessageManager.getString("label.confirm_delete"),
             MessageManager.getString("label.auto_delete"));
     // update the enabled section
-    keepRollMaxOptionsEnabled(!backupfilesKeepAll.isSelected());
+    keepRollMaxOptionsEnabled();
 
     GridBagConstraints kgbc = new GridBagConstraints();
 
@@ -1942,7 +2059,7 @@ public class GPreferences extends JPanel
     keepfilesPanel.add(backupfilesKeepAll.getFalseButton(), kgbc);
 
     kgbc.gridx = 1;
-    // kgbc.fill = GridBagConstraints.HORIZONTAL;
+    kgbc.gridwidth = GridBagConstraints.REMAINDER;
     keepfilesPanel.add(backupfilesRollMaxSpinner, kgbc);
 
     // third row (indented)
@@ -1953,56 +2070,66 @@ public class GPreferences extends JPanel
     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.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;
   }
 
   private JPanel initBackupsTabFilenameExamplesPanel()
   {
-    exampleFilesPanel.setBorder(new TitledBorder(
-            MessageManager.getString("label.examples")));
+    String title = MessageManager.getString("label.example_filenames");
+    TitledBorder tb = new TitledBorder(title);
+    //tb.setTitleFont(LABEL_FONT);
+    exampleFilesPanel.setBorder(tb);
     exampleFilesPanel.setLayout(new GridBagLayout());
 
-    exampleLabel.setText(
-            MessageManager.getString("label.suffix_example_filenames"));
-    exampleLabel.setFont(LABEL_FONT);
-    exampleLabel.setHorizontalAlignment(SwingConstants.LEFT);
+    //inordinately difficult to get this titledborder the right size for the title
 
     backupfilesExampleLabel.setEditable(false);
-    backupfilesExampleLabel.setPreferredSize(new Dimension(300, 100));
+    backupfilesExampleLabel.setPreferredSize(new Dimension(280, 85));
     backupfilesExampleLabel.setAlignmentX(LEFT_ALIGNMENT);
     backupfilesExampleLabel.setAlignmentY(TOP_ALIGNMENT);
     
     backupfilesExampleLabel.setFont(LABEL_FONT_ITALIC);
-    backupfilesExampleLabel.setBackground(exampleLabel.getBackground());
+    backupfilesExampleLabel
+            .setBackground(exampleFilesPanel.getBackground());
 
-    /*
-    exampleScrollPane.setBounds(0, 0, 200, 100);
-    exampleScrollPane.setPreferredSize(new Dimension(800, 800));
-    exampleScrollPane.add(backupfilesExampleLabel);
-    */
     updateBackupFilesExampleLabel();
+    exampleFilesPanel.setMinimumSize(new Dimension(280, 85));
 
     GridBagConstraints gbc = new GridBagConstraints();
-    gbc.anchor = GridBagConstraints.WEST;
+    gbc.anchor = GridBagConstraints.EAST;
 
     gbc.gridy = 0;
-    exampleFilesPanel.add(exampleLabel, gbc);
-    gbc.gridy = 1;
     exampleFilesPanel.add(backupfilesExampleLabel, gbc);
-    // exampleFilesPanel.add(exampleScrollPane, gbc);
     return exampleFilesPanel;
   }
 
-  private void updateBackupFilesExampleLabel()
+  protected void updateBackupFilesExampleLabel()
   {
     int exampleindex = 12;
-    String base = "filename";
-    String extension = ".fa";
+    String base = MessageManager.getString("label.filename");
+    if (base == null || base.length() > 0)
+    {
+      base = "filename.fa";
+    }
 
     String suffix = suffixTemplate.getText();
     int digits = 3;
@@ -2028,7 +2155,8 @@ public class GPreferences extends JPanel
               "Failed casting (Integer) backupfilesRollMaxSpinner.getValue()");
     }
 
-    int surround = 3;
+    int lowersurround = 2;
+    int uppersurround = 0;
     StringBuilder exampleSB = new StringBuilder();
     boolean firstLine = true;
     if (reverse)
@@ -2038,11 +2166,11 @@ public class GPreferences extends JPanel
       int max = keepAll ? exampleindex : rollMax;
       for (int index = min; index <= max; index++)
       {
-        if (index == min + surround && index <= max - surround)
+        if (index == min + lowersurround && index < max - uppersurround - 1)
         {
           exampleSB.append("\n...");
         }
-        else if (index > min + surround && index <= max - surround)
+        else if (index > min + lowersurround && index < max - uppersurround)
         {
           // nothing
         }
@@ -2057,18 +2185,26 @@ public class GPreferences extends JPanel
             exampleSB.append("\n");
           }
           exampleSB.append(BackupFilenameFilter.getBackupFilename(index,
-                  base, suffix, digits, extension));
+                  base, suffix, digits));
           if (min == max)
           {
             // no extra text needed
           }
           else if (index == min)
           {
-            exampleSB.append(" (most recent)");
+            String newest = MessageManager.getString("label.braced_newest");
+            if (newest != null && newest.length() > 0)
+            {
+              exampleSB.append(" "+newest);
+            }
           }
           else if (index == max)
           {
-            exampleSB.append(" (oldest)");
+            String oldest = MessageManager.getString("label.braced_oldest");
+            if (oldest != null && oldest.length() > 0)
+            {
+              exampleSB.append(" "+oldest);
+            }
           }
         }
       }
@@ -2083,11 +2219,11 @@ public class GPreferences extends JPanel
       for (int index = min; index <= max; index++)
       {
 
-        if (index == min + surround && index <= max - surround)
+        if (index == min + lowersurround && index < max - uppersurround - 1)
         {
           exampleSB.append("\n...");
         }
-        else if (index > min + surround && index <= max - surround)
+        else if (index > min + lowersurround && index < max - uppersurround)
         {
           // nothing
         }
@@ -2102,18 +2238,26 @@ public class GPreferences extends JPanel
             exampleSB.append("\n");
           }
           exampleSB.append(BackupFilenameFilter.getBackupFilename(index,
-                  base, suffix, digits, extension));
+                  base, suffix, digits));
           if (min == max)
           {
             // no extra text needed
           }
           else if (index == min)
           {
-            exampleSB.append(" (oldest)");
+            String oldest = MessageManager.getString("label.braced_oldest");
+            if (oldest != null && oldest.length() > 0)
+            {
+              exampleSB.append(" "+oldest);
+            }
           }
           else if (index == max)
           {
-            exampleSB.append(" (most recent)");
+            String newest = MessageManager.getString("label.braced_newest");
+            if (newest != null && newest.length() > 0)
+            {
+              exampleSB.append(" "+newest);
+            }
           }
         }
       }
@@ -2123,8 +2267,27 @@ public class GPreferences extends JPanel
     backupfilesExampleLabel.setText(exampleSB.toString());
   }
 
-  protected void setIntegerSpinner(JSpinner s, int min,
-          int max, int def)
+  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)
@@ -2134,19 +2297,11 @@ public class GPreferences extends JPanel
     SpinnerModel sModel = new SpinnerNumberModel(def, min, max, 1);
     s.setModel(sModel);
 
-    s.addChangeListener(new ChangeListener()
-    {
-      @Override
-      public void stateChanged(ChangeEvent e)
-      {
-        updateBackupFilesExampleLabel();
-      }
-
-    });
+    s.addChangeListener(c);
 
   }
 
-  public static int getSpinnerInt(JSpinner s, int def)
+  protected static int getSpinnerInt(JSpinner s, int def)
   {
     int i = def;
     try
@@ -2160,31 +2315,70 @@ public class GPreferences extends JPanel
     return i;
   }
 
-  private void keepRollMaxOptionsEnabled(boolean enabled)
+  protected void keepRollMaxOptionsEnabled()
   {
+    keepRollMaxOptionsEnabled(backupfilesKeepAll.isEnabled());
+  }
+
+  protected void keepRollMaxOptionsEnabled(boolean tryEnabled)
+  {
+    boolean enabled = tryEnabled && !backupfilesKeepAll.isSelected();
+    oldBackupFilesLabel.setEnabled(enabled);
     backupfilesRollMaxSpinner.setEnabled(enabled);
     backupfilesConfirmDelete.setEnabled(enabled);
+  }
+
+  protected void backupsCustomOptionsSetEnabled(boolean enabled)
+  {
+      backupsOptionsSetEnabled(enabled, false);
+  }
 
+  protected void backupsOptionsSetEnabled(boolean enabled)
+  {
+      backupsOptionsSetEnabled(enabled, true);
   }
-  private void backupsOptionsSetEnabled(boolean enabled)
+
+  protected void backupsOptionsSetEnabled(boolean enabled, boolean all)
   {
+
+    if (all)
+    {
+        presetsPanel.setEnabled(enabled);
+        exampleFilesPanel.setEnabled(enabled);
+
+        backupfilesPresetsCombo.setEnabled(enabled);
+        backupfilesExampleLabel.setEnabled(enabled);
+    }
     suffixPanel.setEnabled(enabled);
     keepfilesPanel.setEnabled(enabled);
-    exampleFilesPanel.setEnabled(enabled);
 
     suffixTemplate.setEnabled(enabled);
     suffixTemplateLabel.setEnabled(enabled);
     suffixDigitsLabel.setEnabled(enabled);
     suffixDigitsSpinner.setEnabled(enabled);
     suffixReverse.setEnabled(enabled);
-    backupfilesKeepAll.setEnabled(enabled);
-    backupfilesRollMaxSpinner.setEnabled(enabled);
-    backupfilesConfirmDelete.setEnabled(enabled);
-    exampleLabel.setEnabled(enabled);
-    exampleScrollPane.setEnabled(enabled);
-    backupfilesExampleLabel.setEnabled(enabled);
+    oldBackupFilesLabel.setEnabled(enabled);
+    backupfilesKeepAllEnabled(enabled);
 
-    keepRollMaxOptionsEnabled(enabled && !backupfilesKeepAll.isSelected());
+    if (enabled && all)
+    {
+      backupsTabUpdatePresets();
+    }
+  }
+
+  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()
@@ -2372,3 +2566,44 @@ 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;
+  }
+}