/**
* Static helper class for executing custom macros.
*/
package com.willwinder.universalgcodesender;
import com.willwinder.universalgcodesender.i18n.Localization;
import com.willwinder.universalgcodesender.model.BackendAPI;
import com.willwinder.universalgcodesender.pendantui.SystemStateBean;
import com.willwinder.universalgcodesender.utils.GUIHelpers;
import java.awt.EventQueue;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;
import net.miginfocom.swing.MigLayout;
/**
*
* @author wwinder
*/
public class MacroHelper {
/**
* Process and send a custom gcode string.
*
* Interactive substitutions can be made with special characters:
* %machine_x% - The machine X location
* %machine_y% - The machine Y location
* %machine_z% - The machine Z location
* %work_x% - The work X location
* %work_y% - The work Y location
* %work_z% - The work Z location
* %prompt|name% - Prompt the user for a value named 'name'.
*
* @param str
* @param backend
*/
public static void executeCustomGcode(final String str, BackendAPI backend) {
if (str == null) {
return;
}
String command = MacroHelper.substituteValues(str, backend);
command = command.replaceAll("(\\r\\n|\\n\\r|\\r|\\n)", "");
final String[] parts = command.split(";");
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
for (String cmd : parts) {
backend.sendGcodeCommand(cmd);
}
} catch (Exception ex) {
GUIHelpers.displayErrorDialog(ex.getMessage());
}
}
});
}
/**
* Interactive substitutions can be made with special characters:
* {machine_x} - The machine X location
* {machine_y} - The machine Y location
* {machine_z} - The machine Z location
* {work_x} - The work X location
* {work_y} - The work Y location
* {work_z} - The work Z location
* {prompt|name} - Prompt the user for a value named 'name'.
*
* @param str
* @param backend
* @return
*/
static private final Pattern PROMPT_REGEX = Pattern.compile("\\{prompt\\|([^\\}]+)\\}");
static private final Pattern MACHINE_X = Pattern.compile("\\{machine_x\\}");
static private final Pattern MACHINE_Y = Pattern.compile("\\{machine_y\\}");
static private final Pattern MACHINE_Z = Pattern.compile("\\{machine_z\\}");
static private final Pattern WORK_X = Pattern.compile("\\{work_x\\}");
static private final Pattern WORK_Y = Pattern.compile("\\{work_y\\}");
static private final Pattern WORK_Z = Pattern.compile("\\{work_z\\}");
protected static String substituteValues(String str, BackendAPI backend) {
SystemStateBean bean = new SystemStateBean();
backend.updateSystemState(bean);
// Early exit if there is nothing to match.
if (!str.contains("{")) {
return str;
}
// Do simple substitutions
String command = str;
command = MACHINE_X.matcher(command).replaceAll(bean.getMachineX());
command = MACHINE_Y.matcher(command).replaceAll(bean.getMachineY());
command = MACHINE_Z.matcher(command).replaceAll(bean.getMachineZ());
command = WORK_X.matcher(command).replaceAll(bean.getWorkX());
command = WORK_Y.matcher(command).replaceAll(bean.getWorkY());
command = WORK_Z.matcher(command).replaceAll(bean.getWorkZ());
// Prompt for additional substitutions
Matcher m = PROMPT_REGEX.matcher(command);
List<String> prompts = new ArrayList<>();
while (m.find()) {
prompts.add(m.group(1));
}
if (prompts.size() > 0) {
List<JTextField> fields = new ArrayList<>();
JPanel myPanel = new JPanel();
myPanel.setLayout(new MigLayout("wrap 2, width 200"));
for (String s : prompts) {
JTextField field = new JTextField();
myPanel.add(new JLabel(s + ":"));
myPanel.add(field, "growx, pushx");
fields.add(field);
}
int result = JOptionPane.showConfirmDialog(null, myPanel,
Localization.getString("macro.substitution"),
JOptionPane.OK_CANCEL_OPTION,
JOptionPane.PLAIN_MESSAGE);
if (result == JOptionPane.OK_OPTION) {
for(int i = 0; i < prompts.size(); i++) {
command = command.replace("{prompt|" + prompts.get(i) + "}", fields.get(i).getText());
}
} else {
command = "";
}
}
return command;
}
}