From af90a850a4ae13afede5b540052599afd15ac98f Mon Sep 17 00:00:00 2001 From: Denis Molony Date: Mon, 12 Dec 2016 18:43:19 +1100 Subject: [PATCH] Checksums optional --- .../diskbrowser/applefile/MerlinSource.java | 2 +- .../diskbrowser/disk/DiskFactory.java | 2 +- .../diskbrowser/dos/AbstractCatalogEntry.java | 12 +++--- .../diskbrowser/duplicates/DiskDetails.java | 18 ++++---- .../duplicates/DiskTableModel.java | 2 +- .../duplicates/DuplicateHandler.java | 29 +++++++------ .../duplicates/DuplicateWindow.java | 10 +++-- .../diskbrowser/duplicates/ProgressState.java | 4 +- .../diskbrowser/gui/DuplicateAction.java | 20 +++++++-- .../bytezone/diskbrowser/gui/TreeBuilder.java | 16 +------- .../diskbrowser/prodos/FileEntry.java | 19 ++++----- .../diskbrowser/utilities/FormatRenderer.java | 41 +++++++++++++++++++ .../diskbrowser/utilities/NumberRenderer.java | 29 +++++++++++++ 13 files changed, 140 insertions(+), 64 deletions(-) create mode 100644 src/com/bytezone/diskbrowser/utilities/FormatRenderer.java create mode 100644 src/com/bytezone/diskbrowser/utilities/NumberRenderer.java diff --git a/src/com/bytezone/diskbrowser/applefile/MerlinSource.java b/src/com/bytezone/diskbrowser/applefile/MerlinSource.java index 51f900d..ad6dda3 100644 --- a/src/com/bytezone/diskbrowser/applefile/MerlinSource.java +++ b/src/com/bytezone/diskbrowser/applefile/MerlinSource.java @@ -30,7 +30,7 @@ public class MerlinSource extends AbstractFile StringBuilder text = new StringBuilder (); text.append ("Name : " + name + "\n"); - if (recordLength > 0) // a prodos text file + if (recordLength > 0) // a prodos text file { text.append (String.format ("Record length : %,8d%n", recordLength)); text.append (String.format ("End of file : %,8d%n", eof)); diff --git a/src/com/bytezone/diskbrowser/disk/DiskFactory.java b/src/com/bytezone/diskbrowser/disk/DiskFactory.java index ac21e13..8006c26 100755 --- a/src/com/bytezone/diskbrowser/disk/DiskFactory.java +++ b/src/com/bytezone/diskbrowser/disk/DiskFactory.java @@ -89,7 +89,7 @@ public class DiskFactory suffix = "dsk"; compressed = true; } - catch (IOException e) + catch (IOException e) // can get EOFException: Unexpected end of ZLIB input stream { e.printStackTrace (); return null; diff --git a/src/com/bytezone/diskbrowser/dos/AbstractCatalogEntry.java b/src/com/bytezone/diskbrowser/dos/AbstractCatalogEntry.java index 41ac3bb..02f800b 100644 --- a/src/com/bytezone/diskbrowser/dos/AbstractCatalogEntry.java +++ b/src/com/bytezone/diskbrowser/dos/AbstractCatalogEntry.java @@ -60,7 +60,7 @@ abstract class AbstractCatalogEntry implements AppleFileSource name = getName ("", entryBuffer); // CATALOG command only formats the LO byte - see Beneath Apple DOS pp4-6 String base = String.format ("%s%s %03d ", (locked) ? "*" : " ", getFileType (), - (entryBuffer[33] & 0xFF)); + (entryBuffer[33] & 0xFF)); catalogName = getName (base, entryBuffer); } @@ -198,6 +198,8 @@ abstract class AbstractCatalogEntry implements AppleFileSource if (ShapeTable.isShapeTable (exactBuffer)) appleFile = new ShapeTable (name, exactBuffer); + else if (name.endsWith (".S")) + appleFile = new MerlinSource (name, exactBuffer); else if (HiResImage.isGif (exactBuffer)) appleFile = new HiResImage (name, exactBuffer); else if (loadAddress == 0x2000 || loadAddress == 0x4000) @@ -210,16 +212,12 @@ abstract class AbstractCatalogEntry implements AppleFileSource else appleFile = new AssemblerProgram (name, exactBuffer, loadAddress); } - else if (name.endsWith (".S")) - appleFile = new MerlinSource (name, exactBuffer); else { appleFile = new AssemblerProgram (name, exactBuffer, loadAddress); - // System.out.printf ("%d %d%n", exactBuffer.length, reportedLength); if ((exactBuffer.length + 4) < buffer.length) - ((AssemblerProgram) appleFile) - .setExtraBuffer (buffer, exactBuffer.length + 4, - buffer.length - (exactBuffer.length + 4)); + ((AssemblerProgram) appleFile).setExtraBuffer (buffer, + exactBuffer.length + 4, buffer.length - (exactBuffer.length + 4)); } // } break; diff --git a/src/com/bytezone/diskbrowser/duplicates/DiskDetails.java b/src/com/bytezone/diskbrowser/duplicates/DiskDetails.java index 543e951..2ccd967 100644 --- a/src/com/bytezone/diskbrowser/duplicates/DiskDetails.java +++ b/src/com/bytezone/diskbrowser/duplicates/DiskDetails.java @@ -19,12 +19,16 @@ public class DiskDetails private boolean isDuplicateName; private boolean isDuplicateChecksum; - public DiskDetails (File file, String rootName, String shortName) + public DiskDetails (File file, String rootName, String shortName, boolean doChecksum) { this.file = file; this.rootName = rootName; this.shortName = shortName; - checksum = ComputeCRC32.getChecksumValue (file); + + if (doChecksum) + checksum = ComputeCRC32.getChecksumValue (file); + else + checksum = 0; } public File getFile () @@ -85,11 +89,11 @@ public class DiskDetails return checksum; } - public boolean delete () - { - // return file.delete (); - return false; - } + // public boolean delete () + // { + // // return file.delete (); + // return false; + // } @Override public String toString () diff --git a/src/com/bytezone/diskbrowser/duplicates/DiskTableModel.java b/src/com/bytezone/diskbrowser/duplicates/DiskTableModel.java index a80ab5b..931f05d 100644 --- a/src/com/bytezone/diskbrowser/duplicates/DiskTableModel.java +++ b/src/com/bytezone/diskbrowser/duplicates/DiskTableModel.java @@ -11,7 +11,7 @@ import com.bytezone.diskbrowser.utilities.Utility; public class DiskTableModel extends AbstractTableModel { static final String[] headers = - { "Path", "Name", "Type", "Size (bytes)", "Dup name", "Dup data", "Checksum" }; + { "Path", "Name", "Type", "Size", "Dup name", "Dup data", "Checksum" }; Map fileNameMap; Map checkSumMap; diff --git a/src/com/bytezone/diskbrowser/duplicates/DuplicateHandler.java b/src/com/bytezone/diskbrowser/duplicates/DuplicateHandler.java index 34f64b3..38a31b0 100644 --- a/src/com/bytezone/diskbrowser/duplicates/DuplicateHandler.java +++ b/src/com/bytezone/diskbrowser/duplicates/DuplicateHandler.java @@ -1,5 +1,6 @@ package com.bytezone.diskbrowser.duplicates; +import java.awt.Dimension; import java.awt.Graphics; import java.io.File; import java.util.HashMap; @@ -21,6 +22,7 @@ public class DuplicateHandler extends SwingWorker private final DuplicateWindow owner; private final JDialog dialog; private final ProgressPanel progressPanel; + private final boolean doChecksums; // list of checksum -> DiskDetails private final Map checksumMap = new HashMap (); @@ -29,18 +31,20 @@ public class DuplicateHandler extends SwingWorker private final Map fileNameMap = new TreeMap (); - public DuplicateHandler (File rootFolder, DuplicateWindow owner) + public DuplicateHandler (File rootFolder, DuplicateWindow owner, boolean doChecksums) { this.rootFolder = rootFolder; this.owner = owner; + this.doChecksums = doChecksums; rootFolderNameLength = rootFolder.getAbsolutePath ().length (); dialog = new JDialog (owner); progressPanel = new ProgressPanel (); + progressPanel.setPreferredSize (new Dimension (485, 300)); dialog.add (progressPanel); - dialog.setSize (500, 400); - dialog.setLocationRelativeTo (null); dialog.setTitle ("Reading disks"); + dialog.pack (); + dialog.setLocationRelativeTo (null); dialog.setVisible (true); } @@ -83,7 +87,7 @@ public class DuplicateHandler extends SwingWorker progressState.incrementType (file, fileName); checkDuplicates (file, fileName); - if ((progressState.totalDisks % 1000) == 0) + if ((progressState.totalDisks % 500) == 0) publish (progressState); } } @@ -92,18 +96,21 @@ public class DuplicateHandler extends SwingWorker private void checkDuplicates (File file, String filename) { String rootName = file.getAbsolutePath ().substring (rootFolderNameLength); - DiskDetails diskDetails = new DiskDetails (file, rootName, filename); + DiskDetails diskDetails = new DiskDetails (file, rootName, filename, doChecksums); if (fileNameMap.containsKey (filename)) fileNameMap.get (filename).addDuplicateName (diskDetails); else fileNameMap.put (filename, diskDetails); - long checksum = diskDetails.getChecksum (); - if (checksumMap.containsKey (checksum)) - checksumMap.get (checksum).addDuplicateChecksum (diskDetails); - else - checksumMap.put (checksum, diskDetails); + if (doChecksums) + { + long checksum = diskDetails.getChecksum (); + if (checksumMap.containsKey (checksum)) + checksumMap.get (checksum).addDuplicateChecksum (diskDetails); + else + checksumMap.put (checksum, diskDetails); + } } @Override @@ -131,8 +138,6 @@ public class DuplicateHandler extends SwingWorker @Override protected void process (List chunks) { - // for (ProgressState progressState : chunks) - // progressState.print (); progressPanel.repaint (); } diff --git a/src/com/bytezone/diskbrowser/duplicates/DuplicateWindow.java b/src/com/bytezone/diskbrowser/duplicates/DuplicateWindow.java index 735ecc5..62024a9 100644 --- a/src/com/bytezone/diskbrowser/duplicates/DuplicateWindow.java +++ b/src/com/bytezone/diskbrowser/duplicates/DuplicateWindow.java @@ -12,10 +12,12 @@ import javax.swing.*; import javax.swing.event.ListSelectionEvent; import javax.swing.event.ListSelectionListener; import javax.swing.table.JTableHeader; +import javax.swing.table.TableColumnModel; import javax.swing.table.TableRowSorter; import com.bytezone.diskbrowser.gui.DuplicateAction; import com.bytezone.diskbrowser.gui.DuplicateAction.DiskTableSelectionListener; +import com.bytezone.diskbrowser.utilities.NumberRenderer; public class DuplicateWindow extends JFrame { @@ -24,7 +26,6 @@ public class DuplicateWindow extends JFrame private final JButton btnExport = new JButton ("Export"); private final JButton btnHide = new JButton ("Close"); - // private DuplicateHandler duplicateHandler; private final List listeners; public DuplicateWindow (File rootFolder, @@ -71,13 +72,14 @@ public class DuplicateWindow extends JFrame public void setDuplicateHandler (DuplicateHandler duplicateHandler) { - // this.duplicateHandler = duplicateHandler; - table.setModel (new DiskTableModel (duplicateHandler)); int[] columnWidths = { 300, 300, 30, 40, 40, 40, 100 }; + TableColumnModel tcm = table.getColumnModel (); for (int i = 0; i < columnWidths.length; i++) - table.getColumnModel ().getColumn (i).setPreferredWidth (columnWidths[i]); + tcm.getColumn (i).setPreferredWidth (columnWidths[i]); + + tcm.getColumn (3).setCellRenderer (NumberRenderer.getIntegerRenderer ()); final TableRowSorter sorter = new TableRowSorter ((DiskTableModel) table.getModel ()); diff --git a/src/com/bytezone/diskbrowser/duplicates/ProgressState.java b/src/com/bytezone/diskbrowser/duplicates/ProgressState.java index 80f76ee..2d08cd5 100644 --- a/src/com/bytezone/diskbrowser/duplicates/ProgressState.java +++ b/src/com/bytezone/diskbrowser/duplicates/ProgressState.java @@ -14,7 +14,7 @@ public class ProgressState private static final String header = " type uncmp .gz .zip"; private static final String line = "-------------- ------- ------- -------"; private static final List suffixes = Utility.suffixes; - private static final Font font = new Font ("Monaco", Font.BOLD, 15); + private static final Font font = new Font ("Monospaced", Font.BOLD, 15); int totalDisks; int totalFolders; @@ -52,7 +52,7 @@ public class ProgressState g.setFont (font); int x = 55; - int y = 55; + int y = 25; int lineHeight = 23; String line; diff --git a/src/com/bytezone/diskbrowser/gui/DuplicateAction.java b/src/com/bytezone/diskbrowser/gui/DuplicateAction.java index f7fbd97..13f5eaa 100644 --- a/src/com/bytezone/diskbrowser/gui/DuplicateAction.java +++ b/src/com/bytezone/diskbrowser/gui/DuplicateAction.java @@ -8,6 +8,7 @@ import java.util.ArrayList; import java.util.List; import javax.swing.Action; +import javax.swing.JOptionPane; import javax.swing.KeyStroke; import com.bytezone.common.DefaultAction; @@ -25,13 +26,13 @@ public class DuplicateAction extends DefaultAction implements RootDirectoryChang public DuplicateAction () { - super ("Check for duplicates...", "Check for duplicate disks", + super ("List disks...", "Display a sortable list of disks", "/com/bytezone/diskbrowser/icons/"); setIcon (Action.SMALL_ICON, "save_delete_16.png"); setIcon (Action.LARGE_ICON_KEY, "save_delete_32.png"); int mask = Toolkit.getDefaultToolkit ().getMenuShortcutKeyMask (); - putValue (Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke (KeyEvent.VK_D, mask)); + putValue (Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke (KeyEvent.VK_L, mask)); setEnabled (false); } @@ -48,8 +49,19 @@ public class DuplicateAction extends DefaultAction implements RootDirectoryChang { if (window == null) { - window = new DuplicateWindow (rootFolder, listeners); - new DuplicateHandler (rootFolder, window).execute (); + Object[] options = { "Generate checksums", "Disk names only", "Cancel" }; + int n = JOptionPane.showOptionDialog (null, + "This command will list all of the disks in the root folder (including\n" + + "nested folders). If you wish to generate a checksum for each disk, it\n" + + "will slow the process down considerably.\n\n" + + "Do you wish to generate checksums?", + "Generate Disk Listing", JOptionPane.YES_NO_CANCEL_OPTION, + JOptionPane.QUESTION_MESSAGE, null, options, options[2]); + if (n < 2) + { + window = new DuplicateWindow (rootFolder, listeners); + new DuplicateHandler (rootFolder, window, n == 0).execute (); + } } else window.setVisible (true); diff --git a/src/com/bytezone/diskbrowser/gui/TreeBuilder.java b/src/com/bytezone/diskbrowser/gui/TreeBuilder.java index 3aa85e0..39972ae 100755 --- a/src/com/bytezone/diskbrowser/gui/TreeBuilder.java +++ b/src/com/bytezone/diskbrowser/gui/TreeBuilder.java @@ -22,9 +22,6 @@ import com.bytezone.diskbrowser.utilities.Utility; public class TreeBuilder { private static SimpleDateFormat sdf = new SimpleDateFormat ("dd MMM yyyy"); - // private static final int DISK_13_SIZE = 116480; - // private static final int DISK_16_SIZE = 143360; - // private static final int DISK_800K_SIZE = 819264; private final FileComparator fileComparator = new FileComparator (); private final JTree tree; @@ -71,19 +68,8 @@ public class TreeBuilder fileNode.setTreeNode (newNode); newNode.setAllowsChildren (true); node.add (newNode); - - continue; } - - // if (file.length () != DISK_16_SIZE && file.length () != DISK_13_SIZE - // && file.length () != DISK_800K_SIZE && file.length () < 200000) - // { - // String name = file.getName ().toLowerCase (); - // if (!name.endsWith (".sdk") && !name.endsWith (".dsk.gz")) - // continue; - // } - - if (Utility.validFileType (file.getName ()) && file.length () > 0) + else if (Utility.validFileType (file.getName ()) && file.length () > 0) { FileNode fileNode = new FileNode (file); DefaultMutableTreeNode newNode = new DefaultMutableTreeNode (fileNode); diff --git a/src/com/bytezone/diskbrowser/prodos/FileEntry.java b/src/com/bytezone/diskbrowser/prodos/FileEntry.java index 2928398..7f97906 100755 --- a/src/com/bytezone/diskbrowser/prodos/FileEntry.java +++ b/src/com/bytezone/diskbrowser/prodos/FileEntry.java @@ -259,6 +259,8 @@ class FileEntry extends CatalogEntry implements ProdosConstants case FILE_TYPE_BINARY: case FILE_TYPE_RELOCATABLE: case FILE_TYPE_SYS: + // if (name.endsWith (".S")) + // file = new MerlinSource (name, exactBuffer, auxType, endOfFile); if (ShapeTable.isShapeTable (exactBuffer)) file = new ShapeTable (name, exactBuffer); else if (SimpleText.isHTML (exactBuffer)) @@ -275,9 +277,8 @@ class FileEntry extends CatalogEntry implements ProdosConstants { file = new AssemblerProgram (name, exactBuffer, auxType); if (exactBuffer.length < buffer.length) - ((AssemblerProgram) file) - .setExtraBuffer (buffer, exactBuffer.length, - buffer.length - exactBuffer.length); + ((AssemblerProgram) file).setExtraBuffer (buffer, exactBuffer.length, + buffer.length - exactBuffer.length); } break; case FILE_TYPE_TEXT: @@ -384,8 +385,8 @@ class FileEntry extends CatalogEntry implements ProdosConstants if (addresses.size () > 0) { byte[] tempBuffer = disk.readSectors (addresses); - buffers.add (new TextBuffer (tempBuffer, auxType, - logicalBlock - addresses.size ())); + buffers.add ( + new TextBuffer (tempBuffer, auxType, logicalBlock - addresses.size ())); addresses.clear (); } logicalBlock += 256; @@ -559,13 +560,11 @@ class FileEntry extends CatalogEntry implements ProdosConstants String locked = (access == 0x00) ? "*" : " "; if (true) return String.format ("%s %03d %s", ProdosConstants.fileTypes[fileType], - blocksUsed, locked) - + name; + blocksUsed, locked) + name; String timeC = created == null ? "" : parentDisk.df.format (created.getTime ()); String timeF = modified == null ? "" : parentDisk.df.format (modified.getTime ()); return String.format ("%s %s%-30s %3d %,10d %15s %15s", - ProdosConstants.fileTypes[fileType], locked, - parentDirectory.name + "/" + name, blocksUsed, endOfFile, timeC, - timeF); + ProdosConstants.fileTypes[fileType], locked, parentDirectory.name + "/" + name, + blocksUsed, endOfFile, timeC, timeF); } } \ No newline at end of file diff --git a/src/com/bytezone/diskbrowser/utilities/FormatRenderer.java b/src/com/bytezone/diskbrowser/utilities/FormatRenderer.java new file mode 100644 index 0000000..975d96c --- /dev/null +++ b/src/com/bytezone/diskbrowser/utilities/FormatRenderer.java @@ -0,0 +1,41 @@ +package com.bytezone.diskbrowser.utilities; + +import java.text.DateFormat; +import java.text.Format; + +import javax.swing.table.DefaultTableCellRenderer; + +public class FormatRenderer extends DefaultTableCellRenderer +{ + private final Format formatter; + + public FormatRenderer (Format formatter) + { + this.formatter = formatter; + } + + @Override + public void setValue (Object value) + { + try + { + if (value != null) + value = formatter.format (value); + } + catch (IllegalArgumentException e) + { + } + + super.setValue (value); + } + + public static FormatRenderer getDateTimeRenderer () + { + return new FormatRenderer (DateFormat.getDateTimeInstance ()); + } + + public static FormatRenderer getTimeRenderer () + { + return new FormatRenderer (DateFormat.getTimeInstance ()); + } +} \ No newline at end of file diff --git a/src/com/bytezone/diskbrowser/utilities/NumberRenderer.java b/src/com/bytezone/diskbrowser/utilities/NumberRenderer.java new file mode 100644 index 0000000..34367d6 --- /dev/null +++ b/src/com/bytezone/diskbrowser/utilities/NumberRenderer.java @@ -0,0 +1,29 @@ +package com.bytezone.diskbrowser.utilities; + +import java.text.NumberFormat; + +import javax.swing.SwingConstants; + +public class NumberRenderer extends FormatRenderer +{ + public NumberRenderer (NumberFormat formatter) + { + super (formatter); + setHorizontalAlignment (SwingConstants.RIGHT); + } + + public static NumberRenderer getCurrencyRenderer () + { + return new NumberRenderer (NumberFormat.getCurrencyInstance ()); + } + + public static NumberRenderer getIntegerRenderer () + { + return new NumberRenderer (NumberFormat.getIntegerInstance ()); + } + + public static NumberRenderer getPercentRenderer () + { + return new NumberRenderer (NumberFormat.getPercentInstance ()); + } +} \ No newline at end of file