Merge pull request #19 from Lisias/issues/18
Fixing https://github.com/AppleCommander/AppleCommander/issues/18
This commit is contained in:
commit
24623b2c20
|
@ -28,6 +28,9 @@ import java.util.List;
|
|||
* <p>
|
||||
* Date Created: Mar 2, 2003
|
||||
* @author Rob Greene
|
||||
*
|
||||
* Changed at: Dec 1, 2017
|
||||
* @author Lisias Toledo
|
||||
*/
|
||||
public interface DirectoryEntry {
|
||||
/**
|
||||
|
@ -37,17 +40,17 @@ public interface DirectoryEntry {
|
|||
* return value should always be a list - a directory
|
||||
* with 0 entries returns an empty list.
|
||||
*/
|
||||
public List<FileEntry> getFiles();
|
||||
public List<FileEntry> getFiles() throws DiskException;
|
||||
|
||||
/**
|
||||
* Create a new FileEntry.
|
||||
*/
|
||||
public FileEntry createFile() throws DiskFullException;
|
||||
|
||||
public FileEntry createFile() throws DiskException;
|
||||
|
||||
/**
|
||||
* Create a new DirectoryEntry.
|
||||
*/
|
||||
public DirectoryEntry createDirectory(String name) throws DiskFullException;
|
||||
public DirectoryEntry createDirectory(String name) throws DiskException;
|
||||
|
||||
/**
|
||||
* Identify if additional directories can be created. This
|
||||
|
@ -56,7 +59,7 @@ public interface DirectoryEntry {
|
|||
* to writing.
|
||||
*/
|
||||
public boolean canCreateDirectories();
|
||||
|
||||
|
||||
/**
|
||||
* Indicates if this disk image can create a file.
|
||||
* If not, the reason may be as simple as it has not beem implemented
|
||||
|
|
|
@ -369,10 +369,10 @@ public class Disk {
|
|||
|
||||
/**
|
||||
* Determine type of disk, and return the appropriate
|
||||
* FormattedDisk object. Returns null if none are
|
||||
* recognized.
|
||||
* FormattedDisk object. Throws an Exception if none is recognized.
|
||||
* @throws DiskUnrecognizedException
|
||||
*/
|
||||
public FormattedDisk[] getFormattedDisks() {
|
||||
public FormattedDisk[] getFormattedDisks() throws DiskUnrecognizedException {
|
||||
if (isProdosFormat()) {
|
||||
return new FormattedDisk[]
|
||||
{ new ProdosFormatDisk(filename, imageOrder) };
|
||||
|
@ -407,7 +407,7 @@ public class Disk {
|
|||
return new FormattedDisk[]
|
||||
{ new GutenbergFormatDisk(filename, imageOrder) };
|
||||
}
|
||||
return null;
|
||||
throw new DiskUnrecognizedException(filename);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -0,0 +1,62 @@
|
|||
/*
|
||||
* AppleCommander - An Apple ][ image utility.
|
||||
* Copyright (C) 2002 by Robert Greene
|
||||
* robgreene at users.sourceforge.net
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
package com.webcodepro.applecommander.storage;
|
||||
|
||||
/**
|
||||
* A DiskCorruptException is thrown during the disk's data structures are corrupted
|
||||
* beyound hope of automatic recovering.
|
||||
* <br>
|
||||
* Created on Nov 30, 2017.
|
||||
* @author Lisias Toledo
|
||||
*/
|
||||
public class DiskCorruptException extends DiskException {
|
||||
|
||||
private static final long serialVersionUID = 0xFFFFFFFF80000000L;
|
||||
|
||||
public enum Kind {
|
||||
RECURSIVE_DIRECTORY_STRUCTURE {
|
||||
public String toString() {
|
||||
return "DiskCorruptException.RecursiveDirectoryStructure"; //$NON-NLS-1$
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public final Kind kind;
|
||||
public final Object offender;
|
||||
|
||||
private DiskCorruptException(final String description, final String imagepath) {
|
||||
super(description, imagepath);
|
||||
this.kind = null;
|
||||
this.offender = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor for DiskFullException.
|
||||
*/
|
||||
public DiskCorruptException(final String imagepath, final Kind kind, final Object offender) {
|
||||
super(kind.toString(), imagepath);
|
||||
this.kind = kind;
|
||||
this.offender = offender;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return super.toString() + " @ " + offender.toString();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
* AppleCommander - An Apple ][ image utility.
|
||||
* Copyright (C) 2002 by Robert Greene
|
||||
* robgreene at users.sourceforge.net
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
package com.webcodepro.applecommander.storage;
|
||||
|
||||
/**
|
||||
* A DiskException is the base class for Disk Exceptions.
|
||||
* <br>
|
||||
* Created on Nov 30, 2017.
|
||||
* @author Lisias Toledo
|
||||
*/
|
||||
public abstract class DiskException extends Exception {
|
||||
|
||||
private static final long serialVersionUID = 0xFFFFFFFF80000000L;
|
||||
|
||||
public final String imagepath;
|
||||
|
||||
/**
|
||||
* Constructor for DiskException.
|
||||
*/
|
||||
public DiskException(final String description, final String imagepath) {
|
||||
super(description);
|
||||
this.imagepath = imagepath;
|
||||
}
|
||||
}
|
|
@ -25,15 +25,18 @@ package com.webcodepro.applecommander.storage;
|
|||
* <br>
|
||||
* Created on Dec 23, 2002.
|
||||
* @author Rob Greene
|
||||
*
|
||||
* Changed at: Dec 1, 2017
|
||||
* @author Lisias Toledo
|
||||
*/
|
||||
public class DiskFullException extends Exception {
|
||||
public class DiskFullException extends DiskException {
|
||||
|
||||
private static final long serialVersionUID = 0xFFFFFFFF80000000L;
|
||||
|
||||
/**
|
||||
* Constructor for DiskFullException.
|
||||
*/
|
||||
public DiskFullException(String description) {
|
||||
super(description);
|
||||
public DiskFullException(final String description, final String imagepath) {
|
||||
super(description, imagepath);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* AppleCommander - An Apple ][ image utility.
|
||||
* Copyright (C) 2002 by Robert Greene
|
||||
* robgreene at users.sourceforge.net
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
package com.webcodepro.applecommander.storage;
|
||||
|
||||
/**
|
||||
* A DiskUnrecognizedException is thrown when the Disk Image being opened is not recognized by any image handler.
|
||||
* <br>
|
||||
* Created at: Jan 8, 2018
|
||||
* @author Lisias Toledo
|
||||
*/
|
||||
public class DiskUnrecognizedException extends DiskException {
|
||||
|
||||
private static final long serialVersionUID = 0xFFFFFFFF80000000L;
|
||||
|
||||
/**
|
||||
* Constructor for DiskFullException.
|
||||
*/
|
||||
public DiskUnrecognizedException(final String imagepath) {
|
||||
super("DiskUnrecognizedException", imagepath);
|
||||
}
|
||||
}
|
|
@ -267,7 +267,7 @@ public abstract class FormattedDisk extends Disk implements DirectoryEntry {
|
|||
* Locate a specific file by filename.
|
||||
* Returns a null if specific filename is not located.
|
||||
*/
|
||||
public FileEntry getFile(String filename) {
|
||||
public FileEntry getFile(String filename) throws DiskException {
|
||||
List files = getFiles();
|
||||
return getFile(files, filename.trim());
|
||||
}
|
||||
|
@ -277,7 +277,7 @@ public abstract class FormattedDisk extends Disk implements DirectoryEntry {
|
|||
* Note that in the instance of a system with directories (ie, ProDOS),
|
||||
* this really returns the first file with the given filename.
|
||||
*/
|
||||
protected FileEntry getFile(List files, String filename) {
|
||||
protected FileEntry getFile(List files, String filename) throws DiskException {
|
||||
FileEntry theFileEntry = null;
|
||||
if (files != null) {
|
||||
for (int i=0; i<files.size(); i++) {
|
||||
|
|
|
@ -407,7 +407,9 @@ public class CpmFormatDisk extends FormattedDisk {
|
|||
* @see com.webcodepro.applecommander.storage.DirectoryEntry#createFile()
|
||||
*/
|
||||
public FileEntry createFile() throws DiskFullException {
|
||||
throw new DiskFullException(textBundle.get("FileCreationNotSupported")); //$NON-NLS-1$
|
||||
throw new DiskFullException(
|
||||
textBundle.get("FileCreationNotSupported") //$NON-NLS-1$
|
||||
, this.getFilename());
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -21,8 +21,12 @@ package com.webcodepro.applecommander.storage.os.dos33;
|
|||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.HashSet;
|
||||
|
||||
import com.webcodepro.applecommander.storage.DirectoryEntry;
|
||||
import com.webcodepro.applecommander.storage.DiskException;
|
||||
import com.webcodepro.applecommander.storage.DiskCorruptException;
|
||||
import com.webcodepro.applecommander.storage.DiskFullException;
|
||||
import com.webcodepro.applecommander.storage.FileEntry;
|
||||
import com.webcodepro.applecommander.storage.FormattedDisk;
|
||||
|
@ -36,6 +40,9 @@ import com.webcodepro.applecommander.util.TextBundle;
|
|||
* <p>
|
||||
* Date created: Oct 4, 2002 12:29:23 AM
|
||||
* @author Rob Greene
|
||||
*
|
||||
* Changed at: Dec 1, 2017
|
||||
* @author Lisias Toledo
|
||||
*/
|
||||
public class DosFormatDisk extends FormattedDisk {
|
||||
private TextBundle textBundle = StorageBundle.getInstance();
|
||||
|
@ -132,14 +139,22 @@ public class DosFormatDisk extends FormattedDisk {
|
|||
|
||||
/**
|
||||
* Retrieve a list of files.
|
||||
* @throws DiskException
|
||||
* @see com.webcodepro.applecommander.storage.FormattedDisk#getFiles()
|
||||
*/
|
||||
public List<FileEntry> getFiles() {
|
||||
public List<FileEntry> getFiles() throws DiskException {
|
||||
List<FileEntry> list = new ArrayList<>();
|
||||
byte[] vtoc = readVtoc();
|
||||
int track = AppleUtil.getUnsignedByte(vtoc[1]);
|
||||
int sector = AppleUtil.getUnsignedByte(vtoc[2]);
|
||||
final Set<DosSectorAddress> visits = new HashSet<>();
|
||||
while (sector != 0) { // bug fix: iterate through all catalog _sectors_
|
||||
|
||||
// Prevents a recursive catalog crawling.
|
||||
final DosSectorAddress address = new DosSectorAddress(track, sector);
|
||||
if ( visits.contains(address)) throw new DiskCorruptException(this.getFilename(), DiskCorruptException.Kind.RECURSIVE_DIRECTORY_STRUCTURE, address);
|
||||
else visits.add(address);
|
||||
|
||||
byte[] catalogSector = readSector(track, sector);
|
||||
int offset = 0x0b;
|
||||
while (offset < 0xff) { // iterate through all entries
|
||||
|
@ -174,7 +189,9 @@ public class DosFormatDisk extends FormattedDisk {
|
|||
track = catalogSector[1];
|
||||
sector = catalogSector[2];
|
||||
}
|
||||
throw new DiskFullException(textBundle.get("DosFormatDisk.NoMoreSpaceError")); //$NON-NLS-1$
|
||||
throw new DiskFullException(
|
||||
textBundle.get("DosFormatDisk.NoMoreSpaceError") //$NON-NLS-1$
|
||||
, this.getFilename());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -457,7 +474,8 @@ public class DosFormatDisk extends FormattedDisk {
|
|||
if (numberOfSectors > getFreeSectors() + fileEntry.getSectorsUsed()) {
|
||||
throw new DiskFullException(
|
||||
textBundle.format("DosFormatDisk.NotEnoughSectorsError", //$NON-NLS-1$
|
||||
numberOfSectors, getFreeSectors()));
|
||||
numberOfSectors, getFreeSectors())
|
||||
, this.getFilename());
|
||||
}
|
||||
// free "old" data and just rewrite stuff...
|
||||
freeSectors(fileEntry);
|
||||
|
|
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
* AppleCommander - An Apple ][ image utility.
|
||||
* Copyright (C) 2002 by Robert Greene
|
||||
* robgreene at users.sourceforge.net
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
package com.webcodepro.applecommander.storage.os.dos33;
|
||||
|
||||
/**
|
||||
* A Container for DOS 3.3 Sector Addresses.
|
||||
* <br>
|
||||
* Created on Dec 13, 2017.
|
||||
* @author Lisias Toledo
|
||||
*/
|
||||
public class DosSectorAddress {
|
||||
|
||||
public final Integer track;
|
||||
public final Integer sector;
|
||||
|
||||
public DosSectorAddress(int track, int sector) {
|
||||
this.track = track;
|
||||
this.sector = sector;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "Track:" + this.track + ", Sector:" + this.sector;
|
||||
}
|
||||
|
||||
public boolean equals(final Object other){
|
||||
if(other == null) return false;
|
||||
if(!(other instanceof DosSectorAddress)) return false;
|
||||
|
||||
final DosSectorAddress o = (DosSectorAddress) other;
|
||||
return this.track == o.track && this.sector == o.sector;
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
int result = 17;
|
||||
result = 31 * result + this.track.hashCode();
|
||||
result = 31 * result + this.sector.hashCode();
|
||||
return result;
|
||||
}
|
||||
}
|
|
@ -172,7 +172,9 @@ public class GutenbergFormatDisk extends FormattedDisk {
|
|||
track = catalogSector[1];
|
||||
sector = catalogSector[2];
|
||||
}
|
||||
throw new DiskFullException(textBundle.get("DosFormatDisk.NoMoreSpaceError")); //$NON-NLS-1$
|
||||
throw new DiskFullException(
|
||||
textBundle.get("DosFormatDisk.NoMoreSpaceError") //$NON-NLS-1$
|
||||
, this.getFilename());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -436,7 +438,8 @@ public class GutenbergFormatDisk extends FormattedDisk {
|
|||
if (numberOfSectors > getFreeSectors() + fileEntry.getSectorsUsed()) {
|
||||
throw new DiskFullException(
|
||||
textBundle.format("DosFormatDisk.NotEnoughSectorsError", //$NON-NLS-1$
|
||||
numberOfSectors, getFreeSectors()));
|
||||
numberOfSectors, getFreeSectors())
|
||||
, this.getFilename());
|
||||
}
|
||||
// free "old" data and just rewrite stuff...
|
||||
// freeSectors(fileEntry); (not going to work...)
|
||||
|
|
|
@ -351,7 +351,7 @@ public class PascalFileEntry implements FileEntry {
|
|||
volEntry.setFileCount(count - 2);
|
||||
dir.set(0, volEntry);
|
||||
disk.putDirectory(dir);
|
||||
throw new DiskFullException(s);
|
||||
throw new DiskFullException(s, this.disk.getFilename());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -233,7 +233,9 @@ public class PascalFormatDisk extends FormattedDisk {
|
|||
putDirectory(dir);
|
||||
return entry;
|
||||
} else {
|
||||
throw new DiskFullException(textBundle.get("PascalFormatDisk.DiskFull")); //$NON-NLS-1$
|
||||
throw new DiskFullException(
|
||||
textBundle.get("PascalFormatDisk.DiskFull") //$NON-NLS-1$
|
||||
, this.getFilename());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* AppleCommander - An Apple ][ image utility.
|
||||
* Copyright (C) 2002 by Robert Greene
|
||||
* robgreene at users.sourceforge.net
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
package com.webcodepro.applecommander.storage.os.prodos;
|
||||
|
||||
/**
|
||||
* A Container for DOS 3.3 Sector Addresses.
|
||||
* <br>
|
||||
* Created on Dec 13, 2017.
|
||||
* @author Lisias Toledo
|
||||
*/
|
||||
public class ProdosBlockAddress {
|
||||
|
||||
public final Integer number;
|
||||
|
||||
public ProdosBlockAddress(int number) {
|
||||
this.number = number;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "Block:" + this.number;
|
||||
}
|
||||
}
|
|
@ -22,6 +22,7 @@ package com.webcodepro.applecommander.storage.os.prodos;
|
|||
import java.util.List;
|
||||
|
||||
import com.webcodepro.applecommander.storage.DirectoryEntry;
|
||||
import com.webcodepro.applecommander.storage.DiskException;
|
||||
import com.webcodepro.applecommander.storage.DiskFullException;
|
||||
import com.webcodepro.applecommander.storage.FileEntry;
|
||||
import com.webcodepro.applecommander.storage.StorageBundle;
|
||||
|
@ -32,21 +33,24 @@ import com.webcodepro.applecommander.util.TextBundle;
|
|||
* <p>
|
||||
* Date Created: Mar 2, 2003
|
||||
* @author Rob Greene
|
||||
*
|
||||
* Changed at: Dec 1, 2017
|
||||
* @author Lisias Toledo
|
||||
*/
|
||||
public class ProdosDirectoryEntry extends ProdosFileEntry implements DirectoryEntry {
|
||||
private TextBundle textBundle = StorageBundle.getInstance();
|
||||
private ProdosSubdirectoryHeader subdirectoryHeader;
|
||||
|
||||
|
||||
/**
|
||||
* Constructor for ProdosDirectoryEntry.
|
||||
*/
|
||||
public ProdosDirectoryEntry(ProdosFormatDisk disk, int block, int offset,
|
||||
public ProdosDirectoryEntry(ProdosFormatDisk disk, int block, int offset,
|
||||
ProdosSubdirectoryHeader subdirectoryHeader) {
|
||||
super(disk, block, offset);
|
||||
this.subdirectoryHeader = subdirectoryHeader;
|
||||
subdirectoryHeader.setProdosDirectoryEntry(this);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the subdirectory header.
|
||||
*/
|
||||
|
@ -60,8 +64,9 @@ public class ProdosDirectoryEntry extends ProdosFileEntry implements DirectoryEn
|
|||
* value should be null. If this a directory, the
|
||||
* return value should always be a list - a directory
|
||||
* with 0 entries returns an empty list.
|
||||
* @throws DiskException
|
||||
*/
|
||||
public List<FileEntry> getFiles() {
|
||||
public List<FileEntry> getFiles() throws DiskException {
|
||||
return getDisk().getFiles(getSubdirectoryHeader().getFileEntryBlock());
|
||||
}
|
||||
|
||||
|
|
|
@ -37,7 +37,7 @@ public class ProdosDiskSizeDoesNotMatchException extends DiskFullException {
|
|||
/**
|
||||
* Constructor for ProdosDiskSizeDoesNotMatchException.
|
||||
*/
|
||||
public ProdosDiskSizeDoesNotMatchException(String description) {
|
||||
super(description);
|
||||
public ProdosDiskSizeDoesNotMatchException(String description, final String imagepath) {
|
||||
super(description, imagepath);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,8 +25,12 @@ import java.util.ArrayList;
|
|||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
import java.util.Set;
|
||||
import java.util.HashSet;
|
||||
|
||||
import com.webcodepro.applecommander.storage.DirectoryEntry;
|
||||
import com.webcodepro.applecommander.storage.DiskException;
|
||||
import com.webcodepro.applecommander.storage.DiskCorruptException;
|
||||
import com.webcodepro.applecommander.storage.DiskFullException;
|
||||
import com.webcodepro.applecommander.storage.FileEntry;
|
||||
import com.webcodepro.applecommander.storage.FormattedDisk;
|
||||
|
@ -40,6 +44,9 @@ import com.webcodepro.applecommander.util.TextBundle;
|
|||
* <p>
|
||||
* Date created: Oct 3, 2002 11:45:25 PM
|
||||
* @author Rob Greene
|
||||
*
|
||||
* Changed at: Dec 1, 2017
|
||||
* @author Lisias Toledo
|
||||
*/
|
||||
public class ProdosFormatDisk extends FormattedDisk {
|
||||
private TextBundle textBundle = StorageBundle.getInstance();
|
||||
|
@ -250,14 +257,15 @@ public class ProdosFormatDisk extends FormattedDisk {
|
|||
}
|
||||
blockNumber = nextBlockNumber;
|
||||
}
|
||||
throw new DiskFullException(textBundle.get("ProdosFormatDisk.UnableToAllocateSpaceError")); //$NON-NLS-1$
|
||||
throw new DiskFullException(textBundle.get("ProdosFormatDisk.UnableToAllocateSpaceError"), this.getFilename()); //$NON-NLS-1$
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve a list of files.
|
||||
* @throws DiskException
|
||||
* @see com.webcodepro.applecommander.storage.FormattedDisk#getFiles()
|
||||
*/
|
||||
public List<FileEntry> getFiles() {
|
||||
public List<FileEntry> getFiles() throws DiskException {
|
||||
return getFiles(VOLUME_DIRECTORY_BLOCK);
|
||||
}
|
||||
|
||||
|
@ -265,9 +273,14 @@ public class ProdosFormatDisk extends FormattedDisk {
|
|||
* Build a list of files, starting in the given block number.
|
||||
* This works for the master as well as the subdirectories.
|
||||
*/
|
||||
protected List<FileEntry> getFiles(int blockNumber) {
|
||||
protected List<FileEntry> getFiles(int blockNumber) throws DiskException {
|
||||
List<FileEntry> files = new ArrayList<>();
|
||||
final Set<Integer> visits = new HashSet<>();
|
||||
while (blockNumber != 0) {
|
||||
// Prevents a recursive catalog crawling.
|
||||
if ( visits.contains(blockNumber)) throw new DiskCorruptException(this.getFilename(), DiskCorruptException.Kind.RECURSIVE_DIRECTORY_STRUCTURE, new ProdosBlockAddress(blockNumber));
|
||||
else visits.add(blockNumber);
|
||||
|
||||
byte[] block = readBlock(blockNumber);
|
||||
int offset = 4;
|
||||
while (offset+ProdosCommonEntry.ENTRY_LENGTH < BLOCK_SIZE) {
|
||||
|
@ -643,7 +656,8 @@ public class ProdosFormatDisk extends FormattedDisk {
|
|||
if (numberOfBlocks > getFreeBlocks() + fileEntry.getBlocksUsed()) {
|
||||
throw new DiskFullException(textBundle.
|
||||
format("ProdosFormatDisk.NotEnoughSpaceOnDiskError", //$NON-NLS-1$
|
||||
numberOfBlocks, getFreeBlocks()));
|
||||
numberOfBlocks, getFreeBlocks())
|
||||
, this.getFilename());
|
||||
}
|
||||
// free "old" data and just rewrite stuff...
|
||||
freeBlocks(fileEntry);
|
||||
|
@ -748,7 +762,8 @@ public class ProdosFormatDisk extends FormattedDisk {
|
|||
if (numberOfBlocks > getFreeBlocks() + fileEntry.getBlocksUsed()) {
|
||||
throw new DiskFullException(textBundle.
|
||||
format("ProdosFormatDisk.NotEnoughSpaceOnDiskError", //$NON-NLS-1$
|
||||
numberOfBlocks, getFreeBlocks()));
|
||||
numberOfBlocks, getFreeBlocks())
|
||||
, this.getFilename());
|
||||
}
|
||||
// free "old" data and just rewrite stuff...
|
||||
freeBlocks(fileEntry);
|
||||
|
@ -915,7 +930,8 @@ public class ProdosFormatDisk extends FormattedDisk {
|
|||
if (numberOfBlocks > getFreeBlocks() + fileEntry.getBlocksUsed()) {
|
||||
throw new DiskFullException(textBundle.
|
||||
format("ProdosFormatDisk.NotEnoughSpaceOnDiskError", //$NON-NLS-1$
|
||||
numberOfBlocks, getFreeBlocks()));
|
||||
numberOfBlocks, getFreeBlocks())
|
||||
, this.getFilename());
|
||||
}
|
||||
// free "old" data and just rewrite stuff...
|
||||
freeBlocks(fileEntry);
|
||||
|
@ -1056,12 +1072,14 @@ public class ProdosFormatDisk extends FormattedDisk {
|
|||
return block;
|
||||
}
|
||||
throw new ProdosDiskSizeDoesNotMatchException(
|
||||
textBundle.get("ProdosFormatDisk.ProdosDiskSizeDoesNotMatchError")); //$NON-NLS-1$
|
||||
textBundle.get("ProdosFormatDisk.ProdosDiskSizeDoesNotMatchError") //$NON-NLS-1$
|
||||
, this.getFilename());
|
||||
}
|
||||
block++;
|
||||
}
|
||||
throw new DiskFullException(
|
||||
textBundle.get("ProdosFormatDisk.NoFreeBlockAvailableError")); //$NON-NLS-1$
|
||||
textBundle.get("ProdosFormatDisk.NoFreeBlockAvailableError") //$NON-NLS-1$
|
||||
, this.getFilename());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1410,6 +1428,8 @@ public class ProdosFormatDisk extends FormattedDisk {
|
|||
}
|
||||
blockNumber = nextBlockNumber;
|
||||
}
|
||||
throw new DiskFullException(textBundle.get("ProdosFormatDisk.UnableToAllocateSpaceError")); //$NON-NLS-1$
|
||||
throw new DiskFullException(
|
||||
textBundle.get("ProdosFormatDisk.UnableToAllocateSpaceError") //$NON-NLS-1$
|
||||
, this.getFilename());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -202,7 +202,7 @@ public class RdosFormatDisk extends FormattedDisk {
|
|||
* Create a new FileEntry.
|
||||
*/
|
||||
public FileEntry createFile() throws DiskFullException {
|
||||
throw new DiskFullException(textBundle.get("FileCreationNotSupported")); //$NON-NLS-1$
|
||||
throw new DiskFullException(textBundle.get("FileCreationNotSupported"), this.getFilename()); //$NON-NLS-1$
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -26,6 +26,7 @@ import java.io.PrintStream;
|
|||
import org.apache.tools.ant.BuildException;
|
||||
import org.apache.tools.ant.Task;
|
||||
import com.webcodepro.applecommander.storage.Disk;
|
||||
import com.webcodepro.applecommander.storage.DiskException;
|
||||
import com.webcodepro.applecommander.storage.FormattedDisk;
|
||||
|
||||
public class AntTask extends Task
|
||||
|
@ -107,7 +108,7 @@ public class AntTask extends Task
|
|||
{
|
||||
com.webcodepro.applecommander.ui.ac.deleteFile(_imageName, _fileName);
|
||||
}
|
||||
catch (IOException io)
|
||||
catch (IOException|DiskException io)
|
||||
{
|
||||
if (_failonerror)
|
||||
throw new BuildException(io);
|
||||
|
@ -121,7 +122,7 @@ public class AntTask extends Task
|
|||
{
|
||||
com.webcodepro.applecommander.ui.ac.setDiskName(_imageName, _volName);
|
||||
}
|
||||
catch (IOException io)
|
||||
catch (IOException|DiskException io)
|
||||
{
|
||||
if (_failonerror)
|
||||
throw new BuildException(io);
|
||||
|
@ -138,7 +139,7 @@ public class AntTask extends Task
|
|||
else // Assume unlock
|
||||
com.webcodepro.applecommander.ui.ac.setFileLocked(_imageName, _fileName, false);
|
||||
}
|
||||
catch (IOException io)
|
||||
catch (IOException|DiskException io)
|
||||
{
|
||||
if (_failonerror)
|
||||
throw new BuildException(io);
|
||||
|
@ -220,7 +221,7 @@ public class AntTask extends Task
|
|||
{
|
||||
com.webcodepro.applecommander.ui.ac.getFiles(_imageName, _outputPath);
|
||||
}
|
||||
catch (IOException io)
|
||||
catch (IOException|DiskException io)
|
||||
{
|
||||
if (_failonerror)
|
||||
throw new BuildException(io);
|
||||
|
|
|
@ -34,7 +34,7 @@ import java.util.List;
|
|||
|
||||
import com.webcodepro.applecommander.storage.DirectoryEntry;
|
||||
import com.webcodepro.applecommander.storage.Disk;
|
||||
import com.webcodepro.applecommander.storage.DiskFullException;
|
||||
import com.webcodepro.applecommander.storage.DiskException;
|
||||
import com.webcodepro.applecommander.storage.FileEntry;
|
||||
import com.webcodepro.applecommander.storage.FileFilter;
|
||||
import com.webcodepro.applecommander.storage.FormattedDisk;
|
||||
|
@ -85,6 +85,9 @@ import com.webcodepro.applecommander.util.TextBundle;
|
|||
* </pre>
|
||||
*
|
||||
* @author John B. Matthews
|
||||
*
|
||||
* Changed at: Dec 1, 2017
|
||||
* @author Lisias Toledo
|
||||
*/
|
||||
public class ac {
|
||||
private static TextBundle textBundle = UiBundle.getInstance();
|
||||
|
@ -154,7 +157,7 @@ public class ac {
|
|||
* Put fileName from the local filesytem into the file named fileOnImageName on the disk named imageName;
|
||||
* Note: only volume level supported; input size unlimited.
|
||||
*/
|
||||
public static void putFile(String fileName, String imageName, String fileOnImageName, String fileType, String address) throws IOException, DiskFullException {
|
||||
public static void putFile(String fileName, String imageName, String fileOnImageName, String fileType, String address) throws IOException, DiskException {
|
||||
Name name = new Name(fileOnImageName);
|
||||
File file = new File(fileName);
|
||||
if (!file.canRead())
|
||||
|
@ -188,7 +191,7 @@ public class ac {
|
|||
* Note: only volume level supported; input size unlimited.
|
||||
*/
|
||||
static void putFile(String imageName, Name name, String fileType,
|
||||
String address) throws IOException, DiskFullException {
|
||||
String address) throws IOException, DiskException {
|
||||
|
||||
ByteArrayOutputStream buf = new ByteArrayOutputStream();
|
||||
byte[] inb = new byte[1024];
|
||||
|
@ -225,7 +228,7 @@ public class ac {
|
|||
* Assume a cc65 style four-byte header with start address in bytes 0-1.
|
||||
*/
|
||||
public static void putCC65(String fileName, String imageName, String fileOnImageName, String fileType)
|
||||
throws IOException, DiskFullException {
|
||||
throws IOException, DiskException {
|
||||
|
||||
byte[] header = new byte[4];
|
||||
if (System.in.read(header, 0, 4) == 4) {
|
||||
|
@ -239,7 +242,7 @@ public class ac {
|
|||
* Assume a cc65 style four-byte header with start address in bytes 0-1.
|
||||
*/
|
||||
static void putCC65(String imageName, Name name, String fileType)
|
||||
throws IOException, DiskFullException {
|
||||
throws IOException, DiskException {
|
||||
|
||||
byte[] header = new byte[4];
|
||||
if (System.in.read(header, 0, 4) == 4) {
|
||||
|
@ -253,7 +256,7 @@ public class ac {
|
|||
* This would only make sense for a ProDOS-formatted disk.
|
||||
*/
|
||||
static void putGEOS(String imageName)
|
||||
throws IOException, DiskFullException {
|
||||
throws IOException, DiskException {
|
||||
putFile(imageName, new Name("GEOS-Should Be ProDOS"), "GEO", "0"); //$NON-NLS-2$ $NON-NLS-3$
|
||||
}
|
||||
|
||||
|
@ -261,7 +264,7 @@ public class ac {
|
|||
* Delete the file named fileName from the disk named imageName.
|
||||
*/
|
||||
static void deleteFile(String imageName, String fileName)
|
||||
throws IOException {
|
||||
throws IOException, DiskException {
|
||||
Disk disk = new Disk(imageName);
|
||||
Name name = new Name(fileName);
|
||||
if (!disk.isSDK() && !disk.isDC42()) {
|
||||
|
@ -287,7 +290,7 @@ public class ac {
|
|||
* filtered according to its type and sent to <stdout>.
|
||||
*/
|
||||
static void getFile(String imageName, String fileName, boolean filter, PrintStream out)
|
||||
throws IOException {
|
||||
throws IOException, DiskException {
|
||||
Disk disk = new Disk(imageName);
|
||||
Name name = new Name(fileName);
|
||||
FormattedDisk[] formattedDisks = disk.getFormattedDisks();
|
||||
|
@ -317,7 +320,7 @@ public class ac {
|
|||
/**
|
||||
* Extract all files in the image according to their respective filetype.
|
||||
*/
|
||||
static void getFiles(String imageName, String directory) throws IOException {
|
||||
static void getFiles(String imageName, String directory) throws IOException, DiskException {
|
||||
Disk disk = new Disk(imageName);
|
||||
if ((directory != null) && (directory.length() > 0)) {
|
||||
// Add a final directory separator if the user didn't supply one
|
||||
|
@ -327,16 +330,16 @@ public class ac {
|
|||
directory = "."+File.separator;
|
||||
}
|
||||
FormattedDisk[] formattedDisks = disk.getFormattedDisks();
|
||||
for (int i = 0; i < formattedDisks.length; i++) {
|
||||
for (int i = 0; i < formattedDisks.length; i++) {
|
||||
FormattedDisk formattedDisk = formattedDisks[i];
|
||||
writeFiles(formattedDisk.getFiles(), directory);
|
||||
writeFiles(formattedDisk.getFiles(), directory);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Recursive routine to write directory and file entries.
|
||||
*/
|
||||
static void writeFiles(List files, String directory) throws IOException {
|
||||
static void writeFiles(List files, String directory) throws IOException, DiskException {
|
||||
Iterator it = files.iterator();
|
||||
while (it.hasNext()) {
|
||||
FileEntry entry = (FileEntry) it.next();
|
||||
|
@ -352,7 +355,7 @@ public class ac {
|
|||
OutputStream output = new FileOutputStream(file);
|
||||
output.write(buf, 0, buf.length);
|
||||
output.close();
|
||||
} else if (entry.isDirectory()) {
|
||||
} else if (entry.isDirectory()) {
|
||||
writeFiles(((DirectoryEntry) entry).getFiles(),directory+entry.getFilename()+File.separator);
|
||||
}
|
||||
}
|
||||
|
@ -364,7 +367,7 @@ public class ac {
|
|||
* file with the given filename.
|
||||
* @deprecated
|
||||
*/
|
||||
static FileEntry getEntry(List files, String fileName) {
|
||||
static FileEntry getEntry(List files, String fileName) throws DiskException {
|
||||
FileEntry entry = null;
|
||||
if (files != null) {
|
||||
for (int i = 0; i < files.size(); i++) {
|
||||
|
@ -406,6 +409,8 @@ public class ac {
|
|||
new Integer(formattedDisk.getUsedSpace()) }));
|
||||
System.out.println();
|
||||
}
|
||||
} catch (DiskException e) {
|
||||
throw new IOException(e);
|
||||
} catch (RuntimeException e) {
|
||||
System.out.println(args[d] + ": " + e.getMessage()); //$NON-NLS-1$
|
||||
System.out.println();
|
||||
|
@ -418,7 +423,7 @@ public class ac {
|
|||
* system with directories (e.g. ProDOS), this really returns the first file
|
||||
* with the given filename.
|
||||
*/
|
||||
static void showFiles(List files, String indent, int display) {
|
||||
static void showFiles(List files, String indent, int display) throws DiskException {
|
||||
for (int i = 0; i < files.size(); i++) {
|
||||
FileEntry entry = (FileEntry) files.get(i);
|
||||
if (!entry.isDeleted()) {
|
||||
|
@ -440,7 +445,7 @@ public class ac {
|
|||
/**
|
||||
* Display information about each disk in args.
|
||||
*/
|
||||
static void getDiskInfo(String[] args) throws IOException {
|
||||
static void getDiskInfo(String[] args) throws IOException, DiskException {
|
||||
for (int d = 1; d < args.length; d++) {
|
||||
Disk disk = new Disk(args[d]);
|
||||
FormattedDisk[] formattedDisks = disk.getFormattedDisks();
|
||||
|
@ -460,7 +465,7 @@ public class ac {
|
|||
* Set the lockState of the file named fileName on the disk named imageName.
|
||||
* Proposed by David Schmidt.
|
||||
*/
|
||||
public static void setFileLocked(String imageName, String name, boolean lockState) throws IOException {
|
||||
public static void setFileLocked(String imageName, String name, boolean lockState) throws IOException, DiskException {
|
||||
setFileLocked(imageName, new Name(name), lockState);
|
||||
}
|
||||
|
||||
|
@ -469,7 +474,7 @@ public class ac {
|
|||
* Proposed by David Schmidt.
|
||||
*/
|
||||
static void setFileLocked(String imageName, Name name,
|
||||
boolean lockState) throws IOException {
|
||||
boolean lockState) throws IOException, DiskException {
|
||||
Disk disk = new Disk(imageName);
|
||||
if (!disk.isSDK() && !disk.isDC42()) {
|
||||
FormattedDisk[] formattedDisks = disk.getFormattedDisks();
|
||||
|
@ -494,7 +499,7 @@ public class ac {
|
|||
* Pascal disks; others ignored. Proposed by David Schmidt.
|
||||
*/
|
||||
public static void setDiskName(String imageName, String volName)
|
||||
throws IOException {
|
||||
throws IOException, DiskException {
|
||||
Disk disk = new Disk(imageName);
|
||||
if (!disk.isSDK() && !disk.isDC42()) {
|
||||
FormattedDisk[] formattedDisks = disk.getFormattedDisks();
|
||||
|
@ -601,7 +606,7 @@ public class ac {
|
|||
this.name = path[path.length - 1];
|
||||
}
|
||||
|
||||
public FileEntry getEntry(FormattedDisk formattedDisk) {
|
||||
public FileEntry getEntry(FormattedDisk formattedDisk) throws DiskException {
|
||||
List files = formattedDisk.getFiles();
|
||||
FileEntry entry = null;
|
||||
for (int i = 0; i < path.length - 1; i++) {
|
||||
|
@ -624,7 +629,7 @@ public class ac {
|
|||
return null;
|
||||
}
|
||||
|
||||
public FileEntry createEntry(FormattedDisk formattedDisk) throws DiskFullException {
|
||||
public FileEntry createEntry(FormattedDisk formattedDisk) throws DiskException {
|
||||
if (path.length == 1) {
|
||||
return formattedDisk.createFile();
|
||||
}
|
||||
|
|
|
@ -26,6 +26,7 @@ import java.io.FileOutputStream;
|
|||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
|
@ -71,6 +72,8 @@ import org.eclipse.swt.widgets.TreeItem;
|
|||
import com.webcodepro.applecommander.compiler.ApplesoftCompiler;
|
||||
import com.webcodepro.applecommander.storage.DirectoryEntry;
|
||||
import com.webcodepro.applecommander.storage.Disk;
|
||||
import com.webcodepro.applecommander.storage.DiskCorruptException;
|
||||
import com.webcodepro.applecommander.storage.DiskException;
|
||||
import com.webcodepro.applecommander.storage.FileEntry;
|
||||
import com.webcodepro.applecommander.storage.FileEntryComparator;
|
||||
import com.webcodepro.applecommander.storage.FileFilter;
|
||||
|
@ -114,6 +117,9 @@ import com.webcodepro.applecommander.util.TextBundle;
|
|||
* <p>
|
||||
* Date created: Nov 17, 2002 9:46:53 PM
|
||||
* @author Rob Greene
|
||||
*
|
||||
* Changed at: Dec 1, 2017
|
||||
* @author Lisias Toledo
|
||||
*/
|
||||
public class DiskExplorerTab {
|
||||
private static final char CTRL_C = 'C' - '@';
|
||||
|
@ -224,7 +230,11 @@ public class DiskExplorerTab {
|
|||
* Single-click handler.
|
||||
*/
|
||||
public void widgetSelected(SelectionEvent event) {
|
||||
changeCurrentFormat(getCurrentFormat()); // minor hack
|
||||
try {
|
||||
changeCurrentFormat(getCurrentFormat()); // minor hack
|
||||
} catch (DiskException e) {
|
||||
DiskExplorerTab.this.diskWindow.handle(e);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Double-click handler.
|
||||
|
@ -248,27 +258,35 @@ public class DiskExplorerTab {
|
|||
diskItem.setText(disks[i].getDiskName());
|
||||
diskItem.setData(disks[i]);
|
||||
directoryTree.setSelection(new TreeItem[] { diskItem });
|
||||
|
||||
|
||||
if (disks[i].canHaveDirectories()) {
|
||||
Iterator files = disks[i].getFiles().iterator();
|
||||
while (files.hasNext()) {
|
||||
FileEntry entry = (FileEntry) files.next();
|
||||
if (entry.isDirectory()) {
|
||||
TreeItem item = new TreeItem(diskItem, SWT.BORDER);
|
||||
item.setText(entry.getFilename());
|
||||
item.setData(entry);
|
||||
addDirectoriesToTree(item, (DirectoryEntry)entry);
|
||||
try {
|
||||
Iterator files = disks[i].getFiles().iterator();
|
||||
while (files.hasNext()) {
|
||||
FileEntry entry = (FileEntry) files.next();
|
||||
if (entry.isDirectory()) {
|
||||
TreeItem item = new TreeItem(diskItem, SWT.BORDER);
|
||||
item.setText(entry.getFilename());
|
||||
item.setData(entry);
|
||||
addDirectoriesToTree(item, (DirectoryEntry)entry);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (DiskException e) {
|
||||
this.diskWindow.handle(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
computeColumnWidths(FormattedDisk.FILE_DISPLAY_STANDARD);
|
||||
computeColumnWidths(FormattedDisk.FILE_DISPLAY_NATIVE);
|
||||
computeColumnWidths(FormattedDisk.FILE_DISPLAY_DETAIL);
|
||||
|
||||
formatChanged = true;
|
||||
fillFileTable(disks[0].getFiles());
|
||||
try {
|
||||
fillFileTable(disks[0].getFiles());
|
||||
} catch (DiskException e) {
|
||||
this.diskWindow.handle(e);
|
||||
}
|
||||
directoryTree.setSelection(new TreeItem[] { directoryTree.getItems()[0] });
|
||||
}
|
||||
/**
|
||||
|
@ -338,11 +356,15 @@ public class DiskExplorerTab {
|
|||
item.setImage(imageManager.get(ImageManager.ICON_IMPORT_FILE));
|
||||
item.addSelectionListener(new SelectionAdapter() {
|
||||
public void widgetSelected(SelectionEvent event) {
|
||||
importFiles();
|
||||
try {
|
||||
importFiles();
|
||||
} catch (DiskException e) {
|
||||
DiskExplorerTab.this.diskWindow.handle(e);
|
||||
}
|
||||
}
|
||||
});
|
||||
item.setEnabled(disks[0].canCreateFile() && disks[0].canWriteFileData());
|
||||
|
||||
|
||||
return menu;
|
||||
}
|
||||
/**
|
||||
|
@ -389,7 +411,11 @@ public class DiskExplorerTab {
|
|||
item.setImage(imageManager.get(ImageManager.ICON_VIEW_FILE));
|
||||
item.addSelectionListener(new SelectionAdapter() {
|
||||
public void widgetSelected(SelectionEvent event) {
|
||||
viewFile(null);
|
||||
try {
|
||||
viewFile(null);
|
||||
} catch (DiskException e) {
|
||||
DiskExplorerTab.this.diskWindow.handle(e);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -444,7 +470,11 @@ public class DiskExplorerTab {
|
|||
item.setText(textBundle.get("ViewAsTextMenuItem")); //$NON-NLS-1$
|
||||
item.addSelectionListener(new SelectionAdapter() {
|
||||
public void widgetSelected(SelectionEvent event) {
|
||||
viewFile(TextFileFilter.class);
|
||||
try {
|
||||
viewFile(TextFileFilter.class);
|
||||
} catch (DiskException e) {
|
||||
DiskExplorerTab.this.diskWindow.handle(e);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -452,7 +482,11 @@ public class DiskExplorerTab {
|
|||
item.setText(textBundle.get("VeiwAsGraphicsMenuItem")); //$NON-NLS-1$
|
||||
item.addSelectionListener(new SelectionAdapter() {
|
||||
public void widgetSelected(SelectionEvent event) {
|
||||
viewFile(GraphicsFileFilter.class);
|
||||
try {
|
||||
viewFile(GraphicsFileFilter.class);
|
||||
} catch (DiskException e) {
|
||||
DiskExplorerTab.this.diskWindow.handle(e);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -879,7 +913,11 @@ public class DiskExplorerTab {
|
|||
* Double-click handler.
|
||||
*/
|
||||
public void widgetDefaultSelected(SelectionEvent event) {
|
||||
viewFile(null);
|
||||
try {
|
||||
viewFile(null);
|
||||
} catch (DiskException e) {
|
||||
DiskExplorerTab.this.diskWindow.handle(e);
|
||||
}
|
||||
}
|
||||
});
|
||||
TableColumn column = null;
|
||||
|
@ -1101,12 +1139,13 @@ public class DiskExplorerTab {
|
|||
}
|
||||
/**
|
||||
* Start the import wizard and import the selected files.
|
||||
* @throws DiskException
|
||||
*/
|
||||
protected void importFiles() {
|
||||
protected void importFiles() throws DiskException {
|
||||
//FIXME: This code has become really ugly!
|
||||
TreeItem treeItem = directoryTree.getSelection()[0];
|
||||
DirectoryEntry directory = (DirectoryEntry) treeItem.getData();
|
||||
ImportWizard wizard = new ImportWizard(shell,
|
||||
ImportWizard wizard = new ImportWizard(shell,
|
||||
imageManager, directory.getFormattedDisk());
|
||||
wizard.open();
|
||||
if (wizard.isWizardCompleted()) {
|
||||
|
@ -1201,8 +1240,9 @@ public class DiskExplorerTab {
|
|||
}
|
||||
/**
|
||||
* Helper function for building fileTree.
|
||||
* @throws DiskException
|
||||
*/
|
||||
protected void addDirectoriesToTree(TreeItem directoryItem, DirectoryEntry directoryEntry) {
|
||||
protected void addDirectoriesToTree(TreeItem directoryItem, DirectoryEntry directoryEntry) throws DiskException {
|
||||
Iterator files = directoryEntry.getFiles().iterator();
|
||||
while (files.hasNext()) {
|
||||
final FileEntry entry = (FileEntry) files.next();
|
||||
|
@ -1228,8 +1268,12 @@ public class DiskExplorerTab {
|
|||
standardFormatToolItem.setToolTipText(textBundle.get("StandardViewHoverText")); //$NON-NLS-1$
|
||||
standardFormatToolItem.setSelection(true);
|
||||
standardFormatToolItem.addSelectionListener(new SelectionAdapter () {
|
||||
public void widgetSelected(SelectionEvent e) {
|
||||
changeCurrentFormat(FormattedDisk.FILE_DISPLAY_STANDARD);
|
||||
public void widgetSelected(SelectionEvent event) {
|
||||
try {
|
||||
changeCurrentFormat(FormattedDisk.FILE_DISPLAY_STANDARD);
|
||||
} catch (DiskException e) {
|
||||
DiskExplorerTab.this.diskWindow.handle(e);
|
||||
}
|
||||
}
|
||||
});
|
||||
nativeFormatToolItem = new ToolItem(toolBar, SWT.RADIO);
|
||||
|
@ -1237,8 +1281,12 @@ public class DiskExplorerTab {
|
|||
nativeFormatToolItem.setText(textBundle.get("NativeViewToolItem")); //$NON-NLS-1$
|
||||
nativeFormatToolItem.setToolTipText(textBundle.get("NativeViewHoverText")); //$NON-NLS-1$
|
||||
nativeFormatToolItem.addSelectionListener(new SelectionAdapter () {
|
||||
public void widgetSelected(SelectionEvent e) {
|
||||
changeCurrentFormat(FormattedDisk.FILE_DISPLAY_NATIVE);
|
||||
public void widgetSelected(SelectionEvent event) {
|
||||
try {
|
||||
changeCurrentFormat(FormattedDisk.FILE_DISPLAY_NATIVE);
|
||||
} catch (DiskException e) {
|
||||
DiskExplorerTab.this.diskWindow.handle(e);
|
||||
}
|
||||
}
|
||||
});
|
||||
detailFormatToolItem = new ToolItem(toolBar, SWT.RADIO);
|
||||
|
@ -1246,13 +1294,17 @@ public class DiskExplorerTab {
|
|||
detailFormatToolItem.setText(textBundle.get("DetailViewToolItem")); //$NON-NLS-1$
|
||||
detailFormatToolItem.setToolTipText(textBundle.get("DetailViewHoverText")); //$NON-NLS-1$
|
||||
detailFormatToolItem.addSelectionListener(new SelectionAdapter () {
|
||||
public void widgetSelected(SelectionEvent e) {
|
||||
changeCurrentFormat(FormattedDisk.FILE_DISPLAY_DETAIL);
|
||||
public void widgetSelected(SelectionEvent event) {
|
||||
try {
|
||||
changeCurrentFormat(FormattedDisk.FILE_DISPLAY_DETAIL);
|
||||
} catch (DiskException e) {
|
||||
DiskExplorerTab.this.diskWindow.handle(e);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
new ToolItem(toolBar, SWT.SEPARATOR);
|
||||
|
||||
|
||||
showDeletedFilesToolItem = new ToolItem(toolBar, SWT.CHECK);
|
||||
showDeletedFilesToolItem.setImage(imageManager.get(ImageManager.ICON_SHOW_DELETED_FILES));
|
||||
showDeletedFilesToolItem.setText(textBundle.get("ShowDeletedFilesToolItem")); //$NON-NLS-1$
|
||||
|
@ -1274,11 +1326,15 @@ public class DiskExplorerTab {
|
|||
importToolItem.setToolTipText(textBundle.get("ImportWizardHoverText")); //$NON-NLS-1$
|
||||
importToolItem.setEnabled(disks[0].canCreateFile() && disks[0].canWriteFileData());
|
||||
importToolItem.addSelectionListener(new SelectionAdapter () {
|
||||
public void widgetSelected(SelectionEvent e) {
|
||||
importFiles();
|
||||
public void widgetSelected(SelectionEvent event) {
|
||||
try {
|
||||
importFiles();
|
||||
} catch (DiskException e) {
|
||||
DiskExplorerTab.this.diskWindow.handle(e);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
exportToolItem = new ToolItem(toolBar, SWT.DROP_DOWN);
|
||||
exportToolItem.setImage(imageManager.get(ImageManager.ICON_EXPORT_FILE));
|
||||
exportToolItem.setText(textBundle.get("ExportWizardToolItem")); //$NON-NLS-1$
|
||||
|
@ -1315,8 +1371,12 @@ public class DiskExplorerTab {
|
|||
viewFileItem.setEnabled(false);
|
||||
viewFileItem.addSelectionListener(new SelectionAdapter () {
|
||||
public void widgetSelected(SelectionEvent event) {
|
||||
if (event.detail != SWT.ARROW) {
|
||||
viewFile(null);
|
||||
if (event.detail != SWT.ARROW) {
|
||||
try {
|
||||
viewFile(null);
|
||||
} catch (DiskException e) {
|
||||
DiskExplorerTab.this.diskWindow.handle(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -1402,8 +1462,9 @@ public class DiskExplorerTab {
|
|||
}
|
||||
/**
|
||||
* Change the current format and refresh the display.
|
||||
* @throws DiskException
|
||||
*/
|
||||
protected void changeCurrentFormat(int newFormat) {
|
||||
protected void changeCurrentFormat(int newFormat) throws DiskException {
|
||||
TreeItem selection = directoryTree.getSelection()[0];
|
||||
Object data = selection.getData();
|
||||
DirectoryEntry directory = (DirectoryEntry) data;
|
||||
|
@ -1522,8 +1583,9 @@ public class DiskExplorerTab {
|
|||
}
|
||||
/**
|
||||
* Open up the view file window for the currently selected file.
|
||||
* @throws DiskException
|
||||
*/
|
||||
protected void viewFile(Class fileFilterClass) {
|
||||
protected void viewFile(Class fileFilterClass) throws DiskException {
|
||||
FileEntry fileEntry = getSelectedFileEntry();
|
||||
if (fileEntry.isDeleted()) {
|
||||
SwtUtil.showErrorDialog(shell, textBundle.get("DeleteFileErrorTitle"), //$NON-NLS-1$
|
||||
|
@ -1584,24 +1646,28 @@ public class DiskExplorerTab {
|
|||
public void handleEvent(Event event) {
|
||||
FileEntry fileEntry = getSelectedFileEntry();
|
||||
if (fileEntry != null && event.type == SWT.KeyUp && (event.stateMask & SWT.CTRL) != 0) {
|
||||
switch (event.character) {
|
||||
case CTRL_C: // Compile Wizard
|
||||
if (getCompileToolItem().isEnabled()) {
|
||||
compileFileWizard();
|
||||
}
|
||||
break;
|
||||
case CTRL_D: // Delete file
|
||||
if (getDeleteToolItem().isEnabled()) {
|
||||
deleteFile();
|
||||
}
|
||||
break;
|
||||
case CTRL_E: // Export Wizard
|
||||
exportFileWizard();
|
||||
break;
|
||||
case CTRL_V: // View file
|
||||
viewFile(null);
|
||||
break;
|
||||
}
|
||||
try {
|
||||
switch (event.character) {
|
||||
case CTRL_C: // Compile Wizard
|
||||
if (getCompileToolItem().isEnabled()) {
|
||||
compileFileWizard();
|
||||
}
|
||||
break;
|
||||
case CTRL_D: // Delete file
|
||||
if (getDeleteToolItem().isEnabled()) {
|
||||
deleteFile();
|
||||
}
|
||||
break;
|
||||
case CTRL_E: // Export Wizard
|
||||
exportFileWizard();
|
||||
break;
|
||||
case CTRL_V: // View file
|
||||
viewFile(null);
|
||||
break;
|
||||
}
|
||||
} catch (DiskException e) {
|
||||
DiskExplorerTab.this.diskWindow.handle(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -1625,39 +1691,46 @@ public class DiskExplorerTab {
|
|||
break;
|
||||
}
|
||||
} else {
|
||||
switch (event.character) {
|
||||
case CTRL_I: // Import Wizard
|
||||
importFiles();
|
||||
break;
|
||||
case CTRL_P: // Print...
|
||||
print();
|
||||
break;
|
||||
case CTRL_S: // Save
|
||||
if (getSaveToolItem().isEnabled()) {
|
||||
save();
|
||||
}
|
||||
break;
|
||||
}
|
||||
try {
|
||||
switch (event.character) {
|
||||
case CTRL_I: // Import Wizard
|
||||
importFiles();
|
||||
break;
|
||||
case CTRL_P: // Print...
|
||||
print();
|
||||
break;
|
||||
case CTRL_S: // Save
|
||||
if (getSaveToolItem().isEnabled()) {
|
||||
save();
|
||||
}
|
||||
break;
|
||||
}
|
||||
} catch (DiskException e) {
|
||||
DiskExplorerTab.this.diskWindow.handle(e);
|
||||
}
|
||||
}
|
||||
} else { // No CTRL key
|
||||
if ((event.stateMask & SWT.ALT) != SWT.ALT) { // Ignore ALT key combinations like alt-F4!
|
||||
switch (event.keyCode) {
|
||||
case SWT.F2: // Standard file display
|
||||
changeCurrentFormat(FormattedDisk.FILE_DISPLAY_STANDARD);
|
||||
break;
|
||||
case SWT.F3: // Native file display
|
||||
changeCurrentFormat(FormattedDisk.FILE_DISPLAY_NATIVE);
|
||||
break;
|
||||
case SWT.F4: // Detail file display
|
||||
changeCurrentFormat(FormattedDisk.FILE_DISPLAY_DETAIL);
|
||||
break;
|
||||
case SWT.F5: // Show deleted files
|
||||
setShowDeletedFiles(!getShowDeletedFilesToolItem().getSelection());
|
||||
getShowDeletedFilesToolItem().setSelection(isShowDeletedFiles());
|
||||
fillFileTable(getCurrentFileList());
|
||||
break;
|
||||
if ((event.stateMask & SWT.ALT) != SWT.ALT) // Ignore ALT key combinations like alt-F4!
|
||||
try {
|
||||
switch (event.keyCode) {
|
||||
case SWT.F2: // Standard file display
|
||||
changeCurrentFormat(FormattedDisk.FILE_DISPLAY_STANDARD);
|
||||
break;
|
||||
case SWT.F3: // Native file display
|
||||
changeCurrentFormat(FormattedDisk.FILE_DISPLAY_NATIVE);
|
||||
break;
|
||||
case SWT.F4: // Detail file display
|
||||
changeCurrentFormat(FormattedDisk.FILE_DISPLAY_DETAIL);
|
||||
break;
|
||||
case SWT.F5: // Show deleted files
|
||||
setShowDeletedFiles(!getShowDeletedFilesToolItem().getSelection());
|
||||
getShowDeletedFilesToolItem().setSelection(isShowDeletedFiles());
|
||||
fillFileTable(getCurrentFileList());
|
||||
break;
|
||||
}
|
||||
}
|
||||
} catch (DiskException e) {
|
||||
DiskExplorerTab.this.diskWindow.handle(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1728,7 +1801,11 @@ public class DiskExplorerTab {
|
|||
printFileHeaders();
|
||||
gc.setFont(normalFont);
|
||||
println(disk.getDiskName());
|
||||
printFiles(disk, 1);
|
||||
try {
|
||||
printFiles(disk, 1);
|
||||
} catch (DiskException e) {
|
||||
DiskExplorerTab.this.diskWindow.handle(e);
|
||||
}
|
||||
}
|
||||
if (y != clientArea.y) { // partial page
|
||||
printFooter();
|
||||
|
@ -1811,7 +1888,7 @@ public class DiskExplorerTab {
|
|||
clientArea.y + clientArea.height + dpiY - point.y);
|
||||
page++;
|
||||
}
|
||||
protected void printFiles(DirectoryEntry directory, int level) {
|
||||
protected void printFiles(DirectoryEntry directory, int level) throws DiskException {
|
||||
Iterator iterator = directory.getFiles().iterator();
|
||||
while (iterator.hasNext()) {
|
||||
FileEntry fileEntry = (FileEntry) iterator.next();
|
||||
|
@ -2027,5 +2104,5 @@ public class DiskExplorerTab {
|
|||
|
||||
protected ToolItem getShowDeletedFilesToolItem() {
|
||||
return showDeletedFilesToolItem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,11 +24,15 @@ import org.eclipse.swt.custom.CTabFolder;
|
|||
import org.eclipse.swt.events.DisposeEvent;
|
||||
import org.eclipse.swt.events.DisposeListener;
|
||||
import org.eclipse.swt.layout.FillLayout;
|
||||
import org.eclipse.swt.widgets.MessageBox;
|
||||
import org.eclipse.swt.widgets.Shell;
|
||||
|
||||
import com.webcodepro.applecommander.storage.DiskCorruptException;
|
||||
import com.webcodepro.applecommander.storage.DiskException;
|
||||
import com.webcodepro.applecommander.storage.FormattedDisk;
|
||||
import com.webcodepro.applecommander.ui.UiBundle;
|
||||
import com.webcodepro.applecommander.ui.swt.util.ImageManager;
|
||||
import com.webcodepro.applecommander.util.TextBundle;
|
||||
|
||||
/**
|
||||
* Displays disk information on the screen.
|
||||
|
@ -46,6 +50,8 @@ public class DiskWindow {
|
|||
private DiskInfoTab diskInfoTab;
|
||||
private DiskMapTab[] diskMapTabs;
|
||||
|
||||
private TextBundle textBundle = UiBundle.getInstance();
|
||||
|
||||
/**
|
||||
* Construct the disk window.
|
||||
*/
|
||||
|
@ -84,6 +90,58 @@ public class DiskWindow {
|
|||
shell.open();
|
||||
}
|
||||
|
||||
/**
|
||||
* Warns user about a Disk Corrupt problem
|
||||
*
|
||||
* @param e
|
||||
*/
|
||||
protected void handle(final DiskCorruptException e) {
|
||||
Shell finalShell = shell;
|
||||
MessageBox box = new MessageBox(finalShell, SWT.ICON_ERROR | SWT.OK);
|
||||
box.setText(textBundle.get("SwtAppleCommander." + e.kind + ".Title")); //$NON-NLS-1$
|
||||
box.setMessage(
|
||||
textBundle.format("SwtAppleCommander.DiskCorruptException.Message", //$NON-NLS-1$
|
||||
e.imagepath
|
||||
));
|
||||
box.open();
|
||||
}
|
||||
|
||||
/**
|
||||
* Warns user about a Generic Disk Error problem
|
||||
*
|
||||
* @param e
|
||||
*/
|
||||
protected void handle(final DiskException e) {
|
||||
if (e instanceof DiskCorruptException) {
|
||||
this.handle((DiskCorruptException) e);
|
||||
return;
|
||||
}
|
||||
final MessageBox box = new MessageBox(shell, SWT.ICON_ERROR | SWT.OK | SWT.MODELESS);
|
||||
box.setText(textBundle.get("SwtAppleCommander.DiskException.Title")); //$NON-NLS-1$
|
||||
box.setMessage(
|
||||
textBundle.format("SwtAppleCommander.DiskException.Message", //$NON-NLS-1$
|
||||
new Object[]{e.imagepath, e.toString()}
|
||||
));
|
||||
box.open();
|
||||
}
|
||||
|
||||
/**
|
||||
* Warns user about an Application Error problem
|
||||
*
|
||||
* @param e
|
||||
*/
|
||||
public void handle(final Exception e) {
|
||||
final TextBundle textBundle = UiBundle.getInstance();
|
||||
Shell finalShell = shell;
|
||||
MessageBox box = new MessageBox(finalShell, SWT.ICON_ERROR | SWT.OK);
|
||||
box.setText(textBundle.get("SwtAppleCommander.UnexpectedErrorTitle")); //$NON-NLS-1$
|
||||
box.setMessage(
|
||||
textBundle.get("SwtAppleCommander.UnexpectedErrorMessage" //$NON-NLS-1$
|
||||
));
|
||||
box.open();
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the standard AppleCommander disk window title.
|
||||
* This is referenced in DiskWindow as well as DiskExplorerTab.
|
||||
|
|
|
@ -39,6 +39,7 @@ import org.eclipse.swt.widgets.ToolItem;
|
|||
import com.webcodepro.applecommander.storage.Disk;
|
||||
import com.webcodepro.applecommander.storage.FormattedDisk;
|
||||
import com.webcodepro.applecommander.storage.Disk.FilenameFilter;
|
||||
import com.webcodepro.applecommander.storage.DiskUnrecognizedException;
|
||||
import com.webcodepro.applecommander.ui.AppleCommander;
|
||||
import com.webcodepro.applecommander.ui.UiBundle;
|
||||
import com.webcodepro.applecommander.ui.UserPreferences;
|
||||
|
@ -171,19 +172,31 @@ public class SwtAppleCommander implements Listener {
|
|||
try {
|
||||
Disk disk = new Disk(fullpath);
|
||||
FormattedDisk[] formattedDisks = disk.getFormattedDisks();
|
||||
if (formattedDisks != null) {
|
||||
DiskWindow window = new DiskWindow(shell, formattedDisks, imageManager);
|
||||
window.open();
|
||||
} else {
|
||||
showUnrecognizedDiskFormatMessage(fullpath);
|
||||
}
|
||||
DiskWindow window = new DiskWindow(shell, formattedDisks, imageManager);
|
||||
window.open();
|
||||
} catch (DiskUnrecognizedException e) {
|
||||
showUnrecognizedDiskFormatMessage(fullpath);
|
||||
} catch (Exception ignored) {
|
||||
ignored.printStackTrace();
|
||||
showUnrecognizedDiskFormatMessage(fullpath);
|
||||
showUnexpectedErrorMessage(fullpath);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays the unrecognized disk format message.
|
||||
* @param fullpath
|
||||
*/
|
||||
protected void showUnexpectedErrorMessage(String fullpath) {
|
||||
Shell finalShell = shell;
|
||||
MessageBox box = new MessageBox(finalShell, SWT.ICON_ERROR | SWT.OK);
|
||||
box.setText(textBundle.get("SwtAppleCommander.UnexpectedErrorTitle")); //$NON-NLS-1$
|
||||
box.setMessage(
|
||||
textBundle.format("SwtAppleCommander.UnexpectedErrorMessage", //$NON-NLS-1$
|
||||
fullpath));
|
||||
box.open();
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays the unrecognized disk format message.
|
||||
* @param fullpath
|
||||
|
|
|
@ -270,13 +270,19 @@ GraphicsFilterAdapter.BadImageMessage=Unexpected graphic file encountered\!
|
|||
# SwtAppleCommander
|
||||
SwtAppleCommander.AppleCommander=AppleCommander
|
||||
SwtAppleCommander.UnrecognizedFormatTitle=Unrecognized Disk Format
|
||||
SwtAppleCommander.UnrecognizedFormatMessage=Unable to load "{0}".\n\nAppleCommander did not recognize the format\nof the disk. Either this is a new format\nor a protected disk.\n\nSorry\!
|
||||
SwtAppleCommander.UnrecognizedFormatMessage=Unable to load "{0}".\n\nAppleCommander did not recognize the format of the disk. Either this is a new format or a protected disk.\n\nSorry\!
|
||||
SwtAppleCommander.OpenDiskImageTooltip=Open a disk image (Ctrl+O)
|
||||
SwtAppleCommander.CreateDiskImageTooltip=Create a disk image (Ctrl+C)
|
||||
SwtAppleCommander.CompareDiskImageTooltip=Compare two disk images (Ctrl+E)
|
||||
SwtAppleCommander.AboutTooltip=About AppleCommander (Ctrl+A)
|
||||
SwtAppleCommander.AboutTitle=About AppleCommander
|
||||
SwtAppleCommander.AboutMessage=AppleCommander\nVersion {0}\n{1}\n\nAppleCommander was created for the express\npurpose of assisting those-who-remember.\n\nI wish you many hours of vintage pleasure\!\n-Rob
|
||||
SwtAppleCommander.UnexpectedErrorTitle=Application Error
|
||||
SwtAppleCommander.UnexpectedErrorMessage=Unfortunately "{0}" triggered an unexpected application error.\n\nPlease report this to the developers.\n\nWe are terribly sorry for the inconvenience\!
|
||||
SwtAppleCommander.DiskCorruptException.RecursiveDirectoryStructure.Title=Recursive Directory structure detected.
|
||||
SwtAppleCommander.DiskCorruptException.Message=Unfortunately "{0}" is corrupted.\n\nYou can't use this disk safely. Please use a First Aid tool to recover your data.\n\nSorry\!
|
||||
SwtAppleCommander.DiskException.Title="Disk Generic Error"
|
||||
SwtAppleCommander.DiskException.Message=Unfortunately "{0}" has an unrecognizable but yet fatal error, internal code "{1}".\n\nYou can't use this disk safely.\n\nSorry\!
|
||||
|
||||
# SwingAppleCommander
|
||||
SwingAppleCommander.MenuFile=File
|
||||
|
|
Loading…
Reference in New Issue