diff --git a/java_console/autoupdate/src/com/rusefi/autoupdate/AutoupdateUtil.java b/java_console/autoupdate/src/com/rusefi/autoupdate/AutoupdateUtil.java
index f863098194..0c4a2062bd 100644
--- a/java_console/autoupdate/src/com/rusefi/autoupdate/AutoupdateUtil.java
+++ b/java_console/autoupdate/src/com/rusefi/autoupdate/AutoupdateUtil.java
@@ -19,6 +19,8 @@ public class AutoupdateUtil {
private static final int BUFFER_SIZE = 32 * 1024;
private static final int STEPS = 1000;
+ // todo: figure out a better way to work with absolute path
+ private static final String APPICON = "/appicon.png";
public static void downloadAutoupdateFile(String localZipFileName, ConnectionAndMeta connectionAndMeta, String title) throws IOException {
HttpURLConnection httpConnection = connectionAndMeta.httpConnection;
@@ -103,6 +105,12 @@ public class AutoupdateUtil {
}
}
+ public static void setAppIcon(JFrame frame) {
+ ImageIcon icon = loadIcon(APPICON);
+ if (icon != null)
+ frame.setIconImage(icon.getImage());
+ }
+
public static class ConnectionAndMeta {
private String zipFileName;
private HttpURLConnection httpConnection;
diff --git a/java_console/ui/resources/com/rusefi/appicon.png b/java_console/shared_ui/resources/com/rusefi/appicon.png
similarity index 100%
rename from java_console/ui/resources/com/rusefi/appicon.png
rename to java_console/shared_ui/resources/com/rusefi/appicon.png
diff --git a/java_console/shared_ui/shared_ui.iml b/java_console/shared_ui/shared_ui.iml
index c51500b928..c258fee90d 100644
--- a/java_console/shared_ui/shared_ui.iml
+++ b/java_console/shared_ui/shared_ui.iml
@@ -4,6 +4,7 @@
+
diff --git a/java_console/shared_ui/src/com/rusefi/ui/AuthTokenPanel.java b/java_console/shared_ui/src/com/rusefi/ui/AuthTokenPanel.java
index 3fe694c8ef..59f556f884 100644
--- a/java_console/shared_ui/src/com/rusefi/ui/AuthTokenPanel.java
+++ b/java_console/shared_ui/src/com/rusefi/ui/AuthTokenPanel.java
@@ -98,7 +98,7 @@ public class AuthTokenPanel {
try {
String data = (String) clipboard.getData(DataFlavor.stringFlavor);
paste.setEnabled(AutoTokenUtil.isToken(data));
- } catch (IOException | UnsupportedFlavorException ex) {
+ } catch (IOException | IllegalStateException | UnsupportedFlavorException ex) {
// ignoring this exception
}
}
diff --git a/java_console/ui/src/main/java/com/rusefi/ConsoleUI.java b/java_console/ui/src/main/java/com/rusefi/ConsoleUI.java
index 43cf3ce46e..b3b1c20188 100644
--- a/java_console/ui/src/main/java/com/rusefi/ConsoleUI.java
+++ b/java_console/ui/src/main/java/com/rusefi/ConsoleUI.java
@@ -1,6 +1,7 @@
package com.rusefi;
import com.rusefi.autodetect.PortDetector;
+import com.rusefi.autoupdate.AutoupdateUtil;
import com.rusefi.config.generated.Fields;
import com.rusefi.core.MessagesCentral;
import com.rusefi.core.Sensor;
@@ -158,7 +159,7 @@ public class ConsoleUI {
}
});
- StartupFrame.setAppIcon(mainFrame.getFrame().getFrame());
+ AutoupdateUtil.setAppIcon(mainFrame.getFrame().getFrame());
mainFrame.getFrame().showFrame(tabbedPane.tabbedPane);
}
diff --git a/java_console/ui/src/main/java/com/rusefi/StartupFrame.java b/java_console/ui/src/main/java/com/rusefi/StartupFrame.java
index 1f6e646d23..b0a75ee4bf 100644
--- a/java_console/ui/src/main/java/com/rusefi/StartupFrame.java
+++ b/java_console/ui/src/main/java/com/rusefi/StartupFrame.java
@@ -36,8 +36,6 @@ import static javax.swing.JOptionPane.YES_NO_OPTION;
* @see FirmwareFlasher
*/
public class StartupFrame {
- // todo: figure out a better way to work with absolute path
- private static final String APPICON = "/appicon.png";
private static final String LOGO = "/com/rusefi/logo.gif";
public static final String LINK_TEXT = "rusEFI (c) 2012-2020";
private static final String URI = "http://rusefi.com/?java_console";
@@ -80,16 +78,10 @@ public class StartupFrame {
}
}
});
- setAppIcon(frame);
+ AutoupdateUtil.setAppIcon(frame);
SerialPortScanner.INSTANCE.startTimer();
}
- public static void setAppIcon(JFrame frame) {
- ImageIcon icon = AutoupdateUtil.loadIcon(APPICON);
- if (icon != null)
- frame.setIconImage(icon.getImage());
- }
-
public void chooseSerialPort() {
realHardwarePanel.setBorder(new TitledBorder(BorderFactory.createLineBorder(Color.darkGray), "Real stm32"));
miscPanel.setBorder(new TitledBorder(BorderFactory.createLineBorder(Color.darkGray), "Miscellaneous"));
diff --git a/java_tools/ts_plugin/build.xml b/java_tools/ts_plugin/build.xml
index 0cc26e482b..45c94c7388 100644
--- a/java_tools/ts_plugin/build.xml
+++ b/java_tools/ts_plugin/build.xml
@@ -32,6 +32,7 @@
+
diff --git a/java_tools/ts_plugin/src/com/rusefi/ts_plugin/PluginBodySandbox.java b/java_tools/ts_plugin/src/com/rusefi/ts_plugin/PluginBodySandbox.java
index a402f4ebcb..086951bc45 100644
--- a/java_tools/ts_plugin/src/com/rusefi/ts_plugin/PluginBodySandbox.java
+++ b/java_tools/ts_plugin/src/com/rusefi/ts_plugin/PluginBodySandbox.java
@@ -1,12 +1,20 @@
package com.rusefi.ts_plugin;
+import com.efiAnalytics.plugin.ecu.ControllerAccess;
import com.rusefi.ui.util.FrameHelper;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
/**
* @see PluginLauncherSandbox
*/
public class PluginBodySandbox {
public static void main(String[] args) {
- new FrameHelper().showFrame(new PluginEntry().getContent());
+ new FrameHelper().showFrame(new PluginEntry(() -> {
+ ControllerAccess controllerAccess = mock(ControllerAccess.class);
+ when(controllerAccess.getEcuConfigurationNames()).thenReturn(new String[]{"dev"});
+ return controllerAccess;
+ }).getContent());
}
}
diff --git a/java_tools/ts_plugin/src/com/rusefi/ts_plugin/PluginEntry.java b/java_tools/ts_plugin/src/com/rusefi/ts_plugin/PluginEntry.java
index 48466e7d4d..b7540d04f9 100644
--- a/java_tools/ts_plugin/src/com/rusefi/ts_plugin/PluginEntry.java
+++ b/java_tools/ts_plugin/src/com/rusefi/ts_plugin/PluginEntry.java
@@ -1,10 +1,6 @@
package com.rusefi.ts_plugin;
import com.efiAnalytics.plugin.ecu.ControllerAccess;
-import com.efiAnalytics.plugin.ecu.ControllerException;
-import com.efiAnalytics.plugin.ecu.ControllerParameter;
-import com.efiAnalytics.plugin.ecu.servers.ControllerParameterServer;
-import com.rusefi.TsTuneReader;
import com.rusefi.autoupdate.AutoupdateUtil;
import com.rusefi.tools.online.Online;
import com.rusefi.tune.xml.Constant;
@@ -16,12 +12,12 @@ import org.jetbrains.annotations.NotNull;
import org.putgemin.VerticalFlowLayout;
import javax.swing.*;
-import javax.xml.bind.JAXBException;
+import java.awt.*;
import java.awt.event.ActionEvent;
import java.io.IOException;
import java.net.URL;
import java.util.Map;
-import java.util.TreeMap;
+import java.util.function.Supplier;
import java.util.jar.Attributes;
import java.util.jar.Manifest;
@@ -37,20 +33,42 @@ public class PluginEntry implements TsPluginBody {
private static final ImageIcon LOGO = AutoupdateUtil.loadIcon("/rusefi_online_color_300.png");
private final JButton upload = new JButton("Upload Current Tune");
- private static final JLabel warning = new JLabel("Please open project");
+ private static final JLabel projectWarning = new JLabel("Please open project");
+ private static final JLabel tuneWarning = new JLabel();
+ private final Supplier controllerAccessSupplier;
+ private String currentConfiguration;
+ private boolean tuneIsOk;
+ private boolean projectIsOk;
+
+ /**
+ * the real constructor - this one is invoked via reflection
+ */
public PluginEntry() {
+ this(ControllerAccess::getInstance);
+ }
+
+ public PluginEntry(Supplier controllerAccessSupplier) {
+ this.controllerAccessSupplier = controllerAccessSupplier;
+ upload.setBackground(new Color(0x90EE90));
new Thread(new Runnable() {
@Override
public void run() {
while (true) {
- boolean isProjectActive = getConfigurationName() != null;
+ String configurationName = getConfigurationName();
+ if ((currentConfiguration == null && configurationName != null)
+ || !currentConfiguration.equals(configurationName)) {
+ handleConfigurationChange(configurationName);
+ }
+
+ boolean isProjectActive = configurationName != null;
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
- warning.setVisible(!isProjectActive);
- upload.setEnabled(isProjectActive);
+ projectWarning.setVisible(!isProjectActive);
+ projectIsOk = isProjectActive;
+ updateUploadEnabled();
}
});
@@ -76,7 +94,7 @@ public class PluginEntry implements TsPluginBody {
return;
}
- Msq tune = writeCurrentTune(ControllerAccess.getInstance(), configurationName);
+ Msq tune = TuneUploder.writeCurrentTune(ControllerAccess.getInstance(), configurationName);
Online.uploadTune(tune, tokenPanel, content);
}
});
@@ -84,13 +102,51 @@ public class PluginEntry implements TsPluginBody {
content.add(new JLabel(getAttribute(BUILT_TIMESTAMP)));
// content.add(new JLabel("Active project: " + getConfigurationName()));
- content.add(warning);
+ content.add(projectWarning);
+ content.add(tuneWarning);
content.add(upload);
content.add(new JLabel(LOGO));
content.add(tokenPanel.getContent());
content.add(new URLLabel(REO));
}
+ private void handleConfigurationChange(String configurationName) {
+ Map fileSystemValues = TuneUploder.getFileSystemValues(configurationName);
+ Constant engineMake = fileSystemValues.get("enginemake");
+ Constant engineCode = fileSystemValues.get("enginecode");
+ Constant vehicleName = fileSystemValues.get("VEHICLENAME");
+ String warning = "";
+ if (isEmpty(engineMake.getValue())) {
+ warning += " engine make";
+ }
+ if (isEmpty(engineCode.getValue())) {
+ warning += " engine code";
+ }
+ if (isEmpty(vehicleName.getValue())) {
+ warning += " vehicle name";
+ }
+ if (warning.isEmpty()) {
+ tuneWarning.setVisible(false);
+ tuneIsOk = true;
+ updateUploadEnabled();
+ } else {
+ tuneWarning.setText("Please set " + warning + " on Base Settings tab
and reopen Project");
+ tuneWarning.setForeground(Color.red);
+ tuneWarning.setVisible(true);
+ tuneIsOk = false;
+ updateUploadEnabled();
+ }
+ currentConfiguration = configurationName;
+ }
+
+ private void updateUploadEnabled() {
+ upload.setEnabled(tuneIsOk && projectIsOk);
+ }
+
+ private boolean isEmpty(String engineCode) {
+ return engineCode == null || engineCode.trim().length() == 0;
+ }
+
@Override
public JComponent getContent() {
return content;
@@ -106,23 +162,8 @@ public class PluginEntry implements TsPluginBody {
}
}
- private static String getArrayValue(double[][] arrayValues) {
- StringBuilder sb = new StringBuilder();
- for (int rowIndex = 0; rowIndex < arrayValues.length; rowIndex++) {
- double[] array = arrayValues[rowIndex];
- sb.append("\n\t");
- for (int colIndex = 0; colIndex < array.length; colIndex++) {
- double value = array[colIndex];
- sb.append(' ');
- sb.append(value);
- }
- }
- sb.append("\n");
- return sb.toString();
- }
-
- public static String getConfigurationName() {
- ControllerAccess controllerAccess = ControllerAccess.getInstance();
+ private String getConfigurationName() {
+ ControllerAccess controllerAccess = controllerAccessSupplier.get();
if (controllerAccess == null) {
System.out.println("No ControllerAccess");
return null;
@@ -133,65 +174,6 @@ public class PluginEntry implements TsPluginBody {
return configurationNames[0];
}
- private static String toString(double scalarValue, int decimalPlaces) {
- // todo: start using decimalPlaces parameter!
- return Double.toString(scalarValue);
- }
-
- private static Msq writeCurrentTune(ControllerAccess controllerAccess, String configurationName) {
- Msq msq = new Msq();
- ControllerParameterServer controllerParameterServer = controllerAccess.getControllerParameterServer();
-
- Msq tsTune = TsTuneReader.readTsTune(configurationName);
- Map byName = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
- for (Constant c : tsTune.findPage().constant) {
- byName.put(c.getName(), c);
- }
-
- try {
- String[] parameterNames = controllerParameterServer.getParameterNames(configurationName);
- for (String parameterName : parameterNames) {
- ControllerParameter cp = controllerParameterServer.getControllerParameter(configurationName, parameterName);
- String type = cp.getParamClass();
- String value;
- if (ControllerParameter.PARAM_CLASS_BITS.equals(type)) {
- value = cp.getStringValue();
- System.out.println("TsPlugin bits " + parameterName + ": " + value);
- } else if (ControllerParameter.PARAM_CLASS_SCALAR.equals(type)) {
- value = toString(cp.getScalarValue(), cp.getDecimalPlaces());
- System.out.println("TsPlugin scalar " + parameterName + ": " + cp.getScalarValue() + "/" + cp.getStringValue());
-
- } else if (ControllerParameter.PARAM_CLASS_ARRAY.equals(type)) {
- value = getArrayValue(cp.getArrayValues());
- } else if ("string".equals(type)) {
- //value = cp.getStringValue();
- // WOW hack
- // TS does not provide values for string parameters?! so we read the file directly
- Constant constant = byName.get(parameterName);
- if (constant == null) {
- System.out.println("Not found in TS tune " + parameterName);
- value = null;
- } else {
- value = constant.getValue();
- System.out.println("TsPlugin name=" + parameterName + " string=" + cp.getStringValue() + "/h=" + value);
- }
- } else {
- System.out.println("TsPlugin name=" + parameterName + " unexpected type " + type + "/" + cp.getStringValue());
- value = cp.getStringValue();
- }
-
- msq.findPage().constant.add(new Constant(parameterName, cp.getUnits(), value));
- }
-
- String fileName = Msq.outputXmlFileName;
- msq.writeXmlFile(fileName);
- return msq;
- } catch (JAXBException | IOException | ControllerException e) {
- System.out.println("Error writing XML: " + e);
- return null;
- }
- }
-
/**
* this method is invoked by refection
*
diff --git a/java_tools/ts_plugin/src/com/rusefi/ts_plugin/TuneUploder.java b/java_tools/ts_plugin/src/com/rusefi/ts_plugin/TuneUploder.java
new file mode 100644
index 0000000000..441e161f32
--- /dev/null
+++ b/java_tools/ts_plugin/src/com/rusefi/ts_plugin/TuneUploder.java
@@ -0,0 +1,104 @@
+package com.rusefi.ts_plugin;
+
+import com.efiAnalytics.plugin.ecu.ControllerAccess;
+import com.efiAnalytics.plugin.ecu.ControllerException;
+import com.efiAnalytics.plugin.ecu.ControllerParameter;
+import com.efiAnalytics.plugin.ecu.servers.ControllerParameterServer;
+import com.rusefi.TsTuneReader;
+import com.rusefi.tune.xml.Constant;
+import com.rusefi.tune.xml.Msq;
+import org.jetbrains.annotations.NotNull;
+
+import javax.xml.bind.JAXBException;
+import java.io.IOException;
+import java.util.Collections;
+import java.util.Map;
+import java.util.TreeMap;
+
+public class TuneUploder {
+ static Msq writeCurrentTune(ControllerAccess controllerAccess, String configurationName) {
+ Msq msq = new Msq();
+ ControllerParameterServer controllerParameterServer = controllerAccess.getControllerParameterServer();
+
+ Map fileSystemValues = getFileSystemValues(configurationName);
+
+ try {
+ String[] parameterNames = controllerParameterServer.getParameterNames(configurationName);
+ for (String parameterName : parameterNames) {
+ handleParameter(configurationName, msq, controllerParameterServer, fileSystemValues, parameterName);
+ }
+
+ String fileName = Msq.outputXmlFileName;
+ msq.writeXmlFile(fileName);
+ return msq;
+ } catch (JAXBException | IOException | ControllerException e) {
+ System.out.println("Error writing XML: " + e);
+ return null;
+ }
+ }
+
+ @NotNull
+ static Map getFileSystemValues(String configurationName) {
+ if (configurationName == null)
+ return Collections.emptyMap();
+ Msq tsTune = TsTuneReader.readTsTune(configurationName);
+ Map byName = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
+ for (Constant c : tsTune.findPage().constant) {
+ byName.put(c.getName(), c);
+ }
+ return byName;
+ }
+
+ private static void handleParameter(String configurationName, Msq msq, ControllerParameterServer controllerParameterServer, Map byName, String parameterName) throws ControllerException {
+ ControllerParameter cp = controllerParameterServer.getControllerParameter(configurationName, parameterName);
+ String type = cp.getParamClass();
+ String value;
+ if (ControllerParameter.PARAM_CLASS_BITS.equals(type)) {
+ value = cp.getStringValue();
+ System.out.println("TsPlugin bits " + parameterName + ": " + value);
+ } else if (ControllerParameter.PARAM_CLASS_SCALAR.equals(type)) {
+ value = toString(cp.getScalarValue(), cp.getDecimalPlaces());
+ System.out.println("TsPlugin scalar " + parameterName + ": " + cp.getScalarValue() + "/" + cp.getStringValue());
+
+ } else if (ControllerParameter.PARAM_CLASS_ARRAY.equals(type)) {
+ value = getArrayValue(cp.getArrayValues());
+ } else if ("string".equals(type)) {
+ //value = cp.getStringValue();
+ // WOW hack
+ // TS does not provide values for string parameters?! so we read the file directly
+ Constant constant = byName.get(parameterName);
+ if (constant == null) {
+ System.out.println("Not found in TS tune " + parameterName);
+ value = null;
+ } else {
+ value = constant.getValue();
+ System.out.println("TsPlugin name=" + parameterName + " string=" + cp.getStringValue() + "/h=" + value);
+ }
+ } else {
+ System.out.println("TsPlugin name=" + parameterName + " unexpected type " + type + "/" + cp.getStringValue());
+ value = cp.getStringValue();
+ }
+
+ msq.findPage().constant.add(new Constant(parameterName, cp.getUnits(), value));
+ }
+
+ private static String getArrayValue(double[][] arrayValues) {
+ StringBuilder sb = new StringBuilder();
+ for (int rowIndex = 0; rowIndex < arrayValues.length; rowIndex++) {
+ double[] array = arrayValues[rowIndex];
+ sb.append("\n\t");
+ for (int colIndex = 0; colIndex < array.length; colIndex++) {
+ double value = array[colIndex];
+ sb.append(' ');
+ sb.append(value);
+ }
+ }
+ sb.append("\n");
+ return sb.toString();
+ }
+
+ private static String toString(double scalarValue, int decimalPlaces) {
+ // todo: start using decimalPlaces parameter!
+ return Double.toString(scalarValue);
+ }
+}
diff --git a/java_tools/ts_plugin/ts_plugin.iml b/java_tools/ts_plugin/ts_plugin.iml
index 37589882cd..9d813fb42d 100644
--- a/java_tools/ts_plugin/ts_plugin.iml
+++ b/java_tools/ts_plugin/ts_plugin.iml
@@ -11,5 +11,6 @@
+
\ No newline at end of file
diff --git a/java_tools/ts_plugin_launcher/.idea/libraries/org_mockito_mockito_all_1_10_19.xml b/java_tools/ts_plugin_launcher/.idea/libraries/org_mockito_mockito_all_1_10_19.xml
new file mode 100644
index 0000000000..403be5147c
--- /dev/null
+++ b/java_tools/ts_plugin_launcher/.idea/libraries/org_mockito_mockito_all_1_10_19.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/java_tools/ts_plugin_launcher/src/com/rusefi/ts_plugin/Updater.java b/java_tools/ts_plugin_launcher/src/com/rusefi/ts_plugin/Updater.java
index a1e303ea1e..9382f106f4 100644
--- a/java_tools/ts_plugin_launcher/src/com/rusefi/ts_plugin/Updater.java
+++ b/java_tools/ts_plugin_launcher/src/com/rusefi/ts_plugin/Updater.java
@@ -5,6 +5,7 @@ import com.rusefi.ui.storage.PersistentConfiguration;
import org.putgemin.VerticalFlowLayout;
import javax.swing.*;
+import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
@@ -61,6 +62,7 @@ public class Updater {
JButton download = new JButton("Update plugin");
if (version != null) {
JButton run = new JButton("Run Version " + version);
+ run.setBackground(new Color(0x90EE90));
run.addActionListener(new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {