mirror of
https://github.com/dmolony/DiskBrowser.git
synced 2024-11-23 19:31:00 +00:00
Moving duplicate handler
This commit is contained in:
parent
bce29f8714
commit
bd1cea9ab2
@ -20,7 +20,6 @@ import com.bytezone.diskbrowser.utilities.HexFormatter;
|
|||||||
|
|
||||||
public class AppleDisk implements Disk
|
public class AppleDisk implements Disk
|
||||||
{
|
{
|
||||||
private static final String newLine = String.format ("%n");
|
|
||||||
private static final int MAX_INTERLEAVE = 3;
|
private static final int MAX_INTERLEAVE = 3;
|
||||||
private static final int SECTOR_SIZE = 256;
|
private static final int SECTOR_SIZE = 256;
|
||||||
private static final int BLOCK_SIZE = 512;
|
private static final int BLOCK_SIZE = 512;
|
||||||
@ -126,13 +125,9 @@ public class AppleDisk implements Disk
|
|||||||
System.out.printf ("Blocks : %,d%n", blocks);
|
System.out.printf ("Blocks : %,d%n", blocks);
|
||||||
}
|
}
|
||||||
|
|
||||||
// int format = buffer[12] & 0xFF;
|
|
||||||
// if (blocks == 0 && format == 1)
|
|
||||||
// {
|
|
||||||
this.blocks = diskData / 4096 * 8; // reduce blocks to a multiple of 8
|
this.blocks = diskData / 4096 * 8; // reduce blocks to a multiple of 8
|
||||||
if (debug)
|
if (debug)
|
||||||
System.out.printf ("Blocks : %,d%n", blocks);
|
System.out.printf ("Blocks : %,d%n", blocks);
|
||||||
// }
|
|
||||||
|
|
||||||
this.sectorSize = 512;
|
this.sectorSize = 512;
|
||||||
this.trackSize = 8 * sectorSize;
|
this.trackSize = 8 * sectorSize;
|
||||||
@ -171,19 +166,6 @@ public class AppleDisk implements Disk
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (false)
|
|
||||||
{
|
|
||||||
System.out.println ();
|
|
||||||
System.out.printf ("File name : %s%n", file.getName ());
|
|
||||||
System.out.printf ("File size : %,d%n", file.length ());
|
|
||||||
System.out.println ("Tracks : " + tracks);
|
|
||||||
System.out.println ("Sectors : " + sectors);
|
|
||||||
System.out.println ("Blocks : " + blocks);
|
|
||||||
System.out.println ("Sector size : " + sectorSize);
|
|
||||||
System.out.println ("Track size : " + trackSize);
|
|
||||||
System.out.println ();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sectorSize != 256 && sectorSize != 512)
|
if (sectorSize != 256 && sectorSize != 512)
|
||||||
throw new FileFormatException ("Invalid sector size : " + sectorSize);
|
throw new FileFormatException ("Invalid sector size : " + sectorSize);
|
||||||
|
|
||||||
@ -601,13 +583,15 @@ public class AppleDisk implements Disk
|
|||||||
{
|
{
|
||||||
StringBuilder text = new StringBuilder ();
|
StringBuilder text = new StringBuilder ();
|
||||||
|
|
||||||
text.append ("Path............ " + file.getAbsolutePath () + newLine);
|
text.append (String.format ("Path............ %s%n", file.getAbsolutePath ()));
|
||||||
|
text.append (String.format ("File name....... %s%n", file.getName ()));
|
||||||
text.append (String.format ("File size....... %,d%n", file.length ()));
|
text.append (String.format ("File size....... %,d%n", file.length ()));
|
||||||
text.append ("Tracks.......... " + tracks + newLine);
|
text.append (String.format ("Tracks.......... %d%n", tracks));
|
||||||
text.append ("Sectors......... " + sectors + newLine);
|
text.append (String.format ("Sectors......... %d%n", sectors));
|
||||||
text.append (String.format ("Blocks.......... %,d%n", blocks));
|
text.append (String.format ("Blocks.......... %,d%n", blocks));
|
||||||
text.append ("Sector size..... " + sectorSize + newLine);
|
text.append (String.format ("Track size...... %,d%n", trackSize));
|
||||||
text.append ("Interleave...... " + interleave + newLine);
|
text.append (String.format ("Sector size..... %d%n", sectorSize));
|
||||||
|
text.append (String.format ("Interleave...... %d", interleave));
|
||||||
|
|
||||||
return text.toString ();
|
return text.toString ();
|
||||||
}
|
}
|
||||||
|
@ -288,7 +288,6 @@ public class DiskFactory
|
|||||||
return disk;
|
return disk;
|
||||||
}
|
}
|
||||||
|
|
||||||
// private static DosDisk checkDos (File file)
|
|
||||||
private static DosDisk checkDos (AppleDisk disk)
|
private static DosDisk checkDos (AppleDisk disk)
|
||||||
{
|
{
|
||||||
if (debug)
|
if (debug)
|
||||||
@ -296,8 +295,6 @@ public class DiskFactory
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// int sectors = file.length () == 143360 ? 16 : 13;
|
|
||||||
// AppleDisk disk = new AppleDisk (file, 35, sectors);
|
|
||||||
if (DosDisk.isCorrectFormat (disk))
|
if (DosDisk.isCorrectFormat (disk))
|
||||||
return new DosDisk (disk);
|
return new DosDisk (disk);
|
||||||
}
|
}
|
||||||
@ -309,7 +306,6 @@ public class DiskFactory
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// private static ProdosDisk checkProdos (File file)
|
|
||||||
private static ProdosDisk checkProdos (AppleDisk disk)
|
private static ProdosDisk checkProdos (AppleDisk disk)
|
||||||
{
|
{
|
||||||
if (debug)
|
if (debug)
|
||||||
@ -317,7 +313,6 @@ public class DiskFactory
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// AppleDisk disk = new AppleDisk (file, 35, 8);
|
|
||||||
if (ProdosDisk.isCorrectFormat (disk))
|
if (ProdosDisk.isCorrectFormat (disk))
|
||||||
return new ProdosDisk (disk);
|
return new ProdosDisk (disk);
|
||||||
}
|
}
|
||||||
@ -348,14 +343,6 @@ public class DiskFactory
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// assumes a track is 4096 bytes
|
|
||||||
// if ((file.length () % 4096) != 0)
|
|
||||||
// {
|
|
||||||
// if (debug)
|
|
||||||
// System.out.printf ("file length not divisible by 4096 : %d%n%n", file.length ());
|
|
||||||
// return null;
|
|
||||||
// }
|
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// truncate the file if necessary
|
// truncate the file if necessary
|
||||||
@ -372,7 +359,6 @@ public class DiskFactory
|
|||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
// e.printStackTrace ();
|
|
||||||
System.out.println (e);
|
System.out.println (e);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -402,13 +388,11 @@ public class DiskFactory
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// private static FormattedDisk checkPascalDisk (File file)
|
|
||||||
private static FormattedDisk checkPascalDisk (AppleDisk disk)
|
private static FormattedDisk checkPascalDisk (AppleDisk disk)
|
||||||
{
|
{
|
||||||
if (debug)
|
if (debug)
|
||||||
System.out.println ("Checking Pascal disk");
|
System.out.println ("Checking Pascal disk");
|
||||||
|
|
||||||
// AppleDisk disk = new AppleDisk (file, 35, 8);
|
|
||||||
File file = disk.getFile ();
|
File file = disk.getFile ();
|
||||||
|
|
||||||
if (!PascalDisk.isCorrectFormat (disk, debug))
|
if (!PascalDisk.isCorrectFormat (disk, debug))
|
||||||
@ -469,9 +453,8 @@ public class DiskFactory
|
|||||||
{
|
{
|
||||||
String old = new String (c + "." + suffix);
|
String old = new String (c + "." + suffix);
|
||||||
String rep = new String ((char) (c + i - 1) + "." + suffix);
|
String rep = new String ((char) (c + i - 1) + "." + suffix);
|
||||||
// System.out.printf ("[%s] [%s]%n", old, rep);
|
|
||||||
File f = new File (fileName.replace (old, rep));
|
File f = new File (fileName.replace (old, rep));
|
||||||
// System.out.println (f);
|
|
||||||
if (!f.exists () || !f.isFile ())
|
if (!f.exists () || !f.isFile ())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@ -483,37 +466,31 @@ public class DiskFactory
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// private static V2dDisk checkV2DDisk (File file)
|
|
||||||
// {
|
|
||||||
// // System.out.println ("possible V2D disk");
|
|
||||||
// new V2dDisk (file);
|
|
||||||
//
|
|
||||||
// return null;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// private static InfocomDisk checkInfocomDisk (File file)
|
|
||||||
private static InfocomDisk checkInfocomDisk (AppleDisk disk)
|
private static InfocomDisk checkInfocomDisk (AppleDisk disk)
|
||||||
{
|
{
|
||||||
if (debug)
|
if (debug)
|
||||||
System.out.println ("Checking Infocom disk");
|
System.out.println ("Checking Infocom disk");
|
||||||
// AppleDisk disk = new AppleDisk (file, 35, 16);
|
|
||||||
if (InfocomDisk.isCorrectFormat (disk))
|
if (InfocomDisk.isCorrectFormat (disk))
|
||||||
return new InfocomDisk (disk);
|
return new InfocomDisk (disk);
|
||||||
|
|
||||||
if (debug)
|
if (debug)
|
||||||
System.out.println ("Not an InfocomDisk disk");
|
System.out.println ("Not an InfocomDisk disk");
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// private static CPMDisk checkCPMDisk (File file)
|
|
||||||
private static CPMDisk checkCPMDisk (AppleDisk disk)
|
private static CPMDisk checkCPMDisk (AppleDisk disk)
|
||||||
{
|
{
|
||||||
if (debug)
|
if (debug)
|
||||||
System.out.println ("Checking CPM disk");
|
System.out.println ("Checking CPM disk");
|
||||||
// AppleDisk disk = new AppleDisk (file, 35, 16);
|
|
||||||
if (CPMDisk.isCorrectFormat (disk))
|
if (CPMDisk.isCorrectFormat (disk))
|
||||||
return new CPMDisk (disk);
|
return new CPMDisk (disk);
|
||||||
|
|
||||||
if (debug)
|
if (debug)
|
||||||
System.out.println ("Not a CPM disk");
|
System.out.println ("Not a CPM disk");
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,14 +1,14 @@
|
|||||||
package com.bytezone.diskbrowser.gui;
|
package com.bytezone.diskbrowser.duplicates;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
|
||||||
import com.bytezone.common.ComputeCRC32;
|
import com.bytezone.common.ComputeCRC32;
|
||||||
|
|
||||||
class DiskDetails
|
public class DiskDetails
|
||||||
{
|
{
|
||||||
private final File file;
|
private final File file;
|
||||||
private long checksum = -1;
|
private long checksum = -1;
|
||||||
boolean duplicate;
|
private boolean duplicate;
|
||||||
|
|
||||||
public DiskDetails (File file)
|
public DiskDetails (File file)
|
||||||
{
|
{
|
||||||
@ -16,6 +16,16 @@ class DiskDetails
|
|||||||
duplicate = false;
|
duplicate = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isDuplicate ()
|
||||||
|
{
|
||||||
|
return duplicate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDuplicate (boolean value)
|
||||||
|
{
|
||||||
|
duplicate = value;
|
||||||
|
}
|
||||||
|
|
||||||
public String getAbsolutePath ()
|
public String getAbsolutePath ()
|
||||||
{
|
{
|
||||||
return file.getAbsolutePath ();
|
return file.getAbsolutePath ();
|
||||||
@ -30,7 +40,8 @@ class DiskDetails
|
|||||||
|
|
||||||
public boolean delete ()
|
public boolean delete ()
|
||||||
{
|
{
|
||||||
return file.delete ();
|
// return file.delete ();
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
141
src/com/bytezone/diskbrowser/duplicates/DuplicateHandler.java
Normal file
141
src/com/bytezone/diskbrowser/duplicates/DuplicateHandler.java
Normal file
@ -0,0 +1,141 @@
|
|||||||
|
package com.bytezone.diskbrowser.duplicates;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.zip.CRC32;
|
||||||
|
import java.util.zip.Checksum;
|
||||||
|
|
||||||
|
import com.bytezone.diskbrowser.disk.AppleDisk;
|
||||||
|
import com.bytezone.diskbrowser.disk.Disk;
|
||||||
|
import com.bytezone.diskbrowser.gui.FileComparator;
|
||||||
|
import com.bytezone.diskbrowser.utilities.Utility;
|
||||||
|
|
||||||
|
public class DuplicateHandler
|
||||||
|
{
|
||||||
|
private static String spaces = " ";
|
||||||
|
private static final FileComparator fileComparator = new FileComparator ();
|
||||||
|
private static final int MAX_NAME_WIDTH = 34;
|
||||||
|
private static final String FORMAT = "%-" + MAX_NAME_WIDTH + "s %,10d%n";
|
||||||
|
|
||||||
|
private final File rootFolder;
|
||||||
|
private int totalDisks;
|
||||||
|
private int totalFolders;
|
||||||
|
|
||||||
|
// total files for each suffix
|
||||||
|
private final Map<String, Integer> typeList = new TreeMap<String, Integer> ();
|
||||||
|
|
||||||
|
// list of unique disk names -> List of File duplicates
|
||||||
|
final Map<String, List<DiskDetails>> duplicateDisks =
|
||||||
|
new TreeMap<String, List<DiskDetails>> ();
|
||||||
|
|
||||||
|
// list of unique disk names -> File
|
||||||
|
private final Map<String, File> diskNames = new HashMap<String, File> ();
|
||||||
|
|
||||||
|
// list of checksum -> File
|
||||||
|
final Map<Long, List<File>> dosMap = new TreeMap<Long, List<File>> ();
|
||||||
|
|
||||||
|
public DuplicateHandler (File rootFolder)
|
||||||
|
{
|
||||||
|
this.rootFolder = rootFolder;
|
||||||
|
countDisks ();
|
||||||
|
}
|
||||||
|
|
||||||
|
void countDisks ()
|
||||||
|
{
|
||||||
|
traverse (rootFolder, 0);
|
||||||
|
|
||||||
|
System.out.printf ("%nFolders ..... %,5d%n", totalFolders);
|
||||||
|
System.out.printf ("Disks ....... %,5d%n%n", totalDisks);
|
||||||
|
|
||||||
|
int grandTotal = 0;
|
||||||
|
for (String key : typeList.keySet ())
|
||||||
|
{
|
||||||
|
int typeTotal = typeList.get (key);
|
||||||
|
grandTotal += typeTotal;
|
||||||
|
System.out.printf ("%13.13s %,6d%n", key + " ...........", typeTotal);
|
||||||
|
}
|
||||||
|
System.out.printf ("%nTotal ....... %,6d%n%n", grandTotal);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void traverse (File directory, int depth)
|
||||||
|
{
|
||||||
|
File[] files = directory.listFiles ();
|
||||||
|
if (files == null || files.length == 0)
|
||||||
|
{
|
||||||
|
System.out.println ("Empty folder : " + directory.getAbsolutePath ());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Arrays.sort (files, fileComparator);
|
||||||
|
|
||||||
|
System.out.printf ("%nFolder: %s%n%n",
|
||||||
|
directory.getAbsolutePath ().substring (rootFolder.getAbsolutePath ().length ()));
|
||||||
|
|
||||||
|
for (File file : files)
|
||||||
|
{
|
||||||
|
if (file.isDirectory ())
|
||||||
|
{
|
||||||
|
++totalFolders;
|
||||||
|
traverse (file, depth + 1);
|
||||||
|
}
|
||||||
|
else if (Utility.validFileType (file.getName ()))
|
||||||
|
{
|
||||||
|
if (file.getName ().endsWith (".gz") && !file.getName ().endsWith ("dsk.gz"))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
++totalDisks;
|
||||||
|
|
||||||
|
String name = file.getName ();
|
||||||
|
int nameLength = name.length ();
|
||||||
|
if (nameLength > MAX_NAME_WIDTH)
|
||||||
|
name = name.substring (0, 15) + "..."
|
||||||
|
+ name.substring (nameLength - MAX_NAME_WIDTH + 18);
|
||||||
|
|
||||||
|
System.out.printf (FORMAT, name, file.length ());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void checksumDos (File file)
|
||||||
|
{
|
||||||
|
if (file.length () != 143360 || file.getAbsolutePath ().contains ("/ZDisks/"))
|
||||||
|
return;
|
||||||
|
|
||||||
|
Disk disk = new AppleDisk (file, 35, 16);
|
||||||
|
byte[] buffer = disk.readSector (0, 0);
|
||||||
|
|
||||||
|
Checksum checksum = new CRC32 ();
|
||||||
|
checksum.update (buffer, 0, buffer.length);
|
||||||
|
long cs = checksum.getValue ();
|
||||||
|
List<File> files = dosMap.get (cs);
|
||||||
|
if (files == null)
|
||||||
|
{
|
||||||
|
files = new ArrayList<File> ();
|
||||||
|
dosMap.put (cs, files);
|
||||||
|
}
|
||||||
|
files.add (file);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void checkDuplicates (File file)
|
||||||
|
{
|
||||||
|
if (diskNames.containsKey (file.getName ()))
|
||||||
|
{
|
||||||
|
List<DiskDetails> diskList = duplicateDisks.get (file.getName ());
|
||||||
|
if (diskList == null)
|
||||||
|
{
|
||||||
|
diskList = new ArrayList<DiskDetails> ();
|
||||||
|
duplicateDisks.put (file.getName (), diskList);
|
||||||
|
diskList.add (new DiskDetails (diskNames.get (file.getName ())));// add original
|
||||||
|
}
|
||||||
|
diskList.add (new DiskDetails (file)); // add the duplicate
|
||||||
|
}
|
||||||
|
else
|
||||||
|
diskNames.put (file.getName (), file);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main (String[] args)
|
||||||
|
{
|
||||||
|
DuplicateHandler dh = new DuplicateHandler (
|
||||||
|
new File ("/Users/denismolony/Apple II stuff/AppleDisk Images II/apple disks"));
|
||||||
|
}
|
||||||
|
}
|
@ -33,11 +33,11 @@ import com.bytezone.diskbrowser.disk.DualDosDisk;
|
|||||||
import com.bytezone.diskbrowser.disk.FormattedDisk;
|
import com.bytezone.diskbrowser.disk.FormattedDisk;
|
||||||
import com.bytezone.diskbrowser.gui.RedoHandler.RedoEvent;
|
import com.bytezone.diskbrowser.gui.RedoHandler.RedoEvent;
|
||||||
import com.bytezone.diskbrowser.gui.RedoHandler.RedoListener;
|
import com.bytezone.diskbrowser.gui.RedoHandler.RedoListener;
|
||||||
|
import com.bytezone.diskbrowser.gui.RootDirectoryAction.RootDirectoryListener;
|
||||||
import com.bytezone.diskbrowser.gui.TreeBuilder.FileNode;
|
import com.bytezone.diskbrowser.gui.TreeBuilder.FileNode;
|
||||||
|
|
||||||
class CatalogPanel extends JTabbedPane
|
class CatalogPanel extends JTabbedPane implements RedoListener, SectorSelectionListener,
|
||||||
implements RedoListener, SectorSelectionListener, QuitListener, FontChangeListener
|
QuitListener, FontChangeListener, RootDirectoryListener
|
||||||
// PreferenceChangeListener
|
|
||||||
{
|
{
|
||||||
private static final String prefsLastDiskUsed = "Last disk used";
|
private static final String prefsLastDiskUsed = "Last disk used";
|
||||||
private static final String prefsLastDosUsed = "Last dos used";
|
private static final String prefsLastDosUsed = "Last dos used";
|
||||||
@ -51,8 +51,8 @@ class CatalogPanel extends JTabbedPane
|
|||||||
private final DocumentCreatorFactory lister;
|
private final DocumentCreatorFactory lister;
|
||||||
private final DiskAndFileSelector selector = new DiskAndFileSelector ();
|
private final DiskAndFileSelector selector = new DiskAndFileSelector ();
|
||||||
private final RedoHandler redoHandler;
|
private final RedoHandler redoHandler;
|
||||||
private DuplicateAction duplicateAction; // this sux
|
|
||||||
private CloseTabAction closeTabAction;
|
private CloseTabAction closeTabAction;
|
||||||
|
private File rootDirectoryFile;
|
||||||
|
|
||||||
public CatalogPanel (MenuHandler mh, RedoHandler redoHandler, Preferences prefs)
|
public CatalogPanel (MenuHandler mh, RedoHandler redoHandler, Preferences prefs)
|
||||||
{
|
{
|
||||||
@ -75,11 +75,16 @@ class CatalogPanel extends JTabbedPane
|
|||||||
addChangeListener (new TabChangeListener ());
|
addChangeListener (new TabChangeListener ());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
File getRootDirectory ()
|
||||||
|
{
|
||||||
|
return rootDirectoryFile;
|
||||||
|
}
|
||||||
|
|
||||||
private void createTabs (Preferences prefs)
|
private void createTabs (Preferences prefs)
|
||||||
{
|
{
|
||||||
String rootDirectory = prefs.get (prefsRootDirectory, "");
|
String rootDirectory = prefs.get (prefsRootDirectory, "");
|
||||||
|
|
||||||
File rootDirectoryFile = new File (rootDirectory);
|
rootDirectoryFile = new File (rootDirectory);
|
||||||
if (!rootDirectoryFile.exists () || !rootDirectoryFile.isDirectory ())
|
if (!rootDirectoryFile.exists () || !rootDirectoryFile.isDirectory ())
|
||||||
{
|
{
|
||||||
System.out.println ("No root directory");
|
System.out.println ("No root directory");
|
||||||
@ -113,11 +118,7 @@ class CatalogPanel extends JTabbedPane
|
|||||||
else
|
else
|
||||||
System.out.println ("no disk selected");
|
System.out.println ("no disk selected");
|
||||||
|
|
||||||
fileTab =
|
insertFileSystemTab (rootDirectoryFile, diskEvent);
|
||||||
new FileSystemTab (rootDirectoryFile, selector, redoHandler, font, diskEvent);
|
|
||||||
fileTab.addTreeMouseListener (new MouseListener ()); // listen for disk selection
|
|
||||||
lister.catalogLister.setNode (fileTab.getRootNode ());
|
|
||||||
insertTab ("Disk Tree", null, fileTab, "Display Apple disks", 0);
|
|
||||||
|
|
||||||
if (diskEvent != null)
|
if (diskEvent != null)
|
||||||
{
|
{
|
||||||
@ -154,6 +155,27 @@ class CatalogPanel extends JTabbedPane
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void rootDirectoryChanged (File root)
|
||||||
|
{
|
||||||
|
// is the user replacing an existing root folder?
|
||||||
|
if (fileTab != null)
|
||||||
|
removeTabAt (0);
|
||||||
|
|
||||||
|
insertFileSystemTab (root, null);
|
||||||
|
setSelectedIndex (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void insertFileSystemTab (File root, DiskSelectedEvent diskEvent)
|
||||||
|
{
|
||||||
|
rootDirectoryFile = root;
|
||||||
|
fileTab =
|
||||||
|
new FileSystemTab (rootDirectoryFile, selector, redoHandler, font, diskEvent);
|
||||||
|
fileTab.addTreeMouseListener (new MouseListener ()); // listen for disk selection
|
||||||
|
lister.catalogLister.setNode (fileTab.getRootNode ());
|
||||||
|
insertTab ("Disk Tree", null, fileTab, "Display Apple disks", 0);
|
||||||
|
}
|
||||||
|
|
||||||
public void activate ()
|
public void activate ()
|
||||||
{
|
{
|
||||||
if (fileTab == null)
|
if (fileTab == null)
|
||||||
@ -168,45 +190,18 @@ class CatalogPanel extends JTabbedPane
|
|||||||
setSelectedIndex (0);
|
setSelectedIndex (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void setDuplicateAction (DuplicateAction action)
|
// void setDuplicateAction (DuplicateAction action)
|
||||||
{
|
// {
|
||||||
this.duplicateAction = action;
|
// this.duplicateAction = action;
|
||||||
if (fileTab != null && fileTab.rootFolder != null)
|
// if (fileTab != null && fileTab.rootFolder != null)
|
||||||
action.setDuplicates (fileTab.rootFolder, fileTab.duplicateDisks);
|
// action.setDuplicates (fileTab.rootFolder, fileTab.duplicateDisks);
|
||||||
}
|
// }
|
||||||
|
|
||||||
void setCloseTabAction (CloseTabAction action)
|
void setCloseTabAction (CloseTabAction action)
|
||||||
{
|
{
|
||||||
this.closeTabAction = action;
|
this.closeTabAction = action;
|
||||||
}
|
}
|
||||||
|
|
||||||
// called by RootDirectoryAction
|
|
||||||
public void changeRootPanel (File root)
|
|
||||||
{
|
|
||||||
// try
|
|
||||||
// {
|
|
||||||
// This might throw a NoDisksFoundException
|
|
||||||
FileSystemTab newFileTab = new FileSystemTab (root, selector, redoHandler, font);
|
|
||||||
|
|
||||||
// is the user replacing an existing root folder?
|
|
||||||
if (fileTab != null)
|
|
||||||
removeTabAt (0);
|
|
||||||
|
|
||||||
fileTab = newFileTab;
|
|
||||||
fileTab.addTreeMouseListener (new MouseListener ()); // listen for disk selection
|
|
||||||
lister.catalogLister.setNode (fileTab.getRootNode ());
|
|
||||||
|
|
||||||
insertTab ("Disk Tree", null, fileTab, null, 0);
|
|
||||||
setSelectedIndex (0);
|
|
||||||
duplicateAction.setDuplicates (fileTab.rootFolder, fileTab.duplicateDisks);
|
|
||||||
// }
|
|
||||||
// catch (NoDisksFoundException e)
|
|
||||||
// {
|
|
||||||
// JOptionPane.showMessageDialog (null, "Folder " + root.getAbsolutePath ()
|
|
||||||
// + " has no valid disk images.", "Bad folder", JOptionPane.ERROR_MESSAGE);
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
|
|
||||||
// called after a double-click in the fileTab
|
// called after a double-click in the fileTab
|
||||||
public void addDiskPanel (FormattedDisk disk, String lastFileUsed, boolean activate)
|
public void addDiskPanel (FormattedDisk disk, String lastFileUsed, boolean activate)
|
||||||
{
|
{
|
||||||
|
@ -53,8 +53,12 @@ public class DiskBrowser extends JFrame implements DiskSelectionListener, QuitLi
|
|||||||
addPanel (diskLayoutPanel, "Disk layout", BorderLayout.EAST);
|
addPanel (diskLayoutPanel, "Disk layout", BorderLayout.EAST);
|
||||||
|
|
||||||
// create actions
|
// create actions
|
||||||
|
DuplicateAction duplicateAction = new DuplicateAction ();
|
||||||
RootDirectoryAction rootDirectoryAction =
|
RootDirectoryAction rootDirectoryAction =
|
||||||
new RootDirectoryAction (null, catalogPanel);
|
new RootDirectoryAction (catalogPanel.getRootDirectory ());
|
||||||
|
rootDirectoryAction.addListener (catalogPanel);
|
||||||
|
rootDirectoryAction.addListener (duplicateAction);
|
||||||
|
|
||||||
RefreshTreeAction refreshTreeAction = new RefreshTreeAction (catalogPanel);
|
RefreshTreeAction refreshTreeAction = new RefreshTreeAction (catalogPanel);
|
||||||
// PreferencesAction preferencesAction = new PreferencesAction (this, prefs);
|
// PreferencesAction preferencesAction = new PreferencesAction (this, prefs);
|
||||||
AbstractAction print = new PrintAction (dataPanel);
|
AbstractAction print = new PrintAction (dataPanel);
|
||||||
@ -64,7 +68,6 @@ public class DiskBrowser extends JFrame implements DiskSelectionListener, QuitLi
|
|||||||
HideLayoutAction hideLayoutAction = new HideLayoutAction (this, layoutBorderPanel);
|
HideLayoutAction hideLayoutAction = new HideLayoutAction (this, layoutBorderPanel);
|
||||||
ShowFreeSectorsAction showFreeAction =
|
ShowFreeSectorsAction showFreeAction =
|
||||||
new ShowFreeSectorsAction (menuHandler, diskLayoutPanel);
|
new ShowFreeSectorsAction (menuHandler, diskLayoutPanel);
|
||||||
DuplicateAction duplicateAction = new DuplicateAction ();
|
|
||||||
CloseTabAction closeTabAction = new CloseTabAction (catalogPanel);
|
CloseTabAction closeTabAction = new CloseTabAction (catalogPanel);
|
||||||
|
|
||||||
// add action buttons to toolbar
|
// add action buttons to toolbar
|
||||||
@ -121,7 +124,7 @@ public class DiskBrowser extends JFrame implements DiskSelectionListener, QuitLi
|
|||||||
quitAction.addQuitListener (diskLayoutPanel);
|
quitAction.addQuitListener (diskLayoutPanel);
|
||||||
quitAction.addQuitListener (this);
|
quitAction.addQuitListener (this);
|
||||||
|
|
||||||
catalogPanel.setDuplicateAction (duplicateAction);
|
// catalogPanel.setDuplicateAction (duplicateAction);
|
||||||
catalogPanel.setCloseTabAction (closeTabAction);
|
catalogPanel.setCloseTabAction (closeTabAction);
|
||||||
|
|
||||||
pack ();
|
pack ();
|
||||||
|
@ -15,9 +15,11 @@ import java.util.Map;
|
|||||||
import javax.swing.*;
|
import javax.swing.*;
|
||||||
|
|
||||||
import com.bytezone.common.DefaultAction;
|
import com.bytezone.common.DefaultAction;
|
||||||
|
import com.bytezone.diskbrowser.duplicates.DiskDetails;
|
||||||
|
import com.bytezone.diskbrowser.gui.RootDirectoryAction.RootDirectoryListener;
|
||||||
import com.bytezone.input.SpringUtilities;
|
import com.bytezone.input.SpringUtilities;
|
||||||
|
|
||||||
public class DuplicateAction extends DefaultAction
|
public class DuplicateAction extends DefaultAction implements RootDirectoryListener
|
||||||
{
|
{
|
||||||
Map<String, List<DiskDetails>> duplicateDisks;
|
Map<String, List<DiskDetails>> duplicateDisks;
|
||||||
int rootFolderLength;
|
int rootFolderLength;
|
||||||
@ -33,12 +35,19 @@ public class DuplicateAction extends DefaultAction
|
|||||||
setIcon (Action.LARGE_ICON_KEY, "save_delete_32.png");
|
setIcon (Action.LARGE_ICON_KEY, "save_delete_32.png");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setDuplicates (File rootFolder, Map<String, List<DiskDetails>> duplicateDisks)
|
// public void setDuplicates (File rootFolder,
|
||||||
|
// Map<String, List<DiskDetails>> duplicateDisks)
|
||||||
|
// {
|
||||||
|
// this.duplicateDisks = duplicateDisks;
|
||||||
|
// this.rootFolderLength = rootFolder.getAbsolutePath ().length ();
|
||||||
|
// setEnabled (duplicateDisks.size () > 0);
|
||||||
|
// }
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void rootDirectoryChanged (File newRootDirectory)
|
||||||
{
|
{
|
||||||
this.duplicateDisks = duplicateDisks;
|
this.rootFolder = newRootDirectory;
|
||||||
this.rootFolderLength = rootFolder.getAbsolutePath ().length ();
|
System.out.println ("gotcha");
|
||||||
this.rootFolder = rootFolder;
|
|
||||||
setEnabled (duplicateDisks.size () > 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -72,7 +81,8 @@ public class DuplicateAction extends DefaultAction
|
|||||||
JPanel mainPanel = new JPanel ();
|
JPanel mainPanel = new JPanel ();
|
||||||
|
|
||||||
List<DiskDetails> disksSelected = new ArrayList<DiskDetails> ();
|
List<DiskDetails> disksSelected = new ArrayList<DiskDetails> ();
|
||||||
List<DuplicatePanel> duplicatePanels = new ArrayList<DuplicateAction.DuplicatePanel> ();
|
List<DuplicatePanel> duplicatePanels =
|
||||||
|
new ArrayList<DuplicateAction.DuplicatePanel> ();
|
||||||
|
|
||||||
public DuplicateWindow ()
|
public DuplicateWindow ()
|
||||||
{
|
{
|
||||||
@ -82,8 +92,8 @@ public class DuplicateAction extends DefaultAction
|
|||||||
|
|
||||||
mainPanel.setLayout (new BoxLayout (mainPanel, BoxLayout.PAGE_AXIS));
|
mainPanel.setLayout (new BoxLayout (mainPanel, BoxLayout.PAGE_AXIS));
|
||||||
|
|
||||||
JScrollPane sp =
|
JScrollPane sp = new JScrollPane (mainPanel, VERTICAL_SCROLLBAR_ALWAYS,
|
||||||
new JScrollPane (mainPanel, VERTICAL_SCROLLBAR_ALWAYS, HORIZONTAL_SCROLLBAR_NEVER);
|
HORIZONTAL_SCROLLBAR_NEVER);
|
||||||
sp.getVerticalScrollBar ().setUnitIncrement (100);
|
sp.getVerticalScrollBar ().setUnitIncrement (100);
|
||||||
add (sp, BorderLayout.CENTER);
|
add (sp, BorderLayout.CENTER);
|
||||||
|
|
||||||
@ -109,7 +119,7 @@ public class DuplicateAction extends DefaultAction
|
|||||||
int count = 0;
|
int count = 0;
|
||||||
for (JCheckBox cb : dp.checkBoxes)
|
for (JCheckBox cb : dp.checkBoxes)
|
||||||
{
|
{
|
||||||
if (count > 0 && dp.duplicateDisks.get (count).duplicate)
|
if (count > 0 && dp.duplicateDisks.get (count).isDuplicate ())
|
||||||
if (!cb.isSelected ())
|
if (!cb.isSelected ())
|
||||||
{
|
{
|
||||||
cb.setSelected (true); // doesn't fire the actionListener!
|
cb.setSelected (true); // doesn't fire the actionListener!
|
||||||
@ -189,9 +199,8 @@ public class DuplicateAction extends DefaultAction
|
|||||||
public synchronized void addResult (List<DiskDetails> duplicateDisks)
|
public synchronized void addResult (List<DiskDetails> duplicateDisks)
|
||||||
{
|
{
|
||||||
// create panel and add it to the window
|
// create panel and add it to the window
|
||||||
DuplicatePanel dp =
|
DuplicatePanel dp = new DuplicatePanel (duplicateDisks, folderNameLength,
|
||||||
new DuplicatePanel (duplicateDisks, folderNameLength, disksSelected, buttonDelete,
|
disksSelected, buttonDelete, buttonClear);
|
||||||
buttonClear);
|
|
||||||
mainPanel.add (dp);
|
mainPanel.add (dp);
|
||||||
duplicatePanels.add (dp);
|
duplicatePanels.add (dp);
|
||||||
|
|
||||||
@ -225,18 +234,18 @@ public class DuplicateAction extends DefaultAction
|
|||||||
JCheckBox cb = new JCheckBox ();
|
JCheckBox cb = new JCheckBox ();
|
||||||
checkBoxes.add (cb);
|
checkBoxes.add (cb);
|
||||||
|
|
||||||
cb.addActionListener (new CheckBoxActionListener (dd, disksSelected, deleteButton,
|
cb.addActionListener (
|
||||||
clearButton));
|
new CheckBoxActionListener (dd, disksSelected, deleteButton, clearButton));
|
||||||
add (cb);
|
add (cb);
|
||||||
if (++count == 1)
|
if (++count == 1)
|
||||||
add (new JLabel ("Source disk"));
|
add (new JLabel ("Source disk"));
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
String text = dd.duplicate ? "Duplicate" : "OK";
|
String text = dd.isDuplicate () ? "Duplicate" : "OK";
|
||||||
add (new JLabel (text));
|
add (new JLabel (text));
|
||||||
}
|
}
|
||||||
String checksum =
|
String checksum = dd.isDuplicate () || count == 1 ? ""
|
||||||
dd.duplicate || count == 1 ? "" : " (checksum = " + dd.getChecksum () + ")";
|
: " (checksum = " + dd.getChecksum () + ")";
|
||||||
add (new JLabel (dd.getAbsolutePath ().substring (folderNameLength) + checksum));
|
add (new JLabel (dd.getAbsolutePath ().substring (folderNameLength) + checksum));
|
||||||
}
|
}
|
||||||
SpringUtilities.makeCompactGrid (this, duplicateDisks.size (), 3, //rows, cols
|
SpringUtilities.makeCompactGrid (this, duplicateDisks.size (), 3, //rows, cols
|
||||||
@ -252,8 +261,8 @@ public class DuplicateAction extends DefaultAction
|
|||||||
JButton deleteButton;
|
JButton deleteButton;
|
||||||
JButton clearButton;
|
JButton clearButton;
|
||||||
|
|
||||||
public CheckBoxActionListener (DiskDetails diskDetails, List<DiskDetails> disksSelected,
|
public CheckBoxActionListener (DiskDetails diskDetails,
|
||||||
JButton deleteButton, JButton clearButton)
|
List<DiskDetails> disksSelected, JButton deleteButton, JButton clearButton)
|
||||||
{
|
{
|
||||||
this.diskDetails = diskDetails;
|
this.diskDetails = diskDetails;
|
||||||
this.disksSelected = disksSelected;
|
this.disksSelected = disksSelected;
|
||||||
@ -306,7 +315,7 @@ public class DuplicateAction extends DefaultAction
|
|||||||
if (firstChecksum < 0)
|
if (firstChecksum < 0)
|
||||||
firstChecksum = dd.getChecksum ();
|
firstChecksum = dd.getChecksum ();
|
||||||
else
|
else
|
||||||
dd.duplicate = (dd.getChecksum () == firstChecksum);
|
dd.setDuplicate (dd.getChecksum () == firstChecksum);
|
||||||
}
|
}
|
||||||
return duplicateDisks;
|
return duplicateDisks;
|
||||||
}
|
}
|
||||||
|
22
src/com/bytezone/diskbrowser/gui/FileComparator.java
Normal file
22
src/com/bytezone/diskbrowser/gui/FileComparator.java
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
package com.bytezone.diskbrowser.gui;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.util.Comparator;
|
||||||
|
|
||||||
|
public class FileComparator implements Comparator<File>
|
||||||
|
{
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int compare (File thisFile, File thatFile)
|
||||||
|
{
|
||||||
|
boolean thisFileIsDirectory = thisFile.isDirectory ();
|
||||||
|
boolean thatFileIsDirectory = thatFile.isDirectory ();
|
||||||
|
|
||||||
|
if (thisFileIsDirectory && !thatFileIsDirectory)
|
||||||
|
return 1;
|
||||||
|
if (!thisFileIsDirectory && thatFileIsDirectory)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
return thisFile.getName ().compareToIgnoreCase (thatFile.getName ());
|
||||||
|
}
|
||||||
|
}
|
@ -10,8 +10,6 @@ package com.bytezone.diskbrowser.gui;
|
|||||||
import java.awt.Font;
|
import java.awt.Font;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.util.Enumeration;
|
import java.util.Enumeration;
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import javax.swing.JTree;
|
import javax.swing.JTree;
|
||||||
import javax.swing.event.TreeExpansionEvent;
|
import javax.swing.event.TreeExpansionEvent;
|
||||||
@ -30,20 +28,18 @@ import com.bytezone.diskbrowser.gui.TreeBuilder.FileNode;
|
|||||||
class FileSystemTab extends AbstractTab
|
class FileSystemTab extends AbstractTab
|
||||||
{
|
{
|
||||||
File rootFolder;
|
File rootFolder;
|
||||||
Map<String, List<DiskDetails>> duplicateDisks;
|
// Map<String, List<DiskDetails>> duplicateDisks;
|
||||||
|
|
||||||
public FileSystemTab (File folder, DiskAndFileSelector selector, RedoHandler navMan,
|
public FileSystemTab (File folder, DiskAndFileSelector selector, RedoHandler navMan,
|
||||||
Font font, DiskSelectedEvent diskEvent) // throws NoDisksFoundException
|
Font font, DiskSelectedEvent diskEvent)
|
||||||
{
|
{
|
||||||
super (navMan, selector, font);
|
super (navMan, selector, font);
|
||||||
this.rootFolder = folder;
|
this.rootFolder = folder;
|
||||||
|
|
||||||
TreeBuilder tb = new TreeBuilder (folder);
|
TreeBuilder tb = new TreeBuilder (folder);
|
||||||
// if (tb.totalDisks == 0)
|
|
||||||
// throw new NoDisksFoundException ();
|
|
||||||
|
|
||||||
duplicateDisks = tb.duplicateDisks;
|
// duplicateDisks = tb.duplicateDisks;
|
||||||
setTree (tb.tree);
|
setTree (tb.getTree ());
|
||||||
setSelectionListener (tree);
|
setSelectionListener (tree);
|
||||||
|
|
||||||
if (diskEvent == null)
|
if (diskEvent == null)
|
||||||
@ -62,28 +58,27 @@ class FileSystemTab extends AbstractTab
|
|||||||
System.out.println ("No disk event");
|
System.out.println ("No disk event");
|
||||||
|
|
||||||
// temporary code while I sort out the DOS checksum feature
|
// temporary code while I sort out the DOS checksum feature
|
||||||
if (tb.dosMap.keySet ().size () > 0)
|
// if (tb.dosMap.keySet ().size () > 0)
|
||||||
{
|
// {
|
||||||
System.out.printf ("Unique DOSs : %4d%n", tb.dosMap.keySet ().size ());
|
// System.out.printf ("Unique DOSs : %4d%n", tb.dosMap.keySet ().size ());
|
||||||
long lastKey = -1;
|
// long lastKey = -1;
|
||||||
int beginIndex = rootFolder.getAbsolutePath ().length ();
|
// int beginIndex = rootFolder.getAbsolutePath ().length ();
|
||||||
for (Long key : tb.dosMap.keySet ())
|
// for (Long key : tb.dosMap.keySet ())
|
||||||
{
|
// {
|
||||||
if (key != lastKey)
|
// if (key != lastKey)
|
||||||
{
|
// {
|
||||||
lastKey = key;
|
// lastKey = key;
|
||||||
System.out.printf ("%,14d (%d)%n", key, tb.dosMap.get (key).size ());
|
// System.out.printf ("%,14d (%d)%n", key, tb.dosMap.get (key).size ());
|
||||||
}
|
// }
|
||||||
for (File file : tb.dosMap.get (key))
|
// for (File file : tb.dosMap.get (key))
|
||||||
System.out.printf (" %s%n",
|
// System.out.printf (" %s%n",
|
||||||
file.getAbsolutePath ().substring (beginIndex));
|
// file.getAbsolutePath ().substring (beginIndex));
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
public FileSystemTab (File folder, DiskAndFileSelector selector, RedoHandler navMan,
|
public FileSystemTab (File folder, DiskAndFileSelector selector, RedoHandler navMan,
|
||||||
Font font)
|
Font font)
|
||||||
// throws NoDisksFoundException
|
|
||||||
{
|
{
|
||||||
this (folder, selector, navMan, font, null); // default to first available disk
|
this (folder, selector, navMan, font, null); // default to first available disk
|
||||||
}
|
}
|
||||||
@ -101,7 +96,7 @@ class FileSystemTab extends AbstractTab
|
|||||||
{
|
{
|
||||||
String currentDiskName = ((FileNode) getSelectedObject ()).file.getAbsolutePath ();
|
String currentDiskName = ((FileNode) getSelectedObject ()).file.getAbsolutePath ();
|
||||||
TreeBuilder tb = new TreeBuilder (rootFolder);
|
TreeBuilder tb = new TreeBuilder (rootFolder);
|
||||||
setTree (tb.tree);
|
setTree (tb.getTree ());
|
||||||
if (currentDiskName != null)
|
if (currentDiskName != null)
|
||||||
showNode (findNode (currentDiskName));
|
showNode (findNode (currentDiskName));
|
||||||
setSelectionListener (tree);
|
setSelectionListener (tree);
|
||||||
|
@ -3,6 +3,8 @@ package com.bytezone.diskbrowser.gui;
|
|||||||
import java.awt.event.ActionEvent;
|
import java.awt.event.ActionEvent;
|
||||||
import java.awt.event.KeyEvent;
|
import java.awt.event.KeyEvent;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import javax.swing.Action;
|
import javax.swing.Action;
|
||||||
import javax.swing.JFileChooser;
|
import javax.swing.JFileChooser;
|
||||||
@ -13,20 +15,21 @@ import com.bytezone.common.Platform;
|
|||||||
|
|
||||||
class RootDirectoryAction extends DefaultAction
|
class RootDirectoryAction extends DefaultAction
|
||||||
{
|
{
|
||||||
File rootDirectory;
|
private File rootDirectory;
|
||||||
CatalogPanel catalogPanel;
|
private final List<RootDirectoryListener> listeners =
|
||||||
|
new ArrayList<RootDirectoryAction.RootDirectoryListener> ();
|
||||||
|
|
||||||
public RootDirectoryAction (File rootDirectory, CatalogPanel catalogPanel)
|
public RootDirectoryAction (File rootDirectory)
|
||||||
{
|
{
|
||||||
super ("Set HOME folder...", "Defines root folder where the disk images are kept",
|
super ("Set HOME folder...", "Defines root folder where the disk images are kept",
|
||||||
"/com/bytezone/diskbrowser/icons/");
|
"/com/bytezone/diskbrowser/icons/");
|
||||||
putValue (Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke ("alt H"));
|
putValue (Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke ("alt H"));
|
||||||
putValue (Action.MNEMONIC_KEY, KeyEvent.VK_H);
|
putValue (Action.MNEMONIC_KEY, KeyEvent.VK_H);
|
||||||
this.rootDirectory = rootDirectory;
|
|
||||||
this.catalogPanel = catalogPanel;
|
|
||||||
|
|
||||||
setIcon (Action.SMALL_ICON, "folder_explore_16.png");
|
setIcon (Action.SMALL_ICON, "folder_explore_16.png");
|
||||||
setIcon (Action.LARGE_ICON_KEY, "folder_explore_32.png");
|
setIcon (Action.LARGE_ICON_KEY, "folder_explore_32.png");
|
||||||
|
|
||||||
|
this.rootDirectory = rootDirectory;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -37,6 +40,7 @@ class RootDirectoryAction extends DefaultAction
|
|||||||
chooser.setFileSelectionMode (JFileChooser.DIRECTORIES_ONLY);
|
chooser.setFileSelectionMode (JFileChooser.DIRECTORIES_ONLY);
|
||||||
if (rootDirectory != null)
|
if (rootDirectory != null)
|
||||||
chooser.setSelectedFile (rootDirectory);
|
chooser.setSelectedFile (rootDirectory);
|
||||||
|
|
||||||
int result = chooser.showDialog (null, "Accept");
|
int result = chooser.showDialog (null, "Accept");
|
||||||
if (result == JFileChooser.APPROVE_OPTION)
|
if (result == JFileChooser.APPROVE_OPTION)
|
||||||
{
|
{
|
||||||
@ -46,8 +50,20 @@ class RootDirectoryAction extends DefaultAction
|
|||||||
if (file != null)
|
if (file != null)
|
||||||
{
|
{
|
||||||
rootDirectory = file;
|
rootDirectory = file;
|
||||||
catalogPanel.changeRootPanel (file);
|
for (RootDirectoryListener listener : listeners)
|
||||||
|
listener.rootDirectoryChanged (file);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void addListener (RootDirectoryListener listener)
|
||||||
|
{
|
||||||
|
if (!listeners.contains (listener))
|
||||||
|
listeners.add (listener);
|
||||||
|
}
|
||||||
|
|
||||||
|
interface RootDirectoryListener
|
||||||
|
{
|
||||||
|
public void rootDirectoryChanged (File newRootDirectory);
|
||||||
|
}
|
||||||
}
|
}
|
@ -4,9 +4,8 @@ import java.awt.image.BufferedImage;
|
|||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.text.SimpleDateFormat;
|
import java.text.SimpleDateFormat;
|
||||||
import java.util.*;
|
import java.util.Arrays;
|
||||||
import java.util.zip.CRC32;
|
import java.util.Date;
|
||||||
import java.util.zip.Checksum;
|
|
||||||
|
|
||||||
import javax.swing.ImageIcon;
|
import javax.swing.ImageIcon;
|
||||||
import javax.swing.JComponent;
|
import javax.swing.JComponent;
|
||||||
@ -15,61 +14,75 @@ import javax.swing.tree.DefaultMutableTreeNode;
|
|||||||
import javax.swing.tree.DefaultTreeCellRenderer;
|
import javax.swing.tree.DefaultTreeCellRenderer;
|
||||||
import javax.swing.tree.DefaultTreeModel;
|
import javax.swing.tree.DefaultTreeModel;
|
||||||
|
|
||||||
import com.bytezone.diskbrowser.disk.AppleDisk;
|
|
||||||
import com.bytezone.diskbrowser.disk.Disk;
|
|
||||||
import com.bytezone.diskbrowser.disk.DiskFactory;
|
import com.bytezone.diskbrowser.disk.DiskFactory;
|
||||||
import com.bytezone.diskbrowser.disk.FormattedDisk;
|
import com.bytezone.diskbrowser.disk.FormattedDisk;
|
||||||
import com.bytezone.diskbrowser.utilities.FileFormatException;
|
import com.bytezone.diskbrowser.utilities.FileFormatException;
|
||||||
|
import com.bytezone.diskbrowser.utilities.Utility;
|
||||||
|
|
||||||
public class TreeBuilder
|
public class TreeBuilder
|
||||||
{
|
{
|
||||||
private static SimpleDateFormat sdf = new SimpleDateFormat ("dd MMM yyyy");
|
private static SimpleDateFormat sdf = new SimpleDateFormat ("dd MMM yyyy");
|
||||||
private static final boolean FULL_TREE = false;
|
private static final int DISK_13_SIZE = 116480;
|
||||||
private static final List<String> suffixes =
|
private static final int DISK_16_SIZE = 143360;
|
||||||
Arrays.asList ("po", "dsk", "do", "hdv", "2mg", "v2d", "nib", "d13", "sdk", "gz");
|
private static final int DISK_800K_SIZE = 819264;
|
||||||
|
|
||||||
FileComparator fc = new FileComparator ();
|
// private static final boolean FULL_TREE_TRAVERSAL = false;
|
||||||
JTree tree;
|
|
||||||
int totalDisks;
|
|
||||||
int totalFolders;
|
|
||||||
|
|
||||||
Map<String, Integer> totalFiles = new TreeMap<String, Integer> ();
|
private final FileComparator fileComparator = new FileComparator ();
|
||||||
|
private final JTree tree;
|
||||||
|
|
||||||
Map<String, List<DiskDetails>> duplicateDisks =
|
// private int totalDisks;
|
||||||
new TreeMap<String, List<DiskDetails>> ();
|
// private int totalFolders;
|
||||||
Map<String, File> diskNames = new HashMap<String, File> ();
|
|
||||||
Map<Long, List<File>> dosMap = new TreeMap<Long, List<File>> ();
|
// // total files for each suffix
|
||||||
|
// private final Map<String, Integer> typeList = new TreeMap<String, Integer> ();
|
||||||
|
//
|
||||||
|
// // list of unique disk names -> List of File duplicates
|
||||||
|
// final Map<String, List<DiskDetails>> duplicateDisks =
|
||||||
|
// new TreeMap<String, List<DiskDetails>> ();
|
||||||
|
//
|
||||||
|
// // list of unique disk names -> File
|
||||||
|
// private final Map<String, File> diskNames = new HashMap<String, File> ();
|
||||||
|
//
|
||||||
|
// // list of checksum -> File
|
||||||
|
// final Map<Long, List<File>> dosMap = new TreeMap<Long, List<File>> ();
|
||||||
|
|
||||||
public TreeBuilder (File folder)
|
public TreeBuilder (File folder)
|
||||||
{
|
{
|
||||||
assert (folder.exists ());
|
assert (folder.exists ());
|
||||||
assert (folder.isDirectory ());
|
assert (folder.isDirectory ());
|
||||||
|
|
||||||
FileNode fn = new FileNode (folder);
|
FileNode fileNode = new FileNode (folder);
|
||||||
DefaultMutableTreeNode root = new DefaultMutableTreeNode (fn);
|
DefaultMutableTreeNode root = new DefaultMutableTreeNode (fileNode);
|
||||||
fn.setTreeNode (root);
|
fileNode.setTreeNode (root);
|
||||||
|
|
||||||
addFiles (root, folder);
|
addFiles (root, folder);
|
||||||
DefaultTreeModel treeModel = new DefaultTreeModel (root);
|
DefaultTreeModel treeModel = new DefaultTreeModel (root);
|
||||||
tree = new JTree (treeModel);
|
tree = new JTree (treeModel);
|
||||||
|
|
||||||
treeModel.setAsksAllowsChildren (true); // allows empty nodes to appear as folders
|
treeModel.setAsksAllowsChildren (true); // allows empty nodes to appear as folders
|
||||||
setDiskIcon ("/com/bytezone/diskbrowser/icons/disk.png");
|
setDiskIcon ("/com/bytezone/diskbrowser/icons/disk.png");
|
||||||
((FileNode) root.getUserObject ()).disks = totalDisks;
|
// ((FileNode) root.getUserObject ()).disks = totalDisks;
|
||||||
|
|
||||||
if (FULL_TREE)
|
// if (FULL_TREE_TRAVERSAL)
|
||||||
{
|
// {
|
||||||
System.out.printf ("%nFolders ..... %,5d%n", totalFolders);
|
// System.out.printf ("%nFolders ..... %,5d%n", totalFolders);
|
||||||
System.out.printf ("Disks ....... %,5d%n%n", totalDisks);
|
// System.out.printf ("Disks ....... %,5d%n%n", totalDisks);
|
||||||
|
//
|
||||||
|
// int grandTotal = 0;
|
||||||
|
// for (String key : typeList.keySet ())
|
||||||
|
// {
|
||||||
|
// int typeTotal = typeList.get (key);
|
||||||
|
// grandTotal += typeTotal;
|
||||||
|
// System.out.printf ("%13.13s %,6d%n", key + " ...........", typeTotal);
|
||||||
|
// }
|
||||||
|
// System.out.printf ("%nTotal ....... %,6d%n%n", grandTotal);
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
int tf = 0;
|
public JTree getTree ()
|
||||||
for (String key : totalFiles.keySet ())
|
|
||||||
{
|
{
|
||||||
int t = totalFiles.get (key);
|
return tree;
|
||||||
tf += t;
|
|
||||||
System.out.printf ("%13.13s %,5d%n", key + " ...........", t);
|
|
||||||
}
|
|
||||||
System.out.printf ("%nTotal ...... %,6d%n%n", tf);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addFiles (DefaultMutableTreeNode node, File directory)
|
private void addFiles (DefaultMutableTreeNode node, File directory)
|
||||||
@ -81,124 +94,127 @@ public class TreeBuilder
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
FileNode parentNode = (FileNode) node.getUserObject ();
|
// FileNode parentNode = (FileNode) node.getUserObject ();
|
||||||
Arrays.sort (files, fc);
|
Arrays.sort (files, fileComparator);
|
||||||
|
|
||||||
for (File file : files)
|
for (File file : files)
|
||||||
{
|
{
|
||||||
if (file.isDirectory ())
|
if (file.isDirectory ())
|
||||||
{
|
{
|
||||||
FileNode fn = new FileNode (file);
|
FileNode fileNode = new FileNode (file);
|
||||||
DefaultMutableTreeNode newNode = new DefaultMutableTreeNode (fn);
|
DefaultMutableTreeNode newNode = new DefaultMutableTreeNode (fileNode);
|
||||||
fn.setTreeNode (newNode);
|
fileNode.setTreeNode (newNode);
|
||||||
newNode.setAllowsChildren (true);
|
newNode.setAllowsChildren (true);
|
||||||
node.add (newNode);
|
node.add (newNode);
|
||||||
totalFolders++;
|
|
||||||
|
|
||||||
if (FULL_TREE)
|
// totalFolders++;
|
||||||
addFiles (newNode, file); // recursion!
|
|
||||||
|
// if (FULL_TREE_TRAVERSAL)
|
||||||
|
// addFiles (newNode, file); // recursion!
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (FULL_TREE)
|
// if (FULL_TREE_TRAVERSAL)
|
||||||
{
|
// {
|
||||||
int pos = file.getName ().lastIndexOf ('.');
|
// int pos = file.getName ().lastIndexOf ('.');
|
||||||
if (pos > 0)
|
// if (pos > 0)
|
||||||
{
|
// {
|
||||||
String type = file.getName ().substring (pos + 1).toLowerCase ();
|
// String type = file.getName ().substring (pos + 1).toLowerCase ();
|
||||||
if (totalFiles.containsKey (type))
|
// if (typeList.containsKey (type))
|
||||||
{
|
// {
|
||||||
int t = totalFiles.get (type);
|
// int t = typeList.get (type);
|
||||||
totalFiles.put (type, ++t);
|
// typeList.put (type, ++t);
|
||||||
}
|
// }
|
||||||
else
|
// else
|
||||||
totalFiles.put (type, 1);
|
// typeList.put (type, 1);
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
if (file.length () != 143360 && file.length () != 116480 && file.length () != 819264
|
if (file.length () != DISK_16_SIZE && file.length () != DISK_13_SIZE
|
||||||
&& file.length () < 200000)
|
&& file.length () != DISK_800K_SIZE && file.length () < 200000)
|
||||||
{
|
{
|
||||||
String name = file.getName ().toLowerCase ();
|
String name = file.getName ().toLowerCase ();
|
||||||
if (!name.endsWith (".sdk") && !name.endsWith (".dsk.gz"))
|
if (!name.endsWith (".sdk") && !name.endsWith (".dsk.gz"))
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
parentNode.disks++;
|
// parentNode.disks++;
|
||||||
String filename = file.getAbsolutePath ();
|
|
||||||
if (validFileType (filename))
|
if (Utility.validFileType (file.getAbsolutePath ()))
|
||||||
{
|
{
|
||||||
FileNode fn = new FileNode (file);
|
FileNode fileNode = new FileNode (file);
|
||||||
DefaultMutableTreeNode newNode = new DefaultMutableTreeNode (fn);
|
DefaultMutableTreeNode newNode = new DefaultMutableTreeNode (fileNode);
|
||||||
fn.setTreeNode (newNode);
|
fileNode.setTreeNode (newNode);
|
||||||
newNode.setAllowsChildren (false);
|
newNode.setAllowsChildren (false);
|
||||||
node.add (newNode);
|
node.add (newNode);
|
||||||
|
|
||||||
if (false)
|
// if (false)
|
||||||
checkDuplicates (file);
|
// checkDuplicates (file);
|
||||||
|
|
||||||
totalDisks++;
|
// totalDisks++;
|
||||||
|
|
||||||
if (false)
|
// if (false)
|
||||||
checksumDos (file);
|
// checksumDos (file);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checksumDos (File file)
|
// private void checksumDos (File file)
|
||||||
{
|
// {
|
||||||
if (file.length () != 143360 || file.getAbsolutePath ().contains ("/ZDisks/"))
|
// if (file.length () != 143360 || file.getAbsolutePath ().contains ("/ZDisks/"))
|
||||||
return;
|
// return;
|
||||||
|
//
|
||||||
|
// Disk disk = new AppleDisk (file, 35, 16);
|
||||||
|
// byte[] buffer = disk.readSector (0, 0);
|
||||||
|
//
|
||||||
|
// Checksum checksum = new CRC32 ();
|
||||||
|
// checksum.update (buffer, 0, buffer.length);
|
||||||
|
// long cs = checksum.getValue ();
|
||||||
|
// List<File> files = dosMap.get (cs);
|
||||||
|
// if (files == null)
|
||||||
|
// {
|
||||||
|
// files = new ArrayList<File> ();
|
||||||
|
// dosMap.put (cs, files);
|
||||||
|
// }
|
||||||
|
// files.add (file);
|
||||||
|
// }
|
||||||
|
|
||||||
Disk disk = new AppleDisk (file, 35, 16);
|
// private void checkDuplicates (File file)
|
||||||
byte[] buffer = disk.readSector (0, 0);
|
// {
|
||||||
|
// if (diskNames.containsKey (file.getName ()))
|
||||||
|
// {
|
||||||
|
// List<DiskDetails> diskList = duplicateDisks.get (file.getName ());
|
||||||
|
// if (diskList == null)
|
||||||
|
// {
|
||||||
|
// diskList = new ArrayList<DiskDetails> ();
|
||||||
|
// duplicateDisks.put (file.getName (), diskList);
|
||||||
|
// diskList.add (new DiskDetails (diskNames.get (file.getName ())));// add original
|
||||||
|
// }
|
||||||
|
// diskList.add (new DiskDetails (file)); // add the duplicate
|
||||||
|
// }
|
||||||
|
// else
|
||||||
|
// diskNames.put (file.getName (), file);
|
||||||
|
// }
|
||||||
|
|
||||||
Checksum checksum = new CRC32 ();
|
// private boolean validFileType (String filename)
|
||||||
checksum.update (buffer, 0, buffer.length);
|
// {
|
||||||
long cs = checksum.getValue ();
|
// int dotPos = filename.lastIndexOf ('.');
|
||||||
List<File> files = dosMap.get (cs);
|
// if (dotPos < 0)
|
||||||
if (files == null)
|
// return false;
|
||||||
{
|
//
|
||||||
files = new ArrayList<File> ();
|
// String suffix = filename.substring (dotPos + 1).toLowerCase ();
|
||||||
dosMap.put (cs, files);
|
//
|
||||||
}
|
// int dotPos2 = filename.lastIndexOf ('.', dotPos - 1);
|
||||||
files.add (file);
|
// if (dotPos2 > 0)
|
||||||
}
|
// {
|
||||||
|
// String suffix2 = filename.substring (dotPos2 + 1, dotPos).toLowerCase ();
|
||||||
private void checkDuplicates (File file)
|
// if (suffix.equals ("gz") && (suffix2.equals ("bxy") || suffix2.equals ("bny")))
|
||||||
{
|
// return false;
|
||||||
if (diskNames.containsKey (file.getName ()))
|
// }
|
||||||
{
|
//
|
||||||
List<DiskDetails> diskList = duplicateDisks.get (file.getName ());
|
// return suffixes.contains (suffix);
|
||||||
if (diskList == null)
|
// }
|
||||||
{
|
|
||||||
diskList = new ArrayList<DiskDetails> ();
|
|
||||||
duplicateDisks.put (file.getName (), diskList);
|
|
||||||
diskList.add (new DiskDetails (diskNames.get (file.getName ())));// add the original
|
|
||||||
}
|
|
||||||
diskList.add (new DiskDetails (file));// add the duplicate
|
|
||||||
}
|
|
||||||
else
|
|
||||||
diskNames.put (file.getName (), file);
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean validFileType (String filename)
|
|
||||||
{
|
|
||||||
int dotPos = filename.lastIndexOf ('.');
|
|
||||||
if (dotPos < 0)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
String suffix = filename.substring (dotPos + 1).toLowerCase ();
|
|
||||||
|
|
||||||
int dotPos2 = filename.lastIndexOf ('.', dotPos - 1);
|
|
||||||
if (dotPos2 > 0)
|
|
||||||
{
|
|
||||||
String suffix2 = filename.substring (dotPos2 + 1, dotPos).toLowerCase ();
|
|
||||||
if (suffix.equals ("gz") && (suffix2.equals ("bxy") || suffix2.equals ("bny")))
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return suffixes.contains (suffix);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setDiskIcon (String iconName)
|
private void setDiskIcon (String iconName)
|
||||||
{
|
{
|
||||||
@ -341,19 +357,20 @@ public class TreeBuilder
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private class FileComparator implements Comparator<File>
|
// private class FileComparator implements Comparator<File>
|
||||||
{
|
// {
|
||||||
@Override
|
// @Override
|
||||||
public int compare (File filea, File fileb)
|
// public int compare (File thisFile, File thatFile)
|
||||||
{
|
// {
|
||||||
boolean fileaIsDirectory = filea.isDirectory ();
|
// boolean thisFileIsDirectory = thisFile.isDirectory ();
|
||||||
boolean filebIsDirectory = fileb.isDirectory ();
|
// boolean thatFileIsDirectory = thatFile.isDirectory ();
|
||||||
|
//
|
||||||
if (fileaIsDirectory && !filebIsDirectory)
|
// if (thisFileIsDirectory && !thatFileIsDirectory)
|
||||||
return -1;
|
// return -1;
|
||||||
if (!fileaIsDirectory && filebIsDirectory)
|
// if (!thisFileIsDirectory && thatFileIsDirectory)
|
||||||
return 1;
|
// return 1;
|
||||||
return filea.getName ().compareToIgnoreCase (fileb.getName ());
|
//
|
||||||
}
|
// return thisFile.getName ().compareToIgnoreCase (thatFile.getName ());
|
||||||
}
|
// }
|
||||||
|
// }
|
||||||
}
|
}
|
@ -3,9 +3,14 @@ package com.bytezone.diskbrowser.utilities;
|
|||||||
import java.awt.Graphics2D;
|
import java.awt.Graphics2D;
|
||||||
import java.awt.Toolkit;
|
import java.awt.Toolkit;
|
||||||
import java.awt.geom.AffineTransform;
|
import java.awt.geom.AffineTransform;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
public class Utility
|
public class Utility
|
||||||
{
|
{
|
||||||
|
public static final List<String> suffixes =
|
||||||
|
Arrays.asList ("po", "dsk", "do", "hdv", "2mg", "v2d", "nib", "d13", "sdk", "gz");
|
||||||
|
|
||||||
// not used - it doesn't work with Oracle's JDK
|
// not used - it doesn't work with Oracle's JDK
|
||||||
public static boolean hasRetinaDisplay ()
|
public static boolean hasRetinaDisplay ()
|
||||||
{
|
{
|
||||||
@ -51,4 +56,23 @@ public class Utility
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static boolean validFileType (String filename)
|
||||||
|
{
|
||||||
|
int dotPos = filename.lastIndexOf ('.');
|
||||||
|
if (dotPos < 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
String suffix = filename.substring (dotPos + 1).toLowerCase ();
|
||||||
|
|
||||||
|
int dotPos2 = filename.lastIndexOf ('.', dotPos - 1);
|
||||||
|
if (dotPos2 > 0)
|
||||||
|
{
|
||||||
|
String suffix2 = filename.substring (dotPos2 + 1, dotPos).toLowerCase ();
|
||||||
|
if (suffix.equals ("gz") && (suffix2.equals ("bxy") || suffix2.equals ("bny")))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return suffixes.contains (suffix);
|
||||||
|
}
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user