JAL-3141 Added i18n for the example filenames in Preferences
[jalview.git] / src / jalview / jbgui / GPreferences.java
index f8fd47b..4477620 100755 (executable)
@@ -23,8 +23,10 @@ package jalview.jbgui;
 import jalview.fts.core.FTSDataColumnPreferences;
 import jalview.fts.core.FTSDataColumnPreferences.PreferenceSource;
 import jalview.fts.service.pdb.PDBFTSRestClient;
+import jalview.gui.JalviewBooleanRadioButtons;
 import jalview.gui.JvSwingUtils;
 import jalview.gui.StructureViewer.ViewerType;
+import jalview.io.BackupFilenameFilter;
 import jalview.util.MessageManager;
 
 import java.awt.BorderLayout;
@@ -42,6 +44,7 @@ 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;
 
@@ -57,10 +60,14 @@ import javax.swing.JLabel;
 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;
@@ -183,8 +190,6 @@ public class GPreferences extends JPanel
   /*
    * Overview tab components
    */
-  protected JPanel overviewTab;
-
   protected JPanel gapColour = new JPanel();
 
   protected JPanel hiddenColour = new JPanel();
@@ -266,16 +271,48 @@ public class GPreferences extends JPanel
 
   protected JCheckBox sortByTree = new JCheckBox();
 
-  /*
-   * DAS Settings tab
-   */
-  protected JPanel dasTab = new JPanel();
 
   /*
    * Web Services tab
    */
   protected JPanel wsTab = new JPanel();
 
+  /*
+   * 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 JCheckBox enableBackupFiles = new JCheckBox();
+
+  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();
+
+  protected JSpinner backupfilesRollMaxSpinner = new JSpinner();
+
+  protected JLabel oldBackupFilesLabel = new JLabel();
+
+  protected JalviewBooleanRadioButtons backupfilesConfirmDelete = new JalviewBooleanRadioButtons();
+
+  protected JLabel exampleLabel = new JLabel();
+
+  protected JTextArea backupfilesExampleLabel = new JTextArea();
+
   /**
    * Creates a new GPreferences object.
    */
@@ -318,6 +355,9 @@ public class GPreferences extends JPanel
     tabbedPane.add(initConnectionsTab(),
             MessageManager.getString("label.connections"));
 
+    tabbedPane.add(initBackupsTab(),
+            MessageManager.getString("label.backups"));
+
     tabbedPane.add(initLinksTab(),
             MessageManager.getString("label.urllinks"));
 
@@ -328,12 +368,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());
@@ -489,6 +523,12 @@ public class GPreferences extends JPanel
     embbedBioJSON.setText(MessageManager.getString("label.embbed_biojson"));
     embbedBioJSON.setBounds(new Rectangle(228, 200, 250, 23));
 
+
+    TitledBorder backupFilesBorder = new TitledBorder(
+            MessageManager
+                    .getString("label.backup_files"));
+
+
     jPanel11.add(jLabel1);
     jPanel11.add(blcjv);
     jPanel11.add(clustaljv);
@@ -526,7 +566,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
@@ -1023,18 +1065,22 @@ public class GPreferences extends JPanel
             MessageManager.getString("label.ov_legacy_gap"));
     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);
+    gapLabel.setVerticalTextPosition(SwingConstants.TOP);
     showHiddenAtStart = new JCheckBox(
             MessageManager.getString("label.ov_show_hide_default"));
     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()
     {
@@ -1091,10 +1137,30 @@ public class GPreferences extends JPanel
     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));
 
@@ -1184,14 +1250,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()
     {
@@ -1490,6 +1556,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
@@ -1613,6 +1682,566 @@ public class GPreferences extends JPanel
     return visualTab;
   }
 
