mirror of https://github.com/rusefi/rusefi.git
305 lines
11 KiB
Java
305 lines
11 KiB
Java
package com.rusefi.ui;
|
|
|
|
import com.devexperts.logging.Logging;
|
|
import com.rusefi.AverageAnglesUtil;
|
|
import com.rusefi.core.ui.AutoupdateUtil;
|
|
import com.rusefi.config.generated.Fields;
|
|
import com.rusefi.core.MessagesCentral;
|
|
import com.rusefi.io.CommandQueue;
|
|
import com.rusefi.ui.util.UiUtils;
|
|
|
|
import javax.swing.*;
|
|
import javax.swing.filechooser.FileNameExtensionFilter;
|
|
import java.awt.*;
|
|
import java.awt.event.ActionEvent;
|
|
import java.awt.event.ActionListener;
|
|
import java.io.IOException;
|
|
import java.util.*;
|
|
import java.util.List;
|
|
import java.util.concurrent.atomic.AtomicBoolean;
|
|
|
|
import static com.rusefi.IoUtil.*;
|
|
import static com.rusefi.config.generated.Fields.CMD_DATE;
|
|
import static com.rusefi.config.generated.Fields.CMD_TRIGGERINFO;
|
|
import static com.rusefi.core.preferences.storage.PersistentConfiguration.getConfig;
|
|
|
|
/**
|
|
* This UI element displays an array of buttons, each for one of the recently used commands
|
|
*/
|
|
|
|
public class RecentCommands {
|
|
private final static Logging log = Logging.getLogging(RecentCommands.class);
|
|
|
|
private final static int NUMBER_OF_COMMANDS = 40;
|
|
private static final String KEY = "recent_commands";
|
|
private static final String DELIMETER = "|";
|
|
private static final String STOPENGINE = "stopengine";
|
|
private static final String SHOWCONFIG = "showconfig";
|
|
private static final String HELP = "help";
|
|
private static final String SENSORINFO = "sensorinfo";
|
|
private static final String IDLEINFO = "idleinfo";
|
|
private static final String ALTINFO = "altinfo";
|
|
private static final String TPSINFO = "tpsinfo";
|
|
private static final String MAPINFO = "mapinfo";
|
|
private static final String ACCELINFO = "accelinfo";
|
|
private static final String CANINFO = "caninfo";
|
|
private static final String TSINFO = "tsinfo";
|
|
private static final String SPEEDINFO = "speedinfo";
|
|
private static final String joystickINFO = "joystickinfo";
|
|
private static final String FUELINFO = "fuelinfo";
|
|
private static final String HIPINFO = "hipinfo";
|
|
private static final String SDINFO = "sdinfo";
|
|
private static final String FSIOINFO = "fsioinfo";
|
|
private static final String PINS = "pins";
|
|
|
|
private final static Map<String, Icon> COMMAND_ICONS = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
|
|
|
|
static {
|
|
COMMAND_ICONS.put(STOPENGINE, AutoupdateUtil.loadIcon("stop.jpg"));
|
|
ImageIcon infoIcon = AutoupdateUtil.loadIcon("info.png");
|
|
COMMAND_ICONS.put(SHOWCONFIG, infoIcon);
|
|
COMMAND_ICONS.put(HELP, AutoupdateUtil.loadIcon("help.jpg"));
|
|
COMMAND_ICONS.put(SENSORINFO, infoIcon);
|
|
COMMAND_ICONS.put(CMD_TRIGGERINFO, AutoupdateUtil.loadIcon("trigger.jpg"));
|
|
COMMAND_ICONS.put(IDLEINFO, infoIcon);
|
|
COMMAND_ICONS.put(ALTINFO, AutoupdateUtil.loadIcon("alternator.jpg"));
|
|
COMMAND_ICONS.put(ACCELINFO, infoIcon);
|
|
COMMAND_ICONS.put(TSINFO, infoIcon);
|
|
COMMAND_ICONS.put(TPSINFO, infoIcon);
|
|
COMMAND_ICONS.put(MAPINFO, infoIcon);
|
|
COMMAND_ICONS.put(joystickINFO, AutoupdateUtil.loadIcon("joystick.png"));
|
|
COMMAND_ICONS.put(CANINFO, infoIcon);
|
|
COMMAND_ICONS.put(FUELINFO, infoIcon);
|
|
COMMAND_ICONS.put(HIPINFO, AutoupdateUtil.loadIcon("knock.jpg"));
|
|
COMMAND_ICONS.put(SDINFO, AutoupdateUtil.loadIcon("sdinfo.jpg"));
|
|
COMMAND_ICONS.put(FSIOINFO, infoIcon);
|
|
COMMAND_ICONS.put(PINS, infoIcon);
|
|
COMMAND_ICONS.put(Fields.CMD_WRITECONFIG, AutoupdateUtil.loadIcon("writeconfig.jpg"));
|
|
COMMAND_ICONS.put(SPEEDINFO, AutoupdateUtil.loadIcon("speedinfo.jpg"));
|
|
}
|
|
|
|
private final JPanel content = new JPanel(new GridLayout(NUMBER_OF_COMMANDS + 1, 1));
|
|
|
|
private static final LinkedHashMap<Entry, Object> entries = new LinkedHashMap<Entry, Object>() {
|
|
@Override
|
|
protected boolean removeEldestEntry(Map.Entry<Entry, Object> eldest) {
|
|
return size() > NUMBER_OF_COMMANDS;
|
|
}
|
|
};
|
|
|
|
private final AtomicBoolean reentrant = new AtomicBoolean();
|
|
|
|
private final JScrollPane messagesScroll = new JScrollPane(content, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
|
|
private final UIContext uiContext;
|
|
|
|
public RecentCommands(UIContext uiContext) {
|
|
this.uiContext = uiContext;
|
|
uiContext.getCommandQueue().addListener(command -> {
|
|
if (!reentrant.get())
|
|
add(command);
|
|
}
|
|
);
|
|
|
|
String value = getConfig().getRoot().getProperty(KEY, null);
|
|
|
|
if (value != null && value.trim().length() > 5) {
|
|
unpack(value);
|
|
} else {
|
|
addDefaults();
|
|
}
|
|
}
|
|
|
|
private void unpack(String value) {
|
|
entries.clear();
|
|
for (String command : value.split("\\" + DELIMETER))
|
|
add(command);
|
|
}
|
|
|
|
private void addDefaults() {
|
|
add(HELP);
|
|
add(SHOWCONFIG);
|
|
add(STOPENGINE);
|
|
add(SENSORINFO);
|
|
add(CMD_TRIGGERINFO);
|
|
add(TSINFO);
|
|
add(SPEEDINFO);
|
|
add(joystickINFO);
|
|
add(CANINFO);
|
|
add(Fields.CMD_WRITECONFIG);
|
|
add("rewriteconfig");
|
|
|
|
add(getEnableCommand("injection"));
|
|
add(getDisableCommand("injection"));
|
|
|
|
add(getEnableCommand("ignition"));
|
|
add(getDisableCommand("ignition"));
|
|
|
|
add(getEnableCommand("self_stimulation"));
|
|
add(getDisableCommand("self_stimulation"));
|
|
|
|
add("blipidle 80 2000");
|
|
add("set_idle_position 50");
|
|
add("sparkbench 5 400 2");
|
|
add("fuelbench 5 400 2");
|
|
add(IDLEINFO);
|
|
add(ALTINFO);
|
|
add(TPSINFO);
|
|
add(MAPINFO);
|
|
add(ACCELINFO);
|
|
add(FUELINFO);
|
|
add(HIPINFO);
|
|
add(SDINFO);
|
|
add(FSIOINFO);
|
|
add(PINS);
|
|
}
|
|
|
|
public void add(String command) {
|
|
if (isBoringCommand(command)) {
|
|
// not useful to remember this one
|
|
return;
|
|
}
|
|
synchronized (entries) {
|
|
entries.put(new Entry(command), null);
|
|
}
|
|
|
|
SwingUtilities.invokeLater(new Runnable() {
|
|
@Override
|
|
public void run() {
|
|
content.removeAll();
|
|
|
|
if (uiContext.getLinkManager().isLogViewer())
|
|
content.add(createButton(uiContext));
|
|
|
|
JButton reset = new JButton(AutoupdateUtil.loadIcon("undo.jpg"));
|
|
reset.setContentAreaFilled(false);
|
|
reset.setFocusPainted(false);
|
|
reset.setBorder(BorderFactory.createEmptyBorder());
|
|
content.add(UiUtils.wrap(reset));
|
|
reset.addActionListener(new ActionListener() {
|
|
@Override
|
|
public void actionPerformed(ActionEvent e) {
|
|
entries.clear();
|
|
addDefaults();
|
|
}
|
|
});
|
|
|
|
synchronized (entries) {
|
|
Set<Entry> sorted = new TreeSet<>(entries.keySet());
|
|
|
|
for (Entry entry : sorted) {
|
|
content.add(createButton(uiContext, reentrant, entry.command));
|
|
}
|
|
}
|
|
UiUtils.trueLayout(content.getParent());
|
|
}
|
|
});
|
|
getConfig().getRoot().setProperty(KEY, pack());
|
|
}
|
|
|
|
public static boolean isBoringCommand(String command) {
|
|
return command.startsWith(getSetCommand(CMD_DATE));
|
|
}
|
|
|
|
public static JComponent createButton(UIContext uiContext, final AtomicBoolean reentrant, final String command) {
|
|
JButton button = new JButton(command);
|
|
Icon icon = COMMAND_ICONS.get(command);
|
|
if (icon != null)
|
|
button.setIcon(icon);
|
|
button.setBorder(BorderFactory.createEmptyBorder(3, 5, 0, 5));
|
|
|
|
button.addActionListener(new ActionListener() {
|
|
@Override
|
|
public void actionPerformed(ActionEvent e) {
|
|
reentrant.set(true);
|
|
int timeout = CommandQueue.getTimeout(command);
|
|
uiContext.getCommandQueue().write(command, timeout);
|
|
reentrant.set(false);
|
|
}
|
|
});
|
|
|
|
return UiUtils.wrap(button);
|
|
}
|
|
|
|
public Component getContent() {
|
|
return messagesScroll;
|
|
}
|
|
|
|
public String pack() {
|
|
StringBuilder sb = new StringBuilder();
|
|
for (Entry command : entries.keySet()) {
|
|
if (sb.length() != 0)
|
|
sb.append(DELIMETER);
|
|
sb.append(command.command);
|
|
}
|
|
return sb.toString();
|
|
}
|
|
|
|
static class Entry implements Comparable<Entry> {
|
|
private final String command;
|
|
|
|
Entry(String command) {
|
|
this.command = command;
|
|
}
|
|
|
|
@Override
|
|
public boolean equals(Object o) {
|
|
if (this == o) return true;
|
|
if (o == null || getClass() != o.getClass()) return false;
|
|
|
|
Entry entry = (Entry) o;
|
|
|
|
return !(command != null ? !command.equals(entry.command) : entry.command != null);
|
|
|
|
}
|
|
|
|
@Override
|
|
public int hashCode() {
|
|
return command != null ? command.hashCode() : 0;
|
|
}
|
|
|
|
@Override
|
|
public String toString() {
|
|
return "{" +
|
|
"command='" + command + '\'' +
|
|
'}';
|
|
}
|
|
|
|
@Override
|
|
public int compareTo(Entry o) {
|
|
return command.compareTo(o.command);
|
|
}
|
|
}
|
|
|
|
public static String getRecent(int index) {
|
|
List<Entry> elements;
|
|
index = Math.max(0, index);
|
|
synchronized (entries) {
|
|
elements = new ArrayList<>(entries.keySet());
|
|
}
|
|
if (index >= elements.size())
|
|
return elements.get(0).command;
|
|
return elements.get(elements.size() - 1 - index).command;
|
|
}
|
|
|
|
|
|
public static JButton createButton(UIContext uiContext) {
|
|
JButton button = new JButton("Read trigger log");
|
|
button.addActionListener(new ActionListener() {
|
|
@Override
|
|
public void actionPerformed(ActionEvent event) {
|
|
JFileChooser fc = UiUtils.getFileChooser(new FileNameExtensionFilter("CSV files", "csv"));
|
|
if (fc.showSaveDialog(null) == JFileChooser.APPROVE_OPTION) {
|
|
String fileName = fc.getSelectedFile().getAbsolutePath();
|
|
String report;
|
|
try {
|
|
report = AverageAnglesUtil.runUtil(fileName);
|
|
} catch (IOException e) {
|
|
throw new IllegalStateException(e);
|
|
}
|
|
MessagesCentral.getInstance().postMessage(AverageAnglesUtil.class, report);
|
|
}
|
|
}
|
|
});
|
|
return button;
|
|
}
|
|
} |