mirror of
https://github.com/AppleCommander/AppleCommander.git
synced 2024-06-02 12:41:32 +00:00
Implement Gutenberg disk translation
This commit is contained in:
parent
1a46ae1126
commit
2eb1437326
|
@ -34,6 +34,7 @@ import com.webcodepro.applecommander.storage.os.cpm.CpmFormatDisk;
|
||||||
import com.webcodepro.applecommander.storage.os.dos33.DosFormatDisk;
|
import com.webcodepro.applecommander.storage.os.dos33.DosFormatDisk;
|
||||||
import com.webcodepro.applecommander.storage.os.dos33.OzDosFormatDisk;
|
import com.webcodepro.applecommander.storage.os.dos33.OzDosFormatDisk;
|
||||||
import com.webcodepro.applecommander.storage.os.dos33.UniDosFormatDisk;
|
import com.webcodepro.applecommander.storage.os.dos33.UniDosFormatDisk;
|
||||||
|
import com.webcodepro.applecommander.storage.os.gutenberg.GutenbergFormatDisk;
|
||||||
import com.webcodepro.applecommander.storage.os.pascal.PascalFormatDisk;
|
import com.webcodepro.applecommander.storage.os.pascal.PascalFormatDisk;
|
||||||
import com.webcodepro.applecommander.storage.os.prodos.ProdosFormatDisk;
|
import com.webcodepro.applecommander.storage.os.prodos.ProdosFormatDisk;
|
||||||
import com.webcodepro.applecommander.storage.os.rdos.RdosFormatDisk;
|
import com.webcodepro.applecommander.storage.os.rdos.RdosFormatDisk;
|
||||||
|
@ -191,7 +192,7 @@ public class Disk {
|
||||||
if (isProdosOrder()) {
|
if (isProdosOrder()) {
|
||||||
imageOrder = new ProdosOrder(diskImageManager);
|
imageOrder = new ProdosOrder(diskImageManager);
|
||||||
} else if (isDosOrder()) {
|
} else if (isDosOrder()) {
|
||||||
imageOrder = new DosOrder(diskImageManager);
|
imageOrder = new DosOrder(diskImageManager);
|
||||||
} else if (isNibbleOrder()) {
|
} else if (isNibbleOrder()) {
|
||||||
imageOrder = new NibbleOrder(diskImageManager);
|
imageOrder = new NibbleOrder(diskImageManager);
|
||||||
}
|
}
|
||||||
|
@ -256,10 +257,13 @@ public class Disk {
|
||||||
} else if (isCpmFormat()) {
|
} else if (isCpmFormat()) {
|
||||||
return new FormattedDisk[]
|
return new FormattedDisk[]
|
||||||
{ new CpmFormatDisk(filename, imageOrder) };
|
{ new CpmFormatDisk(filename, imageOrder) };
|
||||||
|
} else if (isWPFormat()) {
|
||||||
|
return new FormattedDisk[]
|
||||||
|
{ new GutenbergFormatDisk(filename, imageOrder) };
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the diskImage.
|
* Returns the diskImage.
|
||||||
* @return byte[]
|
* @return byte[]
|
||||||
|
@ -556,6 +560,20 @@ public class Disk {
|
||||||
return "RDOS".equals(id); //$NON-NLS-1$
|
return "RDOS".equals(id); //$NON-NLS-1$
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test the disk format to see if this is a WP formatted
|
||||||
|
* disk.
|
||||||
|
*/
|
||||||
|
public boolean isWPFormat() {
|
||||||
|
if (!is140KbDisk()) return false;
|
||||||
|
byte[] vtoc = readSector(17, 7);
|
||||||
|
return (imageOrder.isSizeApprox(APPLE_140KB_DISK)
|
||||||
|
|| imageOrder.isSizeApprox(APPLE_140KB_NIBBLE_DISK))
|
||||||
|
&& vtoc[0x00] == 17 // expect catalog to start on track 17
|
||||||
|
&& vtoc[0x01] == 7 // expect catalog to start on sector 7
|
||||||
|
&& vtoc[0x0f] == -115; // expect 0x8d's every 16 bytes
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Indicates if the disk has changed. Triggered when data is
|
* Indicates if the disk has changed. Triggered when data is
|
||||||
* written and cleared when data is saved.
|
* written and cleared when data is saved.
|
||||||
|
|
|
@ -23,6 +23,7 @@ DiskNameN={0} (Disk {1})
|
||||||
Dos33=DOS 3.3
|
Dos33=DOS 3.3
|
||||||
LockedQ=Locked?
|
LockedQ=Locked?
|
||||||
DirectoryCreationNotSupported=Unable to create directories.
|
DirectoryCreationNotSupported=Unable to create directories.
|
||||||
|
Gutenberg=Gutenberg
|
||||||
|
|
||||||
##### FIX #####
|
##### FIX #####
|
||||||
###############
|
###############
|
||||||
|
@ -155,6 +156,9 @@ DosFormatDisk.InvalidTrackAndSectorCombinationError=Invalid track ({0}), sector
|
||||||
DosFileEntry.DosFileEntryLengthError=A DOS 3.3 file entry must be {0} bytes long\!
|
DosFileEntry.DosFileEntryLengthError=A DOS 3.3 file entry must be {0} bytes long\!
|
||||||
DosFileEntry.UnableToSetAddressError=Unable to set address for DosFileEntry [{0}]
|
DosFileEntry.UnableToSetAddressError=Unable to set address for DosFileEntry [{0}]
|
||||||
|
|
||||||
|
# GutenbergFileEntry
|
||||||
|
GutenbergFileEntry.GutenbergFileEntryLengthError=A Gutenberg file entry must be {0} bytes long\!
|
||||||
|
|
||||||
# CpmFormatDisk
|
# CpmFormatDisk
|
||||||
CpmFormatDisk.DiskName=CP/M Volume
|
CpmFormatDisk.DiskName=CP/M Volume
|
||||||
CpmFormatDisk.Cpm=CP/M
|
CpmFormatDisk.Cpm=CP/M
|
||||||
|
|
|
@ -0,0 +1,553 @@
|
||||||
|
/*
|
||||||
|
* AppleCommander - An Apple ][ image utility.
|
||||||
|
* Copyright (C) 2002, 2008 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.filters;
|
||||||
|
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.PrintWriter;
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.StringTokenizer;
|
||||||
|
|
||||||
|
import com.webcodepro.applecommander.storage.FileEntry;
|
||||||
|
import com.webcodepro.applecommander.storage.FileFilter;
|
||||||
|
import com.webcodepro.applecommander.ui.AppleCommander;
|
||||||
|
import com.webcodepro.applecommander.util.AppleUtil;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extract the contents of an ancient word processor file (might be Word
|
||||||
|
* Perfect) and convert to a text format. Currently supported formats are plain
|
||||||
|
* text, HTML, or RTF. These are not exact duplicates, but they are close
|
||||||
|
* approximations. RTF format is suitable for conversion to other word
|
||||||
|
* processors.
|
||||||
|
* <p>
|
||||||
|
* To choose export format, use the appropriately named select method.
|
||||||
|
* <p>
|
||||||
|
* Date created: Dec 18, 2008 9:09:21 AM
|
||||||
|
*
|
||||||
|
* @author David Schmidt
|
||||||
|
*/
|
||||||
|
public class GutenbergFileFilter implements FileFilter {
|
||||||
|
/*
|
||||||
|
* This list identifies the various rendering options. As the internal
|
||||||
|
* format may change in the future, the internal representation is hidden
|
||||||
|
* and the developer should use the appropriate select method.
|
||||||
|
*/
|
||||||
|
private static final int RENDER_AS_TEXT = 0;
|
||||||
|
private static final int RENDER_AS_HTML = 1;
|
||||||
|
private static final int RENDER_AS_RTF = 2;
|
||||||
|
private int rendering = RENDER_AS_HTML;
|
||||||
|
/**
|
||||||
|
* Constructor for GutenbergFileFilter.
|
||||||
|
*/
|
||||||
|
public GutenbergFileFilter() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Process the given FileEntry and return a byte array with filtered data.
|
||||||
|
*
|
||||||
|
* @see com.webcodepro.applecommander.storage.FileFilter#filter(FileEntry)
|
||||||
|
*/
|
||||||
|
public byte[] filter(FileEntry fileEntry) {
|
||||||
|
byte[] fileData = fileEntry.getFileData();
|
||||||
|
int offset = 0;
|
||||||
|
ByteArrayOutputStream byteArray = new ByteArrayOutputStream(
|
||||||
|
fileData.length);
|
||||||
|
PrintWriter printWriter = new PrintWriter(byteArray, true);
|
||||||
|
while (offset < fileData.length) {
|
||||||
|
fileData[offset] = (byte) (fileData[offset++] & 0x7f);
|
||||||
|
}
|
||||||
|
String preprocess = new String(fileData).trim();
|
||||||
|
handleTranslation(preprocess, printWriter, rendering);
|
||||||
|
printWriter.flush();
|
||||||
|
return byteArray.toByteArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Transform text into desired destination format
|
||||||
|
*/
|
||||||
|
protected void handleTranslation(String raw, PrintWriter output, int rendering) {
|
||||||
|
boolean ignoreBr = false;
|
||||||
|
boolean inHeader = false;
|
||||||
|
boolean inItalics = false;
|
||||||
|
boolean inBold = false;
|
||||||
|
boolean inCenter = false;
|
||||||
|
boolean inUnderline = false;
|
||||||
|
boolean inSuperscript = false;
|
||||||
|
String cooked = raw.replaceAll("\\x00", ""); //$NON-NLS-1$ $NON-NLS-2$ Remove nulls
|
||||||
|
cooked=cooked.replaceAll("<[a|A]1>", ""); //$NON-NLS-1$ $NON-NLS-2$ File start
|
||||||
|
cooked=cooked.replaceAll("<e9>", ""); //$NON-NLS-1$ $NON-NLS-2$ End of file
|
||||||
|
cooked=cooked.replaceAll("<d1>", ""); //$NON-NLS-1$ $NON-NLS-2$ File start
|
||||||
|
cooked=cooked.replaceAll("<s1>", ""); //$NON-NLS-1$ $NON-NLS-2$ File start
|
||||||
|
cooked=cooked.replaceAll("<2>", ""); //$NON-NLS-1$ $NON-NLS-2$ Dunno what this is
|
||||||
|
cooked=cooked.replaceAll("<f9>", ""); //$NON-NLS-1$ $NON-NLS-2$ Dunno what this is
|
||||||
|
cooked=cooked.replaceAll("<i>", ""); //$NON-NLS-1$ $NON-NLS-2$ Dunno what this is
|
||||||
|
cooked=cooked.replaceAll("<i1>", ""); //$NON-NLS-1$ $NON-NLS-2$ Dunno what this is
|
||||||
|
cooked=cooked.replaceAll("<[h|H]1>(.*)", "<h1>$1</h1>"); //$NON-NLS-1$ $NON-NLS-2$ Bound a h1 heading
|
||||||
|
cooked=cooked.replaceAll("<[h|H]2>(.*)", "<h2>$1</h2>"); //$NON-NLS-1$ $NON-NLS-2$ Bound a h2 heading
|
||||||
|
cooked=cooked.replaceAll("<[h|H]3>(.*)", "<h3>$1</h3>"); //$NON-NLS-1$ $NON-NLS-2$ Bound a h3 heading
|
||||||
|
cooked=cooked.replaceAll("<[h|H]4>(.*)", "<h4>$1</h4>"); //$NON-NLS-1$ $NON-NLS-2$ Bound a h4 heading
|
||||||
|
cooked=cooked.replaceAll("<[n|N]1>(.*)", "<h1>$1</h1>"); //$NON-NLS-1$ $NON-NLS-2$ Another kind of heading? Give it boundaries
|
||||||
|
cooked=cooked.replaceAll("<[n|N]2>(.*)", "<h2>$1</h2>"); //$NON-NLS-1$ $NON-NLS-2$ Another kind of heading? Give it boundaries
|
||||||
|
cooked=cooked.replaceAll("<[n|N]3>(.*)", "<h3>$1</h3>"); //$NON-NLS-1$ $NON-NLS-2$ Another kind of heading? Give it boundaries
|
||||||
|
cooked=cooked.replaceAll("<[t|T]1>", "<p>"); //$NON-NLS-1$ $NON-NLS-2$ Tab level 1
|
||||||
|
cooked=cooked.replaceAll("<[t|T]2>(.*)", "<blockquote>$1</blockquote>"); //$NON-NLS-1$ $NON-NLS-2$ Tab level 2
|
||||||
|
cooked=cooked.replaceAll("<[t|T]3>(.*)", "<blockquote><blockquote>$1</blockquote></blockquote>"); //$NON-NLS-1$ $NON-NLS-2$ Tab level 3
|
||||||
|
cooked=cooked.replaceAll("\\x0f", "</i>"); //$NON-NLS-1$ $NON-NLS-2$ Italics off
|
||||||
|
cooked=cooked.replaceAll("\\x01(.*)", " <i>$1</i>"); //$NON-NLS-1$ $NON-NLS-2$ Italics on
|
||||||
|
cooked=cooked.replaceAll("\\x02(.*)", " <i>$1</i>"); //$NON-NLS-1$ $NON-NLS-2$ Italics on
|
||||||
|
cooked=cooked.replaceAll("~", "\""); //$NON-NLS-1$ $NON-NLS-2$ Leading quote
|
||||||
|
cooked=cooked.replaceAll("_", "-"); //$NON-NLS-1$ $NON-NLS-2$
|
||||||
|
StringTokenizer newlines = new StringTokenizer(cooked, "\r", false); //$NON-NLS-1$
|
||||||
|
switch (rendering)
|
||||||
|
{
|
||||||
|
case RENDER_AS_HTML:
|
||||||
|
output.println("<body><html>");
|
||||||
|
break;
|
||||||
|
case RENDER_AS_RTF:
|
||||||
|
output.print("{\\rtf1"); //$NON-NLS-1$
|
||||||
|
output.print("{\\fonttbl{\\f0\\fmodern\\fprq1;}}"); //$NON-NLS-1$
|
||||||
|
output.print("{\\*\\generator AppleCommander "); //$NON-NLS-1$
|
||||||
|
output.print(AppleCommander.VERSION);
|
||||||
|
output.println(";}"); //$NON-NLS-1$
|
||||||
|
output.print("\\f0 "); //$NON-NLS-1$
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
while (newlines.hasMoreTokens())
|
||||||
|
{
|
||||||
|
int mode = 0;
|
||||||
|
String line = newlines.nextToken();
|
||||||
|
StringTokenizer commands = new StringTokenizer(line,"<>",true);
|
||||||
|
while (commands.hasMoreTokens())
|
||||||
|
{
|
||||||
|
String t = commands.nextToken();
|
||||||
|
if (t.equals("<")) //$NON-NLS-1$
|
||||||
|
mode = 1;
|
||||||
|
else if (t.equals(">")) //$NON-NLS-1$
|
||||||
|
mode = 0;
|
||||||
|
else if (mode == 1) {
|
||||||
|
if (t.startsWith("NF")) //$NON-NLS-1$
|
||||||
|
{
|
||||||
|
// do nothing... consume it
|
||||||
|
}
|
||||||
|
else if (t.equalsIgnoreCase("i") && (!inItalics)) //$NON-NLS-1$
|
||||||
|
{
|
||||||
|
// Italics on
|
||||||
|
switch (rendering)
|
||||||
|
{
|
||||||
|
case RENDER_AS_HTML:
|
||||||
|
output.print("<i>"); //$NON-NLS-1$
|
||||||
|
break;
|
||||||
|
case RENDER_AS_RTF:
|
||||||
|
output.println("\\i "); //$NON-NLS-1$
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
inItalics = true;
|
||||||
|
}
|
||||||
|
else if (t.equalsIgnoreCase("/i")) //$NON-NLS-1$
|
||||||
|
{
|
||||||
|
// Italics off
|
||||||
|
switch (rendering)
|
||||||
|
{
|
||||||
|
case RENDER_AS_HTML:
|
||||||
|
output.print("</i>"); //$NON-NLS-1$
|
||||||
|
break;
|
||||||
|
case RENDER_AS_RTF:
|
||||||
|
output.println("\\i0 "); //$NON-NLS-1$
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
inItalics = false;
|
||||||
|
}
|
||||||
|
else if (t.equalsIgnoreCase("p") || t.startsWith("j") || t.startsWith("J")) //$NON-NLS-1$ $NON-NLS-2$ $NON-NLS-3$
|
||||||
|
{
|
||||||
|
switch (rendering)
|
||||||
|
{
|
||||||
|
case RENDER_AS_HTML:
|
||||||
|
output.print("<p>"); //$NON-NLS-1$
|
||||||
|
break;
|
||||||
|
case RENDER_AS_RTF:
|
||||||
|
output.println("\\par "); //$NON-NLS-1$
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
ignoreBr = true;
|
||||||
|
}
|
||||||
|
else if (t.equalsIgnoreCase("UL") && (!inUnderline)) //$NON-NLS-1$
|
||||||
|
{
|
||||||
|
switch (rendering)
|
||||||
|
{
|
||||||
|
// Underline on
|
||||||
|
case RENDER_AS_HTML:
|
||||||
|
output.print("<u>"); //$NON-NLS-1$
|
||||||
|
break;
|
||||||
|
case RENDER_AS_RTF:
|
||||||
|
output.println("\\ul "); //$NON-NLS-1$
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
inUnderline = true;
|
||||||
|
}
|
||||||
|
else if ((t.equalsIgnoreCase("KU") || t.equalsIgnoreCase("KL") || t.equalsIgnoreCase("UK")) && (inUnderline)) //$NON-NLS-1$ $NON-NLS-2$ $NON-NLS-3$
|
||||||
|
{
|
||||||
|
// Underline off
|
||||||
|
switch (rendering)
|
||||||
|
{
|
||||||
|
case RENDER_AS_HTML:
|
||||||
|
output.print("</u>"); //$NON-NLS-1$
|
||||||
|
break;
|
||||||
|
case RENDER_AS_RTF:
|
||||||
|
output.println("\\ulnone "); //$NON-NLS-1$
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
inUnderline = false;
|
||||||
|
}
|
||||||
|
else if ((t.equalsIgnoreCase("BO") || t.equalsIgnoreCase("b1")) && (!inBold)) //$NON-NLS-1$ $NON-NLS-2$
|
||||||
|
{
|
||||||
|
// Bold on
|
||||||
|
switch (rendering)
|
||||||
|
{
|
||||||
|
case RENDER_AS_HTML:
|
||||||
|
output.print("<b>"); //$NON-NLS-1$
|
||||||
|
break;
|
||||||
|
case RENDER_AS_RTF:
|
||||||
|
output.println("\\b "); //$NON-NLS-1$
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
inBold = true;
|
||||||
|
}
|
||||||
|
else if (t.equalsIgnoreCase("KB")) //$NON-NLS-1$
|
||||||
|
{
|
||||||
|
// Bold off
|
||||||
|
switch (rendering)
|
||||||
|
{
|
||||||
|
case RENDER_AS_HTML:
|
||||||
|
output.print("</b>"); //$NON-NLS-1$
|
||||||
|
break;
|
||||||
|
case RENDER_AS_RTF:
|
||||||
|
output.println("\\b0 "); //$NON-NLS-1$
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
inUnderline = false;
|
||||||
|
}
|
||||||
|
else if ((t.equalsIgnoreCase("UFA") || t.equalsIgnoreCase("UFP") || t.equals("UFY") || t.equalsIgnoreCase("f1")) && (inSuperscript == false)) //$NON-NLS-1$ $NON-NLS-2$ $NON-NLS-3$ $NON-NLS-4$
|
||||||
|
{
|
||||||
|
// Superscript on
|
||||||
|
switch (rendering)
|
||||||
|
{
|
||||||
|
case RENDER_AS_HTML:
|
||||||
|
output.print("<sup>"); //$NON-NLS-1$
|
||||||
|
break;
|
||||||
|
case RENDER_AS_RTF:
|
||||||
|
output.println("\\super "); //$NON-NLS-1$
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
inSuperscript = true;
|
||||||
|
}
|
||||||
|
else if ((t.equalsIgnoreCase("UFM") || t.equalsIgnoreCase("f2")) && (inSuperscript == true)) //$NON-NLS-1$ $NON-NLS-2$
|
||||||
|
{
|
||||||
|
// Superscript off
|
||||||
|
switch (rendering)
|
||||||
|
{
|
||||||
|
case RENDER_AS_HTML:
|
||||||
|
output.print("</sup>"); //$NON-NLS-1$
|
||||||
|
break;
|
||||||
|
case RENDER_AS_RTF:
|
||||||
|
output.println("\\nosupersub"); //$NON-NLS-1$
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
inSuperscript = false;
|
||||||
|
}
|
||||||
|
else if (t.equalsIgnoreCase("co") && (inCenter == false)) //$NON-NLS-1$
|
||||||
|
{
|
||||||
|
switch (rendering)
|
||||||
|
{
|
||||||
|
case RENDER_AS_HTML:
|
||||||
|
output.print("<center>"); //$NON-NLS-1$
|
||||||
|
break;
|
||||||
|
case RENDER_AS_RTF:
|
||||||
|
output.println("\\pard\\qc "); //$NON-NLS-1$
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
inCenter = true;
|
||||||
|
ignoreBr = true;
|
||||||
|
}
|
||||||
|
else if (t.equalsIgnoreCase("h8") && (inCenter == true)) //$NON-NLS-1$
|
||||||
|
{
|
||||||
|
// Center off
|
||||||
|
switch (rendering)
|
||||||
|
{
|
||||||
|
case RENDER_AS_HTML:
|
||||||
|
output.print("</center>"); //$NON-NLS-1$
|
||||||
|
break;
|
||||||
|
case RENDER_AS_RTF:
|
||||||
|
output.println("\\par \\pard "); //$NON-NLS-1$
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
inCenter = false;
|
||||||
|
ignoreBr = true;
|
||||||
|
}
|
||||||
|
else if (t.startsWith("h") && (!inHeader)) //$NON-NLS-1$
|
||||||
|
{
|
||||||
|
ignoreBr = true;
|
||||||
|
inHeader = true;
|
||||||
|
switch (rendering)
|
||||||
|
{
|
||||||
|
case RENDER_AS_HTML:
|
||||||
|
if (t.equalsIgnoreCase("h1")) //$NON-NLS-1$
|
||||||
|
output.print("<h1>"); //$NON-NLS-1$
|
||||||
|
else if (t.equalsIgnoreCase("h2")) //$NON-NLS-1$
|
||||||
|
output.print("<h2>"); //$NON-NLS-1$
|
||||||
|
else if (t.equalsIgnoreCase("h3")) //$NON-NLS-1$
|
||||||
|
output.print("<h3>"); //$NON-NLS-1$
|
||||||
|
else if (t.equalsIgnoreCase("h4")) //$NON-NLS-1$
|
||||||
|
output.print("<h4>"); //$NON-NLS-1$
|
||||||
|
break;
|
||||||
|
case RENDER_AS_RTF:
|
||||||
|
if (t.equalsIgnoreCase("h1")) //$NON-NLS-1$
|
||||||
|
output.print("\\pard\\s1\\b\\fs48 "); //$NON-NLS-1$
|
||||||
|
else if (t.equalsIgnoreCase("h2")) //$NON-NLS-1$
|
||||||
|
output.print("\\pard\\s2\\b\\fs36 "); //$NON-NLS-1$
|
||||||
|
else if (t.equalsIgnoreCase("h3")) //$NON-NLS-1$
|
||||||
|
output.print("\\pard\\s3\\b\\fs27 "); //$NON-NLS-1$
|
||||||
|
else if (t.equalsIgnoreCase("h4")) //$NON-NLS-1$
|
||||||
|
output.print("\\pard\\s4\\b\\fs24 "); //$NON-NLS-1$
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
output.println();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if ((t.startsWith("/h")) && (inHeader))
|
||||||
|
{
|
||||||
|
ignoreBr = true;
|
||||||
|
inHeader = false;
|
||||||
|
switch (rendering)
|
||||||
|
{
|
||||||
|
case RENDER_AS_HTML:
|
||||||
|
if (t.equalsIgnoreCase("/h1")) //$NON-NLS-1$
|
||||||
|
output.print("</h1>"); //$NON-NLS-1$
|
||||||
|
else if (t.equalsIgnoreCase("/h2")) //$NON-NLS-1$
|
||||||
|
output.print("</h2>"); //$NON-NLS-1$
|
||||||
|
else if (t.equalsIgnoreCase("/h3")) //$NON-NLS-1$
|
||||||
|
output.print("</h3>"); //$NON-NLS-1$
|
||||||
|
else if (t.equalsIgnoreCase("/h4")) //$NON-NLS-1$
|
||||||
|
output.print("</h4>"); //$NON-NLS-1$
|
||||||
|
break;
|
||||||
|
case RENDER_AS_RTF:
|
||||||
|
output.print("\\b0\\par\\fs24 "); //$NON-NLS-1$
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
output.println();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (t.startsWith("blockquote")) // Indent $NON-NLS-1$
|
||||||
|
{
|
||||||
|
switch (rendering)
|
||||||
|
{
|
||||||
|
case RENDER_AS_HTML:
|
||||||
|
output.print("<blockquote>"); //$NON-NLS-1$
|
||||||
|
break;
|
||||||
|
case RENDER_AS_RTF:
|
||||||
|
output.println(""); //$NON-NLS-1$
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
output.print(" "); //$NON-NLS-1$
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
ignoreBr = true;
|
||||||
|
}
|
||||||
|
else if (t.startsWith("/blockquote")) // Outdent $NON-NLS-1$
|
||||||
|
{
|
||||||
|
switch (rendering)
|
||||||
|
{
|
||||||
|
case RENDER_AS_HTML:
|
||||||
|
output.print("</blockquote>"); //$NON-NLS-1$
|
||||||
|
break;
|
||||||
|
case RENDER_AS_RTF:
|
||||||
|
output.println(""); //$NON-NLS-1$
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
ignoreBr = true;
|
||||||
|
}
|
||||||
|
// else
|
||||||
|
// System.err.println("Ignored command: <"+t+">");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// System.out.println("Data: ["+t+"]");
|
||||||
|
output.print(t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!ignoreBr)
|
||||||
|
handleReturn(output);
|
||||||
|
ignoreBr = false;
|
||||||
|
|
||||||
|
switch (rendering)
|
||||||
|
{
|
||||||
|
// turn off many types of formatting stuff at the end of lines
|
||||||
|
case RENDER_AS_HTML:
|
||||||
|
if (inItalics)
|
||||||
|
output.print("</i>"); //$NON-NLS-1$
|
||||||
|
if (inBold)
|
||||||
|
output.print("</b>"); //$NON-NLS-1$
|
||||||
|
if (inUnderline)
|
||||||
|
output.print("</u>"); //$NON-NLS-1$
|
||||||
|
if (inSuperscript)
|
||||||
|
output.print("</sup>"); //$NON-NLS-1$
|
||||||
|
case RENDER_AS_RTF:
|
||||||
|
if (inItalics)
|
||||||
|
output.print("\\i0 "); //$NON-NLS-1$
|
||||||
|
if (inBold)
|
||||||
|
output.print("\\b0 "); //$NON-NLS-1$
|
||||||
|
if (inUnderline)
|
||||||
|
output.print("\\ulnone"); //$NON-NLS-1$
|
||||||
|
if (inSuperscript)
|
||||||
|
output.print("\\nosupersub"); //$NON-NLS-1$
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
inItalics = false;
|
||||||
|
inBold = false;
|
||||||
|
inUnderline = false;
|
||||||
|
inSuperscript = false;
|
||||||
|
inHeader = false;
|
||||||
|
}
|
||||||
|
// Put the finishing touches on the document
|
||||||
|
switch (rendering)
|
||||||
|
{
|
||||||
|
case RENDER_AS_HTML:
|
||||||
|
output.println("</body></html>"); //$NON-NLS-1$
|
||||||
|
break;
|
||||||
|
case RENDER_AS_RTF:
|
||||||
|
output.println("}"); //$NON-NLS-1$
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deal with carriage-return.
|
||||||
|
*/
|
||||||
|
protected void handleReturn(PrintWriter printWriter) {
|
||||||
|
if (isHtmlRendering())
|
||||||
|
printWriter.println("<br>"); //$NON-NLS-1$
|
||||||
|
else if (isRtfRendering())
|
||||||
|
printWriter.println("\\par"); //$NON-NLS-1$
|
||||||
|
else
|
||||||
|
printWriter.println();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Give suggested file name.
|
||||||
|
*
|
||||||
|
* @see com.webcodepro.applecommander.storage.FileFilter#getSuggestedFileName(FileEntry)
|
||||||
|
*/
|
||||||
|
public String getSuggestedFileName(FileEntry fileEntry) {
|
||||||
|
String fileName = fileEntry.getFilename().trim();
|
||||||
|
String extension = ".txt"; //$NON-NLS-1$
|
||||||
|
if (isHtmlRendering())
|
||||||
|
extension = ".html"; //$NON-NLS-1$
|
||||||
|
else if (isRtfRendering())
|
||||||
|
extension = ".rtf"; //$NON-NLS-1$
|
||||||
|
|
||||||
|
if (!fileName.toLowerCase().endsWith(extension)) {
|
||||||
|
fileName = fileName + extension;
|
||||||
|
}
|
||||||
|
return fileName;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the rendering method.
|
||||||
|
*/
|
||||||
|
protected void setRendering(int rendering) {
|
||||||
|
this.rendering = rendering;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates if this is a text rendering.
|
||||||
|
*/
|
||||||
|
public boolean isTextRendering() {
|
||||||
|
return rendering == RENDER_AS_TEXT;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates if this is an HTML rendering.
|
||||||
|
*/
|
||||||
|
public boolean isHtmlRendering() {
|
||||||
|
return rendering == RENDER_AS_HTML;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates if this is an RTF rendering.
|
||||||
|
*/
|
||||||
|
public boolean isRtfRendering() {
|
||||||
|
return rendering == RENDER_AS_RTF;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Selects the text rendering engine.
|
||||||
|
*/
|
||||||
|
public void selectTextRendering() {
|
||||||
|
rendering = RENDER_AS_TEXT;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Selects the HTML rendering engine.
|
||||||
|
*/
|
||||||
|
public void selectHtmlRendering() {
|
||||||
|
rendering = RENDER_AS_HTML;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Selects the RTF rendering engine.
|
||||||
|
*/
|
||||||
|
public void selectRtfRendering() {
|
||||||
|
rendering = RENDER_AS_RTF;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,343 @@
|
||||||
|
/*
|
||||||
|
* 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.gutenberg;
|
||||||
|
|
||||||
|
import java.text.NumberFormat;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import com.webcodepro.applecommander.storage.Disk;
|
||||||
|
import com.webcodepro.applecommander.storage.DiskFullException;
|
||||||
|
import com.webcodepro.applecommander.storage.FileEntry;
|
||||||
|
import com.webcodepro.applecommander.storage.FileFilter;
|
||||||
|
import com.webcodepro.applecommander.storage.FormattedDisk;
|
||||||
|
import com.webcodepro.applecommander.storage.StorageBundle;
|
||||||
|
import com.webcodepro.applecommander.storage.filters.GutenbergFileFilter;
|
||||||
|
import com.webcodepro.applecommander.util.AppleUtil;
|
||||||
|
import com.webcodepro.applecommander.util.TextBundle;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a DOS file entry on disk.
|
||||||
|
* <p>
|
||||||
|
* Date created: Oct 4, 2002 5:15:25 PM
|
||||||
|
* @author Rob Greene
|
||||||
|
*/
|
||||||
|
public class GutenbergFileEntry implements FileEntry {
|
||||||
|
private TextBundle textBundle = StorageBundle.getInstance();
|
||||||
|
/**
|
||||||
|
* Indicates the length in bytes of the DOS file entry field.
|
||||||
|
*/
|
||||||
|
public static final int FILE_DESCRIPTIVE_ENTRY_LENGTH = 16;
|
||||||
|
/**
|
||||||
|
* Holds the disk the FileEntry is attached to.
|
||||||
|
*/
|
||||||
|
private GutenbergFormatDisk disk;
|
||||||
|
/**
|
||||||
|
* Track of the FileEntry location.
|
||||||
|
*/
|
||||||
|
private int track;
|
||||||
|
/**
|
||||||
|
* Sector of the FileEntry location.
|
||||||
|
*/
|
||||||
|
private int sector;
|
||||||
|
/**
|
||||||
|
* Offset into sector of FileEntry location.
|
||||||
|
*/
|
||||||
|
private int offset;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor for GutenbergFileEntry.
|
||||||
|
*/
|
||||||
|
public GutenbergFileEntry(GutenbergFormatDisk disk, int track, int sector, int offset) {
|
||||||
|
super();
|
||||||
|
this.disk = disk;
|
||||||
|
this.track = track;
|
||||||
|
this.sector = sector;
|
||||||
|
this.offset = offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read the FileEntry from the disk image.
|
||||||
|
*/
|
||||||
|
protected byte[] readFileEntry() {
|
||||||
|
byte[] sectorData = disk.readSector(track, sector);
|
||||||
|
byte[] fileEntry = new byte[FILE_DESCRIPTIVE_ENTRY_LENGTH];
|
||||||
|
System.arraycopy(sectorData, offset, fileEntry, 0, fileEntry.length);
|
||||||
|
return fileEntry;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write the FileEntry to the disk image.
|
||||||
|
*/
|
||||||
|
protected void writeFileEntry(byte[] fileEntry) {
|
||||||
|
if (fileEntry.length != FILE_DESCRIPTIVE_ENTRY_LENGTH) {
|
||||||
|
throw new IllegalArgumentException(textBundle.
|
||||||
|
format("GutenbergFileEntry.GutenbergFileEntryLengthError", //$NON-NLS-1$
|
||||||
|
FILE_DESCRIPTIVE_ENTRY_LENGTH));
|
||||||
|
}
|
||||||
|
byte[] sectorData = disk.readSector(track, sector);
|
||||||
|
System.arraycopy(fileEntry, 0, sectorData, offset, fileEntry.length);
|
||||||
|
disk.writeSector(track, sector, sectorData);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the maximum filename length.
|
||||||
|
*/
|
||||||
|
public int getMaximumFilenameLength() {
|
||||||
|
return 12;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the name of this file.
|
||||||
|
* @see com.webcodepro.applecommander.storage.FileEntry#getFilename()
|
||||||
|
*/
|
||||||
|
public String getFilename() {
|
||||||
|
return AppleUtil.getString(readFileEntry(), 0, getMaximumFilenameLength()).trim();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the name of this file.
|
||||||
|
*/
|
||||||
|
public void setFilename(String filename) {
|
||||||
|
byte[] data = readFileEntry();
|
||||||
|
AppleUtil.setString(data, 0, filename.toUpperCase(), getMaximumFilenameLength());
|
||||||
|
writeFileEntry(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the filetype of this file.
|
||||||
|
* @see com.webcodepro.applecommander.storage.FileEntry#getFiletype()
|
||||||
|
*/
|
||||||
|
public String getFiletype() {
|
||||||
|
return "T"; // Only one file type... text //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the filetype (typeless - unused)
|
||||||
|
*/
|
||||||
|
public void setFiletype(String filetype) {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Identify if this file is locked.
|
||||||
|
* @see com.webcodepro.applecommander.storage.FileEntry#isLocked()
|
||||||
|
*/
|
||||||
|
public boolean isLocked() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the lock indicator (unused)
|
||||||
|
*/
|
||||||
|
public void setLocked(boolean lock) {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compute the size of this file (in bytes).
|
||||||
|
* @see com.webcodepro.applecommander.storage.FileEntry#getSize()
|
||||||
|
*/
|
||||||
|
public int getSize() {
|
||||||
|
// Nothing special, just compute from number of sectors
|
||||||
|
int size = getSectorsUsed() * Disk.SECTOR_SIZE;
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compute the number of sectors used.
|
||||||
|
*/
|
||||||
|
public int getSectorsUsed() {
|
||||||
|
// Follow the chain of sectors to find the end.
|
||||||
|
int track = getTrack();
|
||||||
|
int sector = getSector();
|
||||||
|
int sectors = 0;
|
||||||
|
while (track < 128) {
|
||||||
|
byte[] sectorData = disk.readSector(track, sector);
|
||||||
|
track = AppleUtil.getUnsignedByte(sectorData[0x04]);
|
||||||
|
sector = AppleUtil.getUnsignedByte(sectorData[0x05]);
|
||||||
|
sectors++;
|
||||||
|
}
|
||||||
|
return sectors;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the number of sectors used.
|
||||||
|
*/
|
||||||
|
public void setSectorsUsed(int sectorsUsed) {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Identify if this is a directory file.
|
||||||
|
* @see com.webcodepro.applecommander.storage.FileEntry#isDirectory()
|
||||||
|
*/
|
||||||
|
public boolean isDirectory() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Identify if this file has been deleted.
|
||||||
|
* @see com.webcodepro.applecommander.storage.FileEntry#isDeleted()
|
||||||
|
*/
|
||||||
|
public boolean isDeleted() {
|
||||||
|
return AppleUtil.getUnsignedByte(readFileEntry()[0x0d]) == 0x40;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete this file.
|
||||||
|
*/
|
||||||
|
public void delete() {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the standard file column header information.
|
||||||
|
* This default implementation is intended only for standard mode.
|
||||||
|
* displayMode is specified in FormattedDisk.
|
||||||
|
*/
|
||||||
|
public List getFileColumnData(int displayMode) {
|
||||||
|
NumberFormat numberFormat = NumberFormat.getNumberInstance();
|
||||||
|
List list = new ArrayList();
|
||||||
|
switch (displayMode) {
|
||||||
|
case FormattedDisk.FILE_DISPLAY_NATIVE:
|
||||||
|
list.add(isLocked() ? "*" : " "); //$NON-NLS-1$ //$NON-NLS-2$
|
||||||
|
list.add(getFiletype());
|
||||||
|
numberFormat.setMinimumIntegerDigits(3);
|
||||||
|
list.add(numberFormat.format(getSectorsUsed()));
|
||||||
|
list.add(getFilename());
|
||||||
|
break;
|
||||||
|
case FormattedDisk.FILE_DISPLAY_DETAIL:
|
||||||
|
list.add(isLocked() ? "*" : " "); //$NON-NLS-1$ //$NON-NLS-2$
|
||||||
|
list.add(getFiletype());
|
||||||
|
list.add(getFilename());
|
||||||
|
list.add(numberFormat.format(getSize()));
|
||||||
|
numberFormat.setMinimumIntegerDigits(3);
|
||||||
|
list.add(numberFormat.format(getSectorsUsed()));
|
||||||
|
list.add(isDeleted() ? textBundle.get("Deleted") : ""); //$NON-NLS-1$//$NON-NLS-2$
|
||||||
|
list.add("T" + getTrack() + " S" + getSector()); //$NON-NLS-1$ //$NON-NLS-2$
|
||||||
|
break;
|
||||||
|
default: // FILE_DISPLAY_STANDARD
|
||||||
|
list.add(getFilename());
|
||||||
|
list.add(getFiletype());
|
||||||
|
list.add(numberFormat.format(getSize()));
|
||||||
|
list.add(isLocked() ? textBundle.get("Locked") : ""); //$NON-NLS-1$//$NON-NLS-2$
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the track of first track/sector list sector.
|
||||||
|
*/
|
||||||
|
public int getTrack() {
|
||||||
|
return AppleUtil.getUnsignedByte(readFileEntry()[0x0c]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the track of the first track/sector list sector.
|
||||||
|
*/
|
||||||
|
public void setTrack(int track) {
|
||||||
|
byte[] data = readFileEntry();
|
||||||
|
data[0x0c] = (byte) track;
|
||||||
|
writeFileEntry(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the sector of first track/sector list sector.
|
||||||
|
*/
|
||||||
|
public int getSector() {
|
||||||
|
return AppleUtil.getUnsignedByte(readFileEntry()[0x0d]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the sector of the first track/sector list sector.
|
||||||
|
*/
|
||||||
|
public void setSector(int sector) {
|
||||||
|
byte[] data = readFileEntry();
|
||||||
|
data[0x0d] = (byte) sector;
|
||||||
|
writeFileEntry(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get file data. This handles any operating-system specific issues.
|
||||||
|
*/
|
||||||
|
public byte[] getFileData() {
|
||||||
|
return disk.getFileData(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the file data.
|
||||||
|
*
|
||||||
|
* Note: The address can be set before the data is saved or
|
||||||
|
* after the data is saved. This is an attempt to make the
|
||||||
|
* API more easily usable.
|
||||||
|
*
|
||||||
|
* Empirically, the data must be set before the address is set.
|
||||||
|
*/
|
||||||
|
public void setFileData(byte[] data) throws DiskFullException {
|
||||||
|
disk.setFileData(this, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the suggested FileFilter. This appears to be operating system
|
||||||
|
* specific, so each operating system needs to implement some manner
|
||||||
|
* of guessing the appropriate filter.
|
||||||
|
* FIXME - this code should be a helper class for DOS and RDOS!
|
||||||
|
*/
|
||||||
|
public FileFilter getSuggestedFilter() {
|
||||||
|
return new GutenbergFileFilter();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine if this is an assembly source code file.
|
||||||
|
*/
|
||||||
|
public boolean isAssemblySourceFile() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the FormattedDisk associated with this FileEntry.
|
||||||
|
* This is useful to interfaces that need to retrieve the associated
|
||||||
|
* disk.
|
||||||
|
*/
|
||||||
|
public FormattedDisk getFormattedDisk() {
|
||||||
|
return disk;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates if this filetype requires an address component.
|
||||||
|
* Note that the FormattedDisk also has this method - normally,
|
||||||
|
* this will defer to the method on FormattedDisk, as it will be
|
||||||
|
* more generic.
|
||||||
|
*/
|
||||||
|
public boolean needsAddress() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the address that this file loads at.
|
||||||
|
*/
|
||||||
|
public void setAddress(int address) {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates that this filetype can be compiled.
|
||||||
|
*/
|
||||||
|
public boolean canCompile() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,718 @@
|
||||||
|
/*
|
||||||
|
* AppleCommander - An Apple ][ image utility.
|
||||||
|
* Copyright (C) 2002, 2008 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.gutenberg;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import com.webcodepro.applecommander.storage.DirectoryEntry;
|
||||||
|
import com.webcodepro.applecommander.storage.DiskFullException;
|
||||||
|
import com.webcodepro.applecommander.storage.FileEntry;
|
||||||
|
import com.webcodepro.applecommander.storage.FormattedDisk;
|
||||||
|
import com.webcodepro.applecommander.storage.StorageBundle;
|
||||||
|
import com.webcodepro.applecommander.storage.physical.ImageOrder;
|
||||||
|
import com.webcodepro.applecommander.util.AppleUtil;
|
||||||
|
import com.webcodepro.applecommander.util.TextBundle;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Manages a disk that is in Gutenberg Word Processor format.
|
||||||
|
* <p>
|
||||||
|
* Date created: Dec 17, 2008 04:29:23 PM
|
||||||
|
* @author David Schmidt
|
||||||
|
*/
|
||||||
|
public class GutenbergFormatDisk extends FormattedDisk {
|
||||||
|
private TextBundle textBundle = StorageBundle.getInstance();
|
||||||
|
/**
|
||||||
|
* Indicates the index of the track in the location array.
|
||||||
|
*/
|
||||||
|
public static final int TRACK_LOCATION_INDEX = 0;
|
||||||
|
/**
|
||||||
|
* Indicates the index of the sector in the location array.
|
||||||
|
*/
|
||||||
|
public static final int SECTOR_LOCATION_INDEX = 1;
|
||||||
|
/**
|
||||||
|
* The catalog track.
|
||||||
|
*/
|
||||||
|
public static final int CATALOG_TRACK = 17;
|
||||||
|
/**
|
||||||
|
* The VTOC sector.
|
||||||
|
*/
|
||||||
|
public static final int VTOC_SECTOR = 7;
|
||||||
|
/**
|
||||||
|
* The standard track/sector pairs in a track/sector list.
|
||||||
|
*/
|
||||||
|
public static final int TRACK_SECTOR_PAIRS = 122;
|
||||||
|
/**
|
||||||
|
* The list of filetypes available.
|
||||||
|
*/
|
||||||
|
private static final String[] filetypes = {
|
||||||
|
"T" //$NON-NLS-1$
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Use this inner interface for managing the disk usage data.
|
||||||
|
* This offloads format-specific implementation to the implementing class.
|
||||||
|
*/
|
||||||
|
private class WPDiskUsage implements DiskUsage {
|
||||||
|
private int[] location = null;
|
||||||
|
public boolean hasNext() {
|
||||||
|
return location == null
|
||||||
|
|| (location[TRACK_LOCATION_INDEX] < getTracks()
|
||||||
|
&& location[SECTOR_LOCATION_INDEX] < getSectors());
|
||||||
|
}
|
||||||
|
public void next() {
|
||||||
|
if (location == null) {
|
||||||
|
location = new int[2];
|
||||||
|
} else {
|
||||||
|
location[SECTOR_LOCATION_INDEX]++;
|
||||||
|
if (location[SECTOR_LOCATION_INDEX] >= getSectors()) {
|
||||||
|
location[SECTOR_LOCATION_INDEX] = 0;
|
||||||
|
location[TRACK_LOCATION_INDEX]++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Get the free setting for the bitmap at the current location.
|
||||||
|
* I don't think there is a map stored on disk, however.
|
||||||
|
*/
|
||||||
|
public boolean isFree() {
|
||||||
|
if (location == null || location.length != 2) {
|
||||||
|
throw new IllegalArgumentException(StorageBundle.getInstance()
|
||||||
|
.get("DosFormatDisk.InvalidDimensionError")); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
public boolean isUsed() {
|
||||||
|
return !isFree();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor for GutenbergFormatDisk.
|
||||||
|
*/
|
||||||
|
public GutenbergFormatDisk(String filename, ImageOrder imageOrder) {
|
||||||
|
super(filename, imageOrder);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a GutenbergFormatDisk. All DOS disk images are expected to
|
||||||
|
* be 140K in size.
|
||||||
|
*/
|
||||||
|
public static GutenbergFormatDisk[] create(String filename, ImageOrder imageOrder) {
|
||||||
|
GutenbergFormatDisk disk = new GutenbergFormatDisk(filename, imageOrder);
|
||||||
|
disk.format();
|
||||||
|
return new GutenbergFormatDisk[] { disk };
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Identify the operating system format of this disk as Gutenberg.
|
||||||
|
* @see com.webcodepro.applecommander.storage.FormattedDisk#getFormat()
|
||||||
|
*/
|
||||||
|
public String getFormat() {
|
||||||
|
return textBundle.get("Gutenberg"); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve a list of files.
|
||||||
|
* @see com.webcodepro.applecommander.storage.FormattedDisk#getFiles()
|
||||||
|
*/
|
||||||
|
public List getFiles() {
|
||||||
|
List list = new ArrayList();
|
||||||
|
int track = CATALOG_TRACK;
|
||||||
|
int sector = VTOC_SECTOR;
|
||||||
|
while (track < 40) { // iterate through all catalog sectors
|
||||||
|
byte[] catalogSector = readSector(track, sector);
|
||||||
|
int offset = 0x20; // First entry is 0x20 deep
|
||||||
|
while (offset < 0xff) { // iterate through all entries
|
||||||
|
if (catalogSector[offset] != -96) {
|
||||||
|
list.add(new GutenbergFileEntry(this, track, sector, offset));
|
||||||
|
}
|
||||||
|
offset+= GutenbergFileEntry.FILE_DESCRIPTIVE_ENTRY_LENGTH;
|
||||||
|
}
|
||||||
|
track = AppleUtil.getUnsignedByte(catalogSector[4]); // Pull in the next catalog sector
|
||||||
|
sector = AppleUtil.getUnsignedByte(catalogSector[5]);
|
||||||
|
}
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a FileEntry.
|
||||||
|
*/
|
||||||
|
public FileEntry createFile() throws DiskFullException {
|
||||||
|
byte[] vtoc = readVtoc();
|
||||||
|
int track = AppleUtil.getUnsignedByte(vtoc[1]);
|
||||||
|
int sector = AppleUtil.getUnsignedByte(vtoc[2]);
|
||||||
|
while (sector != 0) { // bug fix: iterate through all catalog _sectors_
|
||||||
|
byte[] catalogSector = readSector(track, sector);
|
||||||
|
int offset = 0x0b;
|
||||||
|
while (offset < 0xff) { // iterate through all entries
|
||||||
|
int value = AppleUtil.getUnsignedByte(catalogSector[offset]);
|
||||||
|
if (value == 0 || value == 0xff) {
|
||||||
|
return new GutenbergFileEntry(this, track, sector, offset);
|
||||||
|
}
|
||||||
|
offset+= GutenbergFileEntry.FILE_DESCRIPTIVE_ENTRY_LENGTH;
|
||||||
|
}
|
||||||
|
track = catalogSector[1];
|
||||||
|
sector = catalogSector[2];
|
||||||
|
}
|
||||||
|
throw new DiskFullException(textBundle.get("DosFormatDisk.NoMoreSpaceError")); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Identify if additional directories can be created. This
|
||||||
|
* may indicate that directories are not available to this
|
||||||
|
* operating system or simply that the disk image is "locked"
|
||||||
|
* to writing.
|
||||||
|
*/
|
||||||
|
public boolean canCreateDirectories() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates if this disk image can create a file.
|
||||||
|
* If not, the reason may be as simple as it has not beem implemented
|
||||||
|
* to something specific about the disk.
|
||||||
|
*/
|
||||||
|
public boolean canCreateFile() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compute the amount of freespace available on the disk.
|
||||||
|
* This algorithm completely ignores tracks and sectors by
|
||||||
|
* running through the entire bitmap stored on the VTOC.
|
||||||
|
* @see com.webcodepro.applecommander.storage.FormattedDisk#getFreeSpace()
|
||||||
|
*/
|
||||||
|
public int getFreeSpace() {
|
||||||
|
return getFreeSectors() * SECTOR_SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Comput the number of free sectors available on the disk.
|
||||||
|
*/
|
||||||
|
public int getFreeSectors() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the amount of used space in bytes.
|
||||||
|
* @see com.webcodepro.applecommander.storage.FormattedDisk#getUsedSpace()
|
||||||
|
*/
|
||||||
|
public int getUsedSpace() {
|
||||||
|
return APPLE_140KB_DISK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compute the number of used sectors on the disk.
|
||||||
|
*/
|
||||||
|
public int getUsedSectors() {
|
||||||
|
return getTotalSectors() - getFreeSectors();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compute the total number of sectors available on the disk.
|
||||||
|
*/
|
||||||
|
public int getTotalSectors() {
|
||||||
|
int tracks = getTracks();
|
||||||
|
int sectors = getSectors();
|
||||||
|
return tracks * sectors;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the WP disk name.
|
||||||
|
* @see com.webcodepro.applecommander.storage.FormattedDisk#getDiskName()
|
||||||
|
*/
|
||||||
|
public String getDiskName() {
|
||||||
|
// Pull the disk name out...
|
||||||
|
return AppleUtil.getString(readVtoc(), 6, 9).trim();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the VTOC (Volume Table Of Contents).
|
||||||
|
*/
|
||||||
|
protected byte[] readVtoc() {
|
||||||
|
return readSector(CATALOG_TRACK, VTOC_SECTOR);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Save the VTOC (Volume Table Of Contents) to disk.
|
||||||
|
*/
|
||||||
|
protected void writeVtoc(byte[] vtoc) {
|
||||||
|
writeSector(CATALOG_TRACK, VTOC_SECTOR, vtoc);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the disk usage iterator.
|
||||||
|
*/
|
||||||
|
public DiskUsage getDiskUsage() {
|
||||||
|
return new WPDiskUsage();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the number of tracks on this disk.
|
||||||
|
*/
|
||||||
|
public int getTracks() {
|
||||||
|
byte[] vtoc = readVtoc();
|
||||||
|
return AppleUtil.getUnsignedByte(vtoc[0x34]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the number of sectors on this disk.
|
||||||
|
*/
|
||||||
|
public int getSectors() {
|
||||||
|
byte[] vtoc = readVtoc();
|
||||||
|
return AppleUtil.getUnsignedByte(vtoc[0x35]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get suggested dimensions for display of bitmap. For DOS 3.3, that information
|
||||||
|
* is stored in the VTOC, and that information is fairly important.
|
||||||
|
* @see com.webcodepro.applecommander.storage.FormattedDisk#getBitmapDimensions()
|
||||||
|
*/
|
||||||
|
public int[] getBitmapDimensions() {
|
||||||
|
int tracks = getTracks();
|
||||||
|
int sectors = getSectors();
|
||||||
|
return new int[] { tracks, sectors };
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the length of the bitmap.
|
||||||
|
*/
|
||||||
|
public int getBitmapLength() {
|
||||||
|
return getTotalSectors();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the labels to use in the bitmap.
|
||||||
|
*/
|
||||||
|
public String[] getBitmapLabels() {
|
||||||
|
return new String[] { textBundle.get("DosFormatDisk.Track"), textBundle.get("DosFormatDisk.Sector") }; //$NON-NLS-1$ //$NON-NLS-2$
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get WP-specific disk information.
|
||||||
|
*/
|
||||||
|
public List getDiskInformation() {
|
||||||
|
List list = super.getDiskInformation();
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the standard file column header information.
|
||||||
|
* This default implementation is intended only for standard mode.
|
||||||
|
*/
|
||||||
|
public List getFileColumnHeaders(int displayMode) {
|
||||||
|
List list = new ArrayList();
|
||||||
|
switch (displayMode) {
|
||||||
|
case FILE_DISPLAY_NATIVE:
|
||||||
|
list.add(new FileColumnHeader(" ", 1, FileColumnHeader.ALIGN_CENTER)); //$NON-NLS-1$
|
||||||
|
list.add(new FileColumnHeader(textBundle.get("DosFormatDisk.Type"), 1, FileColumnHeader.ALIGN_CENTER)); //$NON-NLS-1$
|
||||||
|
list.add(new FileColumnHeader(textBundle.get("DosFormatDisk.SizeInSectors"), 3, FileColumnHeader.ALIGN_RIGHT)); //$NON-NLS-1$
|
||||||
|
list.add(new FileColumnHeader(textBundle.get("Name"), 30, //$NON-NLS-1$
|
||||||
|
FileColumnHeader.ALIGN_LEFT));
|
||||||
|
break;
|
||||||
|
case FILE_DISPLAY_DETAIL:
|
||||||
|
list.add(new FileColumnHeader(" ", 1, FileColumnHeader.ALIGN_CENTER)); //$NON-NLS-1$
|
||||||
|
list.add(new FileColumnHeader(textBundle.get("DosFormatDisk.Type"), 1, FileColumnHeader.ALIGN_CENTER)); //$NON-NLS-1$
|
||||||
|
list.add(new FileColumnHeader(textBundle.get("Name"), 30, //$NON-NLS-1$
|
||||||
|
FileColumnHeader.ALIGN_LEFT));
|
||||||
|
list.add(new FileColumnHeader(textBundle.get("SizeInBytes"), 6, //$NON-NLS-1$
|
||||||
|
FileColumnHeader.ALIGN_RIGHT));
|
||||||
|
list.add(new FileColumnHeader(textBundle.get("DosFormatDisk.SizeInSectors"), 3, FileColumnHeader.ALIGN_RIGHT)); //$NON-NLS-1$
|
||||||
|
list.add(new FileColumnHeader(textBundle.get("DeletedQ"), 7, //$NON-NLS-1$
|
||||||
|
FileColumnHeader.ALIGN_CENTER));
|
||||||
|
list.add(new FileColumnHeader(textBundle.get("DosFormatDisk.TrackAndSectorList"), 7, FileColumnHeader.ALIGN_CENTER)); //$NON-NLS-1$
|
||||||
|
break;
|
||||||
|
default: // FILE_DISPLAY_STANDARD
|
||||||
|
list.addAll(super.getFileColumnHeaders(displayMode));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates if this disk format supports "deleted" files.
|
||||||
|
*/
|
||||||
|
public boolean supportsDeletedFiles() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates if this disk image can read data from a file.
|
||||||
|
*/
|
||||||
|
public boolean canReadFileData() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates if this disk image can write data to a file.
|
||||||
|
*/
|
||||||
|
public boolean canWriteFileData() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Identify if this disk format as not capable of having directories.
|
||||||
|
* @see com.webcodepro.applecommander.storage.FormattedDisk#canHaveDirectories()
|
||||||
|
*/
|
||||||
|
public boolean canHaveDirectories() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates if this disk image can delete a file.
|
||||||
|
*/
|
||||||
|
public boolean canDeleteFile() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the data associated with the specified FileEntry.
|
||||||
|
*/
|
||||||
|
public byte[] getFileData(FileEntry fileEntry) {
|
||||||
|
if ( !(fileEntry instanceof GutenbergFileEntry)) {
|
||||||
|
throw new IllegalArgumentException(textBundle.get("DosFormatDisk.InvalidFileEntryError")); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
GutenbergFileEntry wpEntry = (GutenbergFileEntry) fileEntry;
|
||||||
|
// Size is calculated by sectors used - not actual size - as size varies
|
||||||
|
// on filetype, etc.
|
||||||
|
int filesize = wpEntry.getSectorsUsed();
|
||||||
|
byte[] fileData = null;
|
||||||
|
if (filesize > 0) {
|
||||||
|
fileData = new byte[(wpEntry.getSectorsUsed()) * SECTOR_SIZE];
|
||||||
|
} else {
|
||||||
|
fileData = new byte[0];
|
||||||
|
// don't need to load it - also bypass potential issues
|
||||||
|
return fileData;
|
||||||
|
}
|
||||||
|
int track = wpEntry.getTrack();
|
||||||
|
int sector = wpEntry.getSector();
|
||||||
|
int offset = 0;
|
||||||
|
while (track < 128) {
|
||||||
|
byte[] sectorData = readSector(track,sector);
|
||||||
|
track = AppleUtil.getUnsignedByte(sectorData[0x04]);
|
||||||
|
sector = AppleUtil.getUnsignedByte(sectorData[0x05]);
|
||||||
|
System.arraycopy(sectorData, 6, fileData, offset, sectorData.length-6);
|
||||||
|
offset+= sectorData.length-6;
|
||||||
|
}
|
||||||
|
return fileData;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Writes the raw bytes into the file. This bypasses any special formatting
|
||||||
|
* of the data (such as prepending the data with a length and/or an address).
|
||||||
|
* Typically, the FileEntry.setFileData method should be used.
|
||||||
|
*/
|
||||||
|
public void setFileData(FileEntry fileEntry, byte[] fileData) throws DiskFullException {
|
||||||
|
setFileData((GutenbergFileEntry)fileEntry, fileData);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the data associated with the specified GutenbergFileEntry into sectors
|
||||||
|
* on the disk.
|
||||||
|
*/
|
||||||
|
protected void setFileData(GutenbergFileEntry fileEntry, byte[] data) throws DiskFullException {
|
||||||
|
// compute free space and see if the data will fit!
|
||||||
|
int numberOfDataSectors = (data.length + SECTOR_SIZE - 1) / SECTOR_SIZE;
|
||||||
|
int numberOfSectors = numberOfDataSectors +
|
||||||
|
(numberOfDataSectors + TRACK_SECTOR_PAIRS - 1) / TRACK_SECTOR_PAIRS;
|
||||||
|
if (numberOfSectors > getFreeSectors() + fileEntry.getSectorsUsed()) {
|
||||||
|
throw new DiskFullException(
|
||||||
|
textBundle.format("DosFormatDisk.NotEnoughSectorsError", //$NON-NLS-1$
|
||||||
|
numberOfSectors, getFreeSectors()));
|
||||||
|
}
|
||||||
|
// free "old" data and just rewrite stuff...
|
||||||
|
// freeSectors(fileEntry); (not going to work...)
|
||||||
|
byte[] vtoc = readVtoc();
|
||||||
|
int track = fileEntry.getTrack();
|
||||||
|
int sector = fileEntry.getSector();
|
||||||
|
if (track == 0 || track == 255) {
|
||||||
|
track = 1;
|
||||||
|
sector = 0;
|
||||||
|
while (true) {
|
||||||
|
if (isSectorFree(track,sector,vtoc)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
sector++;
|
||||||
|
if (sector >= getSectors()) {
|
||||||
|
track++;
|
||||||
|
sector = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fileEntry.setTrack(track);
|
||||||
|
fileEntry.setSector(sector);
|
||||||
|
}
|
||||||
|
setSectorUsed(track, sector, vtoc);
|
||||||
|
byte[] trackSectorList = new byte[SECTOR_SIZE];
|
||||||
|
int offset = 0;
|
||||||
|
int trackSectorOffset = 0x0c;
|
||||||
|
int totalSectors = 0;
|
||||||
|
int t=1; // initial search for space
|
||||||
|
int s=0;
|
||||||
|
while (offset < data.length) {
|
||||||
|
// locate next free sector
|
||||||
|
while (true) {
|
||||||
|
if (isSectorFree(t,s,vtoc)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
s++;
|
||||||
|
if (s >= getSectors()) {
|
||||||
|
t++;
|
||||||
|
s = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
setSectorUsed(t,s,vtoc);
|
||||||
|
if (trackSectorOffset >= 0x100) {
|
||||||
|
// filled up the first track/sector list - save it
|
||||||
|
trackSectorList[0x01] = (byte) t;
|
||||||
|
trackSectorList[0x02] = (byte) s;
|
||||||
|
writeSector(track, sector, trackSectorList);
|
||||||
|
trackSectorList = new byte[SECTOR_SIZE];
|
||||||
|
trackSectorOffset = 0x0c;
|
||||||
|
track = t;
|
||||||
|
sector = s;
|
||||||
|
} else {
|
||||||
|
// write out a data sector
|
||||||
|
trackSectorList[trackSectorOffset] = (byte) t;
|
||||||
|
trackSectorList[trackSectorOffset+1] = (byte) s;
|
||||||
|
trackSectorOffset+= 2;
|
||||||
|
byte[] sectorData = new byte[SECTOR_SIZE];
|
||||||
|
int length = Math.min(SECTOR_SIZE, data.length - offset);
|
||||||
|
System.arraycopy(data, offset, sectorData, 0, length);
|
||||||
|
writeSector(t,s,sectorData);
|
||||||
|
offset+= SECTOR_SIZE;
|
||||||
|
}
|
||||||
|
totalSectors++;
|
||||||
|
}
|
||||||
|
writeSector(track, sector, trackSectorList); // last T/S list
|
||||||
|
totalSectors++;
|
||||||
|
fileEntry.setSectorsUsed(totalSectors);
|
||||||
|
writeVtoc(vtoc);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Free sectors used by a GutenbergFileEntry.
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
protected void freeSectors(GutenbergFileEntry GutenbergFileEntry) {
|
||||||
|
byte[] vtoc = readVtoc();
|
||||||
|
int track = GutenbergFileEntry.getTrack();
|
||||||
|
if (track == 255) return;
|
||||||
|
int sector = GutenbergFileEntry.getSector();
|
||||||
|
while (track != 0) {
|
||||||
|
setSectorFree(track,sector,vtoc);
|
||||||
|
byte[] trackSectorList = readSector(track, sector);
|
||||||
|
track = AppleUtil.getUnsignedByte(trackSectorList[0x01]);
|
||||||
|
sector = AppleUtil.getUnsignedByte(trackSectorList[0x02]);
|
||||||
|
for (int i=0x0c; i<0x100; i+=2) {
|
||||||
|
int t = AppleUtil.getUnsignedByte(trackSectorList[i]);
|
||||||
|
if (t == 0) break;
|
||||||
|
int s = AppleUtil.getUnsignedByte(trackSectorList[i+1]);
|
||||||
|
setSectorFree(t,s,vtoc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
writeVtoc(vtoc);
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* Format the disk as DOS 3.3.
|
||||||
|
* @see com.webcodepro.applecommander.storage.FormattedDisk#format()
|
||||||
|
*/
|
||||||
|
public void format() {
|
||||||
|
getImageOrder().format();
|
||||||
|
format(15, 35, 16);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Format the disk as DOS 3.3 given the dymanic parameters.
|
||||||
|
* (Used for UniDOS and OzDOS.)
|
||||||
|
*/
|
||||||
|
protected void format(int firstCatalogSector, int tracksPerDisk,
|
||||||
|
int sectorsPerTrack) {
|
||||||
|
|
||||||
|
writeBootCode();
|
||||||
|
// create catalog sectors
|
||||||
|
byte[] data = new byte[SECTOR_SIZE];
|
||||||
|
for (int sector=firstCatalogSector; sector > 0; sector--) {
|
||||||
|
if (sector > 1) {
|
||||||
|
data[0x01] = CATALOG_TRACK;
|
||||||
|
data[0x02] = (byte)(sector-1);
|
||||||
|
} else {
|
||||||
|
data[0x01] = 0;
|
||||||
|
data[0x02] = 0;
|
||||||
|
}
|
||||||
|
writeSector(CATALOG_TRACK, sector, data);
|
||||||
|
}
|
||||||
|
// create VTOC
|
||||||
|
data[0x01] = CATALOG_TRACK; // track# of first catalog sector
|
||||||
|
data[0x02] = (byte)firstCatalogSector; // sector# of first catalog sector
|
||||||
|
data[0x03] = 3; // DOS 3.3 formatted
|
||||||
|
data[0x06] = (byte)254; // DISK VOLUME#
|
||||||
|
data[0x27] = TRACK_SECTOR_PAIRS;// maximum # of T/S pairs in a sector
|
||||||
|
data[0x30] = CATALOG_TRACK+1; // last track where sectors allocated
|
||||||
|
data[0x31] = 1; // direction of allocation
|
||||||
|
data[0x34] = (byte)tracksPerDisk; // tracks per disk
|
||||||
|
data[0x35] = (byte)sectorsPerTrack;// sectors per track
|
||||||
|
data[0x37] = 1; // 36/37 are # of bytes per sector
|
||||||
|
for (int track=0; track<tracksPerDisk; track++) {
|
||||||
|
for (int sector=0; sector<sectorsPerTrack; sector++) {
|
||||||
|
if (track == 0 || track == CATALOG_TRACK) {
|
||||||
|
setSectorUsed(track, sector, data);
|
||||||
|
} else {
|
||||||
|
setSectorFree(track, sector, data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
writeVtoc(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates if a specific track/sector is free.
|
||||||
|
*/
|
||||||
|
public boolean isSectorFree(int track, int sector, byte[] vtoc) {
|
||||||
|
checkRange(track, sector);
|
||||||
|
byte byt = vtoc[getFreeMapByte(track, sector)];
|
||||||
|
return AppleUtil.isBitSet(byt, getFreeMapBit(sector));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates if a specific track/sector is used.
|
||||||
|
*/
|
||||||
|
public boolean isSectorUsed(int track, int sector, byte[] vtoc) {
|
||||||
|
return !isSectorFree(track, sector, vtoc);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the track/sector indicator to free.
|
||||||
|
*/
|
||||||
|
public void setSectorFree(int track, int sector, byte[] vtoc) {
|
||||||
|
checkRange(track, sector);
|
||||||
|
int offset = getFreeMapByte(track, sector);
|
||||||
|
byte byt = vtoc[offset];
|
||||||
|
byt = AppleUtil.setBit(byt, getFreeMapBit(sector));
|
||||||
|
vtoc[offset] = byt;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the track/sector indicator to used.
|
||||||
|
*/
|
||||||
|
public void setSectorUsed(int track, int sector, byte[] vtoc) {
|
||||||
|
checkRange(track, sector);
|
||||||
|
int offset = getFreeMapByte(track, sector);
|
||||||
|
byte byt = vtoc[offset];
|
||||||
|
byt = AppleUtil.clearBit(byt, getFreeMapBit(sector));
|
||||||
|
vtoc[offset] = byt;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compute the VTOC byte for the T/S map.
|
||||||
|
*/
|
||||||
|
protected int getFreeMapByte(int track, int sector) {
|
||||||
|
int trackOffset = track * 4;
|
||||||
|
int sectorOffset = 1 - ((sector & 0x8) >> 3);
|
||||||
|
return 0x38 + trackOffset + sectorOffset;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compute the VTOC bit for the T/S map.
|
||||||
|
*/
|
||||||
|
protected int getFreeMapBit(int sector) {
|
||||||
|
int bit = sector & 0x7;
|
||||||
|
return bit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validate track/sector range. This just validates the
|
||||||
|
* maximum values allowable for track and sector.
|
||||||
|
*/
|
||||||
|
protected void checkRange(int track, int sector) {
|
||||||
|
if (track > 50 || sector > 32) {
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
textBundle.format("DosFormatDisk.InvalidTrackAndSectorCombinationError", //$NON-NLS-1$
|
||||||
|
track, sector));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the logical disk number. Returns a 0 to indicate no numbering.
|
||||||
|
*/
|
||||||
|
public int getLogicalDiskNumber() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a valid filename for the given filename.
|
||||||
|
*/
|
||||||
|
public String getSuggestedFilename(String filename) {
|
||||||
|
int len = Math.min(filename.length(), 12);
|
||||||
|
return filename.toUpperCase().substring(0, len).trim();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a valid filetype for the given filename. The most simple
|
||||||
|
* format will just assume a filetype of binary. This method is
|
||||||
|
* available for the interface to make an intelligent first guess
|
||||||
|
* as to the filetype.
|
||||||
|
*/
|
||||||
|
public String getSuggestedFiletype(String filename) {
|
||||||
|
return "T"; //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a list of possible file types. Since the filetype is
|
||||||
|
* specific to each operating system, a simple String is used.
|
||||||
|
*/
|
||||||
|
public String[] getFiletypes() {
|
||||||
|
return filetypes;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates if this filetype requires an address component.
|
||||||
|
* For DOS, only the Binary type needs an address.
|
||||||
|
*/
|
||||||
|
public boolean needsAddress(String filetype) {
|
||||||
|
return "B".equals(filetype); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates if this FormattedDisk supports a disk map.
|
||||||
|
*/
|
||||||
|
public boolean supportsDiskMap() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Change to a different ImageOrder. Remains in DOS 3.3 format but
|
||||||
|
* the underlying order can chage.
|
||||||
|
* @see ImageOrder
|
||||||
|
*/
|
||||||
|
public void changeImageOrder(ImageOrder imageOrder) {
|
||||||
|
AppleUtil.changeImageOrderByTrackAndSector(getImageOrder(), imageOrder);
|
||||||
|
setImageOrder(imageOrder);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new DirectoryEntry.
|
||||||
|
* @see com.webcodepro.applecommander.storage.DirectoryEntry#createDirectory()
|
||||||
|
*/
|
||||||
|
public DirectoryEntry createDirectory() throws DiskFullException {
|
||||||
|
throw new UnsupportedOperationException(textBundle.get("DirectoryCreationNotSupported")); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
}
|
|
@ -49,6 +49,7 @@ WordProcessorRenderingMenuItem=Rendering
|
||||||
WordProcessorRenderAsTextMenuItem=Text
|
WordProcessorRenderAsTextMenuItem=Text
|
||||||
WordProcessorRenderAsHtmlMenuItem=HTML
|
WordProcessorRenderAsHtmlMenuItem=HTML
|
||||||
WordProcessorRenderAsRtfMenuItem=RTF
|
WordProcessorRenderAsRtfMenuItem=RTF
|
||||||
|
GutenbergRenderingMenuItem=Gutenberg File Rendered as...
|
||||||
ExportAsGraphicsMenuItem=Graphics...
|
ExportAsGraphicsMenuItem=Graphics...
|
||||||
ExportGraphicsModeMenuItem=Mode
|
ExportGraphicsModeMenuItem=Mode
|
||||||
ExportGraphicsAsHiresBlackAndWhiteMenuItem=Hi-Res B&W
|
ExportGraphicsAsHiresBlackAndWhiteMenuItem=Hi-Res B&W
|
||||||
|
|
|
@ -87,6 +87,7 @@ import com.webcodepro.applecommander.storage.filters.GraphicsFileFilter;
|
||||||
import com.webcodepro.applecommander.storage.filters.IntegerBasicFileFilter;
|
import com.webcodepro.applecommander.storage.filters.IntegerBasicFileFilter;
|
||||||
import com.webcodepro.applecommander.storage.filters.PascalTextFileFilter;
|
import com.webcodepro.applecommander.storage.filters.PascalTextFileFilter;
|
||||||
import com.webcodepro.applecommander.storage.filters.TextFileFilter;
|
import com.webcodepro.applecommander.storage.filters.TextFileFilter;
|
||||||
|
import com.webcodepro.applecommander.storage.filters.GutenbergFileFilter;
|
||||||
import com.webcodepro.applecommander.storage.os.prodos.ProdosDiskSizeDoesNotMatchException;
|
import com.webcodepro.applecommander.storage.os.prodos.ProdosDiskSizeDoesNotMatchException;
|
||||||
import com.webcodepro.applecommander.storage.os.prodos.ProdosFormatDisk;
|
import com.webcodepro.applecommander.storage.os.prodos.ProdosFormatDisk;
|
||||||
import com.webcodepro.applecommander.storage.physical.ByteArrayImageLayout;
|
import com.webcodepro.applecommander.storage.physical.ByteArrayImageLayout;
|
||||||
|
@ -153,6 +154,7 @@ public class DiskExplorerTab {
|
||||||
private FileFilter fileFilter;
|
private FileFilter fileFilter;
|
||||||
private GraphicsFileFilter graphicsFilter = new GraphicsFileFilter();
|
private GraphicsFileFilter graphicsFilter = new GraphicsFileFilter();
|
||||||
private AppleWorksWordProcessorFileFilter awpFilter = new AppleWorksWordProcessorFileFilter();
|
private AppleWorksWordProcessorFileFilter awpFilter = new AppleWorksWordProcessorFileFilter();
|
||||||
|
private GutenbergFileFilter wpFilter = new GutenbergFileFilter();
|
||||||
|
|
||||||
private int currentFormat = FormattedDisk.FILE_DISPLAY_STANDARD;
|
private int currentFormat = FormattedDisk.FILE_DISPLAY_STANDARD;
|
||||||
private boolean formatChanged;
|
private boolean formatChanged;
|
||||||
|
@ -612,6 +614,62 @@ public class DiskExplorerTab {
|
||||||
|
|
||||||
item = new MenuItem(menu, SWT.SEPARATOR);
|
item = new MenuItem(menu, SWT.SEPARATOR);
|
||||||
|
|
||||||
|
item = new MenuItem(menu, SWT.CASCADE);
|
||||||
|
item.setText(textBundle.get("GutenbergRenderingMenuItem")); //$NON-NLS-1$
|
||||||
|
Menu subMenu2 = new Menu(shell, SWT.DROP_DOWN);
|
||||||
|
item.setMenu(subMenu2);
|
||||||
|
subMenu.addMenuListener(new MenuAdapter() {
|
||||||
|
/**
|
||||||
|
* Toggle all sub-menu MenuItems to the proper state to reflect
|
||||||
|
* the current file extension chosen.
|
||||||
|
*/
|
||||||
|
public void menuShown(MenuEvent event) {
|
||||||
|
Menu theMenu = (Menu) event.getSource();
|
||||||
|
MenuItem[] subItems = theMenu.getItems();
|
||||||
|
subItems[0].setSelection(getWPFilter().isTextRendering());
|
||||||
|
subItems[1].setSelection(getWPFilter().isHtmlRendering());
|
||||||
|
subItems[2].setSelection(getWPFilter().isRtfRendering());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
item = new MenuItem(subMenu2, SWT.RADIO);
|
||||||
|
item.setText(textBundle.get("WordProcessorRenderAsTextMenuItem")); //$NON-NLS-1$
|
||||||
|
item.addSelectionListener(new SelectionAdapter() {
|
||||||
|
/**
|
||||||
|
* Set the appropriate rendering style.
|
||||||
|
*/
|
||||||
|
public void widgetSelected(SelectionEvent event) {
|
||||||
|
getWPFilter().selectTextRendering();
|
||||||
|
setFileFilter(getWPFilter());
|
||||||
|
exportFile(null);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
item = new MenuItem(subMenu2, SWT.RADIO);
|
||||||
|
item.setText(textBundle.get("WordProcessorRenderAsHtmlMenuItem")); //$NON-NLS-1$
|
||||||
|
item.addSelectionListener(new SelectionAdapter() {
|
||||||
|
/**
|
||||||
|
* Set the appropriate rendering style.
|
||||||
|
*/
|
||||||
|
public void widgetSelected(SelectionEvent event) {
|
||||||
|
getWPFilter().selectHtmlRendering();
|
||||||
|
setFileFilter(getWPFilter());
|
||||||
|
exportFile(null);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
item = new MenuItem(subMenu2, SWT.RADIO);
|
||||||
|
item.setText(textBundle.get("WordProcessorRenderAsRtfMenuItem")); //$NON-NLS-1$
|
||||||
|
item.addSelectionListener(new SelectionAdapter() {
|
||||||
|
/**
|
||||||
|
* Set the appropriate rendering style.
|
||||||
|
*/
|
||||||
|
public void widgetSelected(SelectionEvent event) {
|
||||||
|
getWPFilter().selectRtfRendering();
|
||||||
|
setFileFilter(getWPFilter());
|
||||||
|
exportFile(null);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
item = new MenuItem(menu, SWT.SEPARATOR);
|
||||||
|
|
||||||
item = new MenuItem(menu, SWT.NONE);
|
item = new MenuItem(menu, SWT.NONE);
|
||||||
item.setText(textBundle.get("ExportAsGraphicsMenuItem")); //$NON-NLS-1$
|
item.setText(textBundle.get("ExportAsGraphicsMenuItem")); //$NON-NLS-1$
|
||||||
item.setEnabled(GraphicsFileFilter.isCodecAvailable());
|
item.setEnabled(GraphicsFileFilter.isCodecAvailable());
|
||||||
|
@ -953,6 +1011,7 @@ public class DiskExplorerTab {
|
||||||
outputStream.write(data);
|
outputStream.write(data);
|
||||||
outputStream.close();
|
outputStream.close();
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
|
ex.printStackTrace();
|
||||||
String errorMessage = ex.getMessage();
|
String errorMessage = ex.getMessage();
|
||||||
if (errorMessage == null) {
|
if (errorMessage == null) {
|
||||||
errorMessage = ex.getClass().getName();
|
errorMessage = ex.getClass().getName();
|
||||||
|
@ -1596,6 +1655,7 @@ public class DiskExplorerTab {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else { // No CTRL key
|
} else { // No CTRL key
|
||||||
|
if ((event.stateMask & SWT.ALT) != SWT.ALT) { // Ignore ALT key combinations like alt-F4!
|
||||||
switch (event.keyCode) {
|
switch (event.keyCode) {
|
||||||
case SWT.F2: // Standard file display
|
case SWT.F2: // Standard file display
|
||||||
changeCurrentFormat(FormattedDisk.FILE_DISPLAY_STANDARD);
|
changeCurrentFormat(FormattedDisk.FILE_DISPLAY_STANDARD);
|
||||||
|
@ -1611,6 +1671,7 @@ public class DiskExplorerTab {
|
||||||
getShowDeletedFilesToolItem().setSelection(isShowDeletedFiles());
|
getShowDeletedFilesToolItem().setSelection(isShowDeletedFiles());
|
||||||
fillFileTable(getCurrentFileList());
|
fillFileTable(getCurrentFileList());
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1939,6 +2000,10 @@ public class DiskExplorerTab {
|
||||||
return awpFilter;
|
return awpFilter;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected GutenbergFileFilter getWPFilter() {
|
||||||
|
return wpFilter;
|
||||||
|
}
|
||||||
|
|
||||||
protected GraphicsFileFilter getGraphicsFilter() {
|
protected GraphicsFileFilter getGraphicsFilter() {
|
||||||
return graphicsFilter;
|
return graphicsFilter;
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,6 +52,7 @@ import com.webcodepro.applecommander.storage.filters.GraphicsFileFilter;
|
||||||
import com.webcodepro.applecommander.storage.filters.IntegerBasicFileFilter;
|
import com.webcodepro.applecommander.storage.filters.IntegerBasicFileFilter;
|
||||||
import com.webcodepro.applecommander.storage.filters.PascalTextFileFilter;
|
import com.webcodepro.applecommander.storage.filters.PascalTextFileFilter;
|
||||||
import com.webcodepro.applecommander.storage.filters.TextFileFilter;
|
import com.webcodepro.applecommander.storage.filters.TextFileFilter;
|
||||||
|
import com.webcodepro.applecommander.storage.filters.GutenbergFileFilter;
|
||||||
import com.webcodepro.applecommander.ui.UiBundle;
|
import com.webcodepro.applecommander.ui.UiBundle;
|
||||||
import com.webcodepro.applecommander.ui.swt.filteradapter.ApplesoftFilterAdapter;
|
import com.webcodepro.applecommander.ui.swt.filteradapter.ApplesoftFilterAdapter;
|
||||||
import com.webcodepro.applecommander.ui.swt.filteradapter.BusinessBASICFilterAdapter;
|
import com.webcodepro.applecommander.ui.swt.filteradapter.BusinessBASICFilterAdapter;
|
||||||
|
@ -187,10 +188,15 @@ public class FileViewerWindow {
|
||||||
imageManager.get(ImageManager.ICON_VIEW_AS_SPREADSHEET)
|
imageManager.get(ImageManager.ICON_VIEW_AS_SPREADSHEET)
|
||||||
));
|
));
|
||||||
nativeFilterAdapterMap.put(AppleWorksWordProcessorFileFilter.class,
|
nativeFilterAdapterMap.put(AppleWorksWordProcessorFileFilter.class,
|
||||||
new TextFilterAdapter(this, textBundle.get("FileViewerWindow.WordprocessorButton"), //$NON-NLS-1$
|
new TextFilterAdapter(this, textBundle.get("FileViewerWindow.WordprocessorButton"), //$NON-NLS-1$
|
||||||
textBundle.get("FileViewerWindow.WordprocessorTooltip"), //$NON-NLS-1$
|
textBundle.get("FileViewerWindow.WordprocessorTooltip"), //$NON-NLS-1$
|
||||||
imageManager.get(ImageManager.ICON_VIEW_AS_WORDPROCESSOR)
|
imageManager.get(ImageManager.ICON_VIEW_AS_WORDPROCESSOR)
|
||||||
));
|
));
|
||||||
|
nativeFilterAdapterMap.put(GutenbergFileFilter.class,
|
||||||
|
new TextFilterAdapter(this, textBundle.get("FileViewerWindow.WordprocessorButton"), //$NON-NLS-1$
|
||||||
|
textBundle.get("FileViewerWindow.WordprocessorTooltip"), //$NON-NLS-1$
|
||||||
|
imageManager.get(ImageManager.ICON_VIEW_AS_WORDPROCESSOR)
|
||||||
|
));
|
||||||
nativeFilterAdapterMap.put(AssemblySourceFileFilter.class,
|
nativeFilterAdapterMap.put(AssemblySourceFileFilter.class,
|
||||||
new TextFilterAdapter(this, textBundle.get("FileViewerWindow.AssemblyButton"), //$NON-NLS-1$
|
new TextFilterAdapter(this, textBundle.get("FileViewerWindow.AssemblyButton"), //$NON-NLS-1$
|
||||||
textBundle.get("FileViewerWindow.AssemblyTooltip"), //$NON-NLS-1$
|
textBundle.get("FileViewerWindow.AssemblyTooltip"), //$NON-NLS-1$
|
||||||
|
|
Loading…
Reference in New Issue
Block a user