From: Ben Soares Date: Wed, 31 Oct 2018 17:04:19 +0000 (+0000) Subject: JAL-3141 Preferences 'Backups' tab now working. Doesn't fit in default space though... X-Git-Tag: Release_2_11_0~17^2~97^2~46 X-Git-Url: http://source.jalview.org/gitweb/?a=commitdiff_plain;h=c42181ee3d353f05ea889874314c8e83291d8ff5;p=jalview.git JAL-3141 Preferences 'Backups' tab now working. Doesn't fit in default space though -- needs adjusting --- diff --git a/resources/lang/Messages.properties b/resources/lang/Messages.properties index bcd63ae..f7cf83d 100644 --- a/resources/lang/Messages.properties +++ b/resources/lang/Messages.properties @@ -1367,3 +1367,21 @@ label.backupfiles_confirm_delete = Confirm delete label.backupfiles_confirm_delete_old_files = Delete the following older version files? label.backupfiles_confirm_save_file = Confirm save file label.backupfiles_confirm_save_file_backupfiles_roll_wrong = Something possibly went wrong with the backups of this file, write the new file anyway? +label.backups = Backups +label.backup_files = Backup Files +label.enable_backupfiles = Enable backup files +label.suffix_format = Suffix format +label.suffix_template = Suffix template (use %n to represent the backup/version index) +label.suffix_template_tooltip = %n in the template will be replaced by the index number. The suffix will appear before the filename extension. +label.index_digits = Number of digits to use for the index +default.suffix_index_digits_min = 1 +default.suffix_index_digits_max = 6 +label.examples = Examples +label.suffix_example_filenames = Some example filenames using these settings: +label.increment_index = Increment filename indexes (like version numbers). Newest file has largest index. +label.reverse_roll = Reverse and "roll" indexes (like rolled log files). Newest files is always indexed as 1. +label.keep_files = Keep Files +label.keep_all_backup_files = Keep all backup files +label.keep_only_this_number_of_backup_files = Keep only this number of most recent backup files +label.confirm_delete = Confirm deletion of old backup files +label.auto_delete = Automatically delete old backup files diff --git a/resources/lang/Messages_es.properties b/resources/lang/Messages_es.properties index 9498aaf..f3be98c 100644 --- a/resources/lang/Messages_es.properties +++ b/resources/lang/Messages_es.properties @@ -1364,7 +1364,13 @@ label.most_bound_molecules = M label.most_polymer_residues = Más Residuos de Polímeros label.cached_structures = Estructuras en Caché label.free_text_search = Búsqueda de texto libre +# dodgy tranlations by Ben and Google translate -- probably could do better label.backupfiles_confirm_delete = Confirmar borrar label.backupfiles_confirm_delete_old_files = ¿Borrar los siguientes archivos? label.backupfiles_confirm_save_file = Confirmar guardar archivo label.backupfiles_confirm_save_file_backupfiles_roll_wrong = Posiblemente algo está mal con los archivos de copia de seguridad. ¿Guardar el nuevo archivo? +label.backups = Backups +label.backup_files = Backup Files +label.enable_backupfiles = Enable use of backup files +label.suffix_format = Suffix format + diff --git a/src/jalview/gui/JalviewBooleanRadioButtons.java b/src/jalview/gui/JalviewBooleanRadioButtons.java new file mode 100644 index 0000000..1f0c35a --- /dev/null +++ b/src/jalview/gui/JalviewBooleanRadioButtons.java @@ -0,0 +1,107 @@ +package jalview.gui; + +import java.awt.Font; +import java.awt.event.ActionListener; + +import javax.swing.AbstractButton; +import javax.swing.ButtonGroup; +import javax.swing.JRadioButton; + +public class JalviewBooleanRadioButtons extends AbstractButton +{ + private static final Font LABEL_FONT = JvSwingUtils.getLabelFont(); + + private ButtonGroup buttonGroup = new ButtonGroup(); + + private JRadioButton buttonTrue = new JRadioButton(); + + private JRadioButton buttonFalse = new JRadioButton(); + + public JalviewBooleanRadioButtons(boolean value, String trueLabel, + String falseLabel) + { + init(); + this.setLabels(trueLabel, falseLabel); + } + + public JalviewBooleanRadioButtons(boolean value) + { + init(); + setSelected(value); + } + + public JalviewBooleanRadioButtons() + { + init(); + } + + protected void init() + { + buttonTrue.setFont(LABEL_FONT); + buttonFalse.setFont(LABEL_FONT); + buttonGroup.add(buttonTrue); + buttonGroup.add(buttonFalse); + } + + public void setLabels(String trueLabel, String falseLabel) + { + buttonTrue.setText(trueLabel); + buttonFalse.setText(falseLabel); + } + + @Override + public void setSelected(boolean b) + { + buttonFalse.setSelected(!b); + // this should probably happen automatically, no harm in forcing the issue! + // setting them this way round so the last setSelected is on buttonTrue + buttonTrue.setSelected(b); + } + + @Override + public boolean isSelected() + { + // unambiguous selection + return buttonTrue.isSelected() && !buttonFalse.isSelected(); + } + + @Override + public void setEnabled(boolean b) + { + buttonTrue.setEnabled(b); + buttonFalse.setEnabled(b); + } + + @Override + public boolean isEnabled() + { + return buttonTrue.isEnabled() && buttonFalse.isEnabled(); + } + + public JRadioButton getTrueButton() + { + return buttonTrue; + } + + public JRadioButton getFalseButton() + { + return buttonFalse; + } + + @Override + public void addActionListener(ActionListener l) + { + buttonTrue.addActionListener(l); + buttonFalse.addActionListener(l); + } + + public void addTrueActionListener(ActionListener l) + { + buttonTrue.addActionListener(l); + } + + public void addFalseActionListener(ActionListener l) + { + buttonFalse.addActionListener(l); + } +} diff --git a/src/jalview/gui/Preferences.java b/src/jalview/gui/Preferences.java index 7d02fac..8e02c2c 100755 --- a/src/jalview/gui/Preferences.java +++ b/src/jalview/gui/Preferences.java @@ -24,6 +24,7 @@ import jalview.analysis.AnnotationSorter.SequenceAnnotationOrder; import jalview.bin.Cache; import jalview.gui.Help.HelpId; import jalview.gui.StructureViewer.ViewerType; +import jalview.io.BackupFiles; import jalview.io.FileFormatI; import jalview.io.JalviewFileChooser; import jalview.io.JalviewFileView; @@ -794,6 +795,25 @@ public class Preferences extends GPreferences Boolean.toString(padGaps.isSelected())); wsPrefs.updateAndRefreshWsMenuConfig(false); + + /* + * Save Backups settings + */ + Cache.applicationProperties.setProperty(BackupFiles.CONFIRM_DELETE_OLD, + Boolean.toString(backupfilesConfirmDelete.isSelected())); + Cache.applicationProperties.setProperty(BackupFiles.ENABLED, + Boolean.toString(enableBackupFiles.isSelected())); + Cache.applicationProperties.setProperty(BackupFiles.NO_MAX, + Boolean.toString(backupfilesKeepAll.isSelected())); + Cache.applicationProperties.setProperty(BackupFiles.REVERSE_ORDER, + Boolean.toString(suffixReverse.isSelected())); + Cache.applicationProperties.setProperty(BackupFiles.SUFFIX, + suffixTemplate.getText()); + Cache.applicationProperties.setProperty(BackupFiles.ROLL_MAX, + Integer.toString(getSpinnerInt(backupfilesRollMaxSpinner, 4))); + Cache.applicationProperties.setProperty(BackupFiles.SUFFIX_DIGITS, + Integer.toString(getSpinnerInt(suffixDigitsSpinner, 3))); + Cache.saveProperties(); Desktop.instance.doConfigureStructurePrefs(); try diff --git a/src/jalview/io/BackupFilenameFilter.java b/src/jalview/io/BackupFilenameFilter.java index 568f1c9..bb2af1c 100644 --- a/src/jalview/io/BackupFilenameFilter.java +++ b/src/jalview/io/BackupFilenameFilter.java @@ -49,6 +49,16 @@ public class BackupFilenameFilter implements FilenameFilter return ret; } + public static String getBackupFilename(int index, String base, + String template, int digits, String extension) + { + String numString = String.format("%0" + digits + "d", index); + String backupSuffix = template.replaceAll(BackupFiles.NUM_PLACEHOLDER, + numString); + String backupfilename = base + backupSuffix + extension; + return backupfilename; + } + } class BackupFilenameParts @@ -120,17 +130,6 @@ class BackupFilenameParts } - public static String getBackupFilename(int index, String base, - String template, - int digits, String extension) - { - String numString = String.format("%0" + digits + "d", index); - String backupSuffix = template.replaceAll(BackupFiles.NUM_PLACEHOLDER, - numString); - String backupfilename = base + backupSuffix + extension; - return backupfilename; - } - public boolean isBackupFile() { return this.isBackupFile; diff --git a/src/jalview/io/BackupFiles.java b/src/jalview/io/BackupFiles.java index ff23cbf..784d8a1 100644 --- a/src/jalview/io/BackupFiles.java +++ b/src/jalview/io/BackupFiles.java @@ -16,6 +16,7 @@ import java.util.TreeMap; * User configurable options are: * BACKUPFILES_ENABLED - boolean flag as to whether to use this mechanism or act as before, including overwriting files as saved. * BACKUPFILES_SUFFIX - a template to insert just before the file extension. Use '%n' to be replaced by a 0-led SUFFIX_DIGITS long integer. + * BACKUPFILES_NO_MAX - flag to turn off setting a maximum number of backup files to keep. * BACKUPFILES_ROLL_MAX - the maximum number of backupfiles to keep for any one alignment or project file. * BACKUPFILES_SUFFIX_DIGITS - the number of digits to insert replace %n with (e.g. BACKUPFILES_SUFFIX_DIGITS = 3 would make "001", "002", etc) * BACKUPFILES_REVERSE_ORDER - if true then "logfile" style numbering and file rolling will occur. If false then ever-increasing version numbering will occur, but old files will still be deleted if there are more than ROLL_MAX backup files. @@ -32,6 +33,8 @@ public class BackupFiles public static String SUFFIX = NS + "_SUFFIX"; + public static String NO_MAX = NS + "_NO_MAX"; + public static String ROLL_MAX = NS + "_ROLL_MAX"; public static String SUFFIX_DIGITS = NS + "_SUFFIX_DIGITS"; @@ -60,6 +63,9 @@ public class BackupFiles // defaultSuffix - default template to use to append to basename of file private String suffix; + // noMax - flag to turn off a maximum number of files + private boolean noMax; + // defaultMax - default max number of backup files private int max; @@ -81,19 +87,22 @@ public class BackupFiles this(new File(filename)); } - // first time defaults for SUFFIX, ROLL_MAX, SUFFIX_DIGITS and REVERSE_ORDER + // first time defaults for SUFFIX, NO_MAX, ROLL_MAX, SUFFIX_DIGITS and + // REVERSE_ORDER public BackupFiles(File file) { - this(file, "-v" + NUM_PLACEHOLDER, 4, 3, false); + this(file, "-v" + NUM_PLACEHOLDER, false, 4, 3, false); } public BackupFiles(File file, - String defaultSuffix, int defaultMax, int defaultDigits, + String defaultSuffix, boolean defaultNoMax, int defaultMax, + int defaultDigits, boolean defaultReverseOrder) { classInit(); this.file = file; this.suffix = Cache.getDefault(SUFFIX, defaultSuffix); + this.noMax = Cache.getDefault(NO_MAX, defaultNoMax); this.max = Cache.getDefault(ROLL_MAX, defaultMax); this.digits = Cache.getDefault(SUFFIX_DIGITS, defaultDigits); this.reverseOrder = Cache.getDefault(REVERSE_ORDER, @@ -182,6 +191,11 @@ public class BackupFiles return path; } + public static String getNumPlaceHolder() + { + return NUM_PLACEHOLDER; + } + public boolean setWriteSuccess(boolean flag) { boolean old = this.tempFileWriteSuccess; @@ -205,7 +219,7 @@ public class BackupFiles { // file doesn't yet exist or backups are not enabled - if ((!file.exists()) || (!enabled) || (max < -1)) + if ((!file.exists()) || (!enabled) || (max < 0)) { // nothing to do return true; @@ -275,24 +289,28 @@ public class BackupFiles // backup style numbering File lastfile = null; - int tempMax = max; - // max == -1 means no limits + int tempMax = noMax ? -1 : max; + // noMax == true means no limits // look for first "gap" in backupFiles - // if tempMax is -1 at this stage just keep going until there's a gap... + // if tempMax is -1 at this stage just keep going until there's a gap, + // then hopefully tempMax gets set to the right index (a positive + // integer so the loop breaks)... // why do I feel a little uneasy about this loop?.. - for (int i = 1; tempMax < 0 || (max >= 0 && i <= max); i++) + for (int i = 1; tempMax < 0 || i <= max; i++) { - if (!bfTreeMap.containsKey(i)) // first non-existent backupfile + if (!bfTreeMap.containsKey(i)) // first index without existent + // backupfile { tempMax = i; } } - for (int m = 0; m < tempMax; m++) + // for (int m = 0; m < tempMax; m++) + for (int n = tempMax; n > 0; n--) { - int n = tempMax - m; + // int n = tempMax - m; String backupfilename = dir + File.separatorChar - + BackupFilenameParts.getBackupFilename(n, basename, + + BackupFilenameFilter.getBackupFilename(n, basename, suffix, digits, extension); File backupfile_n = new File(backupfilename); @@ -302,7 +320,8 @@ public class BackupFiles continue; } - if (m == 0 && backupfile_n.exists()) + // if (m == 0 && backupfile_n.exists()) + if ((!noMax) && n == tempMax && backupfile_n.exists()) { // move the largest (max) rolled file to a temp file and add to the delete list try @@ -343,8 +362,8 @@ public class BackupFiles bfTreeMap.values().toArray(backupFiles); - // max value of -1 means keep all backup files - if (bfTreeMap.size() >= max && max != -1) + // noMax == true means keep all backup files + if ((!noMax) && bfTreeMap.size() >= max) { // need to delete some files to keep number of backups to designated // max @@ -409,7 +428,7 @@ public class BackupFiles // Let's make the new backup file!! yay, got there at last! String latestBackupFilename = dir + File.separatorChar - + BackupFilenameParts.getBackupFilename(nextIndexNum, basename, + + BackupFilenameFilter.getBackupFilename(nextIndexNum, basename, suffix, digits, extension); File latestBackupFile = new File(latestBackupFilename); ret = ret && file.renameTo(latestBackupFile); diff --git a/src/jalview/jbgui/GPreferences.java b/src/jalview/jbgui/GPreferences.java index 6807382..904f559 100755 --- a/src/jalview/jbgui/GPreferences.java +++ b/src/jalview/jbgui/GPreferences.java @@ -20,11 +20,15 @@ */ 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.JalviewBooleanRadioButtons; import jalview.gui.JvSwingUtils; import jalview.gui.StructureViewer.ViewerType; +import jalview.io.BackupFilenameFilter; +import jalview.io.BackupFiles; import jalview.util.MessageManager; import java.awt.BorderLayout; @@ -42,6 +46,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 +62,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; @@ -270,6 +279,42 @@ public class GPreferences extends JPanel */ 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 + */ + + 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 JalviewBooleanRadioButtons backupfilesConfirmDelete = new JalviewBooleanRadioButtons(); + + protected JLabel exampleLabel = new JLabel(); + + protected JScrollPane exampleScrollPane = new JScrollPane(); + + protected JTextArea backupfilesExampleLabel = new JTextArea(); + /** * Creates a new GPreferences object. */ @@ -312,6 +357,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")); @@ -477,6 +525,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); @@ -1630,6 +1684,509 @@ 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 + .setSelected(Cache.getDefault(BackupFiles.ENABLED, true)); + 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; + + // enable checkbox 1 row + gbc.gridwidth = 1; + gbc.gridy = 0; + backupsTab.add(enableBackupFiles, gbc); + + // whole suffix panel next row + initBackupsTabSuffixPanel(); + gbc.gridy = 1; + backupsTab.add(suffixPanel, gbc); + + // keep files panel + initBackupsTabKeepFilesPanel(); + gbc.gridy = 2; + backupsTab.add(keepfilesPanel, gbc); + + // whole examples panel next row + initBackupsTabFilenameExamplesPanel(); + gbc.gridy = 3; + backupsTab.add(exampleFilesPanel, gbc); + + 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); + + 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); + 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; + 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)); + + suffixReverse.setSelected( + Cache.getDefault(BackupFiles.REVERSE_ORDER, false)); + 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 + .setSelected(Cache.getDefault(BackupFiles.NO_MAX, true)); + 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(); + } + }); + + setIntegerSpinner(backupfilesRollMaxSpinner, 1, 999, + Cache.getDefault(BackupFiles.ROLL_MAX, 3)); + + 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()); + + 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.fill = GridBagConstraints.HORIZONTAL; + 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); + return keepfilesPanel; + } + + private JPanel initBackupsTabFilenameExamplesPanel() + { + exampleFilesPanel.setBorder(new TitledBorder( + MessageManager.getString("label.examples"))); + 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(300, 100)); + backupfilesExampleLabel.setAlignmentX(LEFT_ALIGNMENT); + backupfilesExampleLabel.setAlignmentY(TOP_ALIGNMENT); + + backupfilesExampleLabel.setFont(LABEL_FONT_ITALIC); + backupfilesExampleLabel.setBackground(exampleLabel.getBackground()); + + /* + exampleScrollPane.setBounds(0, 0, 200, 100); + exampleScrollPane.setPreferredSize(new Dimension(800, 800)); + exampleScrollPane.add(backupfilesExampleLabel); + */ + updateBackupFilesExampleLabel(); + + GridBagConstraints gbc = new GridBagConstraints(); + gbc.anchor = GridBagConstraints.WEST; + + gbc.gridy = 0; + exampleFilesPanel.add(exampleLabel, gbc); + gbc.gridy = 1; + exampleFilesPanel.add(backupfilesExampleLabel, gbc); + // exampleFilesPanel.add(exampleScrollPane, gbc); + return exampleFilesPanel; + } + + private void updateBackupFilesExampleLabel() + { + int exampleindex = 12; + String 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 surround = 3; + 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 + surround && index <= max - surround) + { + exampleSB.append("\n..."); + } + else if (index > min + surround && index <= max - surround) + { + // 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) + { + exampleSB.append(" (most recent)"); + } + else if (index == max) + { + 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 + surround && index <= max - surround) + { + exampleSB.append("\n..."); + } + else if (index > min + surround && index <= max - surround) + { + // 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) + { + exampleSB.append(" (oldest)"); + } + else if (index == max) + { + exampleSB.append(" (most recent)"); + } + } + } + + } + + backupfilesExampleLabel.setText(exampleSB.toString()); + } + + protected void setIntegerSpinner(JSpinner s, int min, + int max, int def) + { + // integer spinner for number of digits + if (def > max) + { + max = def; + } + SpinnerModel sModel = new SpinnerNumberModel(def, min, max, 1); + s.setModel(sModel); + + s.addChangeListener(new ChangeListener() + { + @Override + public void stateChanged(ChangeEvent e) + { + updateBackupFilesExampleLabel(); + } + + }); + + } + + 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) + { + backupfilesRollMaxSpinner.setEnabled(enabled); + backupfilesConfirmDelete.setEnabled(enabled); + + } + private 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); + backupfilesConfirmDelete.setEnabled(enabled); + exampleLabel.setEnabled(enabled); + exampleScrollPane.setEnabled(enabled); + backupfilesExampleLabel.setEnabled(enabled); + + keepRollMaxOptionsEnabled(enabled && !backupfilesKeepAll.isSelected()); + } + protected void autoIdWidth_actionPerformed() { // TODO Auto-generated method stub