+  /**
+   * 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());
+
+    enableBackupFiles.setFont(LABEL_FONT);
+    enableBackupFiles.setText(
+            MessageManager.getString("label.enable_backupfiles"));
+    enableBackupFiles.addActionListener(new ActionListener()
+    {
+      @Override
+      public void actionPerformed(ActionEvent e)
+      {
+        boolean selected = enableBackupFiles.isSelected();
+        // enable other options only when the first is checked
+        backupsOptionsSetEnabled(selected);
+      }
+    });
+
+    GridBagConstraints gbc = new GridBagConstraints();
+    gbc.weightx = 1.0;
+    gbc.weighty = 0.0;
+    gbc.anchor = GridBagConstraints.NORTHWEST;
+    gbc.fill = GridBagConstraints.NONE;
+
+    // enable checkbox 1 row
+    gbc.gridwidth = 1;
+    gbc.gridy = 0;
+    backupsTab.add(enableBackupFiles, gbc);
+
+    initBackupsTabSuffixPanel();
+    initBackupsTabKeepFilesPanel();
+    initBackupsTabFilenameExamplesPanel();
+
+    /*
+    // set widths of the panels to the max one
+    int maxw = suffixPanel.getWidth();
+    if (maxw < keepfilesPanel.getWidth())
+    {
+      maxw = keepfilesPanel.getWidth();
+    }
+    if (maxw < exampleFilesPanel.getWidth())
+    {
+      maxw = exampleFilesPanel.getWidth();
+    }
+    suffixPanel.setSize(suffixPanel.getHeight(), maxw);
+    keepfilesPanel.setSize(keepfilesPanel.getHeight(), maxw);
+    exampleFilesPanel.setSize(exampleFilesPanel.getHeight(), maxw);
+    */
+
+    // whole suffix panel next row
+    gbc.gridy = 1;
+    backupsTab.add(suffixPanel, gbc);
+
+    // keep files panel
+    gbc.gridy = 2;
+    backupsTab.add(keepfilesPanel, gbc);
+
+    // whole examples panel next row
+    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;
+  }
+
+
+  public JPanel initBackupsTabSuffixPanel()
+  {
+    suffixPanel.setBorder(new TitledBorder(
+            MessageManager.getString("label.suffix_format")));
+    suffixPanel.setLayout(new GridBagLayout());
+
+    suffixTemplateLabel
+            .setText(MessageManager.getString("label.suffix_template"));
+    suffixTemplateLabel.setHorizontalAlignment(SwingConstants.LEFT);
+    suffixTemplateLabel.setFont(LABEL_FONT);
+
+    final String tooltip = JvSwingUtils.wrapTooltip(true, MessageManager
+            .getString("label.suffix_template_tooltip"));
+    suffixTemplate.setToolTipText(tooltip);
+    suffixTemplate.addActionListener(new ActionListener()
+    {
+      @Override
+      public void actionPerformed(ActionEvent e)
+      {
+        updateBackupFilesExampleLabel();
+      }
+
+    });
+    KeyListener kl = new KeyListener()
+    {
+      @Override
+      public void keyReleased(KeyEvent e)
+      {
+        updateBackupFilesExampleLabel();
+      }
+
+      @Override
+      public void keyPressed(KeyEvent e)
+      {
+      }
+
+      // disable use of ':'
+      @Override
+      public void keyTyped(KeyEvent e)
+      {
+        char c = e.getKeyChar();
+        if (c == ':')
+        {
+          // don't process ':'
+          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)
+      {
+        updateBackupFilesExampleLabel();
+      }
+    });
+
+    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 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)
+      {
+        boolean selected = backupfilesKeepAll.isSelected();
+        keepRollMaxOptionsEnabled(!selected);
+        updateBackupFilesExampleLabel();
+      }
+    });
+
+    ChangeListener c = new ChangeListener()
+    {
+      @Override
+      public void stateChanged(ChangeEvent e)
+      {
+        updateBackupFilesExampleLabel();
+      }
+
+    };
+    setIntegerSpinner(backupfilesRollMaxSpinner, 1, 999, 4, true, c);
+
+    backupfilesConfirmDelete.setLabels(
+            MessageManager.getString("label.confirm_delete"),
+            MessageManager.getString("label.auto_delete"));
+    // update the enabled section
+    keepRollMaxOptionsEnabled(!backupfilesKeepAll.isSelected());
+
+    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.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.example_filenames")));
+    exampleFilesPanel.setLayout(new GridBagLayout());
+
+    /*
+    exampleLabel.setText(
+            MessageManager.getString("label.suffix_example_filenames"));
+    exampleLabel.setFont(LABEL_FONT);
+    exampleLabel.setHorizontalAlignment(SwingConstants.LEFT);
+    */
+
+    backupfilesExampleLabel.setEditable(false);
+    backupfilesExampleLabel.setPreferredSize(new Dimension(400, 85));
+    backupfilesExampleLabel.setAlignmentX(LEFT_ALIGNMENT);
+    backupfilesExampleLabel.setAlignmentY(TOP_ALIGNMENT);
+    
+    backupfilesExampleLabel.setFont(LABEL_FONT_ITALIC);
+    backupfilesExampleLabel.setBackground(exampleLabel.getBackground());
+
+    updateBackupFilesExampleLabel();
+
+    GridBagConstraints gbc = new GridBagConstraints();
+    gbc.anchor = GridBagConstraints.WEST;
+    gbc.fill = GridBagConstraints.NONE;
+
+    gbc.gridy = 0;
+    /*
+    exampleFilesPanel.add(exampleLabel, gbc);
+    gbc.gridy = 1;
+    */
+    exampleFilesPanel.add(backupfilesExampleLabel, gbc);
+    return exampleFilesPanel;
+  }
+
+  protected void updateBackupFilesExampleLabel()
+  {
+    int exampleindex = 12;
+    String base = MessageManager.getString("label.filename");
+    if (base == null || base.length() > 0)
+    {
+      base = "filename";
+    }
+    String extension = ".fa";
+
+    String suffix = suffixTemplate.getText();
+    int digits = 3;
+    try {
+      suffixDigitsSpinner.commitEdit();
+      digits = (Integer) suffixDigitsSpinner.getValue();
+      digits = digits < 1 ? 1 : digits;
+    } catch (Exception e)
+    {
+      System.out.println("Failed casting (Integer) suffixTemplateSpinner.getValue()");
+    }
+    boolean reverse = suffixReverse.isSelected();
+    boolean keepAll = backupfilesKeepAll.isSelected();
+    int rollMax = 4;
+    try
+    {
+      backupfilesRollMaxSpinner.commitEdit();
+      rollMax = (Integer) backupfilesRollMaxSpinner.getValue();
+      rollMax = rollMax < 1 ? 1 : rollMax;
+    } catch (Exception e)
+    {
+      System.out.println(
+              "Failed casting (Integer) backupfilesRollMaxSpinner.getValue()");
+    }
+
+    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(BackupFilenameFilter.getBackupFilename(index,
+                  base, suffix, digits, extension));
+          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(BackupFilenameFilter.getBackupFilename(index,
+                  base, suffix, digits, extension));
+          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);
+
+  }
+
+  public 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)
+  {
+    oldBackupFilesLabel.setEnabled(enabled);
+    backupfilesRollMaxSpinner.setEnabled(enabled);
+    backupfilesConfirmDelete.setEnabled(enabled);
+
+  }
+
+  protected void backupsOptionsSetEnabled(boolean 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);
+    oldBackupFilesLabel.setEnabled(enabled);
+    backupfilesConfirmDelete.setEnabled(enabled);
+    exampleLabel.setEnabled(enabled);
+    backupfilesExampleLabel.setEnabled(enabled);
+
+    keepRollMaxOptionsEnabled(enabled && !backupfilesKeepAll.isSelected());
+  }
+
   protected void autoIdWidth_actionPerformed()
   {
     // TODO Auto-generated method stub
@@ -1649,13 +2278,10 @@ public class GPreferences extends JPanel
 
   protected void useLegacyGaps_actionPerformed(ActionEvent e)
   {
-    boolean enabled = useLegacyGap.isSelected();
-    if (enabled)
-    {
-      gapColour.setBackground(Color.WHITE);
-    }
-    gapColour.setEnabled(!enabled);
-    gapLabel.setEnabled(!enabled);
+  }
+
+  protected void resetOvDefaults_actionPerformed(ActionEvent e)
+  {
   }
 
   /**