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.runsimu = Re-run the selected simulations
simpanel.but.ttip.deletesim = Delete the selected simulations simpanel.but.ttip.deletesim = Delete the selected simulations
simpanel.pop.edit = Edit simpanel.pop.edit = Edit
simpanel.pop.copyValues = Copy values
simpanel.pop.plot = Plot / Export simpanel.pop.plot = Plot / Export
simpanel.pop.run = Run simpanel.pop.run = Run
simpanel.pop.delete = Delete simpanel.pop.delete = Delete
simpanel.pop.duplicate = Duplicate simpanel.pop.duplicate = Duplicate
simpanel.pop.exportSimTableToCSV = Export simulation table as CSV file 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.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.dlg.no.simulation.table.rows = Simulation table has no entries\u2026 Please run a simulation first.
simpanel.checkbox.donotask = Do not ask me again 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.DeleteSim1 = Delete the selected simulations?
simpanel.dlg.lbl.DeleteSim2 = <html><i>This operation cannot be undone.</i> simpanel.dlg.lbl.DeleteSim2 = <html><i>This operation cannot be undone.</i>
simpanel.dlg.lbl.DeleteSim3 = Delete simulations simpanel.dlg.lbl.DeleteSim3 = Delete simulations
simpanel.col.Status = Status
simpanel.col.Name = Name simpanel.col.Name = Name
simpanel.col.Motors = Motors simpanel.col.Motors = Motors
simpanel.col.Configuration = Configuration simpanel.col.Configuration = Configuration

View File

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