Merge branch 'tableUndo'

This commit is contained in:
hneemann 2019-09-28 09:25:56 +02:00
commit a5ec767176
22 changed files with 382 additions and 212 deletions

View File

@ -16,14 +16,17 @@ import de.neemann.digital.analyse.quinemc.BoolTable;
import de.neemann.digital.analyse.quinemc.BoolTableByteArray; import de.neemann.digital.analyse.quinemc.BoolTableByteArray;
import de.neemann.digital.analyse.quinemc.ThreeStateValue; import de.neemann.digital.analyse.quinemc.ThreeStateValue;
import de.neemann.digital.lang.Lang; import de.neemann.digital.lang.Lang;
import de.neemann.digital.undo.Copyable;
import java.io.*; import java.io.*;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection;
/** /**
* The description of a truth table. * The description of a truth table.
*/ */
public class TruthTable { public class TruthTable implements Copyable<TruthTable> {
private final ArrayList<Variable> variables; private final ArrayList<Variable> variables;
private final ArrayList<Result> results; private final ArrayList<Result> results;
@ -52,7 +55,7 @@ public class TruthTable {
*/ */
public void save(File filename) throws IOException { public void save(File filename) throws IOException {
XStream xStream = getxStream(); XStream xStream = getxStream();
try (Writer out = new OutputStreamWriter(new FileOutputStream(filename), "utf-8")) { try (Writer out = new OutputStreamWriter(new FileOutputStream(filename), StandardCharsets.UTF_8)) {
out.write("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"); out.write("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n");
xStream.marshal(this, new PrettyPrintWriter(out)); xStream.marshal(this, new PrettyPrintWriter(out));
} }
@ -68,7 +71,7 @@ public class TruthTable {
if (results.size() > 63) if (results.size() > 63)
throw new IOException(Lang.get("err_tableHasToManyResultColumns")); throw new IOException(Lang.get("err_tableHasToManyResultColumns"));
try (Writer out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(filename), "utf-8"))) { try (Writer out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(filename), StandardCharsets.UTF_8))) {
saveHex(out); saveHex(out);
} }
} }
@ -147,6 +150,29 @@ public class TruthTable {
} }
} }
private TruthTable(TruthTable truthTable) {
variables = new ArrayList<>(truthTable.variables.size());
for (Variable v : truthTable.variables)
variables.add(new Variable(v.getIdentifier()));
results = new ArrayList<>();
for (int i = 0; i < truthTable.getResultCount(); i++) {
Result result = truthTable.results.get(i);
addResult(result.getName(), new BoolTableByteArray(result.values));
}
this.modelAnalyzerInfo = truthTable.modelAnalyzerInfo;
}
/**
* Clears the table and sets the given variables
*
* @param vars the variables to use
*/
public void clear(Collection<? extends Variable> vars) {
variables.clear();
variables.addAll(vars);
results.clear();
}
/** /**
* Returns the number of rows * Returns the number of rows
* *
@ -456,30 +482,18 @@ public class TruthTable {
} }
/** /**
* Sets the don't cares to a given value * Modifies all column in the table
* *
* @param b the value to set * @param m the modifier to use
* @return this for chained calls
*/ */
public void setXto(boolean b) { public TruthTable modifyValues(BoolTableByteArray.TableModifier m) {
for (Result r : results) { for (Result r : results) {
BoolTable bt = r.getValues(); BoolTable bt = r.getValues();
if (bt instanceof BoolTableByteArray) if (bt instanceof BoolTableByteArray)
((BoolTableByteArray) bt).setXTo(b ? 1 : 0); ((BoolTableByteArray) bt).modify(m);
}
}
/**
* Set all table entries to the given value.
* Zero and one behave as expected. All other values represent "don't care"
*
* @param value the value to set
*/
public void setAllTo(int value) {
for (Result r : results) {
BoolTable bt = r.getValues();
if (bt instanceof BoolTableByteArray)
((BoolTableByteArray) bt).setAllTo(value);
} }
return this;
} }
/** /**
@ -500,6 +514,31 @@ public class TruthTable {
return modelAnalyzerInfo; return modelAnalyzerInfo;
} }
@Override
public TruthTable createDeepCopy() {
return new TruthTable(this);
}
/**
* @return the names of all input variables
*/
public ArrayList<String> getVarNames() {
ArrayList<String> names = new ArrayList<>();
for (Variable v : variables)
names.add(v.getIdentifier());
return names;
}
/**
* @return the names of al result variables
*/
public ArrayList<String> getResultNames() {
ArrayList<String> names = new ArrayList<>();
for (Result r : results)
names.add(r.getName());
return names;
}
/** /**
* A single result column * A single result column
*/ */

View File

