From e33e9a148878fa168b47abe766879273e5c3ecdb Mon Sep 17 00:00:00 2001 From: hneemann Date: Sun, 22 Mar 2020 11:30:21 +0100 Subject: [PATCH] allows the user to specify ghdl options, see #421 --- .../de/neemann/digital/core/element/Key.java | 19 +++ .../de/neemann/digital/core/element/Keys.java | 17 ++- .../digital/core/extern/ApplicationGHDL.java | 10 +- .../neemann/digital/core/extern/Options.java | 88 ++++++++++++++ .../java/de/neemann/digital/gui/Settings.java | 3 + .../gui/components/AttributeDialog.java | 68 ++++++----- .../digital/gui/components/Editor.java | 3 +- .../digital/gui/components/EditorFactory.java | 16 +-- .../digital/gui/components/EditorPanel.java | 113 ++++++++++++++++++ src/main/resources/lang/lang_de.xml | 27 +++-- src/main/resources/lang/lang_en.xml | 24 +++- src/main/resources/lang/lang_es.xml | 44 +++---- src/main/resources/lang/lang_es_ref.xml | 44 +++---- src/main/resources/lang/lang_pt.xml | 44 +++---- src/main/resources/lang/lang_pt_ref.xml | 44 +++---- .../digital/core/extern/OptionsTest.java | 26 ++++ .../de/neemann/digital/lang/TestLang.java | 2 +- .../resources/dig/backtrack/AllComponents.dig | 2 +- 18 files changed, 443 insertions(+), 151 deletions(-) create mode 100644 src/main/java/de/neemann/digital/core/extern/Options.java create mode 100644 src/main/java/de/neemann/digital/gui/components/EditorPanel.java create mode 100644 src/test/java/de/neemann/digital/core/extern/OptionsTest.java diff --git a/src/main/java/de/neemann/digital/core/element/Key.java b/src/main/java/de/neemann/digital/core/element/Key.java index a6ee425de..015b9303c 100644 --- a/src/main/java/de/neemann/digital/core/element/Key.java +++ b/src/main/java/de/neemann/digital/core/element/Key.java @@ -23,6 +23,7 @@ public class Key { private CheckEnabled checkEnabled; private boolean isSecondary; private boolean requiresRestart = false; + private String panelId; // Both values are always null in digital. // Both are only used within a custom implemented component. @@ -234,6 +235,24 @@ public class Key { return requiresRestart; } + /** + * Moves this key to the panel with the given id + * + * @param panelId the panel id + * @return this for chained calls + */ + public Key setPanelId(String panelId) { + this.panelId = panelId; + return this; + } + + /** + * @return the panel id, null if no panel is set + */ + public String getPanelId() { + return panelId; + } + /** * A integer attribute. * Stores additional combo box values diff --git a/src/main/java/de/neemann/digital/core/element/Keys.java b/src/main/java/de/neemann/digital/core/element/Keys.java index 1ba46a87d..56327a47c 100644 --- a/src/main/java/de/neemann/digital/core/element/Keys.java +++ b/src/main/java/de/neemann/digital/core/element/Keys.java @@ -706,7 +706,22 @@ public final class Keys { * Path to ghdl */ public static final Key SETTINGS_GHDL_PATH - = new Key.KeyFile("ghdlPath", new File("ghdl")).setSecondary(); + = new Key.KeyFile("ghdlPath", new File("ghdl")).setPanelId("ghdl"); + /** + * The ghdl analysis options + */ + public static final Key SETTINGS_GHDL_OPT_ANALYSYS + = new Key<>("ghdlOptAnalysis", "-a --std=08 --ieee=synopsys").setPanelId("ghdl"); + /** + * The ghdl elaboration options + */ + public static final Key SETTINGS_GHDL_OPT_ELABORATION + = new Key<>("ghdlOptElaboration", "-e --std=08 --ieee=synopsys stdIOInterface").setPanelId("ghdl"); + /** + * The ghdl run options + */ + public static final Key SETTINGS_GHDL_OPT_RUN + = new Key<>("ghdlOptRun", "-r --std=08 --ieee=synopsys stdIOInterface --unbuffered").setPanelId("ghdl"); /** * Path to iverilog installation directory diff --git a/src/main/java/de/neemann/digital/core/extern/ApplicationGHDL.java b/src/main/java/de/neemann/digital/core/extern/ApplicationGHDL.java index 93991414a..7701d040e 100644 --- a/src/main/java/de/neemann/digital/core/extern/ApplicationGHDL.java +++ b/src/main/java/de/neemann/digital/core/extern/ApplicationGHDL.java @@ -28,9 +28,9 @@ public class ApplicationGHDL extends ApplicationVHDLStdIO { String ghdl = getGhdlPath().getPath(); file = createVHDLFile(label, code, inputs, outputs); - ProcessStarter.start(file.getParentFile(), ghdl, "-a", "--std=08", "--ieee=synopsys", file.getName()); - ProcessStarter.start(file.getParentFile(), ghdl, "-e", "--std=08", "--ieee=synopsys", "stdIOInterface"); - ProcessBuilder pb = new ProcessBuilder(ghdl, "-r", "--std=08", "--ieee=synopsys", "stdIOInterface", "--unbuffered").redirectErrorStream(true).directory(file.getParentFile()); + ProcessStarter.start(file.getParentFile(), new Options().add(ghdl).addSettings(Keys.SETTINGS_GHDL_OPT_ANALYSYS).add(file.getName()).getArray()); + ProcessStarter.start(file.getParentFile(), new Options().add(ghdl).addSettings(Keys.SETTINGS_GHDL_OPT_ELABORATION).getArray()); + ProcessBuilder pb = new ProcessBuilder(new Options().add(ghdl).addSettings(Keys.SETTINGS_GHDL_OPT_RUN).getList()).redirectErrorStream(true).directory(file.getParentFile()); return new GHDLProcessInterface(pb.start(), file.getParentFile()); } catch (IOException e) { if (file != null) @@ -63,8 +63,8 @@ public class ApplicationGHDL extends ApplicationVHDLStdIO { String ghdl = getGhdlPath().getPath(); file = createVHDLFile(label, code, inputs, outputs); - String m1 = ProcessStarter.start(file.getParentFile(), ghdl, "-a", "--ieee=synopsys", file.getName()); - String m2 = ProcessStarter.start(file.getParentFile(), ghdl, "-e", "--ieee=synopsys", "stdIOInterface"); + String m1 = ProcessStarter.start(file.getParentFile(), new Options().add(ghdl).addSettings(Keys.SETTINGS_GHDL_OPT_ANALYSYS).add(file.getName()).getArray()); + String m2 = ProcessStarter.start(file.getParentFile(), new Options().add(ghdl).addSettings(Keys.SETTINGS_GHDL_OPT_ELABORATION).getArray()); return ProcessStarter.joinStrings(m1, m2); } catch (IOException e) { if (ghdlNotFound(e)) diff --git a/src/main/java/de/neemann/digital/core/extern/Options.java b/src/main/java/de/neemann/digital/core/extern/Options.java new file mode 100644 index 000000000..1ae814b4e --- /dev/null +++ b/src/main/java/de/neemann/digital/core/extern/Options.java @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2020 Helmut Neemann. + * Use of this source code is governed by the GPL v3 license + * that can be found in the LICENSE file. + */ +package de.neemann.digital.core.extern; + +import de.neemann.digital.core.element.Key; +import de.neemann.digital.gui.Settings; + +import java.util.ArrayList; + +/** + * Used to split option strings to a option list + */ +public class Options { + + private final ArrayList list; + + /** + * Creates a new instance + */ + public Options() { + list = new ArrayList<>(); + } + + /** + * Adds a string from the settings + * + * @param key the key to use + * @return this for chained calls + */ + public Options addSettings(Key key) { + return addString(Settings.getInstance().get(key)); + } + + /** + * Adds a string containing many options + * + * @param options the string containing the options + * @return this for chained calls + */ + public Options addString(String options) { + StringBuilder opt = new StringBuilder(); + boolean inQuote = false; + for (int i = 0; i < options.length(); i++) { + char c = options.charAt(i); + if (c == '"') + inQuote = !inQuote; + + if (Character.isWhitespace(c) && !inQuote) { + if (opt.length() > 0) + list.add(opt.toString()); + opt.setLength(0); + } else { + opt.append(c); + } + } + if (opt.length() > 0) + list.add(opt.toString()); + return this; + } + + /** + * Adds a single raw option + * + * @param option the options to add + * @return this for chained calls + */ + public Options add(String option) { + list.add(option); + return this; + } + + /** + * @return the options as a list + */ + public ArrayList getList() { + return list; + } + + /** + * @return the options as an array + */ + public String[] getArray() { + return list.toArray(new String[0]); + } +} diff --git a/src/main/java/de/neemann/digital/gui/Settings.java b/src/main/java/de/neemann/digital/gui/Settings.java index b51eab3f3..ecb5f661d 100644 --- a/src/main/java/de/neemann/digital/gui/Settings.java +++ b/src/main/java/de/neemann/digital/gui/Settings.java @@ -52,6 +52,9 @@ public final class Settings extends SettingsBase { intList.add(Keys.SETTINGS_ATF1502_FITTER); intList.add(Keys.SETTINGS_ATMISP); intList.add(Keys.SETTINGS_GHDL_PATH); + intList.add(Keys.SETTINGS_GHDL_OPT_ANALYSYS); + intList.add(Keys.SETTINGS_GHDL_OPT_ELABORATION); + intList.add(Keys.SETTINGS_GHDL_OPT_RUN); intList.add(Keys.SETTINGS_IVERILOG_PATH); intList.add(Keys.SETTINGS_TOOLCHAIN_CONFIG); intList.add(Keys.SETTINGS_FONT_SCALING); diff --git a/src/main/java/de/neemann/digital/gui/components/AttributeDialog.java b/src/main/java/de/neemann/digital/gui/components/AttributeDialog.java index 6a9373cc6..131eb3da7 100644 --- a/src/main/java/de/neemann/digital/gui/components/AttributeDialog.java +++ b/src/main/java/de/neemann/digital/gui/components/AttributeDialog.java @@ -35,14 +35,13 @@ import java.util.List; */ public class AttributeDialog extends JDialog { private final java.util.List editors; - private final JPanel panel; private final Window parent; private final Point pos; private final ElementAttributes originalAttributes; private final ElementAttributes modifiedAttributes; private final JPanel buttonPanel; - private final ConstraintsBuilder constraints; private final AbstractAction okAction; + private final EditorPanel primaryPanel; private HashMap checkBoxes; private JComponent topMostTextComponent; private VisualElement visualElement; @@ -100,32 +99,32 @@ public class AttributeDialog extends JDialog { this.originalAttributes = elementAttributes; this.modifiedAttributes = new ElementAttributes(elementAttributes); - panel = new JPanel(new GridBagLayout()); + ArrayList panels = new ArrayList(); + primaryPanel = new EditorPanel(EditorPanel.PRIMARY); + panels.add(primaryPanel); editors = new ArrayList<>(); topMostTextComponent = null; - constraints = new ConstraintsBuilder().inset(3).fill(); - JPanel secondaryPanel = null; - ConstraintsBuilder secondaryConstraints = null; - - boolean enableTwoTabs = !addCheckBoxes && enableTwoTabs(list); - - if (enableTwoTabs) { - secondaryPanel = new JPanel(new GridBagLayout()); - secondaryConstraints = new ConstraintsBuilder().inset(3).fill(); + EditorPanel secondaryPanel = null; + if (!addCheckBoxes && enableTwoTabs(list)) { + secondaryPanel = new EditorPanel(EditorPanel.SECONDARY); + panels.add(secondaryPanel); } - boolean isSecondary = false; for (Key key : list) { Editor e = EditorFactory.INSTANCE.create(key, modifiedAttributes.get(key)); editors.add(new EditorHolder(e, key)); - if (key.isSecondary() && enableTwoTabs) { - e.addToPanel(secondaryPanel, key, modifiedAttributes, this, secondaryConstraints); - isSecondary = true; - } else - e.addToPanel(panel, key, modifiedAttributes, this, constraints); + EditorPanel panelToUse = primaryPanel; + if (key.isSecondary() && secondaryPanel != null) + panelToUse = secondaryPanel; + + if (key.getPanelId() != null) + panelToUse = findPanel(panels, key.getPanelId()); + + + e.addToPanel(panelToUse, key, modifiedAttributes, this); if (addCheckBoxes) { if (checkBoxes == null) @@ -134,14 +133,11 @@ public class AttributeDialog extends JDialog { checkBox.setSelected(true); checkBox.setToolTipText(Lang.get("msg_modifyThisAttribute")); checkBoxes.put(key, checkBox); - panel.add(checkBox, constraints.x(2)); + panelToUse.add(checkBox, cb -> cb.x(2)); checkBox.addChangeListener(event -> e.setEnabled(checkBox.isSelected())); } - if (key.isSecondary() && enableTwoTabs) - secondaryConstraints.nextRow(); - else - constraints.nextRow(); + panelToUse.nextRow(); if (topMostTextComponent == null && e instanceof EditorFactory.StringEditor) topMostTextComponent = ((EditorFactory.StringEditor) e).getTextComponent(); @@ -157,14 +153,14 @@ public class AttributeDialog extends JDialog { } - if (isSecondary) { + if (panels.size() == 1) { + getContentPane().add(primaryPanel.getScrollPane()); + } else { JTabbedPane tp = new JTabbedPane(JTabbedPane.TOP); - tp.addTab(Lang.get("attr_primary"), new JScrollPane(panel)); - tp.addTab(Lang.get("attr_secondary"), new JScrollPane(secondaryPanel)); + for (EditorPanel ep : panels) + tp.addTab(Lang.get(ep.getLangKey()), ep.getScrollPane()); getContentPane().add(tp); - } else - getContentPane().add(new JScrollPane(panel)); - + } okAction = new AbstractAction(Lang.get("ok")) { @Override @@ -221,6 +217,16 @@ public class AttributeDialog extends JDialog { JComponent.WHEN_IN_FOCUSED_WINDOW); } + private EditorPanel findPanel(ArrayList panels, String panelId) { + for (EditorPanel p : panels) + if (panelId.equals(p.getPanelId())) + return p; + + EditorPanel p = new EditorPanel(panelId); + panels.add(p); + return p; + } + /** * Sets the dialogs title * @@ -277,9 +283,7 @@ public class AttributeDialog extends JDialog { * @return this for chained calls */ AttributeDialog addButton(String label, ToolTipAction action) { - panel.add(new JLabel(label), constraints); - panel.add(action.createJButton(), constraints.x(1)); - constraints.nextRow(); + primaryPanel.addButton(label, action); return this; } diff --git a/src/main/java/de/neemann/digital/gui/components/Editor.java b/src/main/java/de/neemann/digital/gui/components/Editor.java index 4b690b600..de6932ead 100644 --- a/src/main/java/de/neemann/digital/gui/components/Editor.java +++ b/src/main/java/de/neemann/digital/gui/components/Editor.java @@ -36,9 +36,8 @@ public interface Editor { * @param key the key which is to edit * @param elementAttributes the attributes * @param dialog the containing dialog - * @param constraints the constraints used to place the components in the panel */ - void addToPanel(JPanel panel, Key key, ElementAttributes elementAttributes, AttributeDialog dialog, ConstraintsBuilder constraints); + void addToPanel(EditorPanel panel, Key key, ElementAttributes elementAttributes, AttributeDialog dialog); /** * Used to enable/disable the component. diff --git a/src/main/java/de/neemann/digital/gui/components/EditorFactory.java b/src/main/java/de/neemann/digital/gui/components/EditorFactory.java index 2270ac50a..f044c02f1 100644 --- a/src/main/java/de/neemann/digital/gui/components/EditorFactory.java +++ b/src/main/java/de/neemann/digital/gui/components/EditorFactory.java @@ -122,7 +122,7 @@ public final class EditorFactory { private JLabel label; @Override - public void addToPanel(JPanel panel, Key key, ElementAttributes elementAttributes, AttributeDialog attributeDialog, ConstraintsBuilder constraints) { + public void addToPanel(EditorPanel panel, Key key, ElementAttributes elementAttributes, AttributeDialog attributeDialog) { this.attributeDialog = attributeDialog; label = new JLabel(key.getName() + ": "); final String description = new LineBreaker().toHTML().breakLines(key.getDescription()); @@ -130,12 +130,12 @@ public final class EditorFactory { component = getComponent(elementAttributes); component.setToolTipText(description); if (labelAtTop) { - panel.add(label, constraints.width(2)); - constraints.nextRow(); - panel.add(component, constraints.width(2).dynamicHeight()); + panel.add(label, cb -> cb.width(2)); + panel.nextRow(); + panel.add(component, cb -> cb.width(2).dynamicHeight()); } else { - panel.add(label, constraints); - panel.add(component, constraints.x(1).dynamicWidth()); + panel.add(label); + panel.add(component, cb -> cb.x(1).dynamicWidth()); } } @@ -466,8 +466,8 @@ public final class EditorFactory { } @Override - public void addToPanel(JPanel panel, Key key, ElementAttributes elementAttributes, AttributeDialog attributeDialog, ConstraintsBuilder constraints) { - panel.add(bool, constraints.width(2)); + public void addToPanel(EditorPanel panel, Key key, ElementAttributes elementAttributes, AttributeDialog attributeDialog) { + panel.add(bool, cb -> cb.width(2)); } @Override diff --git a/src/main/java/de/neemann/digital/gui/components/EditorPanel.java b/src/main/java/de/neemann/digital/gui/components/EditorPanel.java new file mode 100644 index 000000000..7d1ac71a9 --- /dev/null +++ b/src/main/java/de/neemann/digital/gui/components/EditorPanel.java @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2020 Helmut Neemann. + * Use of this source code is governed by the GPL v3 license + * that can be found in the LICENSE file. + */ +package de.neemann.digital.gui.components; + +import de.neemann.gui.ToolTipAction; + +import javax.swing.*; +import java.awt.*; + +/** + * Panel used in the editor + */ +public class EditorPanel { + /** + * The Id for the primary panel + */ + public static final String PRIMARY = "primary"; + /** + * The Id for the secondary panel + */ + public static final String SECONDARY = "secondary"; + + private final JPanel panel; + private final ConstraintsBuilder constraints; + private final String id; + + /** + * Creates a new instance + * + * @param id the panels id, used to identify the panel and as part of the language key + */ + public EditorPanel(String id) { + this.id = id; + panel = new JPanel(new GridBagLayout()); + constraints = new ConstraintsBuilder().inset(3).fill(); + } + + /** + * Moves to the next row + */ + public void nextRow() { + constraints.nextRow(); + } + + /** + * @return this panel wrapped with a scroll pane + */ + public Component getScrollPane() { + return new JScrollPane(panel); + } + + /** + * @return the language key + */ + public String getLangKey() { + return "attr_panel_" + id; + } + + /** + * Adds a component using the default constrains + * + * @param component the components to add + */ + public void add(JComponent component) { + panel.add(component, constraints); + } + + /** + * Adds a component + * + * @param component the components to add + * @param c allows to modify the constraints + */ + public void add(JComponent component, Constraints c) { + panel.add(component, c.create(constraints)); + } + + /** + * Adds a button + * + * @param label the label to use + * @param action the action to use + */ + public void addButton(String label, ToolTipAction action) { + panel.add(new JLabel(label), constraints); + panel.add(action.createJButton(), constraints.x(1)); + constraints.nextRow(); + } + + /** + * @return the panels id + */ + public String getPanelId() { + return id; + } + + /** + * The interface used to modify the constraints + */ + interface Constraints { + /** + * Allows to modify the constraints + * + * @param cb the default constraints + * @return the modified constraints + */ + ConstraintsBuilder create(ConstraintsBuilder cb); + } +} + diff --git a/src/main/resources/lang/lang_de.xml b/src/main/resources/lang/lang_de.xml index 080d90c9c..6ed9cf6b0 100644 --- a/src/main/resources/lang/lang_de.xml +++ b/src/main/resources/lang/lang_de.xml @@ -19,8 +19,8 @@ HighZ Oktal Binär - Standard - Erweitert + Standard + Erweitert Verwerfen Bearbeiten Weiter bearbeiten @@ -1313,18 +1313,31 @@ Sind evtl. die Namen der Variablen nicht eindeutig? Die Eingänge eines 8-Bit Addierers könnten also mit "a:8,b:8,c_in" beschrieben werden. Ausgänge Die Ausgänge des externen Prozesses. Es handelt sich um eine kommaseparierte - Liste mit Signalnamen. Bei jedem Signalnamen kann, mit einem Doppelpunkt getrennt, eine Bitanzahl angegeben werden. - Die Ausgänge eines 8-Bit Addierers könnten also mit "s:8,c_out" beschrieben werden. + Liste mit Signalnamen. Bei jedem Signalnamen kann, mit einem Doppelpunkt getrennt, eine Bitanzahl angegeben + werden. + Die Ausgänge eines 8-Bit Addierers könnten also mit "s:8,c_out" beschrieben werden. + Programmcode Der Programmcode welcher ausgeführt werden soll. + GHDL GHDL Pfad der ausführbaren ghdl-Datei. Nur wichtig, wenn ghdl zur Interpretation von - VHDL-Code verwendet werden soll. + VHDL-Code verwendet werden soll. + + Analyse + Optionen, die für die Analyse durch GHDL verwendet werden. + Elaboration + Optionen, die für die Elaboration durch GHDL verwendet werden. + Start + Optionen, die für den Start durch GHDL verwendet werden. IVerilog Pfad zum Icarus-Verilog-Installationsordner. Nur notwendig, wenn Sie iverilog - verwenden möchten, um mit Verilog definierte Komponenten zu simulieren. + verwenden möchten, um mit Verilog definierte Komponenten zu simulieren. + Maximalwert - Wird hier eine Null eingetragen, wird der maximal mögliche Wert verwendet (Alle Bits sind Eins). + Wird hier eine Null eingetragen, wird der maximal mögliche Wert verwendet (Alle Bits + sind Eins). + Ausgabe ist High Der Vorgabewert des DIP-Schalters, wenn die Simulation gestartet wird. diff --git a/src/main/resources/lang/lang_en.xml b/src/main/resources/lang/lang_en.xml index 9b72d8b84..4ccae75a2 100644 --- a/src/main/resources/lang/lang_en.xml +++ b/src/main/resources/lang/lang_en.xml @@ -19,8 +19,8 @@ HighZ Octal Binary - Basic - Advanced + Basic + Advanced Discard Changes Edit Continue editing @@ -1289,15 +1289,27 @@ Outputs The outputs of the external process. It is a comma-separated list of signal names. For each signal name, with a colon separated, a number of bits - can be specified. The outputs of an 8-bit adder could thus be described as "s:8,c_out". + can be specified. The outputs of an 8-bit adder could thus be described as "s:8,c_out". + Programcode The programm code to be executed by the external application. + GHDL GHDL Path to the executable ghdl file. Only necessary if you want to use ghdl to simulate - components defined with vhdl. + components defined with vhdl. + + Analysis + Options used for the GHDL analysis. + Elaboration + Options used for the GHDL elaboration. + Run + Options used for the start of GHDL. + IVerilog - Path to the Icarus verilog installation folder. Only necessary if you want to use iverilog to simulate - components defined with verilog. + Path to the Icarus verilog installation folder. Only necessary if you want to use + iverilog to simulate + components defined with verilog. + Maximum Value If a zero is entered, the maximum possible value is used (all bits are one). diff --git a/src/main/resources/lang/lang_es.xml b/src/main/resources/lang/lang_es.xml index 9fb0e2fee..51ba03cb3 100644 --- a/src/main/resources/lang/lang_es.xml +++ b/src/main/resources/lang/lang_es.xml @@ -9,28 +9,28 @@ máximo Propiedades Abrir circuito - Incluir circuito: - Abre el circuito en una ventana nueva - Ayuda - Muestra una pequeña descripción de este elemento - HEX - Decimal - ASCII - Alta impedancia - Octal - Binario - Básico - Avanzado - Descartar cambios - Editar - Seguir editando - Cargar - Recargar - Recargar último archivo HEX - Guardar - Guardar como archivo HEX - Crear - Crear un circuito en otra ventana + Incluir circuito: + Abre el circuito en una ventana nueva + Ayuda + Muestra una pequeña descripción de este elemento + HEX + Decimal + ASCII + Alta impedancia + Octal + Binario + Básico + Avanzado + Descartar cambios + Editar + Seguir editando + Cargar + Recargar + Recargar último archivo HEX + Guardar + Guardar como archivo HEX + Crear + Crear un circuito en otra ventana Editar por separado Abre el diálogo como no modal Navegador diff --git a/src/main/resources/lang/lang_es_ref.xml b/src/main/resources/lang/lang_es_ref.xml index 2e174c9b0..c4023657c 100644 --- a/src/main/resources/lang/lang_es_ref.xml +++ b/src/main/resources/lang/lang_es_ref.xml @@ -9,28 +9,28 @@ maximum Attributes Open Circuit - Included circuit: - Opens the circuit in a new window. - Help - Shows a short description of this element. - Hex - Decimal - Ascii - HighZ - Octal - Binary - Basic - Advanced - Discard Changes - Edit - Continue editing - Load - Reload - Reload last hex file - Save - Save as HEX file. - Create - Create a circuit in a separate window + Included circuit: + Opens the circuit in a new window. + Help + Shows a short description of this element. + Hex + Decimal + Ascii + HighZ + Octal + Binary + Basic + Advanced + Discard Changes + Edit + Continue editing + Load + Reload + Reload last hex file + Save + Save as HEX file. + Create + Create a circuit in a separate window Edit detached Opens the dialog as a non modal dialog Browser diff --git a/src/main/resources/lang/lang_pt.xml b/src/main/resources/lang/lang_pt.xml index ea4f549a4..1af3fffc9 100644 --- a/src/main/resources/lang/lang_pt.xml +++ b/src/main/resources/lang/lang_pt.xml @@ -9,28 +9,28 @@ A seguir descrevem-se as configurações disponíveis no simulador. Atributos Abrir circuito - Incluir circuito: - Abrir circuito em um nova janela. - Ajuda - Mostrar uma breve descrição desse elemento. - Hexadecimal - Decimal - ASCII - Alta impedância - Octal - Binário - Básico - Avançado - Descartar alterações - Editar - Continuar edição - Carregar - Recarregar - Recarregar último arquivo em hexadecimal - Salvar - Salvar como arquivo HEX. - Criar - Criar circuito em janela separada + Incluir circuito: + Abrir circuito em um nova janela. + Ajuda + Mostrar uma breve descrição desse elemento. + Hexadecimal + Decimal + ASCII + Alta impedância + Octal + Binário + Básico + Avançado + Descartar alterações + Editar + Continuar edição + Carregar + Recarregar + Recarregar último arquivo em hexadecimal + Salvar + Salvar como arquivo HEX. + Criar + Criar circuito em janela separada Editar em separado Abrir diálogo como não modal Navegador diff --git a/src/main/resources/lang/lang_pt_ref.xml b/src/main/resources/lang/lang_pt_ref.xml index 3cda66cd3..942d89c94 100644 --- a/src/main/resources/lang/lang_pt_ref.xml +++ b/src/main/resources/lang/lang_pt_ref.xml @@ -10,28 +10,28 @@ The following describes the available settings of the simulator. Attributes Open Circuit - Included circuit: - Opens the circuit in a new window. - Help - Shows a short description of this element. - Hex - Decimal - Ascii - HighZ - Octal - Binary - Basic - Advanced - Discard Changes - Edit - Continue editing - Load - Reload - Reload last hex file - Save - Save as HEX file. - Create - Create a circuit in a separate window + Included circuit: + Opens the circuit in a new window. + Help + Shows a short description of this element. + Hex + Decimal + Ascii + HighZ + Octal + Binary + Basic + Advanced + Discard Changes + Edit + Continue editing + Load + Reload + Reload last hex file + Save + Save as HEX file. + Create + Create a circuit in a separate window Edit detached Opens the dialog as a non modal dialog Browser diff --git a/src/test/java/de/neemann/digital/core/extern/OptionsTest.java b/src/test/java/de/neemann/digital/core/extern/OptionsTest.java new file mode 100644 index 000000000..29b0685c4 --- /dev/null +++ b/src/test/java/de/neemann/digital/core/extern/OptionsTest.java @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2020 Helmut Neemann. + * Use of this source code is governed by the GPL v3 license + * that can be found in the LICENSE file. + */ +package de.neemann.digital.core.extern; + +import junit.framework.TestCase; + +import java.util.ArrayList; + +public class OptionsTest extends TestCase { + + public void testSimple() { + check(new Options().addString("-a -e -u=zzz"), "-a", "-e", "-u=zzz"); + check(new Options().addString("-a -e -u=\"Hello World\""), "-a", "-e", "-u=\"Hello World\""); + check(new Options().addString("-a -u=\"Hello World\" -e"), "-a", "-u=\"Hello World\"", "-e"); + } + + private void check(Options options, String... opt) { + ArrayList l = options.getList(); + assertEquals(opt.length, l.size()); + for (int i = 0; i < opt.length; i++) + assertEquals(opt[i], l.get(i)); + } +} \ No newline at end of file diff --git a/src/test/java/de/neemann/digital/lang/TestLang.java b/src/test/java/de/neemann/digital/lang/TestLang.java index 9a2ebe0cd..36331be2d 100644 --- a/src/test/java/de/neemann/digital/lang/TestLang.java +++ b/src/test/java/de/neemann/digital/lang/TestLang.java @@ -68,7 +68,7 @@ public class TestLang extends TestCase { StringBuilder sb = new StringBuilder(); for (String key : map.keySet()) { if (!keys.contains(key)) { - if (!(key.startsWith("key_") || key.startsWith("elem_") || key.startsWith("tutorial"))) { + if (!(key.startsWith("key_") || key.startsWith("elem_") || key.startsWith("attr_panel_") || key.startsWith("tutorial"))) { if (sb.length() > 0) sb.append(", "); sb.append('"').append(key).append('"'); diff --git a/src/test/resources/dig/backtrack/AllComponents.dig b/src/test/resources/dig/backtrack/AllComponents.dig index 3c8f6a624..c21b4c88f 100644 --- a/src/test/resources/dig/backtrack/AllComponents.dig +++ b/src/test/resources/dig/backtrack/AllComponents.dig @@ -894,7 +894,7 @@ - +