Include simulation headers in clipboard copy + add to context menu

This commit is contained in:
SiboVG 2023-07-22 01:46:07 +02:00
parent 81ea69d489
commit 3120b2d968
2 changed files with 125 additions and 67 deletions

View File

@ -581,12 +581,13 @@ simpanel.but.ttip.editsim = Edit the selected simulation
simpanel.but.ttip.runsimu = Re-run the selected simulations
simpanel.but.ttip.deletesim = Delete the selected simulations
simpanel.pop.edit = Edit
simpanel.pop.copyValues = Copy values
simpanel.pop.plot = Plot / Export
simpanel.pop.run = Run
simpanel.pop.delete = Delete
simpanel.pop.duplicate = Duplicate
simpanel.pop.exportSimTableToCSV = Export simulation table as CSV file
simpanel.pop.exportSelectedSimsToCSV = Export simulations as CSV file
simpanel.pop.exportSelectedSimsToCSV = Export simulation(s) as CSV file
simpanel.pop.exportToCSV.save.dialog.title = Save as CSV file
simpanel.dlg.no.simulation.table.rows = Simulation table has no entries\u2026 Please run a simulation first.
simpanel.checkbox.donotask = Do not ask me again
@ -594,6 +595,7 @@ simpanel.lbl.defpref = You can change the default operation in the preferences.
simpanel.dlg.lbl.DeleteSim1 = Delete the selected simulations?
simpanel.dlg.lbl.DeleteSim2 = <html><i>This operation cannot be undone.</i>
simpanel.dlg.lbl.DeleteSim3 = Delete simulations
simpanel.col.Status = Status
simpanel.col.Name = Name
simpanel.col.Motors = Motors
simpanel.col.Configuration = Configuration

View File