@ -6,6 +6,8 @@
package de.neemann.digital.analyse; package de.neemann.digital.analyse;
import de.neemann.digital.analyse.quinemc.BoolTable; import de.neemann.digital.analyse.quinemc.BoolTable;
import de.neemann.digital.undo.ModifyException;
import de.neemann.digital.undo.UndoManager;
import javax.swing.event.TableModelEvent; import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener; import javax.swing.event.TableModelListener;
@ -23,31 +25,31 @@ public class TruthTableTableModel implements TableModel {
*/ */
public static final String[] STATENAMES = new String[]{"0", "1", "x"}; public static final String[] STATENAMES = new String[]{"0", "1", "x"};
private final TruthTable truthTable;
private final ArrayList<TableModelListener> listeners = new ArrayList<>(); private final ArrayList<TableModelListener> listeners = new ArrayList<>();
private final UndoManager<TruthTable> undoManager;
/** /**
* Creates a new instance * Creates a new instance
* *
* @param truthTable the truthTable which is to visualize * @param undoManager the undoManager
*/ */
public TruthTableTableModel(TruthTable truthTable) { public TruthTableTableModel(UndoManager<TruthTable> undoManager) {
this.truthTable = truthTable; this.undoManager = undoManager;
} }
@Override @Override
public int getRowCount() { public int getRowCount() {
return truthTable.getRows(); return undoManager.getActual().getRows();
} }
@Override @Override
public int getColumnCount() { public int getColumnCount() {
return truthTable.getCols(); return undoManager.getActual().getCols();
} }
@Override @Override
public String getColumnName(int columnIndex) { public String getColumnName(int columnIndex) {
return truthTable.getColumnName(columnIndex); return undoManager.getActual().getColumnName(columnIndex);
} }
@Override @Override
@ -57,28 +59,39 @@ public class TruthTableTableModel implements TableModel {
@Override @Override
public boolean isCellEditable(int rowIndex, int columnIndex) { public boolean isCellEditable(int rowIndex, int columnIndex) {
return truthTable.isEditable(columnIndex); return undoManager.getActual().isEditable(columnIndex);
} }
@Override @Override
public Object getValueAt(int rowIndex, int columnIndex) { public Object getValueAt(int rowIndex, int columnIndex) {
return truthTable.getValue(rowIndex, columnIndex); return undoManager.getActual().getValue(rowIndex, columnIndex);
} }
@Override @Override
public void setValueAt(Object aValue, int rowIndex, int columnIndex) { public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
if (aValue instanceof Integer) if (aValue instanceof Integer)
truthTable.setValue(rowIndex, columnIndex, (Integer) aValue); setValue(rowIndex, columnIndex, (Integer) aValue);
if (aValue instanceof String) { if (aValue instanceof String) {
if (aValue.toString().equals("0")) if (aValue.toString().equals("0"))
truthTable.setValue(rowIndex, columnIndex, 0); setValue(rowIndex, columnIndex, 0);
else if (aValue.toString().equals("1")) else if (aValue.toString().equals("1"))
truthTable.setValue(rowIndex, columnIndex, 1); setValue(rowIndex, columnIndex, 1);
else else
truthTable.setValue(rowIndex, columnIndex, 2); setValue(rowIndex, columnIndex, 2);
}
}
private void setValue(int rowIndex, int columnIndex, int val) {
int actVal = undoManager.getActual().getValue(rowIndex, columnIndex);
if (actVal != val) {
try {
undoManager.apply(truthTable -> truthTable.setValue(rowIndex, columnIndex, val));
} catch (ModifyException e) {
e.printStackTrace();
} }
fireModelEvent(rowIndex); fireModelEvent(rowIndex);
} }
}
private void fireModelEvent(int rowIndex) { private void fireModelEvent(int rowIndex) {
TableModelEvent e = new TableModelEvent(this, rowIndex); TableModelEvent e = new TableModelEvent(this, rowIndex);
@ -86,6 +99,15 @@ public class TruthTableTableModel implements TableModel {
l.tableChanged(e); l.tableChanged(e);
} }
/**
* Fires a structural table change
*/
public void fireTableChanged() {
TableModelEvent e = new TableModelEvent(this, HEADER_ROW);
for (TableModelListener l : listeners)
l.tableChanged(e);
}
@Override @Override
public void addTableModelListener(TableModelListener l) { public void addTableModelListener(TableModelListener l) {
listeners.add(l); listeners.add(l);
@ -95,13 +117,6 @@ public class TruthTableTableModel implements TableModel {
public void removeTableModelListener(TableModelListener l) { public void removeTableModelListener(TableModelListener l) {
} }
/**
* @return the truth table used by this model
*/
public TruthTable getTable() {
return truthTable;
}
/** /**
* Sets the column name * Sets the column name
* *
@ -109,7 +124,11 @@ public class TruthTableTableModel implements TableModel {
* @param name the new name * @param name the new name
*/ */
public void setColumnName(int columnIndex, String name) { public void setColumnName(int columnIndex, String name) {
truthTable.setColumnName(columnIndex, name); try {
undoManager.apply(truthTable -> truthTable.setColumnName(columnIndex, name));
} catch (ModifyException e) {
e.printStackTrace();
}
fireModelEvent(HEADER_ROW); fireModelEvent(HEADER_ROW);
} }
@ -121,18 +140,26 @@ public class TruthTableTableModel implements TableModel {
*/ */
public void incValue(BoolTable boolTable, int row) { public void incValue(BoolTable boolTable, int row) {
int col = -1; int col = -1;
for (int i = 0; i < truthTable.getResultCount(); i++) { TruthTable tt = undoManager.getActual();
if (truthTable.getResult(i) == boolTable) { for (int i = 0; i < tt.getResultCount(); i++) {
if (tt.getResult(i) == boolTable) {
col = i; col = i;
break; break;
} }
} }
if (col >= 0) { if (col >= 0) {
col += truthTable.getVars().size(); col += tt.getVars().size();
int value = truthTable.getValue(row, col); int value = tt.getValue(row, col);
if (value == 2) value = 0; if (value == 2) value = 0;
else value++; else value++;
setValueAt(value, row, col); setValueAt(value, row, col);
} }
} }
/**
* @return the truth table shown
*/
public TruthTable getTable() {
return undoManager.getActual();
}
} }

View File

@ -32,6 +32,17 @@ public class BoolTableByteArray implements BoolTable {
this.table = table; this.table = table;
} }
/**
* Creates a new instance
*
* @param values the values to initialize the table
*/
public BoolTableByteArray(BoolTable values) {
table = new byte[values.size()];
for (int i = 0; i < values.size(); i++)
table[i] = (byte) values.get(i).asInt();
}
@Override @Override
public int size() { public int size() {
return table.length; return table.length;
@ -79,23 +90,25 @@ public class BoolTableByteArray implements BoolTable {
} }
/** /**
* Sets the don't cares to the given value * Modifies all the table elements using the given modifier.
* *
* @param value the value * @param m the modifier
*/ */
public void setXTo(int value) { public void modify(TableModifier m) {
for (int i = 0; i < table.length; i++) for (int i = 0; i < table.length; i++)
if (table[i] > 1) table[i] = m.modify(table[i]);
table[i] = (byte) value;
} }
/** /**
* Sets all entries to the given value * Modifier to modify the table
*
* @param value the value
*/ */
public void setAllTo(int value) { public interface TableModifier {
for (int i = 0; i < table.length; i++) /**
table[i] = (byte) value; * Creates the modified value
*
* @param b the original value
* @return the modified value
*/
byte modify(byte b);
} }
} }

View File

@ -108,7 +108,7 @@ public class TransitionTableCreator {
} }
// set all to dc // set all to dc
truthTable.setAllTo(2); truthTable.modifyValues(v -> (byte) 2);
// set state output variables // set state output variables
for (State s : states) { for (State s : states) {

View File

@ -5,7 +5,7 @@
*/ */
package de.neemann.digital.gui.components.table; package de.neemann.digital.gui.components.table;
import de.neemann.digital.analyse.TruthTableTableModel; import de.neemann.digital.analyse.TruthTable;
import de.neemann.digital.analyse.expression.Expression; import de.neemann.digital.analyse.expression.Expression;
import de.neemann.digital.analyse.expression.ExpressionException; import de.neemann.digital.analyse.expression.ExpressionException;
import de.neemann.digital.analyse.expression.NamedExpression; import de.neemann.digital.analyse.expression.NamedExpression;
@ -15,10 +15,10 @@ import de.neemann.digital.draw.graphics.text.formatter.LaTeXFormatter;
final class LaTeXExpressionListener implements ExpressionListener { final class LaTeXExpressionListener implements ExpressionListener {
private final StringBuilder sb; private final StringBuilder sb;
LaTeXExpressionListener(TruthTableTableModel model) throws ExpressionException { LaTeXExpressionListener(TruthTable truthTable) throws ExpressionException {
sb = new StringBuilder(); sb = new StringBuilder();
if (model.getTable().getRows() <= 256) { if (truthTable.getRows() <= 256) {
String text = new TruthTableFormatterLaTeX().format(model.getTable()); String text = new TruthTableFormatterLaTeX().format(truthTable);
sb.append(text); sb.append(text);
} }
sb.append("\\begin{eqnarray*}\n"); sb.append("\\begin{eqnarray*}\n");

View File

@ -27,7 +27,7 @@ public class ProgressDialog extends JDialog implements ExpressionCreator.Progres
super(tableDialog, false); super(tableDialog, false);
setDefaultCloseOperation(DISPOSE_ON_CLOSE); setDefaultCloseOperation(DISPOSE_ON_CLOSE);
bar = new JProgressBar(0, tableDialog.getModel().getTable().getResultCount()); bar = new JProgressBar(0, tableDialog.getUndoManager().getActual().getResultCount());
int b = Screen.getInstance().getFontSize(); int b = Screen.getInstance().getFontSize();
bar.setBorder(BorderFactory.createEmptyBorder(b, b, b, b)); bar.setBorder(BorderFactory.createEmptyBorder(b, b, b, b));
final JLabel label = new JLabel(Lang.get("msg_optimizationInProgress")); final JLabel label = new JLabel(Lang.get("msg_optimizationInProgress"));

View File

@ -55,10 +55,9 @@ public class ReorderInputs {
/** /**
* Creates a new table matching the actual state of the items * Creates a new table matching the actual state of the items
* *
* @return the new table
* @throws ExpressionException ExpressionException * @throws ExpressionException ExpressionException
*/ */
public TruthTable reorder() throws ExpressionException { public void reorder() throws ExpressionException {
ArrayList<Variable> newVars = new ArrayList<>(); ArrayList<Variable> newVars = new ArrayList<>();
ArrayList<Variable> deletedVars = new ArrayList<>(table.getVars()); ArrayList<Variable> deletedVars = new ArrayList<>(table.getVars());
@ -79,21 +78,20 @@ public class ReorderInputs {
if (newVars.size() < 2) if (newVars.size() < 2)
throw new ExpressionException(Lang.get("err_tableBecomesToSmall")); throw new ExpressionException(Lang.get("err_tableBecomesToSmall"));
TruthTable newTable = new TruthTable(newVars); TruthTable oldTable = this.table.createDeepCopy();
newTable.setModelAnalyzerInfo(table.getModelAnalyzerInfo());
for (int j = 0; j < table.getResultCount(); j++)
newTable.addResult(table.getResultName(j));
ContextFiller fc = new ContextFiller(newTable.getVars()); table.clear(newVars);
for (int j = 0; j < oldTable.getResultCount(); j++)
table.addResult(oldTable.getResultName(j));
ContextFiller fc = new ContextFiller(table.getVars());
for (Variable v : deletedVars) for (Variable v : deletedVars)
fc.set(v, false); fc.set(v, false);
for (int row = 0; row < newTable.getRows(); row++) { for (int row = 0; row < table.getRows(); row++) {
fc.setContextTo(row); fc.setContextTo(row);
for (int t = 0; t < newTable.getResultCount(); t++) for (int t = 0; t < table.getResultCount(); t++)
newTable.setByContext(t, fc, table.getByContext(t, fc)); table.setByContext(t, fc, oldTable.getByContext(t, fc));
} }
return newTable;
} }
} }

View File

@ -53,23 +53,20 @@ public class ReorderOutputs {
/** /**
* Creates a new table matching the actual state of the items * Creates a new table matching the actual state of the items
* *
* @return the new table
* @throws ExpressionException ExpressionException * @throws ExpressionException ExpressionException
*/ */
public TruthTable reorder() throws ExpressionException { public void reorder() throws ExpressionException {
TruthTable newTable = new TruthTable(table.getVars()); TruthTable oldTable = table.createDeepCopy();
newTable.setModelAnalyzerInfo(table.getModelAnalyzerInfo()); table.clear(oldTable.getVars());
for (String name : names) { for (String name : names) {
for (int i = 0; i < table.getResultCount(); i++) for (int i = 0; i < oldTable.getResultCount(); i++)
if (table.getResultName(i).equals(name)) { if (oldTable.getResultName(i).equals(name)) {
newTable.addResult(table.getResultName(i), table.getResult(i)); table.addResult(oldTable.getResultName(i), oldTable.getResult(i));
break; break;
} }
} }
if (newTable.getResultCount() < 1) if (table.getResultCount() < 1)
throw new ExpressionException(Lang.get("err_oneResultIsRequired")); throw new ExpressionException(Lang.get("err_oneResultIsRequired"));
return newTable;
} }
} }

View File

@ -41,6 +41,8 @@ import de.neemann.digital.gui.components.table.hardware.GenerateCUPL;
import de.neemann.digital.gui.components.table.hardware.GenerateFile; import de.neemann.digital.gui.components.table.hardware.GenerateFile;
import de.neemann.digital.gui.components.table.hardware.HardwareDescriptionGenerator; import de.neemann.digital.gui.components.table.hardware.HardwareDescriptionGenerator;
import de.neemann.digital.lang.Lang; import de.neemann.digital.lang.Lang;
import de.neemann.digital.undo.ModifyException;
import de.neemann.digital.undo.UndoManager;
import de.neemann.gui.*; import de.neemann.gui.*;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -66,7 +68,7 @@ import java.util.prefs.Preferences;
import static de.neemann.digital.analyse.ModelAnalyser.addOne; import static de.neemann.digital.analyse.ModelAnalyser.addOne;
/** /**
* * The dialog used to show the truth table.
*/ */
public class TableDialog extends JDialog { public class TableDialog extends JDialog {
private static final Logger LOGGER = LoggerFactory.getLogger(TableDialog.class); private static final Logger LOGGER = LoggerFactory.getLogger(TableDialog.class);
@ -102,15 +104,16 @@ public class TableDialog extends JDialog {
private final ToolTipAction karnaughMenuAction; private final ToolTipAction karnaughMenuAction;
private final HashMap<String, HardwareDescriptionGenerator> availGenerators = new HashMap<>(); private final HashMap<String, HardwareDescriptionGenerator> availGenerators = new HashMap<>();
private final JMenu hardwareMenu; private final JMenu hardwareMenu;
private final TruthTableTableModel model;
private JCheckBoxMenuItem createJK; private JCheckBoxMenuItem createJK;
private File filename; private File filename;
private TruthTableTableModel model;
private int columnIndex; private int columnIndex;
private AllSolutionsDialog allSolutionsDialog; private AllSolutionsDialog allSolutionsDialog;
private ExpressionListenerStore lastGeneratedExpressions; private ExpressionListenerStore lastGeneratedExpressions;
private KarnaughMapDialog kvMap; private KarnaughMapDialog kvMap;
private JMenuItem lastUsedGenratorMenuItem; private JMenuItem lastUsedGenratorMenuItem;
private Mouse mouse = Mouse.getMouse(); private Mouse mouse = Mouse.getMouse();
private UndoManager<TruthTable> undoManager;
/** /**
* Creates a new instance * Creates a new instance
@ -122,10 +125,15 @@ public class TableDialog extends JDialog {
*/ */
public TableDialog(Window parent, TruthTable truthTable, ElementLibrary library, File filename) { public TableDialog(Window parent, TruthTable truthTable, ElementLibrary library, File filename) {
super(parent, Lang.get("win_table")); super(parent, Lang.get("win_table"));
undoManager = new UndoManager<>(truthTable);
this.library = library; this.library = library;
this.shapeFactory = library.getShapeFactory(); this.shapeFactory = library.getShapeFactory();
this.filename = filename; this.filename = filename;
setDefaultCloseOperation(DISPOSE_ON_CLOSE); setDefaultCloseOperation(DISPOSE_ON_CLOSE);
model = new TruthTableTableModel(undoManager);
model.addTableModelListener(new CalculationTableModelListener());
kvMap = new KarnaughMapDialog(this, (boolTable, row) -> model.incValue(boolTable, row)); kvMap = new KarnaughMapDialog(this, (boolTable, row) -> model.incValue(boolTable, row));
statusBar = new ExpressionComponent(); statusBar = new ExpressionComponent();
@ -182,63 +190,90 @@ public class TableDialog extends JDialog {
} }
bar.add(sizeMenu); bar.add(sizeMenu);
JMenu columnsMenu = new JMenu(Lang.get("menu_table_columns")); JMenu edit = new JMenu(Lang.get("menu_edit"));
bar.add(columnsMenu); bar.add(edit);
columnsMenu.add(new ToolTipAction(Lang.get("menu_table_reorder_inputs")) {
addUndoRedo(edit);
edit.addSeparator();
edit.add(new ToolTipAction(Lang.get("menu_table_reorder_inputs")) {
@Override @Override
public void actionPerformed(ActionEvent e) { public void actionPerformed(ActionEvent e) {
ReorderInputs ri = new ReorderInputs(model.getTable()); ArrayList<String> varNames = undoManager.getActual().getVarNames();
if (new ElementOrderer<>(TableDialog.this, Lang.get("menu_table_reorder_inputs"), ri.getItems()) if (new ElementOrderer<>(TableDialog.this, Lang.get("menu_table_reorder_inputs"), new ElementOrderer.ListOrder<>(varNames))
.addDeleteButton() .addDeleteButton()
.addOkButton() .addOkButton()
.showDialog()) { .showDialog()) {
try { try {
setModel(new TruthTableTableModel(ri.reorder())); undoManager.apply(tt -> {
} catch (ExpressionException e1) { try {
new ReorderInputs(tt, varNames).reorder();
tableChanged();
} catch (ExpressionException ex) {
throw new ModifyException("failed to reorder", ex);
}
});
} catch (ModifyException e1) {
new ErrorMessage().addCause(e1).show(TableDialog.this); new ErrorMessage().addCause(e1).show(TableDialog.this);
} }
} }
} }
}.createJMenuItem()); }.createJMenuItem());
columnsMenu.add(new ToolTipAction(Lang.get("menu_table_columnsAddVariable")) { edit.add(new ToolTipAction(Lang.get("menu_table_columnsAddVariable")) {
@Override @Override
public void actionPerformed(ActionEvent actionEvent) { public void actionPerformed(ActionEvent actionEvent) {
TruthTable t = model.getTable(); try {
t.addVariable(); undoManager.apply(TruthTable::addVariable);
setModel(new TruthTableTableModel(t)); tableChanged();
} catch (ModifyException e) {
new ErrorMessage().addCause(e).show(TableDialog.this);
}
} }
}.setToolTip(Lang.get("menu_table_columnsAddVariable_tt")).createJMenuItem()); }.setToolTip(Lang.get("menu_table_columnsAddVariable_tt")).createJMenuItem());
columnsMenu.add(new ToolTipAction(Lang.get("menu_table_reorder_outputs")) { edit.add(new ToolTipAction(Lang.get("menu_table_reorder_outputs")) {
@Override @Override
public void actionPerformed(ActionEvent e) { public void actionPerformed(ActionEvent e) {
ReorderOutputs ro = new ReorderOutputs(model.getTable()); ArrayList<String> resultNames = undoManager.getActual().getResultNames();
if (new ElementOrderer<>(TableDialog.this, Lang.get("menu_table_reorder_outputs"), ro.getItems()) if (new ElementOrderer<>(TableDialog.this, Lang.get("menu_table_reorder_outputs"), new ElementOrderer.ListOrder<>(resultNames))
.addDeleteButton() .addDeleteButton()
.addOkButton() .addOkButton()
.showDialog()) { .showDialog()) {
try { try {
setModel(new TruthTableTableModel(ro.reorder())); undoManager.apply(tt -> {
} catch (ExpressionException e1) { try {
new ReorderOutputs(tt, resultNames).reorder();
tableChanged();
} catch (ExpressionException ex) {
throw new ModifyException("failed to reorder", ex);
}
});
} catch (ModifyException e1) {
new ErrorMessage().addCause(e1).show(TableDialog.this); new ErrorMessage().addCause(e1).show(TableDialog.this);
} }
} }
} }
}.createJMenuItem()); }.createJMenuItem());
columnsMenu.add(new ToolTipAction(Lang.get("menu_table_columnsAdd")) { edit.add(new ToolTipAction(Lang.get("menu_table_columnsAdd")) {
@Override @Override
public void actionPerformed(ActionEvent actionEvent) { public void actionPerformed(ActionEvent actionEvent) {
TruthTable t = model.getTable(); try {
t.addResult(); undoManager.apply(TruthTable::addResult);
setModel(new TruthTableTableModel(t)); tableChanged();
} catch (ModifyException e) {
new ErrorMessage().addCause(e).show(TableDialog.this);
}
} }
}.setToolTip(Lang.get("menu_table_columnsAdd_tt")).createJMenuItem()); }.setToolTip(Lang.get("menu_table_columnsAdd_tt")).createJMenuItem());
bar.add(columnsMenu); edit.addSeparator();
bar.add(createSetMenu()); createSetMenuEntries(edit);
hardwareMenu = createCreateMenu(); hardwareMenu = createCreateMenu();
bar.add(hardwareMenu); bar.add(hardwareMenu);
@ -256,7 +291,8 @@ public class TableDialog extends JDialog {
setJMenuBar(bar); setJMenuBar(bar);
setModel(new TruthTableTableModel(truthTable)); karnaughMenuAction.setEnabled(undoManager.getActual().getVars().size() <= 4);
calculateExpressions();
getContentPane().add(new JScrollPane(table)); getContentPane().add(new JScrollPane(table));
getContentPane().add(statusBar, BorderLayout.SOUTH); getContentPane().add(statusBar, BorderLayout.SOUTH);
@ -264,6 +300,55 @@ public class TableDialog extends JDialog {
setLocationRelativeTo(parent); setLocationRelativeTo(parent);
} }
private void addUndoRedo(JMenu edit) {
final ToolTipAction undo = new ToolTipAction(Lang.get("menu_undo")) {
@Override
public void actionPerformed(ActionEvent actionEvent) {
if (undoManager.undoAvailable()) {
try {
undoManager.undo();
tableChanged();
} catch (ModifyException e) {
new ErrorMessage().addCause(e).show(TableDialog.this);
}
}
}
}.setAcceleratorCTRLplus("Z");
final ToolTipAction redo = new ToolTipAction(Lang.get("menu_redo")) {
@Override
public void actionPerformed(ActionEvent actionEvent) {
if (undoManager.redoAvailable()) {
try {
undoManager.redo();
tableChanged();
} catch (ModifyException e) {
new ErrorMessage().addCause(e).show(TableDialog.this);
}
}
}
}.setAcceleratorCTRLplus("Y");
edit.add(undo.createJMenuItem());
edit.add(redo.createJMenuItem());
undoManager.addListener(() -> {
undo.setEnabled(undoManager.undoAvailable());
redo.setEnabled(undoManager.redoAvailable());
if (undoManager.isModified())
setTitle("*" + Lang.get("win_table"));
else
setTitle(Lang.get("win_table"));
}).hasChanged();
}
/**
* Called if table was modified.
*/
public void tableChanged() {
karnaughMenuAction.setEnabled(undoManager.getActual().getVars().size() <= 4);
calculateExpressions();
model.fireTableChanged();
}
private void editColumnName(int columnIndex, Point pos) { private void editColumnName(int columnIndex, Point pos) {
ElementAttributes attr = new ElementAttributes(); ElementAttributes attr = new ElementAttributes();
final String name = model.getColumnName(columnIndex); final String name = model.getColumnName(columnIndex);
@ -290,7 +375,8 @@ public class TableDialog extends JDialog {
try { try {
File file = fc.getSelectedFile(); File file = fc.getSelectedFile();
TruthTable truthTable = TruthTable.readFromFile(file); TruthTable truthTable = TruthTable.readFromFile(file);
setModel(new TruthTableTableModel(truthTable)); undoManager.setInitial(truthTable);
tableChanged();
TableDialog.this.filename = file; TableDialog.this.filename = file;
} catch (IOException e1) { } catch (IOException e1) {
new ErrorMessage().addCause(e1).show(TableDialog.this); new ErrorMessage().addCause(e1).show(TableDialog.this);
@ -308,7 +394,7 @@ public class TableDialog extends JDialog {
fc.setFileFilter(new FileNameExtensionFilter(Lang.get("msg_truthTable"), "tru")); fc.setFileFilter(new FileNameExtensionFilter(Lang.get("msg_truthTable"), "tru"));
new SaveAsHelper(TableDialog.this, fc, "tru").checkOverwrite( new SaveAsHelper(TableDialog.this, fc, "tru").checkOverwrite(
file -> { file -> {
model.getTable().save(file); undoManager.getActual().save(file);
TableDialog.this.filename = file; TableDialog.this.filename = file;
} }
); );
@ -320,7 +406,7 @@ public class TableDialog extends JDialog {
@Override @Override
public void actionPerformed(ActionEvent e) { public void actionPerformed(ActionEvent e) {
try { try {
final LaTeXExpressionListener laTeXExpressionListener = new LaTeXExpressionListener(model); final LaTeXExpressionListener laTeXExpressionListener = new LaTeXExpressionListener(undoManager.getActual());
ExpressionListener expressionListener = laTeXExpressionListener; ExpressionListener expressionListener = laTeXExpressionListener;
if (createJK.isSelected()) if (createJK.isSelected())
expressionListener = new ExpressionListenerJK(expressionListener); expressionListener = new ExpressionListenerJK(expressionListener);
@ -339,14 +425,14 @@ public class TableDialog extends JDialog {
@Override @Override
public void actionPerformed(ActionEvent e) { public void actionPerformed(ActionEvent e) {
int res = JOptionPane.OK_OPTION; int res = JOptionPane.OK_OPTION;
if (model.getTable().getVars().size() > 20) if (undoManager.getActual().getVars().size() > 20)
res = JOptionPane.showConfirmDialog(TableDialog.this, Lang.get("msg_tableHasManyRowsConfirm")); res = JOptionPane.showConfirmDialog(TableDialog.this, Lang.get("msg_tableHasManyRowsConfirm"));
if (res == JOptionPane.OK_OPTION) { if (res == JOptionPane.OK_OPTION) {
JFileChooser fc = new MyFileChooser(); JFileChooser fc = new MyFileChooser();
if (TableDialog.this.filename != null) if (TableDialog.this.filename != null)
fc.setSelectedFile(SaveAsHelper.checkSuffix(TableDialog.this.filename, "hex")); fc.setSelectedFile(SaveAsHelper.checkSuffix(TableDialog.this.filename, "hex"));
new SaveAsHelper(TableDialog.this, fc, "hex") new SaveAsHelper(TableDialog.this, fc, "hex")
.checkOverwrite(file -> model.getTable().saveHex(file)); .checkOverwrite(file -> undoManager.getActual().saveHex(file));
} }
} }
}.setToolTip(Lang.get("menu_table_exportHex_tt")).createJMenuItem()); }.setToolTip(Lang.get("menu_table_exportHex_tt")).createJMenuItem());
@ -361,49 +447,53 @@ public class TableDialog extends JDialog {
return fileMenu; return fileMenu;
} }
private JMenu createSetMenu() { private void createSetMenuEntries(JMenu edit) {
JMenu setMenu = new JMenu(Lang.get("menu_table_set")); edit.add(new ToolTipAction(Lang.get("menu_table_setXTo0")) {
setMenu.add(new ToolTipAction(Lang.get("menu_table_setXTo0")) {
@Override @Override
public void actionPerformed(ActionEvent e) { public void actionPerformed(ActionEvent e) {
TruthTable t = model.getTable(); modifyTable(v -> v > 1 ? 0 : v);
t.setXto(false);
setModel(new TruthTableTableModel(t));
} }
}.setToolTip(Lang.get("menu_table_setXTo0_tt")).createJMenuItem()); }.setToolTip(Lang.get("menu_table_setXTo0_tt")).createJMenuItem());
setMenu.add(new ToolTipAction(Lang.get("menu_table_setXTo1")) { edit.add(new ToolTipAction(Lang.get("menu_table_setXTo1")) {
@Override @Override
public void actionPerformed(ActionEvent e) { public void actionPerformed(ActionEvent e) {
TruthTable t = model.getTable(); modifyTable(v -> v > 1 ? 1 : v);
t.setXto(true);
setModel(new TruthTableTableModel(t));
} }
}.setToolTip(Lang.get("menu_table_setXTo1_tt")).createJMenuItem()); }.setToolTip(Lang.get("menu_table_setXTo1_tt")).createJMenuItem());
setMenu.add(new ToolTipAction(Lang.get("menu_table_setAllToX")) { edit.add(new ToolTipAction(Lang.get("menu_table_setAllToX")) {
@Override @Override
public void actionPerformed(ActionEvent e) { public void actionPerformed(ActionEvent e) {
setAllValuesTo(2); modifyTable(v -> (byte) 2);
} }
}.setToolTip(Lang.get("menu_table_setAllToX_tt")).createJMenuItem()); }.setToolTip(Lang.get("menu_table_setAllToX_tt")).createJMenuItem());
setMenu.add(new ToolTipAction(Lang.get("menu_table_setAllTo0")) { edit.add(new ToolTipAction(Lang.get("menu_table_setAllTo0")) {
@Override @Override
public void actionPerformed(ActionEvent e) { public void actionPerformed(ActionEvent e) {
setAllValuesTo(0); modifyTable(v -> (byte) 0);
} }
}.setToolTip(Lang.get("menu_table_setAllTo0_tt")).createJMenuItem()); }.setToolTip(Lang.get("menu_table_setAllTo0_tt")).createJMenuItem());
setMenu.add(new ToolTipAction(Lang.get("menu_table_setAllTo1")) { edit.add(new ToolTipAction(Lang.get("menu_table_setAllTo1")) {
@Override @Override
public void actionPerformed(ActionEvent e) { public void actionPerformed(ActionEvent e) {
setAllValuesTo(1); modifyTable(v -> (byte) 1);
} }
}.setToolTip(Lang.get("menu_table_setAllTo1_tt")).createJMenuItem()); }.setToolTip(Lang.get("menu_table_setAllTo1_tt")).createJMenuItem());
return setMenu; edit.add(new ToolTipAction(Lang.get("menu_table_invert")) {
@Override
public void actionPerformed(ActionEvent e) {
modifyTable(v -> v > 1 ? v : (byte) (1 - v));
}
}.setToolTip(Lang.get("menu_table_invert_tt")).createJMenuItem());
} }
private void setAllValuesTo(int value) { private void modifyTable(BoolTableByteArray.TableModifier m) {
TruthTable t = model.getTable(); try {
t.setAllTo(value); undoManager.apply(truthTable -> truthTable.modifyValues(m));
setModel(new TruthTableTableModel(t)); tableChanged();
} catch (ModifyException e) {
e.printStackTrace();
new ErrorMessage().addCause(e).show(TableDialog.this);
}
} }
private JMenu createCreateMenu() { private JMenu createCreateMenu() {
@ -527,8 +617,8 @@ public class TableDialog extends JDialog {
private void createCircuit(boolean useJKff, boolean useLUTs, ExpressionModifier... modifier) { private void createCircuit(boolean useJKff, boolean useLUTs, ExpressionModifier... modifier) {
try { try {
final ModelAnalyserInfo modelAnalyzerInfo = model.getTable().getModelAnalyzerInfo(); final ModelAnalyserInfo modelAnalyzerInfo = undoManager.getActual().getModelAnalyzerInfo();
CircuitBuilder circuitBuilder = new CircuitBuilder(shapeFactory, model.getTable().getVars()) CircuitBuilder circuitBuilder = new CircuitBuilder(shapeFactory, undoManager.getActual().getVars())
.setUseJK(useJKff) .setUseJK(useJKff)
.setUseLUTs(useLUTs) .setUseLUTs(useLUTs)
.setModelAnalyzerInfo(modelAnalyzerInfo); .setModelAnalyzerInfo(modelAnalyzerInfo);
@ -555,19 +645,6 @@ public class TableDialog extends JDialog {
return model; return model;
} }
/**
* Sets the table model
*
* @param model the model to use
*/
public void setModel(TruthTableTableModel model) {
this.model = model;
model.addTableModelListener(new CalculationTableModelListener());
table.setModel(model);
karnaughMenuAction.setEnabled(model.getTable().getVars().size() <= 4);
calculateExpressions();
}
private String getProjectName() { private String getProjectName() {
if (filename == null) if (filename == null)
return "unknown"; return "unknown";
@ -598,6 +675,13 @@ public class TableDialog extends JDialog {
} }
} }
/**
* @return the undoManager
*/
public UndoManager<TruthTable> getUndoManager() {
return undoManager;
}
private class CalculationTableModelListener implements TableModelListener { private class CalculationTableModelListener implements TableModelListener {
@Override @Override
public void tableChanged(TableModelEvent tableModelEvent) { public void tableChanged(TableModelEvent tableModelEvent) {
@ -613,7 +697,7 @@ public class TableDialog extends JDialog {
if (createJK.isSelected()) if (createJK.isSelected())
expressionListener = new ExpressionListenerJK(expressionListener); expressionListener = new ExpressionListenerJK(expressionListener);
final TruthTable table = model.getTable(); final TruthTable table = undoManager.getActual();
if (table.getVars().size() >= 8) { if (table.getVars().size() >= 8) {
ProgressDialog progress = new ProgressDialog(this); ProgressDialog progress = new ProgressDialog(this);
@ -674,7 +758,8 @@ public class TableDialog extends JDialog {
@Override @Override
public void actionPerformed(ActionEvent actionEvent) { public void actionPerformed(ActionEvent actionEvent) {
setModel(new TruthTableTableModel(new TruthTable(n).addResult())); undoManager.setInitial(new TruthTable(n).addResult());
tableChanged();
} }
} }
@ -702,7 +787,8 @@ public class TableDialog extends JDialog {
i--; i--;
} }
setModel(new TruthTableTableModel(truthTable)); undoManager.setInitial(truthTable);
tableChanged();
} }
} }
@ -735,7 +821,8 @@ public class TableDialog extends JDialog {
i--; i--;
} }
setModel(new TruthTableTableModel(truthTable)); undoManager.setInitial(truthTable);
tableChanged();
} }
} }
@ -746,7 +833,7 @@ public class TableDialog extends JDialog {
JLabel label = (JLabel) super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); JLabel label = (JLabel) super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
label.setHorizontalAlignment(SwingConstants.CENTER); label.setHorizontalAlignment(SwingConstants.CENTER);
label.setFont(font); label.setFont(font);
if (column < model.getTable().getVars().size()) if (column < undoManager.getActual().getVars().size())
label.setBackground(MYGRAY); label.setBackground(MYGRAY);
else else
label.setBackground(Color.WHITE); label.setBackground(Color.WHITE);
@ -761,7 +848,7 @@ public class TableDialog extends JDialog {
} }
} }
private final class StringDefaultTableCellRenderer extends DefaultTableCellRenderer { private static final class StringDefaultTableCellRenderer extends DefaultTableCellRenderer {
private StringDefaultTableCellRenderer() { private StringDefaultTableCellRenderer() {
setHorizontalAlignment(SwingConstants.CENTER); setHorizontalAlignment(SwingConstants.CENTER);
} }
@ -832,13 +919,13 @@ public class TableDialog extends JDialog {
int c = table.getSelectedColumn(); int c = table.getSelectedColumn();
if (r < 0 || c < 0) { if (r < 0 || c < 0) {
r = 0; r = 0;
c = model.getTable().getVars().size(); c = undoManager.getActual().getVars().size();
} }
model.setValueAt(value, r, c); model.setValueAt(value, r, c);
c++; c++;
if (c >= table.getColumnCount()) { if (c >= table.getColumnCount()) {
c = model.getTable().getVars().size(); c = undoManager.getActual().getVars().size();
r++; r++;
if (r >= model.getRowCount()) if (r >= model.getRowCount())
r = 0; r = 0;
@ -859,7 +946,7 @@ public class TableDialog extends JDialog {
@Override @Override
public void actionPerformed(ActionEvent e) { public void actionPerformed(ActionEvent e) {
try { try {
generator.generate(TableDialog.this, filename, model.getTable(), lastGeneratedExpressions); generator.generate(TableDialog.this, filename, undoManager.getActual(), lastGeneratedExpressions);
setLastUsedGenerator(generator); setLastUsedGenerator(generator);
} catch (Exception e1) { } catch (Exception e1) {
new ErrorMessage(Lang.get("msg_errorDuringHardwareExport")).addCause(e1).show(TableDialog.this); new ErrorMessage(Lang.get("msg_errorDuringHardwareExport")).addCause(e1).show(TableDialog.this);

View File

@ -10,6 +10,7 @@ import de.neemann.digital.analyse.TruthTableTableModel;
import de.neemann.digital.analyse.expression.ExpressionException; import de.neemann.digital.analyse.expression.ExpressionException;
import de.neemann.digital.analyse.expression.Variable; import de.neemann.digital.analyse.expression.Variable;
import de.neemann.digital.analyse.quinemc.BoolTable; import de.neemann.digital.analyse.quinemc.BoolTable;
import de.neemann.digital.undo.ModifyException;
import javax.swing.*; import javax.swing.*;
import javax.swing.table.TableModel; import javax.swing.table.TableModel;
@ -20,7 +21,7 @@ import java.util.ArrayList;
/** /**
* Handles reordering of the table columns by mouse drag and drop * Handles reordering of the table columns by mouse drag and drop
*/ */
public class TableReorderManager { class TableReorderManager {
private final TableDialog tableDialog; private final TableDialog tableDialog;
private final JTable table; private final JTable table;
@ -31,7 +32,7 @@ public class TableReorderManager {
* @param tableDialog the TableDialog instance * @param tableDialog the TableDialog instance
* @param table the table which is reordered * @param table the table which is reordered
*/ */
public TableReorderManager(TableDialog tableDialog, JTable table) { TableReorderManager(TableDialog tableDialog, JTable table) {
this.tableDialog = tableDialog; this.tableDialog = tableDialog;
this.table = table; this.table = table;
table.getTableHeader().addMouseListener(new MouseAdapter() { table.getTableHeader().addMouseListener(new MouseAdapter() {
@ -64,24 +65,32 @@ public class TableReorderManager {
} }
if (wasChange) { if (wasChange) {
try {
if (isVarChange(varList, vars)) { if (isVarChange(varList, vars)) {
tableDialog.getUndoManager().apply(tt -> {
try { try {
TruthTable tt = new ReorderInputs(model.getTable(), vars).reorder(); new ReorderInputs(tt, vars).reorder();
tableDialog.setModel(new TruthTableTableModel(tt));
} catch (ExpressionException e) { } catch (ExpressionException e) {
// can't happen because no columns are removed // can't happen because no columns are removed
e.printStackTrace(); e.printStackTrace();
} }
});
tableDialog.tableChanged();
} else if (isResultChange(model.getTable(), results)) { } else if (isResultChange(model.getTable(), results)) {
tableDialog.getUndoManager().apply(tt -> {
try { try {
TruthTable tt = new ReorderOutputs(model.getTable(), results).reorder(); new ReorderOutputs(tt, results).reorder();
tableDialog.setModel(new TruthTableTableModel(tt));
} catch (ExpressionException e) { } catch (ExpressionException e) {
// can't happen because no columns are removed // can't happen because no columns are removed
e.printStackTrace(); e.printStackTrace();
} }
});
tableDialog.tableChanged();
} else } else
tableDialog.setModel(new TruthTableTableModel(model.getTable())); tableDialog.tableChanged();
} catch (ModifyException e) {
e.printStackTrace();
}
} }
} }

View File

@ -45,6 +45,7 @@ public class UndoManager<A extends Copyable<A>> {
modifications = new ArrayList<>(); modifications = new ArrayList<>();
modificationCounter = 0; modificationCounter = 0;
savedCounter = 0; savedCounter = 0;
fireChangedEvent();
} }
@ -187,9 +188,11 @@ public class UndoManager<A extends Copyable<A>> {
* Adds a listener * Adds a listener
* *
* @param listener the listener to add * @param listener the listener to add
* @return the given listener for chained calls.
*/ */
public void addListener(ChangedListener listener) { public ChangedListener addListener(ChangedListener listener) {
listeners.add(listener); listeners.add(listener);
return listener;
} }
/** /**

View File

@ -1546,14 +1546,12 @@ Sind evtl. die Namen der Variablen nicht eindeutig?</string>
<string name="menu_table_new_combinatorial">Kombinatorisch</string> <string name="menu_table_new_combinatorial">Kombinatorisch</string>
<string name="menu_table_new_sequential">Automat</string> <string name="menu_table_new_sequential">Automat</string>
<string name="menu_table_new_sequential_bidir">Automat bidirektional</string> <string name="menu_table_new_sequential_bidir">Automat bidirektional</string>
<string name="menu_table_columns">Spalten</string>
<string name="menu_table_reorder_inputs">Eingangsvariablen umsortieren/löschen</string> <string name="menu_table_reorder_inputs">Eingangsvariablen umsortieren/löschen</string>
<string name="menu_table_reorder_outputs">Ergebnisspalten umsortieren/löschen</string> <string name="menu_table_reorder_outputs">Ergebnisspalten umsortieren/löschen</string>
<string name="menu_table_columnsAdd">Ergebnisspalte hinzufügen</string> <string name="menu_table_columnsAdd">Ergebnisspalte hinzufügen</string>
<string name="menu_table_columnsAdd_tt">Fügt der Tabelle eine Ergebnisspalte hinzu.</string> <string name="menu_table_columnsAdd_tt">Fügt der Tabelle eine Ergebnisspalte hinzu.</string>
<string name="menu_table_columnsAddVariable">Eingangsvariable hinzufügen</string> <string name="menu_table_columnsAddVariable">Eingangsvariable hinzufügen</string>
<string name="menu_table_columnsAddVariable_tt">Fügt der Tabelle eine Variablenspalte hinzu.</string> <string name="menu_table_columnsAddVariable_tt">Fügt der Tabelle eine Variablenspalte hinzu.</string>
<string name="menu_table_set">Setzen</string>
<string name="menu_table_setXTo0">Setze X auf 0</string> <string name="menu_table_setXTo0">Setze X auf 0</string>
<string name="menu_table_setXTo0_tt">Setzt die Don't Cares auf 0.</string> <string name="menu_table_setXTo0_tt">Setzt die Don't Cares auf 0.</string>
<string name="menu_table_setXTo1">Setze X auf 1</string> <string name="menu_table_setXTo1">Setze X auf 1</string>
@ -1565,6 +1563,9 @@ Sind evtl. die Namen der Variablen nicht eindeutig?</string>
<string name="menu_table_setAllTo0_tt">Setzt alle Werte auf Null.</string> <string name="menu_table_setAllTo0_tt">Setzt alle Werte auf Null.</string>
<string name="menu_table_setAllTo1">Alles auf 1 setzen</string> <string name="menu_table_setAllTo1">Alles auf 1 setzen</string>
<string name="menu_table_setAllTo1_tt">Setzt alle Werte auf Eins.</string> <string name="menu_table_setAllTo1_tt">Setzt alle Werte auf Eins.</string>
<string name="menu_table_invert">Alle Bits invertieren</string>
<string name="menu_table_invert_tt">Aus einer "1" wird eine "0" und umgekehrt. Don't Cares bleiben unverändert.
</string>
<string name="menu_table_showAllSolutions">Lösungsdialog anzeigen</string> <string name="menu_table_showAllSolutions">Lösungsdialog anzeigen</string>
<string name="menu_table_showAllSolutions_tt">Zeigt den Lösungsdialog wieder an, wenn er manuell geschlossen wurde.</string> <string name="menu_table_showAllSolutions_tt">Zeigt den Lösungsdialog wieder an, wenn er manuell geschlossen wurde.</string>
<string name="menu_terminalDelete">Löschen</string> <string name="menu_terminalDelete">Löschen</string>

View File

@ -1529,14 +1529,12 @@
<string name="menu_table_new_combinatorial">Combinatorial</string> <string name="menu_table_new_combinatorial">Combinatorial</string>
<string name="menu_table_new_sequential">Sequential</string> <string name="menu_table_new_sequential">Sequential</string>
<string name="menu_table_new_sequential_bidir">Sequential bidirectional</string> <string name="menu_table_new_sequential_bidir">Sequential bidirectional</string>
<string name="menu_table_columns">Columns</string>
<string name="menu_table_reorder_inputs">Reorder/Delete Input Variables</string> <string name="menu_table_reorder_inputs">Reorder/Delete Input Variables</string>
<string name="menu_table_columnsAddVariable">Add Input Variable</string> <string name="menu_table_columnsAddVariable">Add Input Variable</string>
<string name="menu_table_columnsAddVariable_tt">Adds a new input variable to the table.</string> <string name="menu_table_columnsAddVariable_tt">Adds a new input variable to the table.</string>
<string name="menu_table_reorder_outputs">Reorder/Delete Output Columns</string> <string name="menu_table_reorder_outputs">Reorder/Delete Output Columns</string>
<string name="menu_table_columnsAdd">Add Output Column</string> <string name="menu_table_columnsAdd">Add Output Column</string>
<string name="menu_table_columnsAdd_tt">Adds a new result column to the table.</string> <string name="menu_table_columnsAdd_tt">Adds a new result column to the table.</string>
<string name="menu_table_set">Set</string>
<string name="menu_table_setXTo0">Set X to 0</string> <string name="menu_table_setXTo0">Set X to 0</string>
<string name="menu_table_setXTo0_tt">Sets the Don't Cares to 0.</string> <string name="menu_table_setXTo0_tt">Sets the Don't Cares to 0.</string>
<string name="menu_table_setXTo1">Set X to 1</string> <string name="menu_table_setXTo1">Set X to 1</string>
@ -1548,6 +1546,8 @@
<string name="menu_table_setAllTo0_tt">Set all values to zero.</string> <string name="menu_table_setAllTo0_tt">Set all values to zero.</string>
<string name="menu_table_setAllTo1">Set all to 1</string> <string name="menu_table_setAllTo1">Set all to 1</string>
<string name="menu_table_setAllTo1_tt">Set all values to one.</string> <string name="menu_table_setAllTo1_tt">Set all values to one.</string>
<string name="menu_table_invert">Invert all bits</string>
<string name="menu_table_invert_tt">A "1" becomes a "0" and vice versa. Don't cares remain unchanged.</string>
<string name="menu_table_showAllSolutions">Show results dialog</string> <string name="menu_table_showAllSolutions">Show results dialog</string>
<string name="menu_table_showAllSolutions_tt">Shows the results dialog again if it was closed manually.</string> <string name="menu_table_showAllSolutions_tt">Shows the results dialog again if it was closed manually.</string>
<string name="menu_terminalDelete">Delete</string> <string name="menu_terminalDelete">Delete</string>

View File

@ -1293,14 +1293,12 @@
<string name="menu_table_new_combinatorial">Combinacional</string> <string name="menu_table_new_combinatorial">Combinacional</string>
<string name="menu_table_new_sequential">Secuencial</string> <string name="menu_table_new_sequential">Secuencial</string>
<string name="menu_table_new_sequential_bidir">Secuencial bidireccional</string> <string name="menu_table_new_sequential_bidir">Secuencial bidireccional</string>
<string name="menu_table_columns">Columnas</string>
<string name="menu_table_reorder_inputs">Reordena/Borra variables de entrada</string> <string name="menu_table_reorder_inputs">Reordena/Borra variables de entrada</string>
<string name="menu_table_reorder_outputs">Reordena/Borra columnas de salida</string> <string name="menu_table_reorder_outputs">Reordena/Borra columnas de salida</string>
<string name="menu_table_columnsAdd">Añade columna de salida</string> <string name="menu_table_columnsAdd">Añade columna de salida</string>
<string name="menu_table_columnsAdd_tt">Añade una nueva columna de resultado a la tabla.</string> <string name="menu_table_columnsAdd_tt">Añade una nueva columna de resultado a la tabla.</string>
<string name="menu_table_columnsAddVariable">Añade variable de entrada</string> <string name="menu_table_columnsAddVariable">Añade variable de entrada</string>
<string name="menu_table_columnsAddVariable_tt">Añade una nueva variable de entrada a la tabla.</string> <string name="menu_table_columnsAddVariable_tt">Añade una nueva variable de entrada a la tabla.</string>
<string name="menu_table_set">Fijar</string>
<string name="menu_table_setXTo0">Fijar X a 0</string> <string name="menu_table_setXTo0">Fijar X a 0</string>
<string name="menu_table_setXTo0_tt">Convierte los "indiferentes" a 0.</string> <string name="menu_table_setXTo0_tt">Convierte los "indiferentes" a 0.</string>
<string name="menu_table_setXTo1">Poner X a 1</string> <string name="menu_table_setXTo1">Poner X a 1</string>

View File

@ -1306,14 +1306,12 @@
<string name="menu_table_new_combinatorial">Combinatorial</string> <string name="menu_table_new_combinatorial">Combinatorial</string>
<string name="menu_table_new_sequential">Sequential</string> <string name="menu_table_new_sequential">Sequential</string>
<string name="menu_table_new_sequential_bidir">Sequential bidirectional</string> <string name="menu_table_new_sequential_bidir">Sequential bidirectional</string>
<string name="menu_table_columns">Columns</string>
<string name="menu_table_reorder_inputs">Reorder/Delete Input Variables</string> <string name="menu_table_reorder_inputs">Reorder/Delete Input Variables</string>
<string name="menu_table_reorder_outputs">Reorder/Delete Output Columns</string> <string name="menu_table_reorder_outputs">Reorder/Delete Output Columns</string>
<string name="menu_table_columnsAdd">Add Output Column</string> <string name="menu_table_columnsAdd">Add Output Column</string>
<string name="menu_table_columnsAdd_tt">Adds a new result column to the table.</string> <string name="menu_table_columnsAdd_tt">Adds a new result column to the table.</string>
<string name="menu_table_columnsAddVariable">Add Input Variable</string> <string name="menu_table_columnsAddVariable">Add Input Variable</string>
<string name="menu_table_columnsAddVariable_tt">Adds a new input variable to the table.</string> <string name="menu_table_columnsAddVariable_tt">Adds a new input variable to the table.</string>
<string name="menu_table_set">Set</string>
<string name="menu_table_setXTo0">Set X to 0</string> <string name="menu_table_setXTo0">Set X to 0</string>
<string name="menu_table_setXTo0_tt">Sets the Don't Cares to 0.</string> <string name="menu_table_setXTo0_tt">Sets the Don't Cares to 0.</string>
<string name="menu_table_setXTo1">Set X to 1</string> <string name="menu_table_setXTo1">Set X to 1</string>

View File

@ -1362,14 +1362,12 @@
<string name="menu_table_new_combinatorial">Combinacional</string> <string name="menu_table_new_combinatorial">Combinacional</string>
<string name="menu_table_new_sequential">Sequencial</string> <string name="menu_table_new_sequential">Sequencial</string>
<string name="menu_table_new_sequential_bidir">Sequencial bidirecional</string> <string name="menu_table_new_sequential_bidir">Sequencial bidirecional</string>
<string name="menu_table_columns">Colunas</string>
<string name="menu_table_reorder_inputs">Reordenar/remover variáveis de entrada</string> <string name="menu_table_reorder_inputs">Reordenar/remover variáveis de entrada</string>
<string name="menu_table_columnsAddVariable">Adicionar variável de entrada</string> <string name="menu_table_columnsAddVariable">Adicionar variável de entrada</string>
<string name="menu_table_columnsAddVariable_tt">Adicionar uma nova variável de entrada à tabela.</string> <string name="menu_table_columnsAddVariable_tt">Adicionar uma nova variável de entrada à tabela.</string>
<string name="menu_table_reorder_outputs">Reordenar/remover colunas de saída</string> <string name="menu_table_reorder_outputs">Reordenar/remover colunas de saída</string>
<string name="menu_table_columnsAdd">Adicionar coluna de saída</string> <string name="menu_table_columnsAdd">Adicionar coluna de saída</string>
<string name="menu_table_columnsAdd_tt">Adicionar uma nova coluna de resultado à tabela.</string> <string name="menu_table_columnsAdd_tt">Adicionar uma nova coluna de resultado à tabela.</string>
<string name="menu_table_set">Definir</string>
<string name="menu_table_setXTo0">Definir X como 0</string> <string name="menu_table_setXTo0">Definir X como 0</string>
<string name="menu_table_setXTo0_tt">Definir "don't cares" como 0.</string> <string name="menu_table_setXTo0_tt">Definir "don't cares" como 0.</string>
<string name="menu_table_setXTo1">Definir X como 1</string> <string name="menu_table_setXTo1">Definir X como 1</string>

View File

@ -1373,14 +1373,12 @@
<string name="menu_table_new_combinatorial">Combinatorial</string> <string name="menu_table_new_combinatorial">Combinatorial</string>
<string name="menu_table_new_sequential">Sequential</string> <string name="menu_table_new_sequential">Sequential</string>
<string name="menu_table_new_sequential_bidir">Sequential bidirectional</string> <string name="menu_table_new_sequential_bidir">Sequential bidirectional</string>
<string name="menu_table_columns">Columns</string>
<string name="menu_table_reorder_inputs">Reorder/Delete Input Variables</string> <string name="menu_table_reorder_inputs">Reorder/Delete Input Variables</string>
<string name="menu_table_columnsAddVariable">Add Input Variable</string> <string name="menu_table_columnsAddVariable">Add Input Variable</string>
<string name="menu_table_columnsAddVariable_tt">Adds a new input variable to the table.</string> <string name="menu_table_columnsAddVariable_tt">Adds a new input variable to the table.</string>
<string name="menu_table_reorder_outputs">Reorder/Delete Output Columns</string> <string name="menu_table_reorder_outputs">Reorder/Delete Output Columns</string>
<string name="menu_table_columnsAdd">Add Output Column</string> <string name="menu_table_columnsAdd">Add Output Column</string>
<string name="menu_table_columnsAdd_tt">Adds a new result column to the table.</string> <string name="menu_table_columnsAdd_tt">Adds a new result column to the table.</string>
<string name="menu_table_set">Set</string>
<string name="menu_table_setXTo0">Set X to 0</string> <string name="menu_table_setXTo0">Set X to 0</string>
<string name="menu_table_setXTo0_tt">Sets the Don't Cares to 0.</string> <string name="menu_table_setXTo0_tt">Sets the Don't Cares to 0.</string>
<string name="menu_table_setXTo1">Set X to 1</string> <string name="menu_table_setXTo1">Set X to 1</string>

View File

@ -115,6 +115,7 @@ public class ScreenShots {
.press("F1") .press("F1")
.add(new MainScreenShot("distribution/screenshot.png")) .add(new MainScreenShot("distribution/screenshot.png"))
.execute(); /**/ .execute(); /**/
new GuiTester() new GuiTester()
.press("F10") .press("F10")
.press("RIGHT", 4) .press("RIGHT", 4)
@ -157,7 +158,7 @@ public class ScreenShots {
.add(new GuiTester.CloseTopMost()) .add(new GuiTester.CloseTopMost())
.add(new GuiTester.CloseTopMost()) .add(new GuiTester.CloseTopMost())
.add(new GuiTester.CloseTopMost()) .add(new GuiTester.CloseTopMost())
.execute(); .execute();/**/
File trafficLight = new File(Resources.getRoot(), "../../main/fsm/trafficLightBlink.fsm"); File trafficLight = new File(Resources.getRoot(), "../../main/fsm/trafficLightBlink.fsm");
new GuiTester() new GuiTester()
@ -179,13 +180,14 @@ public class ScreenShots {
ReorderOutputs ro = new ReorderOutputs(tt); ReorderOutputs ro = new ReorderOutputs(tt);
ro.getItems().swap(3, 4); ro.getItems().swap(3, 4);
ro.getItems().swap(4, 5); ro.getItems().swap(4, 5);
tableDialog.setModel(new TruthTableTableModel(ro.reorder())); ro.reorder();
tableDialog.tableChanged();
})) }))
.delay(500) .delay(500)
.add(closeAllSolutionsDialog()) .add(closeAllSolutionsDialog())
.delay(500) .delay(500)
.press("F10") .press("F10")
.press("RIGHT", 4) .press("RIGHT", 3)
.press("DOWN", 2) .press("DOWN", 2)
.press("ENTER") .press("ENTER")
.delay(500) .delay(500)
@ -217,7 +219,7 @@ public class ScreenShots {
.add(new GuiTester.CloseTopMost()) .add(new GuiTester.CloseTopMost())
.add(new GuiTester.CloseTopMost()) .add(new GuiTester.CloseTopMost())
.add(new GuiTester.CloseTopMost()) .add(new GuiTester.CloseTopMost())
.execute();/**/ .execute();
} }
private static GuiTester.WindowCheck<Window> closeAllSolutionsDialog() { private static GuiTester.WindowCheck<Window> closeAllSolutionsDialog() {

View File

@ -21,8 +21,7 @@ public class LaTeXExpressionListenerTest extends TestCase {
.addVariable("A") .addVariable("A")
.addVariable("B") .addVariable("B")
.addResult("Y", new BoolTableBoolArray(new boolean[]{false, false, true, false})); .addResult("Y", new BoolTableBoolArray(new boolean[]{false, false, true, false}));
TruthTableTableModel model = new TruthTableTableModel(tt); LaTeXExpressionListener l = new LaTeXExpressionListener(tt);
LaTeXExpressionListener l = new LaTeXExpressionListener(model);
l.resultFound("Y", Operation.and(new Variable("A"), new Not(new Variable("B")))); l.resultFound("Y", Operation.and(new Variable("A"), new Not(new Variable("B"))));
l.close(); l.close();

View File

@ -21,9 +21,10 @@ public class TestReorderInputs extends TestCase {
col.set(i, i + 1); col.set(i, i + 1);
ReorderInputs reorderInputs = new ReorderInputs(t); TruthTable newTable = t.createDeepCopy();
ReorderInputs reorderInputs = new ReorderInputs(newTable);
reorderInputs.getItems().swap(1, 2); reorderInputs.getItems().swap(1, 2);
TruthTable newTable = reorderInputs.reorder(); reorderInputs.reorder();
ContextFiller cf = new ContextFiller(t.getVars()); ContextFiller cf = new ContextFiller(t.getVars());
@ -39,9 +40,10 @@ public class TestReorderInputs extends TestCase {
for (int i = 0; i < t.getRows(); i++) for (int i = 0; i < t.getRows(); i++)
col.set(i, i + 1); col.set(i, i + 1);
ReorderInputs reorderInputs = new ReorderInputs(t); TruthTable newTable = t.createDeepCopy();
ReorderInputs reorderInputs = new ReorderInputs(newTable);
reorderInputs.getItems().delete(2); reorderInputs.getItems().delete(2);
TruthTable newTable = reorderInputs.reorder(); reorderInputs.reorder();
assertEquals(2, newTable.getVars().size()); assertEquals(2, newTable.getVars().size());
assertEquals(1, newTable.getResultCount()); assertEquals(1, newTable.getResultCount());

View File

@ -19,9 +19,10 @@ public class TestReorderOutputs extends TestCase {
for (int i = 0; i < t.getRows(); i++) for (int i = 0; i < t.getRows(); i++)
col.set(i, i + 1); col.set(i, i + 1);
ReorderOutputs reorderOutputs = new ReorderOutputs(t); TruthTable newTable = t.createDeepCopy();
ReorderOutputs reorderOutputs = new ReorderOutputs(newTable);
reorderOutputs.getItems().delete(1); reorderOutputs.getItems().delete(1);
TruthTable newTable = reorderOutputs.reorder(); reorderOutputs.reorder();
assertEquals(3, newTable.getVars().size()); assertEquals(3, newTable.getVars().size());
assertEquals(1, newTable.getResultCount()); assertEquals(1, newTable.getResultCount());

View File

@ -332,7 +332,7 @@ public class TestInGUI extends TestCase {
new GuiTester() new GuiTester()
.use(create4BitCounterTruthTable) .use(create4BitCounterTruthTable)
.press("F10") .press("F10")
.press("RIGHT", 4) .press("RIGHT", 3)
.press("DOWN", 2) .press("DOWN", 2)
.press("ENTER") .press("ENTER")
.delay(500) .delay(500)
@ -424,7 +424,7 @@ public class TestInGUI extends TestCase {
})) }))
.delay(500) .delay(500)
.press("F10") .press("F10")
.press("RIGHT", 4) .press("RIGHT", 3)
.press("DOWN", 7) .press("DOWN", 7)
.press("RIGHT") .press("RIGHT")
.press("DOWN", 2) .press("DOWN", 2)
@ -947,7 +947,7 @@ public class TestInGUI extends TestCase {
assertEquals(4, model.getRowCount()); assertEquals(4, model.getRowCount());
for (int i = 0; i < 4; i++) { for (int i = 0; i < 4; i++) {
final Object valueAt = model.getValueAt(i, 1); final Object valueAt = model.getValueAt(i, 1);
assertEquals("0x0", valueAt.toString()); assertEquals("0", valueAt.toString());
} }
found(); found();
} }