/**
* 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;
}
}