@ -110,6 +110,7 @@ public class SimulationPanel extends JPanel {
private final JPopupMenu pm;
private final SimulationAction editSimulationAction;
private final SimulationAction copyValuesSimulationAction;
private final SimulationAction runSimulationAction;
private final SimulationAction plotSimulationAction;
private final SimulationAction duplicateSimulationAction;
@ -129,6 +130,7 @@ public class SimulationPanel extends JPanel {
// Simulation actions
SimulationAction newSimulationAction = new NewSimulationAction();
editSimulationAction = new EditSimulationAction();
copyValuesSimulationAction = new CopyValuesSimulationAction();
runSimulationAction = new RunSimulationAction();
plotSimulationAction = new PlotSimulationAction();
duplicateSimulationAction = new DuplicateSimulationAction();
@ -184,10 +186,12 @@ public class SimulationPanel extends JPanel {
simulationTable.setDefaultRenderer(Object.class, new JLabelRenderer());
simulationTableModel.setColumnWidths(simulationTable.getColumnModel());
simulationTable.setFillsViewportHeight(true);
simulationTable.registerKeyboardAction(copyValuesSimulationAction, "Copy", RocketActions.COPY_KEY_STROKE, JComponent.WHEN_FOCUSED);
// Context menu
pm = new JPopupMenu();
pm.add(editSimulationAction);
pm.add(copyValuesSimulationAction);
pm.add(duplicateSimulationAction);
pm.add(deleteSimulationAction);
pm.addSeparator();
@ -480,36 +484,40 @@ public class SimulationPanel extends JPanel {
}
private void copySimulationAction() {
private void copySimulationValuesAction() {
int numCols = simulationTable.getColumnCount();
int numRows = simulationTable.getSelectedRowCount();
int[] rowsSelected = simulationTable.getSelectedRows();
if (numRows!=rowsSelected[rowsSelected.length-1]-rowsSelected[0]+1 || numRows!=rowsSelected.length) {
if (numRows != (rowsSelected[rowsSelected.length-1] - rowsSelected[0] + 1) || numRows != rowsSelected.length) {
JOptionPane.showMessageDialog(null, "Invalid Copy Selection", "Invalid Copy Selection", JOptionPane.ERROR_MESSAGE);
return;
}
StringBuilder excelStr =new StringBuilder();
for (int k = 1; k < numCols; k++) {
excelStr.append(simulationTable.getColumnName(k));
if (k < numCols-1) {
excelStr.append("\t");
StringBuilder valuesStr = new StringBuilder();
// Copy the column names
valuesStr.append(trans.get("simpanel.col.Status")).append("\t");
for (int i = 1; i < numCols; i++) {
valuesStr.append(simulationTable.getColumnName(i));
if (i < numCols-1) {
valuesStr.append("\t");
}
}
excelStr.append("\n");
valuesStr.append("\n");
// Copy the values
for (int i = 0; i < numRows; i++) {
for (int j = 1; j < numCols; j++) {
excelStr.append(simulationTable.getValueAt(rowsSelected[i], j));
for (int j = 0; j < numCols; j++) {
valuesStr.append(simulationTable.getValueAt(rowsSelected[i], j).toString());
if (j < numCols-1) {
excelStr.append("\t");
valuesStr.append("\t");
}
}
excelStr.append("\n");
valuesStr.append("\n");
}
StringSelection sel = new StringSelection(excelStr.toString());
StringSelection sel = new StringSelection(valuesStr.toString());
Clipboard cb = Toolkit.getDefaultToolkit().getSystemClipboard();
cb.setContents(sel, sel);
@ -545,6 +553,7 @@ public class SimulationPanel extends JPanel {
private void updateButtonStates() {
editSimulationAction.updateEnabledState();
copyValuesSimulationAction.updateEnabledState();
deleteSimulationAction.updateEnabledState();
runSimulationAction.updateEnabledState();
plotSimulationAction.updateEnabledState();
@ -595,6 +604,61 @@ public class SimulationPanel extends JPanel {
return simulationTable.getSelectionModel();
}
private String getSimulationToolTip(Simulation sim, boolean includeSimName) {
String tip;
FlightData data = sim.getSimulatedData();
tip = "<html>";
if (includeSimName) {
tip += "<b>" + sim.getName() + "</b><br>";
}
switch (sim.getStatus()) {
case CANT_RUN:
tip += trans.get("simpanel.ttip.noData")+"<br>";
break;
case LOADED:
tip += trans.get("simpanel.ttip.loaded") + "<br>";
break;
case UPTODATE:
tip += trans.get("simpanel.ttip.uptodate") + "<br>";
break;
case OUTDATED:
tip += trans.get("simpanel.ttip.outdated") + "<br>";
break;
case EXTERNAL:
tip += trans.get("simpanel.ttip.external") + "<br>";
return tip;
case NOT_SIMULATED:
tip += trans.get("simpanel.ttip.notSimulated");
return tip;
}
if (data == null) {
tip += trans.get("simpanel.ttip.noData");
return tip;
}
WarningSet warnings = data.getWarningSet();
if (warnings.isEmpty()) {
tip += trans.get("simpanel.ttip.noWarnings");
return tip;
}
tip += trans.get("simpanel.ttip.warnings");
for (Warning w : warnings) {
tip += "<br>" + w.toString();
}
return tip;
}
private String getSimulationToolTip(Simulation sim) {
return getSimulationToolTip(sim, true);
}
private void openDialog(boolean plotMode, boolean isNewSimulation, final Simulation... sims) {
SimulationEditDialog d = new SimulationEditDialog(SwingUtilities.getWindowAncestor(this), document, isNewSimulation, sims);
if (plotMode) {
@ -670,6 +734,25 @@ public class SimulationPanel extends JPanel {
}
}
class CopyValuesSimulationAction extends SimulationAction {
public CopyValuesSimulationAction() {
putValue(NAME, trans.get("simpanel.pop.copyValues"));
this.putValue(MNEMONIC_KEY, KeyEvent.VK_C);
this.putValue(ACCELERATOR_KEY, RocketActions.COPY_KEY_STROKE);
this.putValue(SMALL_ICON, Icons.EDIT_COPY);
}
@Override
public void actionPerformed(ActionEvent e) {
copySimulationValuesAction();
}
@Override
public void updateEnabledState() {
setEnabled(simulationTable.getSelectedRowCount() > 0);
}
}
class RunSimulationAction extends SimulationAction {
public RunSimulationAction() {
putValue(NAME, trans.get("simpanel.pop.run"));
@ -852,53 +935,24 @@ public class SimulationPanel extends JPanel {
}
return component;
}
private String getSimulationToolTip(Simulation sim) {
String tip;
FlightData data = sim.getSimulatedData();
tip = "<html><b>" + sim.getName() + "</b><br>";
switch (sim.getStatus()) {
case CANT_RUN:
tip += trans.get("simpanel.ttip.noData")+"<br>";
break;
case LOADED:
tip += trans.get("simpanel.ttip.loaded") + "<br>";
break;
case UPTODATE:
tip += trans.get("simpanel.ttip.uptodate") + "<br>";
break;
case OUTDATED:
tip += trans.get("simpanel.ttip.outdated") + "<br>";
break;
case EXTERNAL:
tip += trans.get("simpanel.ttip.external") + "<br>";
return tip;
case NOT_SIMULATED:
tip += trans.get("simpanel.ttip.notSimulated");
return tip;
}
if (data == null) {
tip += trans.get("simpanel.ttip.noData");
return tip;
}
WarningSet warnings = data.getWarningSet();
private class StatusLabel extends StyledLabel {
private Simulation simulation;
if (warnings.isEmpty()) {
tip += trans.get("simpanel.ttip.noWarnings");
return tip;
public StatusLabel(Simulation simulation, float size) {
super(size);
this.simulation = simulation;
}
tip += trans.get("simpanel.ttip.warnings");
for (Warning w : warnings) {
tip += "<br>" + w.toString();
public void replaceSimulation(Simulation simulation) {
this.simulation = simulation;
}
return tip;
@Override
public String toString() {
String text = getSimulationToolTip(simulation, false);
return text.replace("<br>", "-").replaceAll("<[^>]*>","");
}
}
@ -909,31 +963,33 @@ public class SimulationPanel extends JPanel {
super(
//// Status and warning column
new Column("") {
private JLabel label = null;
private StatusLabel label = null;
@Override
public Object getValueAt(int row) {
if (row < 0 || row >= document.getSimulationCount())
return null;
Simulation simulation = document.getSimulation(row);
// Initialize the label
if (label == null) {
label = new StyledLabel(2f);
label = new StatusLabel(simulation, 2f);
label.setIconTextGap(1);
// label.setFont(label.getFont().deriveFont(Font.BOLD));
} else {
label.replaceSimulation(simulation);
}
// Set simulation status icon
Simulation.Status status = document.getSimulation(row).getStatus();
Simulation.Status status = simulation.getStatus();
label.setIcon(Icons.SIMULATION_STATUS_ICON_MAP.get(status));
// Set warning marker
if (status == Simulation.Status.NOT_SIMULATED ||
status == Simulation.Status.EXTERNAL) {
label.setText("");
} else {
WarningSet w = document.getSimulation(row).getSimulatedWarnings();