Merge remote-tracking branch 'allevaton/master'

This commit is contained in:
Joey Lawrance 2014-03-12 10:24:50 -04:00
commit c495b63e85
6 changed files with 375 additions and 107 deletions

View File

@ -9,71 +9,95 @@ version = '2.7.2'
description = 'Logisim: Logic Simulator'
launch4j {
mainClassName = project.mainClassName // launch4j should know this from the application plugin, right?
jar = "lib/"+project.name+"-"+project.version+".jar"
// launch4j should know this from the application plugin, right?
mainClassName = project.mainClassName
jar = "lib/"+project.name+"-"+project.version+".jar"
}
buildscript {
repositories {
ivy {
artifactPattern 'http://gradle-launch4j.googlecode.com/files/[module]-[revision].[ext]'
}
mavenCentral()
}
dependencies {
classpath 'edu.sc.seis:gradle-launch4j:1.0.5', 'net.sourceforge.nekohtml:nekohtml:1.9.18', 'javax.help:javahelp:2.0.05'
}
repositories {
ivy {
artifactPattern 'http://gradle-launch4j.googlecode.com/files/[module]-[revision].[ext]'
}
mavenCentral()
}
dependencies {
classpath \
'edu.sc.seis:gradle-launch4j:1.0.5',
'net.sourceforge.nekohtml:nekohtml:1.9.18',
'javax.help:javahelp:2.0.05'
}
}
repositories {
mavenCentral()
maven {
url 'http://nexus.gephi.org/nexus/content/repositories/public'
}
mavenCentral()
maven {
url 'http://nexus.gephi.org/nexus/content/repositories/public'
}
}
dependencies {
compile 'javax.help:javahelp:2.0.05', 'com.connectina.swing:fontchooser:1.0', 'org.apache.commons:commons-lang3:3.1', 'net.sourceforge.collections:collections-generic:4.01', 'org.apache.xmlgraphics:batik-svggen:1.7', 'org.apache.xmlgraphics:batik-swing:1.7', 'org.apache.xmlgraphics:batik-transcoder:1.7', fileTree(dir: 'libs', include: '*.jar')
testCompile 'junit:junit:4.11'
compile \
'javax.help:javahelp:2.0.05',
'com.connectina.swing:fontchooser:1.0',
'org.apache.commons:commons-lang3:3.1',
'net.sourceforge.collections:collections-generic:4.01',
'org.apache.xmlgraphics:batik-svggen:1.7',
'org.apache.xmlgraphics:batik-swing:1.7',
'org.apache.xmlgraphics:batik-transcoder:1.7',
// Native JDK logger (java.util.logging)
//'org.slf4j:slf4j-jdk14:1.7.5',
// Simplified logger (less lines)
'org.slf4j:slf4j-simple:1.6.1',
// Logging does nothing (use for release builds)
//'org.slf4j:slf4j-nop:1.7.5',
// Local dependencies convention: ./libs/*.jar
fileTree(dir: 'libs', include: '*.jar')
testCompile 'junit:junit:4.11'
}
processResources << {
println "Processing Java Help..."
def parser = new org.cyberneko.html.parsers.SAXParser()
def doc_src = 'src/main/resources/doc'
def doc_target = 'build/resources/main/doc'
println "Processing Java Help..."
def parser = new org.cyberneko.html.parsers.SAXParser()
def doc_src = 'src/main/resources/doc'
def doc_target = 'build/resources/main/doc'
file(doc_src).listFiles().each { locale ->
if (locale.name.length() == 2) { // Locale names are two characters long
// Build contents.xml with the id=>text mapping from locale/html/contents.html
def dict = [:]
def doc = new XmlParser(parser).parse("${doc_src}/${locale.name}/html/contents.html")
doc.'**'.A.each { dict[it.@id] = it.text() }
file(doc_src).listFiles().each { locale ->
if (locale.name.length() == 2) { // Locale names are two characters long
// Build contents.xml with the id=>text mapping from locale/html/contents.html
def dict = [:]
def doc = new XmlParser(parser).parse("${doc_src}/${locale.name}/html/contents.html")
doc.'**'.A.each { dict[it.@id] = it.text() }
// Rewrite support/base-contents.xml as locale/contents.xml.
def contents = new XmlParser().parse("${doc_src}/support/base-contents.xml")
contents.'**'.'tocitem'.each {
it.@text = (dict.containsKey(it.@target)) ? dict[it.@target] : it.@target
}
new XmlNodePrinter(new File("${doc_target}/${locale.name}/contents.xml").newPrintWriter("UTF-8")).print(contents)
// Rewrite support/base-contents.xml as locale/contents.xml.
def contents = new XmlParser().parse("${doc_src}/support/base-contents.xml")
contents.'**'.'tocitem'.each {
it.@text = (dict.containsKey(it.@target)) ? dict[it.@target] : it.@target
}
new XmlNodePrinter(new File("${doc_target}/${locale.name}/contents.xml").newPrintWriter("UTF-8")).print(contents)
// Build JavaHelp map
def map = new XmlParser().parse("${doc_src}/support/base-map.jhm")
map.'**'.'mapID'.each { it.@url = "${locale.name}/${it.@url}" }
new XmlNodePrinter(new PrintWriter(new FileWriter("${doc_target}/map_${locale.name}.jhm"))).print(map)
// Build JavaHelp map
def map = new XmlParser().parse("${doc_src}/support/base-map.jhm")
map.'**'.'mapID'.each { it.@url = "${locale.name}/${it.@url}" }
new XmlNodePrinter(new PrintWriter(new FileWriter("${doc_target}/map_${locale.name}.jhm"))).print(map)
// Build HelpSet
def hs = new File("${doc_src}/support/base-doc.hs")
def out = new PrintWriter(new FileWriter("${doc_target}/doc_${locale.name}.hs"))
hs.eachLine { out.println(it.replace("{lang}", locale.name)) }
out.close()
// Build HelpSet
def hs = new File("${doc_src}/support/base-doc.hs")
def out = new PrintWriter(new FileWriter("${doc_target}/doc_${locale.name}.hs"))
hs.eachLine { out.println(it.replace("{lang}", locale.name)) }
out.close()
// JavaHelp index
javaexec {
main = 'com.sun.java.help.search.Indexer'
classpath = sourceSets.main.compileClasspath
args '-c', 'jhindexer.cfg', '-db', "${doc_target}/search_lookup_${locale.name}", '-locale', locale.name, "${doc_target}/${locale.name}/html/guide", "${doc_target}/${locale.name}/html/libs"
}
}
}
// JavaHelp index
javaexec {
main = 'com.sun.java.help.search.Indexer'
classpath = sourceSets.main.compileClasspath
args '-c', 'jhindexer.cfg', '-db', "${doc_target}/search_lookup_${locale.name}", '-locale', locale.name, "${doc_target}/${locale.name}/html/guide", "${doc_target}/${locale.name}/html/libs"
}
}
}
}

