diff --git a/src/com/bytezone/diskbrowser/cpm/CPMDisk.java b/src/com/bytezone/diskbrowser/cpm/CPMDisk.java index 35f1ef9..921f9ba 100644 --- a/src/com/bytezone/diskbrowser/cpm/CPMDisk.java +++ b/src/com/bytezone/diskbrowser/cpm/CPMDisk.java @@ -159,6 +159,8 @@ public class CPMDisk extends AbstractFormattedDisk text.append (newLine); } text.append (line); + if (version != 0) + text.append ("Version: " + version); return new DefaultAppleFileSource ("CPM Disk ", text.toString (), this); } diff --git a/src/com/bytezone/diskbrowser/duplicates/DeleteWindow.java b/src/com/bytezone/diskbrowser/duplicates/DeleteWindow.java new file mode 100644 index 0000000..90d85b8 --- /dev/null +++ b/src/com/bytezone/diskbrowser/duplicates/DeleteWindow.java @@ -0,0 +1,124 @@ +package com.bytezone.diskbrowser.duplicates; + +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.io.File; +import java.util.ArrayList; +import java.util.List; + +import javax.swing.*; +import javax.swing.table.AbstractTableModel; +import javax.swing.table.TableColumnModel; + +import com.bytezone.diskbrowser.gui.DuplicateAction.DiskTableSelectionListener; + +public class DeleteWindow extends JFrame implements DiskTableSelectionListener +{ + private List lines = new ArrayList (); + private final JButton btnHide = new JButton ("Close"); + private final RootFolderData rootFolderData; + + private final DeleteTableModel deleteTableModel = new DeleteTableModel (); + private final JTable table = new JTable (deleteTableModel); + + public DeleteWindow (RootFolderData rootFolderData) + { + super ("Duplicate Disks"); + + JScrollPane scrollPane = + new JScrollPane (table, ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS, + ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER); + + table.setFillsViewportHeight (true); + + table.setShowGrid (true); + table.setGridColor (Color.LIGHT_GRAY); + + add (scrollPane, BorderLayout.CENTER); + + JPanel panel = new JPanel (); + panel.add (btnHide); + add (panel, BorderLayout.SOUTH); + + btnHide.addActionListener (new ActionListener () + { + @Override + public void actionPerformed (ActionEvent e) + { + setVisible (false); + } + }); + + scrollPane.setPreferredSize (new Dimension (700, 400)); + setDefaultCloseOperation (HIDE_ON_CLOSE); + + this.rootFolderData = rootFolderData; + rootFolderData.listeners.add (this); + + int[] columnWidths = { 400, 30, 70, 100 }; + TableColumnModel tcm = table.getColumnModel (); + for (int i = 0; i < columnWidths.length; i++) + tcm.getColumn (i).setPreferredWidth (columnWidths[i]); + + pack (); + setLocationRelativeTo (null); + } + + @Override + public void diskSelected (DiskDetails diskDetails) + { + lines = rootFolderData.listDuplicates (diskDetails.getChecksum ()); + deleteTableModel.fireTableDataChanged (); + } + + class DeleteTableModel extends AbstractTableModel + { + final String[] headers = { "Name", "Type", "Size", "Checksum", }; + + @Override + public int getRowCount () + { + return lines.size (); + } + + @Override + public int getColumnCount () + { + return headers.length; + } + + @Override + public String getColumnName (int column) + { + return headers[column]; + } + + @Override + public Object getValueAt (int rowIndex, int columnIndex) + { + DiskDetails diskDetails = lines.get (rowIndex); + switch (columnIndex) + { + case 0: + return diskDetails.getRootName () + File.separator + diskDetails.getFileName (); + case 1: + return diskDetails.getType (); + case 2: + return diskDetails.getSize (); + case 3: + return diskDetails.getChecksum (); + default: + return "?"; + } + } + + @Override + public Class getColumnClass (int columnIndex) + { + return lines.isEmpty () ? Object.class : getValueAt (0, columnIndex).getClass (); + } + } +} \ No newline at end of file diff --git a/src/com/bytezone/diskbrowser/duplicates/DiskDetails.java b/src/com/bytezone/diskbrowser/duplicates/DiskDetails.java index 9e4f396..78a432b 100644 --- a/src/com/bytezone/diskbrowser/duplicates/DiskDetails.java +++ b/src/com/bytezone/diskbrowser/duplicates/DiskDetails.java @@ -5,6 +5,7 @@ import java.util.ArrayList; import java.util.List; import com.bytezone.common.ComputeCRC32; +import com.bytezone.diskbrowser.utilities.Utility; public class DiskDetails { @@ -12,6 +13,8 @@ public class DiskDetails private long checksum; private final String rootName; // full path without the root folder private final String shortName; // file name in lower case + private final String type; + private final long size; private final List duplicateChecksums = new ArrayList (); private final List duplicateNames = new ArrayList (); @@ -24,6 +27,8 @@ public class DiskDetails this.file = file; this.rootName = rootName; this.shortName = shortName; + this.type = Utility.getSuffix (shortName); + this.size = file.length (); if (doChecksum) checksum = ComputeCRC32.getChecksumValue (file); @@ -79,6 +84,16 @@ public class DiskDetails return rootName; } + public String getType () + { + return type; + } + + public long getSize () + { + return size; + } + public String getShortName () { return shortName; @@ -103,7 +118,7 @@ public class DiskDetails @Override public String toString () { - return String.format ("%-40s %3d %s %3d %s", rootName, duplicateChecksums.size (), - isDuplicateChecksum, duplicateNames.size (), isDuplicateName); + return String.format ("%3d %1.1s %3d %1.1s %-40s ", duplicateChecksums.size (), + isDuplicateChecksum, duplicateNames.size (), isDuplicateName, rootName); } } \ No newline at end of file diff --git a/src/com/bytezone/diskbrowser/duplicates/DiskTableModel.java b/src/com/bytezone/diskbrowser/duplicates/DiskTableModel.java index c12020b..6b0e895 100644 --- a/src/com/bytezone/diskbrowser/duplicates/DiskTableModel.java +++ b/src/com/bytezone/diskbrowser/duplicates/DiskTableModel.java @@ -5,8 +5,6 @@ import java.util.List; import javax.swing.table.AbstractTableModel; -import com.bytezone.diskbrowser.utilities.Utility; - public class DiskTableModel extends AbstractTableModel { static final String[] headers = @@ -119,7 +117,8 @@ public class DiskTableModel extends AbstractTableModel shortName = diskDetails.getShortName (); fileName = diskDetails.getFileName (); checksum = diskDetails.getChecksum (); - type = Utility.getSuffix (shortName); + // type = Utility.getSuffix (shortName); + type = diskDetails.getType (); size = diskDetails.getFile ().length (); String rootName = diskDetails.getRootName (); diff --git a/src/com/bytezone/diskbrowser/duplicates/DisksWindow.java b/src/com/bytezone/diskbrowser/duplicates/DisksWindow.java index da971fd..fe7c15c 100644 --- a/src/com/bytezone/diskbrowser/duplicates/DisksWindow.java +++ b/src/com/bytezone/diskbrowser/duplicates/DisksWindow.java @@ -7,6 +7,8 @@ import java.awt.FlowLayout; import java.awt.Rectangle; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; import java.util.ArrayList; import java.util.List; @@ -26,6 +28,7 @@ public class DisksWindow extends JFrame private final JTable table; private final JButton btnExport = new JButton ("Export"); + private final JButton btnDelete = new JButton ("Duplicates"); private final JButton btnHide = new JButton ("Close"); private final JButton btnTotals = new JButton ("Totals"); private final JPanel topPanel = new JPanel (); @@ -37,6 +40,7 @@ public class DisksWindow extends JFrame private DiskTableModel diskTableModel; private final RootFolderData rootFolderData; + private final DeleteWindow deleteWindow; public DisksWindow (RootFolderData rootFolderData) { @@ -59,6 +63,7 @@ public class DisksWindow extends JFrame panel.add (btnTotals); panel.add (btnHide); panel.add (btnExport); + panel.add (btnDelete); add (panel, BorderLayout.SOUTH); topPanel.setLayout (new FlowLayout (FlowLayout.LEFT, 10, 5)); @@ -85,6 +90,15 @@ public class DisksWindow extends JFrame } }); + btnDelete.addActionListener (new ActionListener () + { + @Override + public void actionPerformed (ActionEvent e) + { + deleteWindow.setVisible (true); + } + }); + btnExport.addActionListener (new ActionListener () { @Override @@ -96,6 +110,8 @@ public class DisksWindow extends JFrame scrollPane.setPreferredSize (new Dimension (1200, 700)); setDefaultCloseOperation (HIDE_ON_CLOSE); + + deleteWindow = new DeleteWindow (rootFolderData); } // called from DuplicateSwingWorker @@ -148,6 +164,16 @@ public class DisksWindow extends JFrame } }); + table.addMouseListener (new MouseAdapter () + { + @Override + public void mousePressed (MouseEvent mouseEvent) + { + if (mouseEvent.getClickCount () == 2) + deleteWindow.setVisible (true); + } + }); + for (int i = 0; i < Utility.suffixes.size (); i++) { int total = rootFolderData.getTotalType (i); @@ -178,6 +204,7 @@ public class DisksWindow extends JFrame private String getFilterText () { StringBuilder filterText = new StringBuilder (); + for (JCheckBox box : boxes) if (box.isSelected ()) { diff --git a/src/com/bytezone/diskbrowser/duplicates/RootFolderData.java b/src/com/bytezone/diskbrowser/duplicates/RootFolderData.java index c7dfba7..65229a4 100644 --- a/src/com/bytezone/diskbrowser/duplicates/RootFolderData.java +++ b/src/com/bytezone/diskbrowser/duplicates/RootFolderData.java @@ -11,7 +11,7 @@ import java.util.Map; import java.util.TreeMap; import javax.swing.JButton; -import javax.swing.JDialog; +import javax.swing.JFrame; import javax.swing.JPanel; import com.bytezone.diskbrowser.gui.DuplicateAction.DiskTableSelectionListener; @@ -45,7 +45,7 @@ public class RootFolderData // Progress dialog ProgressPanel progressPanel; - public JDialog dialogTotals; + public JFrame dialogTotals; JPanel southPanel; JButton btnCancel; JButton btnOK; @@ -57,13 +57,13 @@ public class RootFolderData btnOK = new JButton ("OK"); progressPanel = new ProgressPanel (); - progressPanel.setPreferredSize (new Dimension (560, 300)); + progressPanel.setPreferredSize (new Dimension (560, 340)); - dialogTotals = new JDialog (disksWindow); + dialogTotals = new JFrame ("Disk Totals"); dialogTotals.add (progressPanel, BorderLayout.CENTER); southPanel.add (btnCancel); // needs to be here for the pack() dialogTotals.add (southPanel, BorderLayout.SOUTH); - dialogTotals.setTitle ("Disk Totals"); + // dialogTotals.setTitle ("Disk Totals"); dialogTotals.pack (); dialogTotals.setLocationRelativeTo (null); @@ -192,6 +192,20 @@ public class RootFolderData } } + public List listDuplicates (long checksum) + { + List list = new ArrayList (); + DiskDetails original = checksumMap.get (checksum); + if (original != null) + { + list.add (original); + for (DiskDetails dd : original.getDuplicateChecksums ()) + list.add (dd); + } + + return list; + } + public int getTotalType (int type) { return typeTotals[0][type] + typeTotals[1][type] + typeTotals[2][type]; @@ -267,6 +281,18 @@ public class RootFolderData grandTotal[1], grandTotal[2], grandTotal[3]); y += 10; g.drawString (line, x, y); + + if (doChecksums) + { + // line = String.format ("Unique checksums: %,7d%n", + // checksumMap.size ()); + // y += lineHeight; + // g.drawString (line, x, y); + line = String.format ("duplicates ... %,7d%n", + totalDisks - checksumMap.size ()); + y += lineHeight + 10; + g.drawString (line, x, y); + } } } } \ No newline at end of file