/******************************************************************************* * This file is part of logisim-evolution. * * logisim-evolution is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * logisim-evolution is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with logisim-evolution. If not, see <http://www.gnu.org/licenses/>. * * Original code by Carl Burch (http://www.cburch.com), 2011. * Subsequent modifications by : * + Haute École Spécialisée Bernoise * http://www.bfh.ch * + Haute École du paysage, d'ingénierie et d'architecture de Genève * http://hepia.hesge.ch/ * + Haute École d'Ingénierie et de Gestion du Canton de Vaud * http://www.heig-vd.ch/ * The project is currently maintained by : * + REDS Institute - HEIG-VD * Yverdon-les-Bains, Switzerland * http://reds.heig-vd.ch *******************************************************************************/ package com.cburch.logisim.analyze.gui; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.List; import javax.swing.JButton; import javax.swing.JCheckBox; import javax.swing.JComboBox; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JTextField; import com.cburch.logisim.analyze.model.AnalyzerModel; import com.cburch.logisim.analyze.model.Expression; import com.cburch.logisim.analyze.model.VariableList; import com.cburch.logisim.circuit.Circuit; import com.cburch.logisim.circuit.CircuitMutation; import com.cburch.logisim.file.LogisimFileActions; import com.cburch.logisim.proj.Project; import com.cburch.logisim.proj.Projects; import com.cburch.logisim.std.gates.CircuitBuilder; import com.cburch.logisim.util.StringUtil; class BuildCircuitButton extends JButton { private class DialogPanel extends JPanel { private static final long serialVersionUID = 1L; private JLabel projectLabel = new JLabel(); private JComboBox<Object> project; private JLabel nameLabel = new JLabel(); private JTextField name = new JTextField(10); private JCheckBox twoInputs = new JCheckBox(); private JCheckBox nands = new JCheckBox(); DialogPanel() { List<Project> projects = Projects.getOpenProjects(); Object[] options = new Object[projects.size()]; Object initialSelection = null; for (int i = 0; i < options.length; i++) { Project proj = projects.get(i); options[i] = new ProjectItem(proj); if (proj == model.getCurrentProject()) { initialSelection = options[i]; } } project = new JComboBox<>(options); if (options.length == 1) { project.setSelectedItem(options[0]); project.setEnabled(false); } else if (initialSelection != null) { project.setSelectedItem(initialSelection); } Circuit defaultCircuit = model.getCurrentCircuit(); if (defaultCircuit != null) { name.setText(defaultCircuit.getName()); name.selectAll(); } VariableList outputs = model.getOutputs(); boolean enableNands = true; for (int i = 0; i < outputs.size(); i++) { String output = outputs.get(i); Expression expr = model.getOutputExpressions().getExpression( output); if (expr != null && expr.containsXor()) { enableNands = false; break; } } nands.setEnabled(enableNands); GridBagLayout gb = new GridBagLayout(); GridBagConstraints gc = new GridBagConstraints(); setLayout(gb); gc.anchor = GridBagConstraints.LINE_START; gc.fill = GridBagConstraints.NONE; gc.gridx = 0; gc.gridy = 0; gb.setConstraints(projectLabel, gc); add(projectLabel); gc.gridx = 1; gb.setConstraints(project, gc); add(project); gc.gridy++; gc.gridx = 0; gb.setConstraints(nameLabel, gc); add(nameLabel); gc.gridx = 1; gb.setConstraints(name, gc); add(name); gc.gridy++; gb.setConstraints(twoInputs, gc); add(twoInputs); gc.gridy++; gb.setConstraints(nands, gc); add(nands); projectLabel.setText(Strings.get("buildProjectLabel")); nameLabel.setText(Strings.get("buildNameLabel")); twoInputs.setText(Strings.get("buildTwoInputsLabel")); nands.setText(Strings.get("buildNandsLabel")); } } private class MyListener implements ActionListener { public void actionPerformed(ActionEvent event) { Project dest = null; String name = null; boolean twoInputs = false; boolean useNands = false; boolean replace = false; boolean ok = false; while (!ok) { DialogPanel dlog = new DialogPanel(); int action = JOptionPane.showConfirmDialog(parent, dlog, Strings.get("buildDialogTitle"), JOptionPane.OK_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE); if (action != JOptionPane.OK_OPTION) return; ProjectItem projectItem = (ProjectItem) dlog.project .getSelectedItem(); if (projectItem == null) { JOptionPane.showMessageDialog(parent, Strings.get("buildNeedProjectError"), Strings.get("buildDialogErrorTitle"), JOptionPane.ERROR_MESSAGE); continue; } dest = projectItem.project; name = dlog.name.getText().trim(); if (name.equals("")) { JOptionPane.showMessageDialog(parent, Strings.get("buildNeedCircuitError"), Strings.get("buildDialogErrorTitle"), JOptionPane.ERROR_MESSAGE); continue; } if (dest.getLogisimFile().getCircuit(name) != null) { int choice = JOptionPane.showConfirmDialog(parent, StringUtil.format( Strings.get("buildConfirmReplaceMessage"), name), Strings .get("buildConfirmReplaceTitle"), JOptionPane.YES_NO_OPTION); if (choice != JOptionPane.YES_OPTION) { continue; } replace = true; } twoInputs = dlog.twoInputs.isSelected(); useNands = dlog.nands.isSelected(); ok = true; } performAction(dest, name, replace, twoInputs, useNands); } } private static class ProjectItem { Project project; ProjectItem(Project project) { this.project = project; } @Override public String toString() { return project.getLogisimFile().getDisplayName(); } } private static final long serialVersionUID = 1L; private MyListener myListener = new MyListener(); private JFrame parent; private AnalyzerModel model; BuildCircuitButton(JFrame parent, AnalyzerModel model) { this.parent = parent; this.model = model; addActionListener(myListener); } void localeChanged() { setText(Strings.get("buildCircuitButton")); } private void performAction(Project dest, String name, boolean replace, final boolean twoInputs, final boolean useNands) { if (replace) { final Circuit circuit = dest.getLogisimFile().getCircuit(name); if (circuit == null) { JOptionPane.showMessageDialog(parent, "Internal error prevents replacing circuit.", "Internal Error", JOptionPane.ERROR_MESSAGE); return; } CircuitMutation xn = CircuitBuilder.build(circuit, model, twoInputs, useNands); dest.doAction(xn.toAction(Strings.getter("replaceCircuitAction"))); } else { // add the circuit Circuit circuit = new Circuit(name, dest.getLogisimFile(),dest); CircuitMutation xn = CircuitBuilder.build(circuit, model, twoInputs, useNands); xn.execute(); dest.doAction(LogisimFileActions.addCircuit(circuit)); dest.setCurrentCircuit(circuit); } } }