[fixes #244] Multi-selection in Motors, Recovery & Stages panels

This commit is contained in:
SiboVG 2022-02-14 18:21:44 +01:00
parent 2683b7a08e
commit 105e3c02f0
5 changed files with 336 additions and 103 deletions

View File

@ -3,6 +3,9 @@ package net.sf.openrocket.gui.main.flightconfigpanel;
import java.awt.Color; import java.awt.Color;
import java.awt.Component; import java.awt.Component;
import java.awt.Font; import java.awt.Font;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import javax.swing.JComponent; import javax.swing.JComponent;
import javax.swing.JLabel; import javax.swing.JLabel;
@ -17,6 +20,7 @@ import javax.swing.event.ListSelectionListener;
import javax.swing.table.AbstractTableModel; import javax.swing.table.AbstractTableModel;
import javax.swing.table.DefaultTableCellRenderer; import javax.swing.table.DefaultTableCellRenderer;
import net.sf.openrocket.util.ArrayList;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -183,6 +187,27 @@ public abstract class FlightConfigurablePanel<T extends FlightConfigurableCompon
return null; return null;
} }
protected List<T> getSelectedComponents() {
int[] cols = Arrays.stream(table.getSelectedColumns()).map(table::convertRowIndexToModel).toArray();
int[] rows = Arrays.stream(table.getSelectedRows()).map(table::convertRowIndexToModel).toArray();
if (Arrays.stream(cols).min().isEmpty() || Arrays.stream(rows).min().isEmpty() ||
Arrays.stream(cols).min().getAsInt() < 0 || Arrays.stream(rows).min().getAsInt() < 0) {
return null;
}
List<T> components = new ArrayList<>();
for (int row : rows) {
for (int col : cols) {
Object tableValue = table.getModel().getValueAt(row, col);
if (tableValue instanceof Pair) {
@SuppressWarnings("unchecked")
Pair<String, T> selectedComponent = (Pair<String, T>) tableValue;
components.add(selectedComponent.getV());
}
}
}
return components;
}
protected FlightConfigurationId getSelectedConfigurationId() { protected FlightConfigurationId getSelectedConfigurationId() {
int col = table.convertColumnIndexToModel(table.getSelectedColumn()); int col = table.convertColumnIndexToModel(table.getSelectedColumn());
int row = table.convertRowIndexToModel(table.getSelectedRow()); int row = table.convertRowIndexToModel(table.getSelectedRow());
@ -201,6 +226,31 @@ public abstract class FlightConfigurablePanel<T extends FlightConfigurableCompon
return FlightConfigurationId.ERROR_FCID; return FlightConfigurationId.ERROR_FCID;
} }
protected List<FlightConfigurationId> getSelectedConfigurationIds() {
int col = table.convertColumnIndexToModel(table.getSelectedColumn());
int[] rows = Arrays.stream(table.getSelectedRows()).map(table::convertRowIndexToModel).toArray();
if (Arrays.stream(rows).min().isEmpty() || Arrays.stream(rows).min().getAsInt() < 0 || col < 0 ||
Arrays.stream(rows).max().getAsInt() >= table.getRowCount() || col >= table.getColumnCount() ) {
return null;
}
Object[] tableValues = Arrays.stream(rows).mapToObj(c -> table.getModel().getValueAt(c, col)).toArray();
List<FlightConfigurationId> Ids = new ArrayList<>();
for (Object tableValue : tableValues) {
if (tableValue instanceof Pair) {
@SuppressWarnings("unchecked")
Pair<FlightConfigurationId, T> selectedComponent = (Pair<FlightConfigurationId, T>) tableValue;
FlightConfigurationId fcid = selectedComponent.getU();
Ids.add(fcid);
} else if (tableValue instanceof FlightConfigurationId) {
Ids.add((FlightConfigurationId) tableValue);
} else {
Ids.add(FlightConfigurationId.ERROR_FCID);
}
}
return Ids;
}
protected abstract class FlightConfigurableCellRenderer extends DefaultTableCellRenderer { protected abstract class FlightConfigurableCellRenderer extends DefaultTableCellRenderer {
@Override @Override

View File

@ -3,6 +3,10 @@ package net.sf.openrocket.gui.main.flightconfigpanel;
import java.awt.event.ActionEvent; import java.awt.event.ActionEvent;
import java.awt.event.ActionListener; import java.awt.event.ActionListener;
import java.util.EventObject; import java.util.EventObject;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import javax.swing.JButton; import javax.swing.JButton;
import javax.swing.JPanel; import javax.swing.JPanel;
@ -27,6 +31,7 @@ import net.sf.openrocket.rocketcomponent.RocketComponent;
import net.sf.openrocket.rocketvisitors.ListComponents; import net.sf.openrocket.rocketvisitors.ListComponents;
import net.sf.openrocket.rocketvisitors.ListMotorMounts; import net.sf.openrocket.rocketvisitors.ListMotorMounts;
import net.sf.openrocket.startup.Application; import net.sf.openrocket.startup.Application;
import net.sf.openrocket.util.ArrayList;
import net.sf.openrocket.util.StateChangeListener; import net.sf.openrocket.util.StateChangeListener;
import net.sf.openrocket.gui.widgets.SelectColorButton; import net.sf.openrocket.gui.widgets.SelectColorButton;
@ -163,51 +168,71 @@ public class FlightConfigurationPanel extends JPanel implements StateChangeListe
* create simulation for new configuration * create simulation for new configuration
*/ */
private void addOrCopyConfiguration(boolean copy) { private void addOrCopyConfiguration(boolean copy) {
FlightConfiguration newConfig; Map<FlightConfigurationId, FlightConfiguration> newConfigs = new LinkedHashMap<>();
FlightConfigurationId newId;
// create or copy configuration // create or copy configuration
if (copy) { if (copy) {
FlightConfigurationId oldId = this.motorConfigurationPanel.getSelectedConfigurationId(); List<FlightConfigurationId> oldIds = getSelectedConfigurationIds();
FlightConfiguration oldConfig = rocket.getFlightConfiguration(oldId); if (oldIds == null || oldIds.size() == 0) return;
newConfig = oldConfig.copy(null); for (FlightConfigurationId oldId : oldIds) {
newId = newConfig.getId(); final FlightConfiguration oldConfig = rocket.getFlightConfiguration(oldId);
for (RocketComponent c : rocket) { final FlightConfiguration newConfig = oldConfig.copy(null);
if (c instanceof FlightConfigurableComponent) { final FlightConfigurationId newId = newConfig.getId();
((FlightConfigurableComponent) c).copyFlightConfiguration(oldId, newId);
for (RocketComponent c : rocket) {
if (c instanceof FlightConfigurableComponent) {
((FlightConfigurableComponent) c).copyFlightConfiguration(oldId, newId);
}
} }
newConfigs.put(newId, newConfig);
} }
} else { } else {
newConfig = new FlightConfiguration(rocket, null); final FlightConfiguration newConfig = new FlightConfiguration(rocket, null);
newId = newConfig.getId(); final FlightConfigurationId newId = newConfig.getId();
newConfigs.put(newId, newConfig);
} }
// associate configuration with Id and select it for (FlightConfigurationId newId : newConfigs.keySet()) {
rocket.setFlightConfiguration(newId, newConfig); // associate configuration with Id and select it
rocket.setSelectedConfiguration(newId); rocket.setFlightConfiguration(newId, newConfigs.get(newId));
// create simulation for configuration // create simulation for configuration
Simulation newSim = new Simulation(rocket); Simulation newSim = new Simulation(rocket);
OpenRocketDocument doc = BasicFrame.findDocument(rocket); OpenRocketDocument doc = BasicFrame.findDocument(rocket);
if (doc != null) { if (doc != null) {
newSim.setName(doc.getNextSimulationName()); newSim.setName(doc.getNextSimulationName());
doc.addSimulation(newSim); doc.addSimulation(newSim);
} }
}
rocket.setSelectedConfiguration((FlightConfigurationId) newConfigs.keySet().toArray()[0]);
} }
private void renameConfiguration() { private void renameConfiguration() {
FlightConfigurationId currentId = this.motorConfigurationPanel.getSelectedConfigurationId(); List<FlightConfigurationId> fcIds = getSelectedConfigurationIds();
new RenameConfigDialog(SwingUtilities.getWindowAncestor(this), rocket, currentId).setVisible(true); if (fcIds == null) return;
FlightConfigurationId initFcId = fcIds.get(0);
new RenameConfigDialog(SwingUtilities.getWindowAncestor(this), rocket, initFcId).setVisible(true);
String newName = rocket.getFlightConfiguration(initFcId).getName();
for (int i = 1; i < fcIds.size(); i++) {
rocket.getFlightConfiguration(fcIds.get(i)).setName(newName);
}
} }
private void removeConfiguration() { private void removeConfiguration() {
FlightConfigurationId currentId = this.motorConfigurationPanel.getSelectedConfigurationId(); List<FlightConfigurationId> fcIds = getSelectedConfigurationIds();
if (currentId == null) if (fcIds == null || fcIds.size() == 0)
return; return;
document.removeFlightConfigurationAndSimulations(currentId);
for (FlightConfigurationId fcId : fcIds) {
document.removeFlightConfigurationAndSimulations(fcId);
}
configurationChanged(ComponentChangeEvent.NONFUNCTIONAL_CHANGE); configurationChanged(ComponentChangeEvent.NONFUNCTIONAL_CHANGE);
} }
@ -253,6 +278,19 @@ public class FlightConfigurationPanel extends JPanel implements StateChangeListe
} }
private List<FlightConfigurationId> getSelectedConfigurationIds() {
switch (tabs.getSelectedIndex()) {
case MOTOR_TAB_INDEX:
return this.motorConfigurationPanel.getSelectedConfigurationIds();
case RECOVERY_TAB_INDEX:
return this.recoveryConfigurationPanel.getSelectedConfigurationIds();
case SEPARATION_TAB_INDEX:
return this.separationConfigurationPanel.getSelectedConfigurationIds();
default:
return null;
}
}
@Override @Override
public void stateChanged(EventObject e) { public void stateChanged(EventObject e) {
updateButtonState(); updateButtonState();

View File

@ -7,6 +7,7 @@ import java.awt.event.ActionListener;
import java.awt.event.KeyEvent; import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter; import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent; import java.awt.event.MouseEvent;
import java.util.List;
import javax.swing.BorderFactory; import javax.swing.BorderFactory;
import javax.swing.AbstractAction; import javax.swing.AbstractAction;
@ -186,7 +187,7 @@ public class MotorConfigurationPanel extends FlightConfigurablePanel<MotorMount>
JTable configurationTable = new JTable(configurationTableModel); JTable configurationTable = new JTable(configurationTableModel);
configurationTable.getTableHeader().setReorderingAllowed(false); configurationTable.getTableHeader().setReorderingAllowed(false);
configurationTable.setCellSelectionEnabled(true); configurationTable.setCellSelectionEnabled(true);
configurationTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); configurationTable.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
configurationTable.setDefaultRenderer(Object.class, new MotorTableCellRenderer()); configurationTable.setDefaultRenderer(Object.class, new MotorTableCellRenderer());
configurationTable.addMouseListener(new MouseAdapter() { configurationTable.addMouseListener(new MouseAdapter() {
@ -224,86 +225,140 @@ public class MotorConfigurationPanel extends FlightConfigurablePanel<MotorMount>
} }
public void selectMotor() { public void selectMotor() {
MotorMount curMount = getSelectedComponent(); List<MotorMount> mounts = getSelectedComponents();
FlightConfigurationId fcid= getSelectedConfigurationId(); List<FlightConfigurationId> fcIds = getSelectedConfigurationIds();
if ( (null == fcid )||( null == curMount )){ if ((mounts == null) || (fcIds == null) || mounts.size() == 0 || fcIds.size() == 0) {
return; return;
} }
if( fcid.equals( FlightConfigurationId.DEFAULT_VALUE_FCID)){ boolean update = false;
throw new IllegalStateException("Attempting to set a motor on the default FCID."); MotorMount initMount = mounts.get(0);
} FlightConfigurationId initFcId = fcIds.get(0);
double initDelay = curMount.getMotorConfig(fcid).getEjectionDelay(); for (FlightConfigurationId fcId : fcIds) {
if (fcId.equals( FlightConfigurationId.DEFAULT_VALUE_FCID)) {
throw new IllegalStateException("Attempting to set a motor on the default FCID.");
}
}
motorChooserDialog.setMotorMountAndConfig( fcid, curMount ); double initDelay = initMount.getMotorConfig(initFcId).getEjectionDelay();
motorChooserDialog.setMotorMountAndConfig(initFcId, initMount);
motorChooserDialog.setVisible(true); motorChooserDialog.setVisible(true);
Motor mtr = motorChooserDialog.getSelectedMotor(); Motor mtr = motorChooserDialog.getSelectedMotor();
double d = motorChooserDialog.getSelectedDelay(); double d = motorChooserDialog.getSelectedDelay();
if (mtr != null) {
if (mtr == curMount.getMotorConfig(fcid).getMotor() && d == initDelay) {
return;
}
final MotorConfiguration templateConfig = curMount.getMotorConfig(fcid);
final MotorConfiguration newConfig = new MotorConfiguration( curMount, fcid, templateConfig);
newConfig.setMotor(mtr);
newConfig.setEjectionDelay(d);
curMount.setMotorConfig( newConfig, fcid);
if (mtr != null) {
for (MotorMount mount : mounts) {
for (FlightConfigurationId fcId : fcIds) {
if (mtr != mount.getMotorConfig(fcId).getMotor() || d != initDelay) {
update = true;
final MotorConfiguration templateConfig = mount.getMotorConfig(fcId);
final MotorConfiguration newConfig = new MotorConfiguration(mount, fcId, templateConfig);
newConfig.setMotor(mtr);
newConfig.setEjectionDelay(d);
mount.setMotorConfig(newConfig, fcId);
}
}
}
}
if (update) {
fireTableDataChanged(ComponentChangeEvent.MOTOR_CHANGE); fireTableDataChanged(ComponentChangeEvent.MOTOR_CHANGE);
} }
} }
private void removeMotor() { private void removeMotor() {
MotorMount curMount = getSelectedComponent(); List<MotorMount> mounts = getSelectedComponents();
FlightConfigurationId fcid= getSelectedConfigurationId(); List<FlightConfigurationId> fcIds = getSelectedConfigurationIds();
if ( (null == fcid )||( null == curMount )){ if ((mounts == null) || (fcIds == null) || mounts.size() == 0 || fcIds.size() == 0) {
return; return;
} }
curMount.setMotorConfig( null, fcid); for (MotorMount mount : mounts) {
for (FlightConfigurationId fcId : fcIds) {
mount.setMotorConfig(null, fcId);
}
}
fireTableDataChanged(ComponentChangeEvent.MOTOR_CHANGE); fireTableDataChanged(ComponentChangeEvent.MOTOR_CHANGE);
} }
private void selectIgnition() { private void selectIgnition() {
MotorMount curMount = getSelectedComponent(); List<MotorMount> mounts = getSelectedComponents();
FlightConfigurationId fcid = getSelectedConfigurationId(); List<FlightConfigurationId> fcIds = getSelectedConfigurationIds();
if ((null == fcid) || (null == curMount)) { if ((mounts == null) || (fcIds == null) || mounts.size() == 0 || fcIds.size() == 0) {
return; return;
} }
MotorConfiguration curInstance = curMount.getMotorConfig(fcid); boolean update = false;
IgnitionEvent initialIgnitionEvent = curInstance.getIgnitionEvent(); MotorMount initMount = mounts.get(0);
double initialIgnitionDelay = curInstance.getIgnitionDelay(); FlightConfigurationId initFcId = fcIds.get(0);
MotorConfiguration initConfig = initMount.getMotorConfig(initFcId);
IgnitionEvent initialIgnitionEvent = initConfig.getIgnitionEvent();
double initialIgnitionDelay = initConfig.getIgnitionDelay();
// this call also performs the update changes // this call also performs the update changes
IgnitionSelectionDialog ignitionDialog = new IgnitionSelectionDialog( IgnitionSelectionDialog ignitionDialog = new IgnitionSelectionDialog(
SwingUtilities.getWindowAncestor(this.flightConfigurationPanel), SwingUtilities.getWindowAncestor(this.flightConfigurationPanel),
fcid, initFcId,
curMount); initMount);
ignitionDialog.setVisible(true); ignitionDialog.setVisible(true);
if (!initialIgnitionEvent.equals(curInstance.getIgnitionEvent()) || (initialIgnitionDelay != curInstance.getIgnitionDelay())) { if (!initialIgnitionEvent.equals(initConfig.getIgnitionEvent()) || (initialIgnitionDelay != initConfig.getIgnitionDelay())) {
update = true;
}
for (int i = 0; i < mounts.size(); i++) {
for (int j = 0; j < fcIds.size(); j++) {
if ((i == 0) && (j == 0)) break;
MotorConfiguration config = mounts.get(i).getMotorConfig(fcIds.get(j));
initialIgnitionEvent = config.getIgnitionEvent();
initialIgnitionDelay = config.getIgnitionDelay();
config.setIgnitionEvent(initConfig.getIgnitionEvent());
config.setIgnitionDelay(initConfig.getIgnitionDelay());
if (!initialIgnitionEvent.equals(config.getIgnitionEvent()) || (initialIgnitionDelay != config.getIgnitionDelay())) {
update = true;
}
}
}
if (update) {
fireTableDataChanged(ComponentChangeEvent.MOTOR_CHANGE); fireTableDataChanged(ComponentChangeEvent.MOTOR_CHANGE);
} }
} }
private void resetIgnition() { private void resetIgnition() {
MotorMount curMount = getSelectedComponent(); List<MotorMount> mounts = getSelectedComponents();
FlightConfigurationId fcid= getSelectedConfigurationId(); List<FlightConfigurationId> fcIds = getSelectedConfigurationIds();
if ( (null == fcid )||( null == curMount )){ if ((mounts == null) || (fcIds == null) || mounts.size() == 0 || fcIds.size() == 0) {
return; return;
} }
MotorConfiguration curInstance = curMount.getMotorConfig(fcid);
IgnitionEvent initialIgnitionEvent = curInstance.getIgnitionEvent();
double initialIgnitionDelay = curInstance.getIgnitionDelay();
curInstance.useDefaultIgnition(); boolean update = false;
for (MotorMount mount : mounts) {
for (FlightConfigurationId fcId : fcIds) {
MotorConfiguration config = mount.getMotorConfig(fcId);
IgnitionEvent initialIgnitionEvent = config.getIgnitionEvent();
double initialIgnitionDelay = config.getIgnitionDelay();
if (!initialIgnitionEvent.equals(curInstance.getIgnitionEvent()) || (initialIgnitionDelay != curInstance.getIgnitionDelay())) { config.useDefaultIgnition();
if (!initialIgnitionEvent.equals(config.getIgnitionEvent()) || (initialIgnitionDelay != config.getIgnitionDelay())) {
update = true;
}
}
}
if (update) {
fireTableDataChanged(ComponentChangeEvent.MOTOR_CHANGE); fireTableDataChanged(ComponentChangeEvent.MOTOR_CHANGE);
} }
} }

View File

@ -5,6 +5,7 @@ import java.awt.event.ActionListener;
import java.awt.event.KeyEvent; import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter; import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent; import java.awt.event.MouseEvent;
import java.util.List;
import javax.swing.AbstractAction; import javax.swing.AbstractAction;
import javax.swing.JButton; import javax.swing.JButton;
@ -82,7 +83,7 @@ public class RecoveryConfigurationPanel extends FlightConfigurablePanel<Recovery
JTable recoveryTable = new JTable(recoveryTableModel); JTable recoveryTable = new JTable(recoveryTableModel);
recoveryTable.getTableHeader().setReorderingAllowed(false); recoveryTable.getTableHeader().setReorderingAllowed(false);
recoveryTable.setCellSelectionEnabled(true); recoveryTable.setCellSelectionEnabled(true);
recoveryTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); recoveryTable.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
recoveryTable.addMouseListener(new MouseAdapter() { recoveryTable.addMouseListener(new MouseAdapter() {
@Override @Override
public void mouseClicked(MouseEvent e) { public void mouseClicked(MouseEvent e) {
@ -112,30 +113,74 @@ public class RecoveryConfigurationPanel extends FlightConfigurablePanel<Recovery
} }
public void selectDeployment() { public void selectDeployment() {
RecoveryDevice c = getSelectedComponent(); List<RecoveryDevice> devices = getSelectedComponents();
FlightConfigurationId fcid = getSelectedConfigurationId(); List<FlightConfigurationId> fcIds = getSelectedConfigurationIds();
if ((c == null) || (fcid == null)) { if ((devices == null) || (fcIds == null) || (devices.size() == 0) || fcIds.size() == 0) {
return; return;
} }
DeploymentConfiguration initialConfig = c.getDeploymentConfigurations().get(fcid).copy(fcid);
JDialog d = new DeploymentSelectionDialog(SwingUtilities.getWindowAncestor(this), rocket, c); boolean update = false;
RecoveryDevice initDevice = devices.get(0);
FlightConfigurationId initFcId = fcIds.get(0);
DeploymentConfiguration initialConfig = initDevice.getDeploymentConfigurations().get(initFcId).copy(initFcId);
JDialog d = new DeploymentSelectionDialog(SwingUtilities.getWindowAncestor(this), rocket, initDevice);
d.setVisible(true); d.setVisible(true);
if (!initialConfig.equals(c.getDeploymentConfigurations().get(fcid))) {
if (!initialConfig.equals(initDevice.getDeploymentConfigurations().get(initFcId))) {
update = true;
}
double deployDelay = initDevice.getDeploymentConfigurations().get(initFcId).getDeployDelay();
double deployAltitude = initDevice.getDeploymentConfigurations().get(initFcId).getDeployAltitude();
DeployEvent deployEvent = initDevice.getDeploymentConfigurations().get(initFcId).getDeployEvent();
for (int i = 0; i < devices.size(); i++) {
for (int j = 0; j < fcIds.size(); j++) {
if ((i == 0) && (j == 0)) break;
final RecoveryDevice device = devices.get(i);
final FlightConfigurationId fcId = fcIds.get(j);
DeploymentConfiguration config = device.getDeploymentConfigurations().get(fcId).copy(fcId);
initialConfig = config.copy(fcId);
config.setDeployDelay(deployDelay);
config.setDeployAltitude(deployAltitude);
config.setDeployEvent(deployEvent);
device.getDeploymentConfigurations().set(fcId, config);
if (!initialConfig.equals(device.getDeploymentConfigurations().get(fcId))) {
update = true;
}
}
}
if (update) {
fireTableDataChanged(ComponentChangeEvent.AERODYNAMIC_CHANGE); fireTableDataChanged(ComponentChangeEvent.AERODYNAMIC_CHANGE);
} }
} }
private void resetDeployment() { private void resetDeployment() {
RecoveryDevice c = getSelectedComponent(); List<RecoveryDevice> devices = getSelectedComponents();
FlightConfigurationId fcid = getSelectedConfigurationId(); List<FlightConfigurationId> fcIds = getSelectedConfigurationIds();
if ((c == null) || (fcid == null)) { if ((devices == null) || (fcIds == null) || (devices.size() == 0) || fcIds.size() == 0) {
return; return;
} }
DeploymentConfiguration initialConfig = c.getDeploymentConfigurations().get(fcid).copy(fcid);
FlightConfigurationId id = rocket.getSelectedConfiguration().getFlightConfigurationID(); boolean update = false;
c.getDeploymentConfigurations().reset(id); for (RecoveryDevice device : devices) {
if (!initialConfig.equals(c.getDeploymentConfigurations().get(fcid))) { for (FlightConfigurationId fcId : fcIds) {
DeploymentConfiguration initialConfig = device.getDeploymentConfigurations().get(fcId).copy(fcId);
device.getDeploymentConfigurations().reset(fcId);
if (!initialConfig.equals(device.getDeploymentConfigurations().get(fcId))) {
update = true;
}
}
}
if (update) {
fireTableDataChanged(ComponentChangeEvent.AERODYNAMIC_CHANGE); fireTableDataChanged(ComponentChangeEvent.AERODYNAMIC_CHANGE);
} }
} }

View File

@ -5,6 +5,7 @@ import java.awt.event.ActionListener;
import java.awt.event.KeyEvent; import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter; import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent; import java.awt.event.MouseEvent;
import java.util.List;
import javax.swing.AbstractAction; import javax.swing.AbstractAction;
import javax.swing.JButton; import javax.swing.JButton;
@ -25,6 +26,7 @@ import net.sf.openrocket.rocketcomponent.ComponentChangeEvent;
import net.sf.openrocket.rocketcomponent.FlightConfigurationId; import net.sf.openrocket.rocketcomponent.FlightConfigurationId;
import net.sf.openrocket.rocketcomponent.Rocket; import net.sf.openrocket.rocketcomponent.Rocket;
import net.sf.openrocket.rocketcomponent.StageSeparationConfiguration; import net.sf.openrocket.rocketcomponent.StageSeparationConfiguration;
import net.sf.openrocket.rocketcomponent.StageSeparationConfiguration.SeparationEvent;
import net.sf.openrocket.startup.Application; import net.sf.openrocket.startup.Application;
import net.sf.openrocket.unit.UnitGroup; import net.sf.openrocket.unit.UnitGroup;
import net.sf.openrocket.gui.widgets.SelectColorButton; import net.sf.openrocket.gui.widgets.SelectColorButton;
@ -101,7 +103,7 @@ public class SeparationConfigurationPanel extends FlightConfigurablePanel<AxialS
JTable separationTable = new JTable(separationTableModel); JTable separationTable = new JTable(separationTableModel);
separationTable.getTableHeader().setReorderingAllowed(false); separationTable.getTableHeader().setReorderingAllowed(false);
separationTable.setCellSelectionEnabled(true); separationTable.setCellSelectionEnabled(true);
separationTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); separationTable.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
separationTable.addMouseListener(new MouseAdapter() { separationTable.addMouseListener(new MouseAdapter() {
@Override @Override
public void mouseClicked(MouseEvent e) { public void mouseClicked(MouseEvent e) {
@ -118,32 +120,75 @@ public class SeparationConfigurationPanel extends FlightConfigurablePanel<AxialS
} }
public void selectSeparation() { public void selectSeparation() {
AxialStage stage = getSelectedComponent(); List<AxialStage> stages = getSelectedComponents();
FlightConfigurationId fcid = getSelectedConfigurationId(); List<FlightConfigurationId> fcIds = getSelectedConfigurationIds();
if ((stage == null) || (fcid == null)) { if ((stages == null) || (fcIds == null) || (stages.size() == 0) || (fcIds.size() == 0)) {
return; return;
} }
StageSeparationConfiguration initialConfig = stage.getSeparationConfigurations().get(fcid).copy(fcid);
JDialog d = new SeparationSelectionDialog(SwingUtilities.getWindowAncestor(this), rocket, stage); boolean update = false;
AxialStage initStage = stages.get(0);
FlightConfigurationId initFcId = fcIds.get(0);
StageSeparationConfiguration initialConfig = initStage.getSeparationConfigurations().get(initFcId).copy(initFcId);
JDialog d = new SeparationSelectionDialog(SwingUtilities.getWindowAncestor(this), rocket, initStage);
d.setVisible(true); d.setVisible(true);
if (!initialConfig.equals(stage.getSeparationConfigurations().get(fcid))) {
if (!initialConfig.equals(initStage.getSeparationConfigurations().get(initFcId))) {
update = true;
}
double separationDelay = initStage.getSeparationConfigurations().get(initFcId).getSeparationDelay();
SeparationEvent separationEvent= initStage.getSeparationConfigurations().get(initFcId).getSeparationEvent();
for (int i = 0; i < stages.size(); i++) {
for (int j = 0; j < fcIds.size(); j++) {
if ((i == 0) && (j == 0)) break;
final AxialStage stage = stages.get(i);
final FlightConfigurationId fcId = fcIds.get(j);
StageSeparationConfiguration config = stage.getSeparationConfigurations().get(fcId);
initialConfig = config.copy(fcId);
if (stage.getSeparationConfigurations().isDefault(config)) {
config = config.clone();
}
config.setSeparationDelay(separationDelay);
config.setSeparationEvent(separationEvent);
stage.getSeparationConfigurations().set(fcId, config);
if (!initialConfig.equals(config)) {
update = true;
}
}
}
if (update) {
fireTableDataChanged(ComponentChangeEvent.AEROMASS_CHANGE); fireTableDataChanged(ComponentChangeEvent.AEROMASS_CHANGE);
} }
} }
private void resetSeparation() { private void resetSeparation() {
AxialStage stage = getSelectedComponent(); List<AxialStage> stages = getSelectedComponents();
FlightConfigurationId fcid = getSelectedConfigurationId(); List<FlightConfigurationId> fcIds = getSelectedConfigurationIds();
if ((stage == null) || (fcid == null)) { if ((stages == null) || (fcIds == null) || (stages.size() == 0) || (fcIds.size() == 0)) {
return; return;
} }
StageSeparationConfiguration initialConfig = stage.getSeparationConfigurations().get(fcid).copy(fcid); boolean update = false;
// why? for (AxialStage stage : stages) {
FlightConfigurationId id = rocket.getSelectedConfiguration().getFlightConfigurationID(); for (FlightConfigurationId fcId : fcIds) {
stage.getSeparationConfigurations().reset(id); StageSeparationConfiguration initialConfig = stage.getSeparationConfigurations().get(fcId).copy(fcId);
stage.getSeparationConfigurations().reset(fcId);
if (!initialConfig.equals(stage.getSeparationConfigurations().get(fcid))) { if (!initialConfig.equals(stage.getSeparationConfigurations().get(fcId))) {
update = true;
}
}
}
if (update) {
fireTableDataChanged(ComponentChangeEvent.AEROMASS_CHANGE); fireTableDataChanged(ComponentChangeEvent.AEROMASS_CHANGE);
} }
} }