/** * Configure the controller settings. */ /* Copywrite 2016 Will Winder This file is part of Universal Gcode Sender (UGS). UGS 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. UGS 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 UGS. If not, see <http://www.gnu.org/licenses/>. */ package com.willwinder.universalgcodesender.uielements.panels; import com.google.gson.JsonObject; import com.willwinder.universalgcodesender.gcode.util.CommandProcessorLoader; import com.willwinder.universalgcodesender.i18n.Localization; import com.willwinder.universalgcodesender.uielements.IChanged; import com.willwinder.universalgcodesender.uielements.components.ProcessorConfigCheckbox; import com.willwinder.universalgcodesender.uielements.helpers.AbstractUGSSettings; import com.willwinder.universalgcodesender.utils.ControllerSettings.ProcessorConfig; import com.willwinder.universalgcodesender.utils.ControllerSettings.ProcessorConfigGroups; import com.willwinder.universalgcodesender.utils.FirmwareUtils; import com.willwinder.universalgcodesender.utils.FirmwareUtils.ConfigTuple; import com.willwinder.universalgcodesender.utils.GUIHelpers; import com.willwinder.universalgcodesender.utils.Settings; import java.io.IOException; import java.util.Arrays; import java.util.Map; import java.util.logging.Level; import java.util.logging.Logger; import javax.swing.JButton; import javax.swing.JComboBox; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTable; import javax.swing.SwingUtilities; import javax.swing.event.TableModelEvent; import javax.swing.table.DefaultTableModel; import javax.swing.table.TableCellEditor; import net.miginfocom.swing.MigLayout; import org.apache.commons.lang3.StringUtils; /** * * @author wwinder */ public class ControllerProcessorSettingsPanel extends AbstractUGSSettings { private static Logger logger = Logger.getLogger(ControllerProcessorSettingsPanel.class.getName()); private final Map<String,ConfigTuple> configFiles; JComboBox controllerConfigs; final JTable customRemoverTable; final JButton add = new JButton(Localization.getString("settings.processors.add")); final JButton remove = new JButton(Localization.getString("settings.processors.remove")); private boolean updatingCombo = false; public ControllerProcessorSettingsPanel(Settings settings, IChanged changer, Map<String,ConfigTuple> configFiles) { super(settings, changer); this.configFiles = configFiles; this.controllerConfigs = new JComboBox(configFiles.keySet().toArray()); this.customRemoverTable = initCustomRemoverTable(new JTable()); super.updateComponents(); controllerConfigs.addActionListener(e -> { if (!updatingCombo) super.updateComponents();}); add.addActionListener(e -> this.addNewPatternRemover()); remove.addActionListener(e -> this.removeSelectedPatternRemover()); } public ControllerProcessorSettingsPanel(Settings settings, Map<String,ConfigTuple> configFiles) { this(settings, null, configFiles); } private void addNewPatternRemover() { DefaultTableModel model = (DefaultTableModel) this.customRemoverTable.getModel(); model.addRow(new Object[]{true, ""}); } private void removeSelectedPatternRemover() { int[] rows = customRemoverTable.getSelectedRows(); Arrays.sort(rows); DefaultTableModel model = (DefaultTableModel) this.customRemoverTable.getModel(); for (int i = rows.length; i > 0; i--) { int row = rows[i-1]; model.removeRow(row); } } @Override public void save() { // In case there are in-progress changes. TableCellEditor editor = customRemoverTable.getCellEditor(); if (editor != null) { editor.stopCellEditing(); } ConfigTuple ct = configFiles.get(controllerConfigs.getSelectedItem()); ct.loader.getProcessorConfigs().Custom.clear(); // Roll up the pattern processors. DefaultTableModel model = (DefaultTableModel) this.customRemoverTable.getModel(); for (int i = 0; i < customRemoverTable.getRowCount(); i++) { JsonObject args = new JsonObject(); String pattern = model.getValueAt(i, 1).toString(); if (!StringUtils.isEmpty(pattern)) { args.addProperty("pattern", pattern); ProcessorConfig pc = new ProcessorConfig( "PatternRemover", (Boolean) model.getValueAt(i, 0), true, args); ct.loader.getProcessorConfigs().Custom.add(pc); } } try { FirmwareUtils.save(ct.file, ct.loader); } catch (IOException ex) { GUIHelpers.displayErrorDialog("Problem saving controller config: " + ex.getMessage()); logger.log(Level.SEVERE, null, ex); } } @Override synchronized public void restoreDefaults() throws Exception { FirmwareUtils.restoreDefaults((String)controllerConfigs.getSelectedItem()); updatingCombo = true; String selected = (String) controllerConfigs.getSelectedItem(); this.controllerConfigs.removeAllItems(); for (String item : configFiles.keySet()) { this.controllerConfigs.addItem(item); } controllerConfigs.setSelectedItem(selected); updatingCombo = false; updateComponentsInternal(settings); } @Override public String getHelpMessage() { return Localization.getString("settings.processors.help"); } /** * ------------------------------ * | [ controller ] | * | [ ] front processor 1 | * | [ ] front processor 2 | * | [ ] end processor 1 | * | [ ] end processor 2 | * * | [+] [-] | * | ________________________ | * | | Enabled | Pattern | | * | | [y] | T\d+ | | * | | [n] | M30 | | * | ------------------------ | * |____________________________| */ @Override protected void updateComponentsInternal(Settings s) { this.removeAll(); initCustomRemoverTable(customRemoverTable); setLayout(new MigLayout("wrap 1, inset 5", "fill")); super.addIgnoreChanges(controllerConfigs); ConfigTuple ct = configFiles.get(controllerConfigs.getSelectedItem()); ProcessorConfigGroups pcg = ct.loader.getProcessorConfigs(); System.out.println(ct.file); for (ProcessorConfig pc : pcg.Front) { add(new ProcessorConfigCheckbox(pc, CommandProcessorLoader.getHelpForConfig(pc))); } for (ProcessorConfig pc : pcg.End) { add(new ProcessorConfigCheckbox(pc, CommandProcessorLoader.getHelpForConfig(pc))); } JPanel buttonPanel = new JPanel(); buttonPanel.setLayout(new MigLayout("wrap 3", "grow, fill", "")); add(buttonPanel, add); add(buttonPanel, new JLabel()); add(buttonPanel, remove); addIgnoreChanges(buttonPanel); DefaultTableModel model = (DefaultTableModel) this.customRemoverTable.getModel(); for (ProcessorConfig pc : pcg.Custom) { Boolean enabled = pc.enabled; String pattern = ""; if (pc.args != null && !pc.args.get("pattern").isJsonNull()) { pattern = pc.args.get("pattern").getAsString(); } model.addRow(new Object[]{enabled, pattern}); } addIgnoreChanges(new JScrollPane(customRemoverTable), "height 100"); SwingUtilities.updateComponentTreeUI(this); } private JTable initCustomRemoverTable(JTable table) { final String[] columnNames = { Localization.getString("settings.processors.enabled"), Localization.getString("PatternRemover") }; final Class[] columnTypes = { Boolean.class, String.class }; DefaultTableModel model = new DefaultTableModel(null, columnNames) { @Override public Class<?> getColumnClass(int idx) { return columnTypes[idx]; } }; table.setModel(model); table.getTableHeader().setReorderingAllowed(false); table.getModel().addTableModelListener((TableModelEvent e) -> change()); return table; } }