diff --git a/src/com/cburch/draw/shapes/SvgCreator.java b/src/com/cburch/draw/shapes/SvgCreator.java index 5a3813f..799143b 100644 --- a/src/com/cburch/draw/shapes/SvgCreator.java +++ b/src/com/cburch/draw/shapes/SvgCreator.java @@ -143,7 +143,9 @@ class SvgCreator { elt.setAttribute("fill", "none"); } else { Color fill = shape.getValue(DrawAttr.FILL_COLOR); - if (!colorMatches(fill, Color.BLACK)) { + if (colorMatches(fill, Color.BLACK)) { + elt.removeAttribute("fill"); + } else { elt.setAttribute("fill", getColorString(fill)); } if (showOpacity(fill)) { diff --git a/src/com/cburch/draw/shapes/SvgReader.java b/src/com/cburch/draw/shapes/SvgReader.java index a93d3eb..05b12f6 100644 --- a/src/com/cburch/draw/shapes/SvgReader.java +++ b/src/com/cburch/draw/shapes/SvgReader.java @@ -49,7 +49,7 @@ public class SvgReader { String fill = elt.getAttribute("fill"); if (stroke.equals("") || stroke.equals("none")) { ret.setValue(DrawAttr.PAINT_TYPE, DrawAttr.PAINT_FILL); - } else if (fill.equals("") || fill.equals("none")) { + } else if (fill.equals("none")) { ret.setValue(DrawAttr.PAINT_TYPE, DrawAttr.PAINT_STROKE); } else { ret.setValue(DrawAttr.PAINT_TYPE, DrawAttr.PAINT_STROKE_FILL); @@ -69,6 +69,7 @@ public class SvgReader { } if (attrs.contains(DrawAttr.FILL_COLOR)) { String color = elt.getAttribute("fill"); + if (color.equals("")) color = "#000000"; String opacity = elt.getAttribute("fill-opacity"); if (!color.equals("none")) { ret.setValue(DrawAttr.FILL_COLOR, getColor(color, opacity)); diff --git a/src/com/cburch/logisim/LogisimVersion.java b/src/com/cburch/logisim/LogisimVersion.java index 9b30d7d..675e22a 100644 --- a/src/com/cburch/logisim/LogisimVersion.java +++ b/src/com/cburch/logisim/LogisimVersion.java @@ -15,7 +15,7 @@ public class LogisimVersion { } public static LogisimVersion parse(String versionString) { - String[] parts = versionString.split("."); + String[] parts = versionString.split("\\."); int major = 0; int minor = 0; int release = 0; diff --git a/src/com/cburch/logisim/circuit/CircuitChange.java b/src/com/cburch/logisim/circuit/CircuitChange.java index c9df26b..28e93c9 100644 --- a/src/com/cburch/logisim/circuit/CircuitChange.java +++ b/src/com/cburch/logisim/circuit/CircuitChange.java @@ -145,20 +145,28 @@ class CircuitChange { } } - void execute(CircuitMutator mutator) { + void execute(CircuitMutator mutator, ReplacementMap prevReplacements) { switch (type) { - case CLEAR: mutator.clear(circuit); break; - case ADD: mutator.add(circuit, comp); break; + case CLEAR: mutator.clear(circuit); prevReplacements.reset(); break; + case ADD: prevReplacements.add(comp); break; case ADD_ALL: - for (Component comp : comps) mutator.add(circuit, comp); + for (Component comp : comps) prevReplacements.add(comp); break; - case REMOVE: mutator.remove(circuit, comp); break; + case REMOVE: prevReplacements.remove(comp); break; case REMOVE_ALL: - for (Component comp : comps) mutator.remove(circuit, comp); + for (Component comp : comps) prevReplacements.remove(comp); + break; + case REPLACE: prevReplacements.append((ReplacementMap) newValue); break; + case SET: + mutator.replace(circuit, prevReplacements); + prevReplacements.reset(); + mutator.set(circuit, comp, attr, newValue); + break; + case SET_FOR_CIRCUIT: + mutator.replace(circuit, prevReplacements); + prevReplacements.reset(); + mutator.setForCircuit(circuit, attr, newValue); break; - case REPLACE: mutator.replace(circuit, (ReplacementMap) newValue); break; - case SET: mutator.set(circuit, comp, attr, newValue); break; - case SET_FOR_CIRCUIT: mutator.setForCircuit(circuit, attr, newValue); break; default: throw new IllegalArgumentException("unknown change type " + type); } } diff --git a/src/com/cburch/logisim/circuit/CircuitMutation.java b/src/com/cburch/logisim/circuit/CircuitMutation.java index 79e471a..d46bfb5 100644 --- a/src/com/cburch/logisim/circuit/CircuitMutation.java +++ b/src/com/cburch/logisim/circuit/CircuitMutation.java @@ -103,8 +103,21 @@ public final class CircuitMutation extends CircuitTransaction { @Override protected void run(CircuitMutator mutator) { + Circuit curCircuit = null; + ReplacementMap curReplacements = null; for (CircuitChange change : changes) { - change.execute(mutator); + Circuit circ = change.getCircuit(); + if (circ != curCircuit) { + if (curCircuit != null) { + mutator.replace(curCircuit, curReplacements); + } + curCircuit = circ; + curReplacements = new ReplacementMap(); + } + change.execute(mutator, curReplacements); + } + if (curCircuit != null) { + mutator.replace(curCircuit, curReplacements); } } } \ No newline at end of file diff --git a/src/com/cburch/logisim/circuit/RadixOption.java b/src/com/cburch/logisim/circuit/RadixOption.java index 0710a44..337cc07 100644 --- a/src/com/cburch/logisim/circuit/RadixOption.java +++ b/src/com/cburch/logisim/circuit/RadixOption.java @@ -4,12 +4,13 @@ package com.cburch.logisim.circuit; import com.cburch.logisim.data.Attribute; +import com.cburch.logisim.data.AttributeOption; import com.cburch.logisim.data.Attributes; import com.cburch.logisim.data.BitWidth; import com.cburch.logisim.data.Value; import com.cburch.logisim.util.StringGetter; -public abstract class RadixOption { +public abstract class RadixOption extends AttributeOption { public static final RadixOption RADIX_2 = new Radix2(); public static final RadixOption RADIX_8 = new Radix8(); public static final RadixOption RADIX_10_UNSIGNED = new Radix10Unsigned(); @@ -35,6 +36,7 @@ public abstract class RadixOption { private StringGetter displayGetter; private RadixOption(String saveName, StringGetter displayGetter) { + super(saveName, displayGetter); this.saveName = saveName; this.displayGetter = displayGetter; } @@ -47,6 +49,7 @@ public abstract class RadixOption { return saveName; } + @Override public String toDisplayString() { return displayGetter.get(); } diff --git a/src/com/cburch/logisim/circuit/ReplacementMap.java b/src/com/cburch/logisim/circuit/ReplacementMap.java index e6dfd38..6308165 100644 --- a/src/com/cburch/logisim/circuit/ReplacementMap.java +++ b/src/com/cburch/logisim/circuit/ReplacementMap.java @@ -39,6 +39,11 @@ public class ReplacementMap { this.inverse = inverse; } + public void reset() { + map.clear(); + inverse.clear(); + } + public boolean isEmpty() { return map.isEmpty() && inverse.isEmpty(); } diff --git a/src/com/cburch/logisim/circuit/WireIterator.java b/src/com/cburch/logisim/circuit/WireIterator.java index 5850dc6..232aff1 100644 --- a/src/com/cburch/logisim/circuit/WireIterator.java +++ b/src/com/cburch/logisim/circuit/WireIterator.java @@ -28,6 +28,15 @@ class WireIterator implements Iterator { if (curY < destY) deltaY = 10; else if (curY > destY) deltaY = -10; else deltaY = 0; + + int offX = (destX - curX) % 10; + if (offX != 0) { // should not happen, but in case it does... + destX = curX + deltaX * ((destX - curX) / 10); + } + int offY = (destY - curY) % 10; + if (offY != 0) { // should not happen, but in case it does... + destY = curY + deltaY * ((destY - curY) / 10); + } } public boolean hasNext() { diff --git a/src/com/cburch/logisim/file/LogisimFile.java b/src/com/cburch/logisim/file/LogisimFile.java index bb0141c..c2a2d19 100644 --- a/src/com/cburch/logisim/file/LogisimFile.java +++ b/src/com/cburch/logisim/file/LogisimFile.java @@ -270,8 +270,8 @@ public class LogisimFile extends Library implements LibraryEventSource { factories.add(((AddTool) tool).getFactory()); } } - for (AddTool tool : tools) { - Circuit circuit = (Circuit) tool.getFactory(); + + for (Circuit circuit : getCircuits()) { for (Component comp : circuit.getNonWires()) { if (factories.contains(comp.getFactory())) { return StringUtil.format(Strings.get("unloadUsedError"), @@ -300,10 +300,6 @@ public class LogisimFile extends Library implements LibraryEventSource { fireEvent(LibraryEvent.SET_MAIN, circuit); } - public void setOptions(Options options) { - this.options = options; - } - // // other methods // diff --git a/src/com/cburch/logisim/file/Options.java b/src/com/cburch/logisim/file/Options.java index f22ee3e..045db17 100644 --- a/src/com/cburch/logisim/file/Options.java +++ b/src/com/cburch/logisim/file/Options.java @@ -32,11 +32,15 @@ public class Options { GATE_UNDEFINED_IGNORE, Integer.valueOf(1000), Integer.valueOf(0), }; - private AttributeSet attrs = AttributeSets.fixedSet(ATTRIBUTES, DEFAULTS); - private MouseMappings mmappings = new MouseMappings(); - private ToolbarData toolbar = new ToolbarData(); + private AttributeSet attrs; + private MouseMappings mmappings; + private ToolbarData toolbar; - public Options() { } + public Options() { + attrs = AttributeSets.fixedSet(ATTRIBUTES, DEFAULTS); + mmappings = new MouseMappings(); + toolbar = new ToolbarData(); + } public AttributeSet getAttributeSet() { return attrs; diff --git a/src/com/cburch/logisim/file/XmlReader.java b/src/com/cburch/logisim/file/XmlReader.java index 2aa7849..7b27e57 100644 --- a/src/com/cburch/logisim/file/XmlReader.java +++ b/src/com/cburch/logisim/file/XmlReader.java @@ -94,7 +94,7 @@ class XmlReader { if (name.equals("circuit") || name.equals("lib")) { ; // Nothing to do: Done earlier. } else if (name.equals("options")) { - initAttributeSet(elt, file.getOptions().getAttributeSet(), null); + initAttributeSet(sub_elt, file.getOptions().getAttributeSet(), null); } else if (name.equals("mappings")) { initMouseMappings(sub_elt); } else if (name.equals("toolbar")) { diff --git a/src/com/cburch/logisim/gui/generic/LDialog.java b/src/com/cburch/logisim/gui/generic/LDialog.java index 82675c3..3133b64 100644 --- a/src/com/cburch/logisim/gui/generic/LDialog.java +++ b/src/com/cburch/logisim/gui/generic/LDialog.java @@ -1,3 +1,6 @@ +/* Copyright (c) 2010, Carl Burch. License information is located in the + * com.cburch.logisim.Main source code and at www.cburch.com/logisim/. */ + package com.cburch.logisim.gui.generic; import java.awt.Frame; diff --git a/src/com/cburch/logisim/gui/generic/LFrame.java b/src/com/cburch/logisim/gui/generic/LFrame.java index 7b3c0c2..14d66df 100644 --- a/src/com/cburch/logisim/gui/generic/LFrame.java +++ b/src/com/cburch/logisim/gui/generic/LFrame.java @@ -1,3 +1,6 @@ +/* Copyright (c) 2010, Carl Burch. License information is located in the + * com.cburch.logisim.Main source code and at www.cburch.com/logisim/. */ + package com.cburch.logisim.gui.generic; import java.awt.Image; diff --git a/src/com/cburch/logisim/gui/main/Frame.java b/src/com/cburch/logisim/gui/main/Frame.java index ed4b98f..99e7dd6 100644 --- a/src/com/cburch/logisim/gui/main/Frame.java +++ b/src/com/cburch/logisim/gui/main/Frame.java @@ -7,6 +7,12 @@ import java.awt.BorderLayout; import java.awt.Color; import java.awt.Container; import java.awt.Dimension; +import java.awt.GraphicsConfiguration; +import java.awt.GraphicsDevice; +import java.awt.GraphicsEnvironment; +import java.awt.IllegalComponentStateException; +import java.awt.Point; +import java.awt.Rectangle; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.beans.PropertyChangeEvent; @@ -45,6 +51,7 @@ import com.cburch.logisim.proj.Project; import com.cburch.logisim.proj.ProjectActions; import com.cburch.logisim.proj.ProjectEvent; import com.cburch.logisim.proj.ProjectListener; +import com.cburch.logisim.proj.Projects; import com.cburch.logisim.tools.SetAttributeAction; import com.cburch.logisim.tools.Tool; import com.cburch.logisim.util.HorizontalSplitPane; @@ -65,12 +72,6 @@ public class Frame extends LFrame implements LocaleListener { public void projectChanged(ProjectEvent event) { int action = event.getAction(); - if (action == ProjectEvent.ACTION_COMPLETE - || action == ProjectEvent.UNDO_COMPLETE - || action == ProjectEvent.ACTION_SET_FILE) { - enableSave(); - } - if (action == ProjectEvent.ACTION_SET_FILE) { computeTitle(); proj.setTool(proj.getOptions().getToolbarData().getFirstTool()); @@ -93,6 +94,8 @@ public class Frame extends LFrame implements LocaleListener { public void libraryChanged(LibraryEvent e) { if (e.getAction() == LibraryEvent.SET_NAME) { computeTitle(); + } else if (e.getAction() == LibraryEvent.DIRTY_STATE) { + enableSave(); } } @@ -259,6 +262,10 @@ public class Frame extends LFrame implements LocaleListener { this.setSize(AppPreferences.WINDOW_WIDTH.get().intValue(), AppPreferences.WINDOW_HEIGHT.get().intValue()); + Point prefPoint = getInitialLocation(); + if (prefPoint != null) { + this.setLocation(prefPoint); + } this.setExtendedState(AppPreferences.WINDOW_STATE.get().intValue()); menuListener.register(mainPanel); @@ -372,6 +379,7 @@ public class Frame extends LFrame implements LocaleListener { s = StringUtil.format(Strings.get("titleFileKnown"), name); } this.setTitle(s); + myProjectListener.enableSave(); } void viewAttributes(Tool newTool) { @@ -436,6 +444,15 @@ public class Frame extends LFrame implements LocaleListener { Dimension dim = getSize(); AppPreferences.WINDOW_WIDTH.set(Integer.valueOf(dim.width)); AppPreferences.WINDOW_HEIGHT.set(Integer.valueOf(dim.height)); + Point loc; + try { + loc = getLocationOnScreen(); + } catch (IllegalComponentStateException e) { + loc = Projects.getLocation(this); + } + if (loc != null) { + AppPreferences.WINDOW_LOCATION.set(loc.x + "," + loc.y); + } AppPreferences.WINDOW_LEFT_SPLIT.set(Double.valueOf(leftRegion.getFraction())); AppPreferences.WINDOW_MAIN_SPLIT.set(Double.valueOf(mainRegion.getFraction())); } @@ -468,4 +485,62 @@ public class Frame extends LFrame implements LocaleListener { } return ret; } + + private static Point getInitialLocation() { + String s = AppPreferences.WINDOW_LOCATION.get(); + if (s == null) return null; + int comma = s.indexOf(','); + if (comma < 0) return null; + try { + int x = Integer.parseInt(s.substring(0, comma)); + int y = Integer.parseInt(s.substring(comma + 1)); + while (isProjectFrameAt(x, y)) { + x += 20; + y += 20; + } + Rectangle desired = new Rectangle(x, y, 50, 50); + + int gcBestSize = 0; + Point gcBestPoint = null; + GraphicsEnvironment ge; + ge = GraphicsEnvironment.getLocalGraphicsEnvironment(); + for (GraphicsDevice gd : ge.getScreenDevices()) { + for (GraphicsConfiguration gc : gd.getConfigurations()) { + Rectangle gcBounds = gc.getBounds(); + if (gcBounds.intersects(desired)) { + Rectangle inter = gcBounds.intersection(desired); + int size = inter.width * inter.height; + if (size > gcBestSize) { + gcBestSize = size; + int x2 = Math.max(gcBounds.x, Math.min(inter.x, + inter.x + inter.width - 50)); + int y2 = Math.max(gcBounds.y, Math.min(inter.y, + inter.y + inter.height - 50)); + gcBestPoint = new Point(x2, y2); + } + } + } + } + if (gcBestPoint != null) { + if (isProjectFrameAt(gcBestPoint.x, gcBestPoint.y)) { + gcBestPoint = null; + } + } + return gcBestPoint; + } catch (Throwable t) { + return null; + } + } + + private static boolean isProjectFrameAt(int x, int y) { + for (Project current : Projects.getOpenProjects()) { + Frame frame = current.getFrame(); + if (frame != null) { + Point loc = frame.getLocationOnScreen(); + int d = Math.abs(loc.x - x) + Math.abs(loc.y - y); + if (d <= 3) return true; + } + } + return false; + } } diff --git a/src/com/cburch/logisim/gui/menu/MenuHelp.java b/src/com/cburch/logisim/gui/menu/MenuHelp.java index c88be13..f0f9bc9 100644 --- a/src/com/cburch/logisim/gui/menu/MenuHelp.java +++ b/src/com/cburch/logisim/gui/menu/MenuHelp.java @@ -26,7 +26,7 @@ class MenuHelp extends JMenu implements ActionListener { private JMenuItem library = new JMenuItem(); private JMenuItem about = new JMenuItem(); private HelpSet helpSet; - private String helpSetUrl; + private String helpSetUrl = ""; private JHelp helpComponent; private LFrame helpFrame; @@ -77,11 +77,11 @@ class MenuHelp extends JMenu implements ActionListener { private void loadBroker() { String helpUrl = Strings.get("helpsetUrl"); - if (helpUrl == null) helpUrl = "doc/en/doc.hs"; + if (helpUrl == null) helpUrl = "doc/doc_en.hs"; if (helpSet == null || helpFrame == null || !helpUrl.equals(helpSetUrl)) { - ClassLoader cl = MenuHelp.class.getClassLoader(); + ClassLoader loader = MenuHelp.class.getClassLoader(); try { - URL hsURL = HelpSet.findHelpSet(cl, helpUrl); + URL hsURL = HelpSet.findHelpSet(loader, helpUrl); if (hsURL == null) { disableHelp(); JOptionPane.showMessageDialog(menubar.getParentWindow(), @@ -100,6 +100,7 @@ class MenuHelp extends JMenu implements ActionListener { } else { helpFrame.getContentPane().removeAll(); helpFrame.getContentPane().add(helpComponent); + helpComponent.revalidate(); } } catch (Exception e) { disableHelp(); diff --git a/src/com/cburch/logisim/gui/start/Startup.java b/src/com/cburch/logisim/gui/start/Startup.java index 2faac76..e2b4e5a 100644 --- a/src/com/cburch/logisim/gui/start/Startup.java +++ b/src/com/cburch/logisim/gui/start/Startup.java @@ -400,7 +400,7 @@ public class Startup { System.err.println(); //OK System.err.println(Strings.get("argOptionHeader")); //OK System.err.println(" " + Strings.get("argAccentsOption")); //OK - System.err.println(" " + Strings.get("argClearPropsOption")); //OK + System.err.println(" " + Strings.get("argClearOption")); //OK System.err.println(" " + Strings.get("argEmptyOption")); //OK System.err.println(" " + Strings.get("argGatesOption")); //OK System.err.println(" " + Strings.get("argHelpOption")); //OK diff --git a/src/com/cburch/logisim/prefs/AppPreferences.java b/src/com/cburch/logisim/prefs/AppPreferences.java index d6cb710..03b7b5b 100644 --- a/src/com/cburch/logisim/prefs/AppPreferences.java +++ b/src/com/cburch/logisim/prefs/AppPreferences.java @@ -144,6 +144,8 @@ public class AppPreferences { = create(new PrefMonitorInt("windowWidth", 640)); public static final PrefMonitor WINDOW_HEIGHT = create(new PrefMonitorInt("windowHeight", 480)); + public static final PrefMonitor WINDOW_LOCATION + = create(new PrefMonitorString("windowLocation", "0,0")); public static final PrefMonitor WINDOW_MAIN_SPLIT = create(new PrefMonitorDouble("windowMainSplit", 0.25)); public static final PrefMonitor WINDOW_LEFT_SPLIT diff --git a/src/com/cburch/logisim/proj/Projects.java b/src/com/cburch/logisim/proj/Projects.java index 6a41c60..6228fb5 100644 --- a/src/com/cburch/logisim/proj/Projects.java +++ b/src/com/cburch/logisim/proj/Projects.java @@ -5,6 +5,7 @@ package com.cburch.logisim.proj; import java.awt.Dimension; import java.awt.Point; +import java.awt.Window; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.beans.PropertyChangeListener; @@ -12,6 +13,7 @@ import java.io.File; import java.util.ArrayList; import java.util.Collections; import java.util.List; +import java.util.WeakHashMap; import com.cburch.logisim.file.Loader; import com.cburch.logisim.gui.main.Frame; @@ -21,6 +23,9 @@ import com.cburch.logisim.util.PropertyChangeWeakSupport; public class Projects { public static final String projectListProperty = "projectList"; + private static final WeakHashMap frameLocations + = new WeakHashMap(); + private static void projectRemoved(Project proj, Frame frame, MyListener listener) { frame.removeWindowListener(listener); @@ -40,6 +45,9 @@ public class Projects { Frame frame = (Frame) event.getSource(); if ((frame.getExtendedState() & Frame.ICONIFIED) == 0) { mostRecentFrame = frame; + try { + frameLocations.put(frame, frame.getLocationOnScreen()); + } catch (Throwable t) { } } } @@ -159,4 +167,9 @@ public class Projects { public static void removePropertyChangeListener(String propertyName, PropertyChangeListener listener) { propertySupport.removePropertyChangeListener(propertyName, listener); } + + public static Point getLocation(Window win) { + Point ret = frameLocations.get(win); + return ret == null ? null : (Point) ret.clone(); + } } diff --git a/src/com/cburch/logisim/std/arith/Comparator.java b/src/com/cburch/logisim/std/arith/Comparator.java index 3229154..d286d3f 100644 --- a/src/com/cburch/logisim/std/arith/Comparator.java +++ b/src/com/cburch/logisim/std/arith/Comparator.java @@ -10,6 +10,7 @@ import com.cburch.logisim.data.BitWidth; import com.cburch.logisim.data.Bounds; import com.cburch.logisim.data.Direction; import com.cburch.logisim.data.Value; +import com.cburch.logisim.instance.Instance; import com.cburch.logisim.instance.InstanceFactory; import com.cburch.logisim.instance.InstancePainter; import com.cburch.logisim.instance.InstanceState; @@ -115,4 +116,18 @@ public class Comparator extends InstanceFactory { painter.drawPort(EQ, "=", Direction.WEST); painter.drawPort(LT, "<", Direction.WEST); } + + + // + // methods for instances + // + @Override + protected void configureNewInstance(Instance instance) { + instance.addAttributeListener(); + } + + @Override + protected void instanceAttributeChanged(Instance instance, Attribute attr) { + instance.fireInvalidated(); + } } diff --git a/src/com/cburch/logisim/std/base/BitExtender.java b/src/com/cburch/logisim/std/base/BitExtender.java index 61893d0..4dcf8c7 100644 --- a/src/com/cburch/logisim/std/base/BitExtender.java +++ b/src/com/cburch/logisim/std/base/BitExtender.java @@ -103,6 +103,9 @@ public class BitExtender extends InstanceFactory { protected void instanceAttributeChanged(Instance instance, Attribute attr) { if (attr == ATTR_TYPE) { configurePorts(instance); + instance.fireInvalidated(); + } else { + instance.fireInvalidated(); } } diff --git a/src/com/cburch/logisim/std/gates/XnorGate.java b/src/com/cburch/logisim/std/gates/XnorGate.java index d3c77fc..719697d 100644 --- a/src/com/cburch/logisim/std/gates/XnorGate.java +++ b/src/com/cburch/logisim/std/gates/XnorGate.java @@ -54,7 +54,12 @@ class XnorGate extends AbstractGate { @Override protected Value computeOutput(Value[] inputs, int numInputs, InstanceState state) { - return GateFunctions.computeOddParity(inputs, numInputs).not(); + Object behavior = state.getAttributeValue(GateAttributes.ATTR_XOR); + if (behavior == GateAttributes.XOR_ODD) { + return GateFunctions.computeOddParity(inputs, numInputs).not(); + } else { + return GateFunctions.computeExactlyOne(inputs, numInputs).not(); + } } @Override diff --git a/src/com/cburch/logisim/std/gates/XorGate.java b/src/com/cburch/logisim/std/gates/XorGate.java index 244eec4..02efd8a 100644 --- a/src/com/cburch/logisim/std/gates/XorGate.java +++ b/src/com/cburch/logisim/std/gates/XorGate.java @@ -28,8 +28,15 @@ class XorGate extends AbstractGate { @Override public String getRectangularLabel(AttributeSet attrs) { if (attrs == null) return ""; + boolean isOdd = false; Object behavior = attrs.getValue(GateAttributes.ATTR_XOR); - return behavior == GateAttributes.XOR_ODD ? "2k+1" : "1"; + if (behavior == GateAttributes.XOR_ODD) { + Object inputs = attrs.getValue(GateAttributes.ATTR_INPUTS); + if (inputs == null || ((Integer) inputs).intValue() != 2) { + isOdd = true; + } + } + return isOdd ? "2k+1" : "=1"; } @Override diff --git a/src/com/cburch/logisim/tools/SelectTool.java b/src/com/cburch/logisim/tools/SelectTool.java index 4b95f72..0180290 100644 --- a/src/com/cburch/logisim/tools/SelectTool.java +++ b/src/com/cburch/logisim/tools/SelectTool.java @@ -380,7 +380,18 @@ public class SelectTool extends Tool { if (state == MOVING && e.getKeyCode() == KeyEvent.VK_SHIFT) { handleMoveDrag(canvas, curDx, curDy, e.getModifiersEx()); } else { - processKeyEvent(canvas, e, KeyConfigurationEvent.KEY_PRESSED); + switch (e.getKeyCode()) { + case KeyEvent.VK_BACK_SPACE: + case KeyEvent.VK_DELETE: + if (!canvas.getSelection().isEmpty()) { + Action act = SelectionActions.clear(canvas.getSelection()); + canvas.getProject().doAction(act); + e.consume(); + } + break; + default: + processKeyEvent(canvas, e, KeyConfigurationEvent.KEY_PRESSED); + } } } diff --git a/src/com/cburch/logisim/tools/move/MoveResult.java b/src/com/cburch/logisim/tools/move/MoveResult.java index 4772812..76a2958 100644 --- a/src/com/cburch/logisim/tools/move/MoveResult.java +++ b/src/com/cburch/logisim/tools/move/MoveResult.java @@ -68,11 +68,25 @@ public class MoveResult { } public void print(PrintStream out) { + boolean printed = false; for (Component w : replacements.getAdditions()) { + printed = true; out.println("add " + w); } for (Component w : replacements.getRemovals()) { + printed = true; out.println("del " + w); } + for (Component w : replacements.getReplacedComponents()) { + printed = true; + out.print("repl " + w + " by"); + for (Component w2 : replacements.getComponentsReplacing(w)) { + out.print(" " + w2); + } + out.println(); + } + if (!printed) { + out.println("no replacements"); + } } }