diff --git a/src/com/webcodepro/applecommander/ui/swt/FileViewerWindow.java b/src/com/webcodepro/applecommander/ui/swt/FileViewerWindow.java index d6c7627..818438c 100644 --- a/src/com/webcodepro/applecommander/ui/swt/FileViewerWindow.java +++ b/src/com/webcodepro/applecommander/ui/swt/FileViewerWindow.java @@ -19,28 +19,42 @@ */ package com.webcodepro.applecommander.ui.swt; +import com.webcodepro.applecommander.storage.AppleWorksDataBaseFileFilter; +import com.webcodepro.applecommander.storage.AppleWorksSpreadSheetFileFilter; +import com.webcodepro.applecommander.storage.AppleWorksWordProcessorFileFilter; +import com.webcodepro.applecommander.storage.ApplesoftFileFilter; import com.webcodepro.applecommander.storage.FileEntry; import com.webcodepro.applecommander.storage.FileFilter; -import com.webcodepro.applecommander.storage.FormattedDisk; import com.webcodepro.applecommander.storage.GraphicsFileFilter; +import com.webcodepro.applecommander.storage.HexDumpFileFilter; +import com.webcodepro.applecommander.storage.IntegerBasicFileFilter; +import com.webcodepro.applecommander.storage.TextFileFilter; +import com.webcodepro.applecommander.util.ApplesoftToken; +import com.webcodepro.applecommander.util.ApplesoftTokenizer; import java.io.ByteArrayInputStream; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.ScrolledComposite; +import org.eclipse.swt.custom.StyleRange; +import org.eclipse.swt.custom.StyledText; import org.eclipse.swt.events.DisposeEvent; import org.eclipse.swt.events.DisposeListener; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Font; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.graphics.ImageData; import org.eclipse.swt.graphics.ImageLoader; +import org.eclipse.swt.graphics.Point; import org.eclipse.swt.layout.FillLayout; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Listener; import org.eclipse.swt.widgets.Shell; import org.eclipse.swt.widgets.ToolBar; import org.eclipse.swt.widgets.ToolItem; @@ -57,12 +71,19 @@ public class FileViewerWindow { private Shell shell; private FileEntry fileEntry; + private FileFilter nativeFilter; private ScrolledComposite content; private ToolBar toolBar; - private ToolItem imageToolItem; + private ToolItem nativeToolItem; private ToolItem hexDumpToolItem; + private ToolItem rawDumpToolItem; private ToolItem printToolItem; + + private Font courier; + private Color black; + private Color blue; + private Color green; /** * Construct the file viewer window. @@ -71,6 +92,7 @@ public class FileViewerWindow { this.parentShell = shell; this.fileEntry = fileEntry; this.imageManager = imageManager; + this.nativeFilter = fileEntry.getSuggestedFilter(); } /** @@ -98,55 +120,12 @@ public class FileViewerWindow { gridData = new GridData(GridData.FILL_BOTH); content.setLayoutData(gridData); - FileFilter filter = fileEntry.getSuggestedFilter(); - Color red = new Color(shell.getDisplay(), 255, 0, 0); - if (filter instanceof GraphicsFileFilter) { - byte[] imageBytes = filter.filter(fileEntry); - ByteArrayInputStream inputStream = new ByteArrayInputStream(imageBytes); - ImageLoader imageLoader = new ImageLoader(); - ImageData[] imageData = imageLoader.load(inputStream); - final Image image = new Image(shell.getDisplay(), imageData[0]); - - GridLayout layout = new GridLayout(); - content.setLayout(layout); - gridData = new GridData(); - gridData.widthHint = imageData[0].width; - gridData.heightHint = imageData[0].height; - ImageCanvas imageCanvas = new ImageCanvas(content, SWT.NONE, image, gridData); - content.setContent(imageCanvas); - content.setExpandHorizontal(true); - content.setExpandVertical(true); - content.setMinWidth(imageData[0].width); - content.setMinHeight(imageData[0].height); - -// ImageCanvas imageCanvas = new ImageCanvas(content, SWT.BORDER, image, gridData); -// imageCanvas.addListener(SWT.KeyUp, this); - - - -// Canvas canvas = new Canvas (content, SWT.NONE); -// content.setContent(canvas); -// canvas.addPaintListener (new PaintListener () { -// public void paintControl (PaintEvent e) { -// e.gc.drawImage (image, 0, 0); -// } -// }); - -// Label label = new Label(content, SWT.NONE); -// label.setImage(image); -// content.setContent(label); - } else { - // Garbage: - final Composite c1 = new Composite(content, SWT.NONE); - content.setContent(c1); - c1.setBackground(red); - GridLayout layout = new GridLayout(); - layout.numColumns = 4; - c1.setLayout(layout); - Button b1 = new Button (c1, SWT.PUSH); - b1.setText("first button"); - c1.setSize(c1.computeSize(SWT.DEFAULT, SWT.DEFAULT)); - } + courier = new Font(shell.getDisplay(), "Courier", 10, SWT.NORMAL); + black = new Color(shell.getDisplay(), 0, 0, 0); + blue = new Color(shell.getDisplay(), 0, 0, 192); + green = new Color(shell.getDisplay(), 0, 192, 0); + + displayNativeFormat(); shell.open(); } @@ -155,6 +134,10 @@ public class FileViewerWindow { * Dispose of all shared resources. */ private void dispose(DisposeEvent event) { + courier.dispose(); + black.dispose(); + blue.dispose(); + green.dispose(); System.gc(); } @@ -163,28 +146,96 @@ public class FileViewerWindow { */ private void createFileToolBar(Composite composite, Object layoutData) { toolBar = new ToolBar(composite, SWT.FLAT); -// toolBar.addListener(SWT.KeyUp, createToolbarCommandHandler()); + toolBar.addListener(SWT.KeyUp, createToolbarCommandHandler()); if (layoutData != null) toolBar.setLayoutData(layoutData); - imageToolItem = new ToolItem(toolBar, SWT.RADIO); - imageToolItem.setImage(imageManager.get(ImageManager.ICON_VIEW_AS_IMAGE)); - imageToolItem.setText("Image"); - imageToolItem.setToolTipText("Displays file as an image"); - imageToolItem.setSelection(true); - imageToolItem.addSelectionListener(new SelectionAdapter () { - public void widgetSelected(SelectionEvent e) { - //changeCurrentFormat(FormattedDisk.FILE_DISPLAY_STANDARD); - } - }); + if (nativeFilter instanceof ApplesoftFileFilter || nativeFilter instanceof IntegerBasicFileFilter) { + nativeToolItem = new ToolItem(toolBar, SWT.RADIO); + nativeToolItem.setImage(imageManager.get(ImageManager.ICON_VIEW_AS_BASIC_PROGRAM)); + nativeToolItem.setText("BASIC"); + nativeToolItem.setToolTipText("Displays file as BASIC program (F2)"); + nativeToolItem.setSelection(true); + nativeToolItem.addSelectionListener(new SelectionAdapter () { + public void widgetSelected(SelectionEvent e) { + displayNativeFormat(); + } + }); + } else if (nativeFilter instanceof AppleWorksDataBaseFileFilter) { + nativeToolItem = new ToolItem(toolBar, SWT.RADIO); + nativeToolItem.setImage(imageManager.get(ImageManager.ICON_VIEW_AS_DATABASE)); + nativeToolItem.setText("Database"); + nativeToolItem.setToolTipText("Displays file as a database file (F2)"); + nativeToolItem.setSelection(true); + nativeToolItem.addSelectionListener(new SelectionAdapter () { + public void widgetSelected(SelectionEvent e) { + displayNativeFormat(); + } + }); + } else if (nativeFilter instanceof AppleWorksSpreadSheetFileFilter) { + nativeToolItem = new ToolItem(toolBar, SWT.RADIO); + nativeToolItem.setImage(imageManager.get(ImageManager.ICON_VIEW_AS_SPREADSHEET)); + nativeToolItem.setText("Spreadsheet"); + nativeToolItem.setToolTipText("Displays file as a spreadsheet file (F2)"); + nativeToolItem.setSelection(true); + nativeToolItem.addSelectionListener(new SelectionAdapter () { + public void widgetSelected(SelectionEvent e) { + displayNativeFormat(); + } + }); + } else if (nativeFilter instanceof AppleWorksWordProcessorFileFilter) { + nativeToolItem = new ToolItem(toolBar, SWT.RADIO); + nativeToolItem.setImage(imageManager.get(ImageManager.ICON_VIEW_AS_WORDPROCESSOR)); + nativeToolItem.setText("Wordprocessor"); + nativeToolItem.setToolTipText("Displays file as a wordprocessor file (F2)"); + nativeToolItem.setSelection(true); + nativeToolItem.addSelectionListener(new SelectionAdapter () { + public void widgetSelected(SelectionEvent e) { + displayNativeFormat(); + } + }); + } else if (nativeFilter instanceof GraphicsFileFilter) { + nativeToolItem = new ToolItem(toolBar, SWT.RADIO); + nativeToolItem.setImage(imageManager.get(ImageManager.ICON_VIEW_AS_IMAGE)); + nativeToolItem.setText("Image"); + nativeToolItem.setToolTipText("Displays file as an image (F2)"); + nativeToolItem.setSelection(true); + nativeToolItem.addSelectionListener(new SelectionAdapter () { + public void widgetSelected(SelectionEvent e) { + displayNativeFormat(); + } + }); + } else if (nativeFilter instanceof TextFileFilter) { + nativeToolItem = new ToolItem(toolBar, SWT.RADIO); + nativeToolItem.setImage(imageManager.get(ImageManager.ICON_VIEW_AS_TEXTFILE)); + nativeToolItem.setText("Text"); + nativeToolItem.setToolTipText("Displays file as a text file (F2)"); + nativeToolItem.setSelection(true); + nativeToolItem.addSelectionListener(new SelectionAdapter () { + public void widgetSelected(SelectionEvent e) { + displayNativeFormat(); + } + }); + } hexDumpToolItem = new ToolItem(toolBar, SWT.RADIO); hexDumpToolItem.setImage(imageManager.get(ImageManager.ICON_VIEW_IN_HEX)); hexDumpToolItem.setText("Hex Dump"); - hexDumpToolItem.setToolTipText("Displays file as a hex dump"); + hexDumpToolItem.setToolTipText("Displays file as a hex dump (F3)"); hexDumpToolItem.setSelection(false); hexDumpToolItem.addSelectionListener(new SelectionAdapter () { public void widgetSelected(SelectionEvent e) { - //changeCurrentFormat(FormattedDisk.FILE_DISPLAY_STANDARD); + displayHexFormat(); + } + }); + + rawDumpToolItem = new ToolItem(toolBar, SWT.RADIO); + rawDumpToolItem.setImage(imageManager.get(ImageManager.ICON_VIEW_IN_RAW_HEX)); + rawDumpToolItem.setText("Raw Dump"); + rawDumpToolItem.setToolTipText("Displays file as a raw hex dump (F4)"); + rawDumpToolItem.setSelection(false); + rawDumpToolItem.addSelectionListener(new SelectionAdapter () { + public void widgetSelected(SelectionEvent e) { + displayRawFormat(); } }); @@ -192,7 +243,7 @@ public class FileViewerWindow { ToolItem copy = new ToolItem(toolBar, SWT.PUSH); copy.setText("Copy"); - copy.setText("Copies selection to the clipboard"); + copy.setToolTipText("Copies selection to the clipboard"); copy.setEnabled(false); new ToolItem(toolBar, SWT.SEPARATOR); @@ -204,10 +255,179 @@ public class FileViewerWindow { printToolItem.setEnabled(true); printToolItem.addSelectionListener(new SelectionAdapter () { public void widgetSelected(SelectionEvent e) { - //saveAs(); + // FIXME + Control control = content.getContent(); + if (control instanceof StyledText) { + StyledText styledText = (StyledText) control; + styledText.print(); + } } }); toolBar.pack(); } + protected void displayNativeFormat() { + Control oldContent = content.getContent(); + if (oldContent != null) { + oldContent.dispose(); + content.setContent(null); + } + + if (nativeToolItem != null) nativeToolItem.setSelection(true); + hexDumpToolItem.setSelection(false); + rawDumpToolItem.setSelection(false); + + if (nativeFilter instanceof ApplesoftFileFilter) { + StyledText styledText = new StyledText(content, SWT.NONE); + styledText.setForeground(black); + styledText.setFont(courier); + styledText.setEditable(false); + + ApplesoftTokenizer tokenizer = new ApplesoftTokenizer(fileEntry); + boolean firstLine = true; + while (tokenizer.hasMoreTokens()) { + ApplesoftToken token = tokenizer.getNextToken(); + if (token == null) { + continue; // should be end of program... + } else if (token.isLineNumber()) { + if (firstLine) { + firstLine = false; + } else { + styledText.append("\n"); + } + styledText.append(Integer.toString(token.getLineNumber())); + styledText.append(" "); + } else if (token.isCommandSeparator() || token.isExpressionSeparator()) { + styledText.append(token.getStringValue()); + } else if (token.isEndOfCommand()) { + styledText.append("\n"); + } else if (token.isString()) { + int caretOffset = styledText.getCharCount(); + styledText.append(token.getStringValue()); + StyleRange styleRange = new StyleRange(); + styleRange.start = caretOffset; + styleRange.length = token.getStringValue().length(); + styleRange.foreground = green; + styledText.setStyleRange(styleRange); + } else if (token.isToken()) { + int caretOffset = styledText.getCharCount(); + styledText.append(token.getTokenString()); + StyleRange styleRange = new StyleRange(); + styleRange.start = caretOffset; + styleRange.length = token.getTokenString().length(); + //styleRange.fontStyle = SWT.BOLD; + styleRange.foreground = blue; + styledText.setStyleRange(styleRange); + } + } + Point size = styledText.computeSize(SWT.DEFAULT, SWT.DEFAULT, true); + content.setContent(styledText); + content.setExpandHorizontal(true); + content.setExpandVertical(true); + content.setMinWidth(size.x); + content.setMinHeight(size.y); + } else if (nativeFilter instanceof IntegerBasicFileFilter) { + String basicDump = new String(nativeFilter.filter(fileEntry)); + createTextWidget(content, basicDump); + } else if (nativeFilter instanceof AppleWorksDataBaseFileFilter) { + String basicDump = new String(nativeFilter.filter(fileEntry)); + createTextWidget(content, basicDump); + } else if (nativeFilter instanceof AppleWorksSpreadSheetFileFilter) { + String basicDump = new String(nativeFilter.filter(fileEntry)); + createTextWidget(content, basicDump); + } else if (nativeFilter instanceof AppleWorksWordProcessorFileFilter) { + String basicDump = new String(nativeFilter.filter(fileEntry)); + createTextWidget(content, basicDump); + } else if (nativeFilter instanceof GraphicsFileFilter) { + byte[] imageBytes = nativeFilter.filter(fileEntry); + ByteArrayInputStream inputStream = new ByteArrayInputStream(imageBytes); + ImageLoader imageLoader = new ImageLoader(); + ImageData[] imageData = imageLoader.load(inputStream); + final Image image = new Image(shell.getDisplay(), imageData[0]); + + GridLayout layout = new GridLayout(); + content.setLayout(layout); + GridData gridData = new GridData(); + gridData.widthHint = imageData[0].width; + gridData.heightHint = imageData[0].height; + ImageCanvas imageCanvas = new ImageCanvas(content, SWT.NONE, image, gridData); + content.setContent(imageCanvas); + content.setExpandHorizontal(true); + content.setExpandVertical(true); + content.setMinWidth(imageData[0].width); + content.setMinHeight(imageData[0].height); + } else if (nativeFilter instanceof TextFileFilter) { + String textDump = new String(nativeFilter.filter(fileEntry)); + createTextWidget(content, textDump); + } else { + displayHexFormat(); + } + } + protected void createTextWidget(Composite composite, String text) { + StyledText styledText = new StyledText(composite, SWT.NONE); + styledText.setText(text); + styledText.setFont(courier); + styledText.setEditable(false); + //styledText.setWordWrap(true); // seems to throw size out-of-whack + Point size = styledText.computeSize(SWT.DEFAULT, SWT.DEFAULT, true); + content.setContent(styledText); + content.setExpandHorizontal(true); + content.setExpandVertical(true); + content.setMinWidth(size.x); + content.setMinHeight(size.y); + } + protected void displayHexFormat() { + Control oldContent = content.getContent(); + if (oldContent != null) { + oldContent.dispose(); + content.setContent(null); + } + + if (nativeToolItem != null) nativeToolItem.setSelection(false); + hexDumpToolItem.setSelection(true); + rawDumpToolItem.setSelection(false); + + FileFilter filter = new HexDumpFileFilter(); + String hexDump = new String(filter.filter(fileEntry)); + createTextWidget(content, hexDump); + } + protected void displayRawFormat() { + Control oldContent = content.getContent(); + if (oldContent != null) { + oldContent.dispose(); + content.setContent(null); + } + + if (nativeToolItem != null) nativeToolItem.setSelection(false); + hexDumpToolItem.setSelection(false); + rawDumpToolItem.setSelection(true); + + String rawDump = new String( + fileEntry.getFormattedDisk().getFileData(fileEntry)); + createTextWidget(content, rawDump); + } + /** + * The toolbar command handler contains the global toolbar + * actions. The intent is that the listener is then added to + * multiple visual components. + */ + private Listener createToolbarCommandHandler() { + return new Listener() { + public void handleEvent(Event event) { + if (event.type == SWT.KeyUp) { + switch (event.keyCode) { + case SWT.F2: // the "native" file format (image, text, etc) + displayNativeFormat(); + break; + case SWT.F3: // Hex format + displayHexFormat(); + break; + case SWT.F4: // "Raw" hex format + displayRawFormat(); + break; + } + } + } + }; + } }