mirror of
https://github.com/AppleCommander/AppleCommander.git
synced 2024-12-21 01:30:34 +00:00
Now validating Applesoft import in user interface. #119
This commit is contained in:
parent
643de4b4b1
commit
709ce6b47f
@ -33,6 +33,16 @@ public class ImportSpecification {
|
||||
private String filetype;
|
||||
private int address;
|
||||
private boolean rawFileImport;
|
||||
private byte[] fileData;
|
||||
|
||||
public ImportSpecification(ImportSpecification orig) {
|
||||
this.sourceFilename = orig.sourceFilename;
|
||||
this.targetFilename = orig.targetFilename;
|
||||
this.filetype = orig.filetype;
|
||||
this.address = orig.address;
|
||||
this.rawFileImport = orig.rawFileImport;
|
||||
this.fileData = orig.fileData;
|
||||
}
|
||||
/**
|
||||
* Create the ImportSpecification with default values.
|
||||
*/
|
||||
@ -118,4 +128,22 @@ public class ImportSpecification {
|
||||
public void setRawFileImport(boolean rawFileImport) {
|
||||
this.rawFileImport = rawFileImport;
|
||||
}
|
||||
/**
|
||||
* Set the binary file data (only done with validated file types).
|
||||
*/
|
||||
public void setFileData(byte[] fileData) {
|
||||
this.fileData = fileData;
|
||||
}
|
||||
/**
|
||||
* Get the binary file data (only done with validated file types).
|
||||
*/
|
||||
public byte[] getFileData() {
|
||||
return fileData;
|
||||
}
|
||||
/**
|
||||
* Answers true if this specification has file data attached.
|
||||
*/
|
||||
public boolean hasFileData() {
|
||||
return fileData != null;
|
||||
}
|
||||
}
|
||||
|
@ -17,6 +17,7 @@ dependencies {
|
||||
implementation project(':lib:ac-api')
|
||||
|
||||
implementation "net.sf.applecommander:applesingle-api:$asVersion"
|
||||
implementation "net.sf.applecommander:bastools-api:$btVersion"
|
||||
|
||||
testImplementation "junit:junit:$junitVersion"
|
||||
testImplementation "org.apache.commons:commons-lang3:$commonsLang3Version"
|
||||
|
@ -19,85 +19,14 @@
|
||||
*/
|
||||
package com.webcodepro.applecommander.ui.swt;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.eclipse.swt.SWT;
|
||||
import org.eclipse.swt.custom.CTabFolder;
|
||||
import org.eclipse.swt.custom.CTabItem;
|
||||
import org.eclipse.swt.custom.SashForm;
|
||||
import org.eclipse.swt.events.MenuAdapter;
|
||||
import org.eclipse.swt.events.MenuEvent;
|
||||
import org.eclipse.swt.events.SelectionAdapter;
|
||||
import org.eclipse.swt.events.SelectionEvent;
|
||||
import org.eclipse.swt.events.SelectionListener;
|
||||
import org.eclipse.swt.graphics.Font;
|
||||
import org.eclipse.swt.graphics.GC;
|
||||
import org.eclipse.swt.graphics.Point;
|
||||
import org.eclipse.swt.graphics.Rectangle;
|
||||
import org.eclipse.swt.layout.GridData;
|
||||
import org.eclipse.swt.layout.GridLayout;
|
||||
import org.eclipse.swt.printing.PrintDialog;
|
||||
import org.eclipse.swt.printing.Printer;
|
||||
import org.eclipse.swt.printing.PrinterData;
|
||||
import org.eclipse.swt.widgets.Composite;
|
||||
import org.eclipse.swt.widgets.Event;
|
||||
import org.eclipse.swt.widgets.FileDialog;
|
||||
import org.eclipse.swt.widgets.Label;
|
||||
import org.eclipse.swt.widgets.Listener;
|
||||
import org.eclipse.swt.widgets.Menu;
|
||||
import org.eclipse.swt.widgets.MenuItem;
|
||||
import org.eclipse.swt.widgets.MessageBox;
|
||||
import org.eclipse.swt.widgets.ProgressBar;
|
||||
import org.eclipse.swt.widgets.Shell;
|
||||
import org.eclipse.swt.widgets.Table;
|
||||
import org.eclipse.swt.widgets.TableColumn;
|
||||
import org.eclipse.swt.widgets.TableItem;
|
||||
import org.eclipse.swt.widgets.ToolBar;
|
||||
import org.eclipse.swt.widgets.ToolItem;
|
||||
import org.eclipse.swt.widgets.Tree;
|
||||
import org.eclipse.swt.widgets.TreeItem;
|
||||
|
||||
import com.webcodepro.applecommander.compiler.ApplesoftCompiler;
|
||||
import com.webcodepro.applecommander.storage.DirectoryEntry;
|
||||
import com.webcodepro.applecommander.storage.Disk;
|
||||
import com.webcodepro.applecommander.storage.DiskException;
|
||||
import com.webcodepro.applecommander.storage.FileEntry;
|
||||
import com.webcodepro.applecommander.storage.FileEntryComparator;
|
||||
import com.webcodepro.applecommander.storage.FileFilter;
|
||||
import com.webcodepro.applecommander.storage.FormattedDisk;
|
||||
import com.webcodepro.applecommander.storage.*;
|
||||
import com.webcodepro.applecommander.storage.FormattedDisk.FileColumnHeader;
|
||||
import com.webcodepro.applecommander.storage.filters.AppleWorksDataBaseFileFilter;
|
||||
import com.webcodepro.applecommander.storage.filters.AppleWorksSpreadSheetFileFilter;
|
||||
import com.webcodepro.applecommander.storage.filters.AppleWorksWordProcessorFileFilter;
|
||||
import com.webcodepro.applecommander.storage.filters.ApplesoftFileFilter;
|
||||
import com.webcodepro.applecommander.storage.filters.AssemblySourceFileFilter;
|
||||
import com.webcodepro.applecommander.storage.filters.BinaryFileFilter;
|
||||
import com.webcodepro.applecommander.storage.filters.BusinessBASICFileFilter;
|
||||
import com.webcodepro.applecommander.storage.filters.GraphicsFileFilter;
|
||||
import com.webcodepro.applecommander.storage.filters.GutenbergFileFilter;
|
||||
import com.webcodepro.applecommander.storage.filters.IntegerBasicFileFilter;
|
||||
import com.webcodepro.applecommander.storage.filters.PascalTextFileFilter;
|
||||
import com.webcodepro.applecommander.storage.filters.TextFileFilter;
|
||||
import com.webcodepro.applecommander.storage.filters.*;
|
||||
import com.webcodepro.applecommander.storage.os.prodos.ProdosDiskSizeDoesNotMatchException;
|
||||
import com.webcodepro.applecommander.storage.os.prodos.ProdosFormatDisk;
|
||||
import com.webcodepro.applecommander.storage.physical.ByteArrayImageLayout;
|
||||
import com.webcodepro.applecommander.storage.physical.DosOrder;
|
||||
import com.webcodepro.applecommander.storage.physical.ImageOrder;
|
||||
import com.webcodepro.applecommander.storage.physical.NibbleOrder;
|
||||
import com.webcodepro.applecommander.storage.physical.ProdosOrder;
|
||||
import com.webcodepro.applecommander.storage.physical.*;
|
||||
import com.webcodepro.applecommander.ui.ImportSpecification;
|
||||
import com.webcodepro.applecommander.ui.UiBundle;
|
||||
import com.webcodepro.applecommander.ui.UserPreferences;
|
||||
@ -111,8 +40,28 @@ import com.webcodepro.applecommander.util.AppleUtil;
|
||||
import com.webcodepro.applecommander.util.Host;
|
||||
import com.webcodepro.applecommander.util.StreamUtil;
|
||||
import com.webcodepro.applecommander.util.TextBundle;
|
||||
|
||||
import io.github.applecommander.applesingle.AppleSingle;
|
||||
import org.eclipse.swt.SWT;
|
||||
import org.eclipse.swt.custom.CTabFolder;
|
||||
import org.eclipse.swt.custom.CTabItem;
|
||||
import org.eclipse.swt.custom.SashForm;
|
||||
import org.eclipse.swt.events.*;
|
||||
import org.eclipse.swt.graphics.Font;
|
||||
import org.eclipse.swt.graphics.GC;
|
||||
import org.eclipse.swt.graphics.Point;
|
||||
import org.eclipse.swt.graphics.Rectangle;
|
||||
import org.eclipse.swt.layout.GridData;
|
||||
import org.eclipse.swt.layout.GridLayout;
|
||||
import org.eclipse.swt.printing.PrintDialog;
|
||||
import org.eclipse.swt.printing.Printer;
|
||||
import org.eclipse.swt.printing.PrinterData;
|
||||
import org.eclipse.swt.widgets.*;
|
||||
|
||||
import java.io.*;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.List;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* Build the Disk File tab for the Disk Window.
|
||||
@ -1193,10 +1142,15 @@ public class DiskExplorerTab {
|
||||
i+1, specs.size()));
|
||||
nameLabel.setText(spec.getSourceFilename());
|
||||
progressBar.setSelection(i);
|
||||
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
|
||||
InputStream input = new FileInputStream(spec.getSourceFilename());
|
||||
StreamUtil.copy(input, buffer);
|
||||
byte[] fileData = buffer.toByteArray();
|
||||
byte[] fileData = null;
|
||||
if (spec.hasFileData()) {
|
||||
fileData = spec.getFileData();
|
||||
} else {
|
||||
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
|
||||
InputStream input = new FileInputStream(spec.getSourceFilename());
|
||||
StreamUtil.copy(input, buffer);
|
||||
fileData = buffer.toByteArray();
|
||||
}
|
||||
FileEntry fileEntry = directory.createFile();
|
||||
fileEntry.setFilename(spec.getTargetFilename());
|
||||
fileEntry.setFiletype(spec.getFiletype());
|
||||
|
@ -19,34 +19,6 @@
|
||||
*/
|
||||
package com.webcodepro.applecommander.ui.swt.wizard.importfile;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.Iterator;
|
||||
import java.util.Optional;
|
||||
|
||||
import org.eclipse.swt.SWT;
|
||||
import org.eclipse.swt.events.SelectionAdapter;
|
||||
import org.eclipse.swt.events.SelectionEvent;
|
||||
import org.eclipse.swt.layout.FillLayout;
|
||||
import org.eclipse.swt.layout.GridData;
|
||||
import org.eclipse.swt.layout.GridLayout;
|
||||
import org.eclipse.swt.layout.RowData;
|
||||
import org.eclipse.swt.layout.RowLayout;
|
||||
import org.eclipse.swt.widgets.Button;
|
||||
import org.eclipse.swt.widgets.Combo;
|
||||
import org.eclipse.swt.widgets.Composite;
|
||||
import org.eclipse.swt.widgets.FileDialog;
|
||||
import org.eclipse.swt.widgets.Label;
|
||||
import org.eclipse.swt.widgets.MessageBox;
|
||||
import org.eclipse.swt.widgets.Shell;
|
||||
import org.eclipse.swt.widgets.Table;
|
||||
import org.eclipse.swt.widgets.TableColumn;
|
||||
import org.eclipse.swt.widgets.TableItem;
|
||||
import org.eclipse.swt.widgets.Text;
|
||||
|
||||
import com.webcodepro.applecommander.storage.os.prodos.ProdosFormatDisk;
|
||||
import com.webcodepro.applecommander.ui.ImportSpecification;
|
||||
import com.webcodepro.applecommander.ui.UiBundle;
|
||||
@ -55,11 +27,19 @@ import com.webcodepro.applecommander.ui.swt.util.SwtUtil;
|
||||
import com.webcodepro.applecommander.ui.swt.wizard.WizardPane;
|
||||
import com.webcodepro.applecommander.util.AppleUtil;
|
||||
import com.webcodepro.applecommander.util.TextBundle;
|
||||
|
||||
import io.github.applecommander.applesingle.AppleSingle;
|
||||
import io.github.applecommander.applesingle.AppleSingleReader;
|
||||
import io.github.applecommander.applesingle.ProdosFileInfo;
|
||||
import io.github.applecommander.applesingle.Utilities;
|
||||
import org.eclipse.swt.SWT;
|
||||
import org.eclipse.swt.events.SelectionAdapter;
|
||||
import org.eclipse.swt.events.SelectionEvent;
|
||||
import org.eclipse.swt.layout.*;
|
||||
import org.eclipse.swt.widgets.*;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.Iterator;
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* Allow the used to choose the files to import into the disk image.
|
||||
@ -362,6 +342,22 @@ public class ImportSelectFilesWizardPane extends WizardPane {
|
||||
dialog.setDefaultButton(button);
|
||||
button.addSelectionListener(new SelectionAdapter() {
|
||||
public void widgetSelected(SelectionEvent e) {
|
||||
try {
|
||||
// Make an attempt at validating before accepting the change
|
||||
ImportSpecification temp = new ImportSpecification(spec);
|
||||
temp.setTargetFilename(getWizard().getDisk().
|
||||
getSuggestedFilename(filenameText.getText()));
|
||||
temp.setFiletype(filetypes.getItem(
|
||||
filetypes.getSelectionIndex()));
|
||||
temp.setAddress(AppleUtil.convertFormattedWord(
|
||||
getAddressText().getText()));
|
||||
temp.setRawFileImport(getRawCheckBox().getSelection());
|
||||
wizard.validate(temp);
|
||||
} catch (Throwable t) {
|
||||
SwtUtil.showErrorDialog(wizard.getDialog(), "Error", t.getMessage());
|
||||
return;
|
||||
}
|
||||
|
||||
spec.setTargetFilename(getWizard().getDisk().
|
||||
getSuggestedFilename(filenameText.getText()));
|
||||
spec.setFiletype(filetypes.getItem(
|
||||
|
@ -19,17 +19,29 @@
|
||||
*/
|
||||
package com.webcodepro.applecommander.ui.swt.wizard.importfile;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.swt.widgets.Shell;
|
||||
|
||||
import com.webcodepro.applecommander.storage.FormattedDisk;
|
||||
import com.webcodepro.applecommander.ui.ImportSpecification;
|
||||
import com.webcodepro.applecommander.ui.UiBundle;
|
||||
import com.webcodepro.applecommander.ui.swt.util.ImageManager;
|
||||
import com.webcodepro.applecommander.ui.swt.wizard.Wizard;
|
||||
import com.webcodepro.applecommander.ui.swt.wizard.WizardPane;
|
||||
import com.webcodepro.applecommander.util.ApplesoftTokenizer;
|
||||
import io.github.applecommander.bastools.api.Configuration;
|
||||
import io.github.applecommander.bastools.api.Parser;
|
||||
import io.github.applecommander.bastools.api.TokenReader;
|
||||
import io.github.applecommander.bastools.api.Visitors;
|
||||
import io.github.applecommander.bastools.api.model.Program;
|
||||
import io.github.applecommander.bastools.api.model.Token;
|
||||
import org.eclipse.swt.widgets.Shell;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Queue;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* The Disk Import Wizard.
|
||||
@ -38,6 +50,7 @@ import com.webcodepro.applecommander.ui.swt.wizard.WizardPane;
|
||||
* @author Rob Greene
|
||||
*/
|
||||
public class ImportWizard extends Wizard {
|
||||
private static Set<String> APPLESOFT_FILETYPES = Set.of("B", "BAS");
|
||||
private FormattedDisk disk;
|
||||
private List<ImportSpecification> importSpecifications;
|
||||
/**
|
||||
@ -58,9 +71,40 @@ public class ImportWizard extends Wizard {
|
||||
/**
|
||||
* Add an import specification.
|
||||
*/
|
||||
public void addImportSpecification(ImportSpecification importSpecification) {
|
||||
public void addImportSpecification(ImportSpecification importSpecification) throws IOException {
|
||||
validate(importSpecification);
|
||||
getImportSpecifications().add(importSpecification);
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform validation for some problematic file type imports.
|
||||
*/
|
||||
public void validate(ImportSpecification importSpecification) throws IOException {
|
||||
if (APPLESOFT_FILETYPES.contains(importSpecification.getFiletype())) {
|
||||
try {
|
||||
// 1. Validate that this is a binary Applesoft file.
|
||||
byte[] data = Files.readAllBytes(Path.of(importSpecification.getSourceFilename()));
|
||||
ApplesoftTokenizer tokenizer = new ApplesoftTokenizer(data);
|
||||
while (tokenizer.hasMoreTokens()) {
|
||||
tokenizer.getNextToken(); // Make sure we can loop through entire program
|
||||
}
|
||||
importSpecification.setFileData(data);
|
||||
} catch (Throwable ignored) {
|
||||
try {
|
||||
// 2. Make an attempt at tokenizing the file (assuming it's text).
|
||||
File file = new File(importSpecification.getSourceFilename());
|
||||
Configuration config = Configuration.builder().sourceFile(file).build();
|
||||
Queue<Token> tokens = TokenReader.tokenize(config.sourceFile);
|
||||
Parser parser = new Parser(tokens);
|
||||
Program program = parser.parse();
|
||||
byte[] data = Visitors.byteVisitor(config).dump(program);
|
||||
importSpecification.setFileData(data);
|
||||
} catch (Throwable ignored2) {
|
||||
throw new IOException("File does not appear to be an Applesoft program");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Remove an import specification.
|
||||
*/
|
||||
|
Loading…
Reference in New Issue
Block a user