View File

@ -18,7 +18,6 @@ import javax.swing.SwingConstants;
* HexEditor is a GUI component for editing Hex values.
*
* @author Carl Burch
*
*/
@SuppressWarnings("serial")
public class HexEditor extends JComponent implements Scrollable {
@ -32,7 +31,8 @@ public class HexEditor extends JComponent implements Scrollable {
public void bytesChanged(HexModel source, long start, long numBytes,
int[] oldValues) {
repaint(0, measures.toY(start),
getWidth(), measures.toY(start + numBytes) + measures.getCellHeight());
getWidth(), measures.toY(start + numBytes) +
measures.getCellHeight());
}
}
@ -42,6 +42,10 @@ public class HexEditor extends JComponent implements Scrollable {
private Caret caret;
private Highlighter highlighter;
/**
* Constructs a hex editor object, based on a model
* @param model The model to base the editor on
*/
public HexEditor(HexModel model) {
this.model = model;
this.listener = new Listener();
@ -49,13 +53,15 @@ public class HexEditor extends JComponent implements Scrollable {
this.caret = new Caret(this);
this.highlighter = new Highlighter(this);
// Nick A: change the font here
this.setFont( new Font( "Dialog", Font.PLAIN, 16 ) );
setOpaque(true);
setBackground(Color.WHITE);
if (model != null) {
model.addHexModelListener(listener);
}
measures.recompute();
}
@ -63,22 +69,45 @@ public class HexEditor extends JComponent implements Scrollable {
Highlighter getHighlighter() { return highlighter; }
/**
* Return the editor's base model
* @return the model
*/
public HexModel getModel() {
return model;
}
/**
* Get the caret object (cursor)
* @return the caret object
*/
public Caret getCaret() {
return caret;
}
/**
* Extends the current highlighted regions.
* @param start where to begin
* @param end where to end
* @param color the color of the highlight
* @return the highlighted region's handle
*/
public Object addHighlight(int start, int end, Color color) {
return highlighter.add(start, end, color);
}
/**
* Removes the highlighted region.
* @param tag the highlighted object
*/
public void removeHighlight(Object tag) {
highlighter.remove(tag);
}
/**
* Sets the model, if one doesn't exist or wants to be changed
* @param value the new model
*/
public void setModel(HexModel value) {
if (model == value) {
return;
@ -98,6 +127,11 @@ public class HexEditor extends JComponent implements Scrollable {
measures.recompute();
}
/**
* Scroll to the visible address (location of the caret).
* @param start where to begin
* @param end where to end
*/
public void scrollAddressToVisible(int start, int end) {
if (start < 0 || end < 0) {
return;
@ -115,18 +149,33 @@ public class HexEditor extends JComponent implements Scrollable {
}
}
/**
* Sets the current font and updates metrics
* @param value the new font object
*/
@Override
public void setFont(Font value) {
super.setFont(value);
measures.recompute();
}
/**
* Sets the bounds of the hex fields.
* @param x the x coordinate
* @param y the y coordinate
* @param width the width to adjust the metrics by
* @param height the height to adjust the metrics by
*/
@Override
public void setBounds(int x, int y, int width, int height) {
super.setBounds(x, y, width, height);
measures.widthChanged();
}
/**
* Repaints the objects
* @param g the graphics handle
*/
@Override
protected void paintComponent(Graphics g) {
measures.ensureComputed(g);
@ -148,11 +197,16 @@ public class HexEditor extends JComponent implements Scrollable {
long xaddr1 = measures.toAddress(getWidth(), clip.y + clip.height) + 1;
highlighter.paint(g, xaddr0, xaddr1);
int newSize = (int)(Math.log10(clip.width*clip.height)*4);
this.setFont( new Font( "Dialog", Font.PLAIN, newSize ) );
g.setColor(getForeground());
Font baseFont = g.getFont();
FontMetrics baseFm = g.getFontMetrics(baseFont);
Font labelFont = baseFont.deriveFont(Font.ITALIC);
FontMetrics labelFm = g.getFontMetrics(labelFont);
int cols = measures.getColumnCount();
int baseX = measures.getBaseX();
int baseY = measures.toY(xaddr0) + baseFm.getAscent() + baseFm.getLeading() / 2;
@ -161,6 +215,7 @@ public class HexEditor extends JComponent implements Scrollable {
int labelChars = measures.getLabelChars();
int cellWidth = measures.getCellWidth();
int cellChars = measures.getCellChars();
for(long a = xaddr0; a < xaddr1; a += cols, baseY += dy) {
String label = toHex(a, labelChars);
g.setFont(labelFont);
@ -179,6 +234,12 @@ public class HexEditor extends JComponent implements Scrollable {
caret.paintForeground(g, xaddr0, xaddr1);
}
/**
* Convert a value to hex
* @param value the long value
* @param chars the characters value
* @return the converted hex string
*/
private String toHex(long value, int chars) {
String ret = Long.toHexString(value);
int retLen = ret.length();
@ -198,15 +259,26 @@ public class HexEditor extends JComponent implements Scrollable {
//
// selection methods
//
/**
* Is there a selection?
* @return if it exists
*/
public boolean selectionExists() {
return caret.getMark() >= 0 && caret.getDot() >= 0;
}
/**
* Select every hex editor
*/
public void selectAll() {
caret.setDot(model.getLastOffset(), false);
caret.setDot(0, true);
}
/**
* Clear the selection
*/
public void delete() {
long p0 = caret.getMark();
long p1 = caret.getDot();
@ -223,11 +295,20 @@ public class HexEditor extends JComponent implements Scrollable {
//
// Scrollable methods
//
/**
* Returns the preferred size of the viewport
* @return the dimensions object
*/
@Override
public Dimension getPreferredScrollableViewportSize() {
return getPreferredSize();
}
/**
* Get the increment in which to scroll
* @return the scrolling increment
*/
@Override
public int getScrollableUnitIncrement(Rectangle vis,
int orientation, int direction) {
@ -247,6 +328,9 @@ public class HexEditor extends JComponent implements Scrollable {
}
}
/**
* Get the block increment so we don't scroll in the middle of one
*/
@Override
public int getScrollableBlockIncrement(Rectangle vis,
int orientation, int direction) {

View File

@ -3,6 +3,8 @@
package com.cburch.logisim;
import org.slf4j.*;
/**
* Handles everything involving Logisim's version number
* @author Carl Burch, Ryan Steinmetz
@ -11,6 +13,8 @@ package com.cburch.logisim;
public class LogisimVersion implements Comparable<LogisimVersion> {
private static final int FINAL_REVISION = Integer.MAX_VALUE / 4;
private static final Logger logger = LoggerFactory.getLogger( LogisimVersion.class );
/**
* Creates a new LogisimVersion object without a revision number
* @param major
@ -64,8 +68,7 @@ public class LogisimVersion implements Comparable<LogisimVersion> {
}
} catch (NumberFormatException e) {
System.out.println( "Something went wrong when parsing the version string:\n" );
e.printStackTrace();
logger.warn( "Something went wrong when parsing the version string." );
}
return new LogisimVersion(major, minor, release, revision);

View File

@ -22,6 +22,9 @@ package com.cburch.logisim;
import com.cburch.logisim.gui.start.Startup;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Main entry point into Logisim.
*
@ -33,11 +36,19 @@ public class Main {
public static final String VERSION_NAME = VERSION.toString();
public static final int COPYRIGHT_YEAR = 2012;
/** Logger */
public static final Logger logger = LoggerFactory.getLogger( Main.class );
/**
* Entry point
* @param args Command line arguments
*/
public static void main(String[] args) {
Startup startup = Startup.parseArgs(args);
if (startup == null) {
System.exit(0);
} else {
logger.info( "Starting Logisim" );
startup.run();
}
}

View File

@ -13,6 +13,7 @@ import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Stack;
import javax.swing.JFileChooser;
import javax.swing.JOptionPane;
import javax.swing.JScrollPane;
@ -24,9 +25,19 @@ import com.cburch.logisim.tools.Library;
import com.cburch.logisim.util.JFileChoosers;
import com.cburch.logisim.util.MacCompatibility;
import com.cburch.logisim.util.ZipClassLoader;
import static com.cburch.logisim.util.LocaleString.*;
import org.slf4j.*;
/**
* A class to encapsulate loading functionality
* of files or library objects
*/
public class Loader implements LibraryLoader {
private static final Logger logger =
LoggerFactory.getLogger( Loader.class );
public static final String LOGISIM_EXTENSION = ".circ";
public static final FileFilter LOGISIM_FILTER = new LogisimFileFilter();
public static final FileFilter JAR_FILTER = new JarFileFilter();
@ -66,31 +77,53 @@ public class Loader implements LibraryLoader {
private Stack<File> filesOpening = new Stack<File>();
private Map<File,File> substitutions = new HashMap<File,File>();
/**
* Constructor
* @param parent the parent
*/
public Loader(Component parent) {
this.parent = parent;
clear();
}
/**
* Get built-in functionality.
* @return the built-in functionality
*/
public Builtin getBuiltin() {
return builtin;
}
/**
* Sets the parent of the component from a high level.
* @param value the component's new parent
*/
public void setParent(Component value) {
parent = value;
}
/**
* Get substitutions from a source file
* @param source the source file
* @return the returned file
*/
private File getSubstitution(File source) {
File ret = substitutions.get(source);
return ret == null ? source : ret;
}
//
// file chooser related methods
//
/**
* Get the file from the file chooser
* @return the selected file
*/
public File getMainFile() {
return mainFile;
}
/**
* Spawns a file chooser
* @return the JFileChooser
*/
public JFileChooser createChooser() {
return JFileChoosers.createAt(getCurrentDirectory());
}
@ -110,17 +143,25 @@ public class Loader implements LibraryLoader {
mainFile = value;
}
//
// more substantive methods accessed from outside this package
//
/**
* More substantive methods accessed from outside this package.
*/
public void clear() {
filesOpening.clear();
mainFile = null;
}
/**
* Open a file from an array of files to substitute.
* @param file the main file
* @param substitutions the substitution files
* @return A functioning LogisimFile
* @throws LoadFailedException if there was an error loading the file
*/
public LogisimFile openLogisimFile(File file, Map<File,File> substitutions)
throws LoadFailedException {
this.substitutions = substitutions;
// FIXME allevaton: What's up with this? Try finally with no catch?
try {
return openLogisimFile(file);
} finally {
@ -128,6 +169,12 @@ public class Loader implements LibraryLoader {
}
}
/**
* Open a file from the hard drive.
* @param file the file object
* @return the LogisimFile object
* @throws LoadFailedException if there was a problem loading the file
*/
public LogisimFile openLogisimFile(File file) throws LoadFailedException {
try {
LogisimFile ret = loadLogisimFile(file);
@ -138,22 +185,38 @@ public class Loader implements LibraryLoader {
showMessages(ret);
return ret;
} catch (LoaderException e) {
logger.error( "An error occurred when loading the file.\n"
+ e.getMessage() );
throw new LoadFailedException(e.getMessage(), e.isShown());
}
}
/**
* Open a file from an input stream
* @param reader The input stream
* @return a fully functioning LogisimFile object
* @throws LoadFailedException if it failed to load
* @throws IOException if another error occurred
*/
public LogisimFile openLogisimFile(InputStream reader)
throws LoadFailedException, IOException {
LogisimFile ret = null;
try {
ret = LogisimFile.load(reader, this);
} catch (LoaderException e) {
logger.error( "An error occurred when loading the file.\n"
+ e.getMessage() );
return null;
}
showMessages(ret);
return ret;
}
/**
* Loads a specified Logisim library
* @param file the library file
* @return the library object
*/
public Library loadLogisimLibrary(File file) {
File actual = getSubstitution(file);
LoadedLibrary ret = LibraryManager.instance.loadLogisimLibrary(this, actual);
@ -164,15 +227,31 @@ public class Loader implements LibraryLoader {
return ret;
}
/**
* Loads a library as a jar
* @param file the jar file
* @param className the class in the jar
* @return the library object
*/
public Library loadJarLibrary(File file, String className) {
File actual = getSubstitution(file);
return LibraryManager.instance.loadJarLibrary(this, actual, className);
}
/**
* Reload the specified library.
* @param lib The specified library
*/
public void reload(LoadedLibrary lib) {
LibraryManager.instance.reload(this, lib);
}
/**
* Save the current file.
* @param file The source file
* @param dest The destination file
* @return if the safe was a success
*/
public boolean save(LogisimFile file, File dest) {
Library reference = LibraryManager.instance.findReference(file, dest);
if (reference != null) {
@ -190,7 +269,10 @@ public class Loader implements LibraryLoader {
try {
try {
MacCompatibility.setFileCreatorAndType(dest, "LGSM", "circ");
} catch (IOException e) { }
} catch (IOException e) {
logger.warn( "Could not set Mac compatible"
+ " file associative flags (file creator and type)" );
}
fwrite = new FileOutputStream(dest);
file.write(fwrite, this);
file.setName(toProjectName(dest));
@ -200,6 +282,7 @@ public class Loader implements LibraryLoader {
LibraryManager.instance.fileSaved(this, dest, oldFile, file);
} catch (IOException e) {
if (backupCreated) {
logger.info( "Backup found, recovering from it." );
recoverBackup(backup, dest);
}
@ -220,6 +303,7 @@ public class Loader implements LibraryLoader {
fwrite.close();
} catch (IOException e) {
if (backupCreated) {
logger.info( "Backup found, recovering from it." );
recoverBackup(backup, dest);
}
if (dest.exists() && dest.length() == 0) {
@ -254,6 +338,11 @@ public class Loader implements LibraryLoader {
return true;
}
/**
* Get a name for a backup file
* @param base the base file
* @return the backup file
*/
private static File determineBackupName(File base) {
File dir = base.getParentFile();
String name = base.getName();
@ -271,6 +360,11 @@ public class Loader implements LibraryLoader {
return null;
}
/**
* Recover from a backup.
* @param backup the backup file to recover from
* @param dest where does the backup file go
*/
private static void recoverBackup(File backup, File dest) {
if (backup != null && backup.exists()) {
if (dest.exists()) {
@ -281,13 +375,17 @@ public class Loader implements LibraryLoader {
}
}
//
// methods for LibraryManager
//
/**
* Loads a Logisim file
* @param request the requested file
* @return the completed file object
*/
LogisimFile loadLogisimFile(File request) throws LoadFailedException {
File actual = getSubstitution(request);
for (File fileOpening : filesOpening) {
if (fileOpening.equals(actual)) {
logger.error( "An error occurred when opening the file.\n"
+ _("logisimCircularError" ) );
throw new LoadFailedException(_("logisimCircularError",
toProjectName(actual)));
}
@ -298,6 +396,8 @@ public class Loader implements LibraryLoader {
try {
ret = LogisimFile.load(actual, this);
} catch (IOException e) {
logger.error( "An error occurred when opening the file.\n"
+ _("logisimCircularError" ) );
throw new LoadFailedException(_("logisimLoadError",
toProjectName(actual), e.toString()));
} finally {
@ -307,6 +407,12 @@ public class Loader implements LibraryLoader {
return ret;
}
/**
* Loads a Java jar file as a library
* @param request the requested jar file
* @param string the class name specified in the file
* @return the loaded library
*/
Library loadJarFile(File request, String className) throws LoadFailedException {
File actual = getSubstitution(request);
// Up until 2.1.8, this was written to use a URLClassLoader, which
@ -339,9 +445,11 @@ public class Loader implements LibraryLoader {
try {
retClass = loader.loadClass(className);
} catch (ClassNotFoundException e) {
logger.error( "Class not found" );
throw new LoadFailedException(_("jarClassNotFoundError", className));
}
if (!(Library.class.isAssignableFrom(retClass))) {
logger.error( "Class not library" );
throw new LoadFailedException(_("jarClassNotLibraryError", className));
}
@ -350,6 +458,7 @@ public class Loader implements LibraryLoader {
try {
ret = (Library) retClass.newInstance();
} catch (Exception e) {
logger.error( "Class not library" );
throw new LoadFailedException(_("jarLibraryNotCreatedError", className));
}
return ret;
@ -358,18 +467,34 @@ public class Loader implements LibraryLoader {
//
// Library methods
//
/**
* Loads a Logisim library
* @param desc the file descriptor
* @return the library object
*/
@Override
public Library loadLibrary(String desc) {
return LibraryManager.instance.loadLibrary(this, desc);
}
/**
* Gets a descriptor from a library
* @param lib the library
* @return the descriptor
*/
@Override
public String getDescriptor(Library lib) {
return LibraryManager.instance.getDescriptor(this, lib);
}
/**
* Shows an error based on its description, also logs it
* @param description the error text
*/
@Override
public void showError(String description) {
logger.error( description );
if (!filesOpening.empty()) {
File top = filesOpening.peek();
String init = toProjectName(top) + ":";
@ -403,6 +528,10 @@ public class Loader implements LibraryLoader {
}
}
/**
* Show the messages from a file
* @param source the file to load from
*/
private void showMessages(LogisimFile source) {
if (source == null) {
return;
@ -420,6 +549,13 @@ public class Loader implements LibraryLoader {
//
// helper methods
//
/**
* Get a file from a name
* @param name file name
* @param filter the file name filter
* @return the file object
*/
File getFileFor(String name, FileFilter filter) {
// Determine the actual file name.
File file = new File(name);
@ -447,6 +583,11 @@ public class Loader implements LibraryLoader {
return file;
}
/**
* Conform a file to the current project
* @param file the destined file
* @return the project name
*/
private String toProjectName(File file) {
String ret = file.getName();
if (ret.endsWith(LOGISIM_EXTENSION)) {

View File

@ -13,6 +13,9 @@ import java.io.File;
import javax.swing.UIManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.cburch.logisim.Main;
import com.cburch.logisim.file.LoadFailedException;
import com.cburch.logisim.file.Loader;
@ -25,11 +28,17 @@ import com.cburch.logisim.proj.Project;
import com.cburch.logisim.proj.ProjectActions;
import com.cburch.logisim.util.LocaleManager;
import com.cburch.logisim.util.MacCompatibility;
import static com.cburch.logisim.util.LocaleString.*;
/**
* A class to encapsulate the startup process
*/
public class Startup {
private static Startup startupTemp = null;
private static final Logger logger = LoggerFactory.getLogger( Startup.class );
static void doOpen(File file) {
if (startupTemp != null) {
startupTemp.doOpenFile(file);
@ -76,11 +85,14 @@ public class Startup {
MacOsAdapter.register();
MacOsAdapter.addListeners(true);
} catch (ClassNotFoundException e) {
logger.warn( "Failed to register handler: " + e.getLocalizedMessage() );
return;
} catch (Exception t) {
try {
MacOsAdapter.addListeners(false);
} catch (Exception t2) { }
} catch (Exception t2) {
logger.warn( "Failed to register MacOS adapters" );
}
}
}
@ -121,15 +133,19 @@ public class Startup {
return Collections.unmodifiableMap(substitutions);
}
/**
* Starts splash screen and launches Logisim
*/
public void run() {
if (isTty) {
try {
TtyInterface.run(this);
return;
} catch (Exception t) {
t.printStackTrace();
} catch (Exception e) {
logger.error( "Logisim failed to start.\nException: "
+ e.getLocalizedMessage() );
e.printStackTrace();
System.exit(-1);
return;
}
}
@ -140,9 +156,10 @@ public class Startup {
try {
monitor = new SplashScreen();
monitor.setVisible(true);
} catch (Exception t) {
} catch (Exception e) {
monitor = null;
showSplash = false;
logger.warn( "Not showing the splash screen, for some reason" );
}
}
@ -158,7 +175,7 @@ public class Startup {
if (count < 0) {
// this will never happen, but the optimizer doesn't know that...
//OK
System.err.println("FATAL ERROR - no components");
logger.error( "FATAL - no components were found");
System.exit(-1);
}
@ -199,7 +216,8 @@ public class Startup {
ProjectActions.doOpen(monitor, fileToOpen, substitutions);
} catch (LoadFailedException ex) {
//OK
System.err.println(fileToOpen.getName() + ": " + ex.getMessage());
logger.error( "Could not open "
+ fileToOpen.getName() + ": " + ex.getMessage() );
System.exit(-1);
}
if (first) {
@ -227,12 +245,12 @@ public class Startup {
}
}
//OK
System.err.println(_("invalidLocaleError"));
logger.warn(_("invalidLocaleError"));
//OK
System.err.println(_("invalidLocaleOptionsHeader"));
logger.warn(_("invalidLocaleOptionsHeader"));
for (int i = 0; i < opts.length; i++) {
//OK
System.err.println(" " + opts[i].toString());
logger.warn(" " + opts[i].toString());
}
System.exit(-1);
}
@ -254,8 +272,8 @@ public class Startup {
}
/**
* Parses the command-line arguments to com.cburch.logisim.Main
* @param args
* @return A Startup object
* @param args command line arguments
* @return A Startup object or null if it fails
*/
public static Startup parseArgs(String[] args) {
// see whether we'll be using any graphics
@ -303,7 +321,7 @@ public class Startup {
String[] fmts = args[i].split(",");
if (fmts.length == 0) {
//OK
System.err.println(_("ttyFormatError"));
logger.warn(_("ttyFormatError"));
}
for (int j = 0; j < fmts.length; j++) {
String fmt = fmts[j].trim();
@ -333,7 +351,7 @@ public class Startup {
File b = new File(args[i + 2]);
if (ret.substitutions.containsKey(a)) {
//OK
System.err.println(_("argDuplicateSubstitutionError"));
logger.error(_("argDuplicateSubstitutionError"));
return null;
} else {
ret.substitutions.put(a, b);
@ -341,7 +359,7 @@ public class Startup {
}
} else {
//OK
System.err.println(_("argTwoSubstitutionError"));
logger.error(_("argTwoSubstitutionError"));
return null;
}
} else if (arg.equals("-load")) {
@ -349,26 +367,26 @@ public class Startup {
i++;
if (ret.loadFile != null) {
//OK
System.err.println(_("loadMultipleError"));
logger.warn(_("loadMultipleError"));
}
File f = new File(args[i]);
ret.loadFile = f;
} else {
//OK
System.err.println(_("loadNeedsFileError"));
logger.error(_("loadNeedsFileError"));
return null;
}
} else if (arg.equals("-empty")) {
if (ret.templFile != null || ret.templEmpty || ret.templPlain) {
//OK
System.err.println(_("argOneTemplateError"));
logger.error(_("argOneTemplateError"));
return null;
}
ret.templEmpty = true;
} else if (arg.equals("-plain")) {
if (ret.templFile != null || ret.templEmpty || ret.templPlain) {
//OK
System.err.println(_("argOneTemplateError"));
logger.error(_("argOneTemplateError"));
return null;
}
ret.templPlain = true;
@ -389,7 +407,7 @@ public class Startup {
AppPreferences.GATE_SHAPE.set(AppPreferences.SHAPE_RECTANGULAR);
} else {
//OK
System.err.println(_("argGatesOptionError"));
logger.error(_("argGatesOptionError"));
System.exit(-1);
}
} else if (arg.equals("-locale")) {
@ -412,13 +430,13 @@ public class Startup {
AppPreferences.ACCENTS_REPLACE.setBoolean(true);
} else {
//OK
System.err.println(_("argAccentsOptionError"));
logger.error(_("argAccentsOptionError"));
System.exit(-1);
}
} else if (arg.equals("-template")) {
if (ret.templFile != null || ret.templEmpty || ret.templPlain) {
//OK
System.err.println(_("argOneTemplateError"));
logger.error(_("argOneTemplateError"));
return null;
}
i++;
@ -429,11 +447,11 @@ public class Startup {
ret.templFile = new File(args[i]);
if (!ret.templFile.exists()) {
//OK
System.err.println(String.format(
logger.warn(String.format(
_("templateMissingError"), args[i]));
} else if (!ret.templFile.canRead()) {
//OK
System.err.println(String.format(
logger.warn(String.format(
_("templateCannotReadError"), args[i]));
}
} else if (arg.equals("-nosplash")) {
@ -449,49 +467,36 @@ public class Startup {
}
if (ret.isTty && ret.filesToOpen.isEmpty()) {
//OK
System.err.println(_("ttyNeedsFileError"));
logger.error(_("ttyNeedsFileError"));
return null;
}
if (ret.loadFile != null && !ret.isTty) {
//OK
System.err.println(_("loadNeedsTtyError"));
logger.error(_("loadNeedsTtyError"));
return null;
}
return ret;
}
/**
* Prints command line help functionality
*/
private static void printUsage() {
//OK
System.err.println(String.format(_("argUsage"), Startup.class.getName()));
//OK
System.err.println();
//OK
System.err.println(_("argOptionHeader"));
//OK
System.err.println(" " + _("argAccentsOption"));
//OK
System.err.println(" " + _("argClearOption"));
//OK
System.err.println(" " + _("argEmptyOption"));
//OK
System.err.println(" " + _("argGatesOption"));
//OK
System.err.println(" " + _("argHelpOption"));
//OK
System.err.println(" " + _("argLoadOption"));
//OK
System.err.println(" " + _("argLocaleOption"));
//OK
System.err.println(" " + _("argNoSplashOption"));
//OK
System.err.println(" " + _("argPlainOption"));
//OK
System.err.println(" " + _("argSubOption"));
//OK
System.err.println(" " + _("argTemplateOption"));
//OK
System.err.println(" " + _("argTtyOption"));
//OK
System.err.println(" " + _("argVersionOption"));
System.exit(-1);
}