diff --git a/swing/src/net/sf/openrocket/gui/main/flightconfigpanel/FlightConfigurablePanel.java b/swing/src/net/sf/openrocket/gui/main/flightconfigpanel/FlightConfigurablePanel.java index a937c56dd..593cbdc8a 100644 --- a/swing/src/net/sf/openrocket/gui/main/flightconfigpanel/FlightConfigurablePanel.java +++ b/swing/src/net/sf/openrocket/gui/main/flightconfigpanel/FlightConfigurablePanel.java @@ -3,6 +3,9 @@ package net.sf.openrocket.gui.main.flightconfigpanel; import java.awt.Color; import java.awt.Component; import java.awt.Font; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; import javax.swing.JComponent; import javax.swing.JLabel; @@ -17,6 +20,7 @@ import javax.swing.event.ListSelectionListener; import javax.swing.table.AbstractTableModel; import javax.swing.table.DefaultTableCellRenderer; +import net.sf.openrocket.util.ArrayList; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -183,6 +187,27 @@ public abstract class FlightConfigurablePanel 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 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 selectedComponent = (Pair) tableValue; + components.add(selectedComponent.getV()); + } + } + } + return components; + } + protected FlightConfigurationId getSelectedConfigurationId() { int col = table.convertColumnIndexToModel(table.getSelectedColumn()); int row = table.convertRowIndexToModel(table.getSelectedRow()); @@ -201,6 +226,31 @@ public abstract class FlightConfigurablePanel 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 Ids = new ArrayList<>(); + for (Object tableValue : tableValues) { + if (tableValue instanceof Pair) { + @SuppressWarnings("unchecked") + Pair selectedComponent = (Pair) 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 { @Override diff --git a/swing/src/net/sf/openrocket/gui/main/flightconfigpanel/MotorConfigurationPanel.java b/swing/src/net/sf/openrocket/gui/main/flightconfigpanel/MotorConfigurationPanel.java index 457c8644f..81d3e1df0 100644 --- a/swing/src/net/sf/openrocket/gui/main/flightconfigpanel/MotorConfigurationPanel.java +++ b/swing/src/net/sf/openrocket/gui/main/flightconfigpanel/MotorConfigurationPanel.java @@ -9,6 +9,7 @@ import java.awt.event.FocusListener; import java.awt.event.KeyEvent; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; +import java.util.List; import javax.swing.BorderFactory; import javax.swing.AbstractAction; @@ -189,7 +190,7 @@ public class MotorConfigurationPanel extends FlightConfigurablePanel JTable configurationTable = new JTable(configurationTableModel); configurationTable.getTableHeader().setReorderingAllowed(false); configurationTable.setCellSelectionEnabled(true); - configurationTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); + configurationTable.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION); configurationTable.setDefaultRenderer(Object.class, new MotorTableCellRenderer()); configurationTable.addMouseListener(new MouseAdapter() { @@ -261,86 +262,140 @@ public class MotorConfigurationPanel extends FlightConfigurablePanel } public void selectMotor() { - MotorMount curMount = getSelectedComponent(); - FlightConfigurationId fcid= getSelectedConfigurationId(); - if ( (null == fcid )||( null == curMount )){ - return; - } + List mounts = getSelectedComponents(); + List fcIds = getSelectedConfigurationIds(); + if ((mounts == null) || (fcIds == null) || mounts.size() == 0 || fcIds.size() == 0) { + return; + } - if( fcid.equals( FlightConfigurationId.DEFAULT_VALUE_FCID)){ - throw new IllegalStateException("Attempting to set a motor on the default FCID."); - } + boolean update = false; + 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); Motor mtr = motorChooserDialog.getSelectedMotor(); 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); } } private void removeMotor() { - MotorMount curMount = getSelectedComponent(); - FlightConfigurationId fcid= getSelectedConfigurationId(); - if ( (null == fcid )||( null == curMount )){ + List mounts = getSelectedComponents(); + List fcIds = getSelectedConfigurationIds(); + if ((mounts == null) || (fcIds == null) || mounts.size() == 0 || fcIds.size() == 0) { return; } - - curMount.setMotorConfig( null, fcid); + + for (MotorMount mount : mounts) { + for (FlightConfigurationId fcId : fcIds) { + mount.setMotorConfig(null, fcId); + } + } fireTableDataChanged(ComponentChangeEvent.MOTOR_CHANGE); } private void selectIgnition() { - MotorMount curMount = getSelectedComponent(); - FlightConfigurationId fcid = getSelectedConfigurationId(); - if ((null == fcid) || (null == curMount)) { + List mounts = getSelectedComponents(); + List fcIds = getSelectedConfigurationIds(); + if ((mounts == null) || (fcIds == null) || mounts.size() == 0 || fcIds.size() == 0) { return; } - MotorConfiguration curInstance = curMount.getMotorConfig(fcid); - IgnitionEvent initialIgnitionEvent = curInstance.getIgnitionEvent(); - double initialIgnitionDelay = curInstance.getIgnitionDelay(); + boolean update = false; + MotorMount initMount = mounts.get(0); + 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 IgnitionSelectionDialog ignitionDialog = new IgnitionSelectionDialog( SwingUtilities.getWindowAncestor(this.flightConfigurationPanel), - fcid, - curMount); + initFcId, + initMount); 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); } } private void resetIgnition() { - MotorMount curMount = getSelectedComponent(); - FlightConfigurationId fcid= getSelectedConfigurationId(); - if ( (null == fcid )||( null == curMount )){ - return; - } - MotorConfiguration curInstance = curMount.getMotorConfig(fcid); - IgnitionEvent initialIgnitionEvent = curInstance.getIgnitionEvent(); - double initialIgnitionDelay = curInstance.getIgnitionDelay(); - - curInstance.useDefaultIgnition(); + List mounts = getSelectedComponents(); + List fcIds = getSelectedConfigurationIds(); + if ((mounts == null) || (fcIds == null) || mounts.size() == 0 || fcIds.size() == 0) { + return; + } - if (!initialIgnitionEvent.equals(curInstance.getIgnitionEvent()) || (initialIgnitionDelay != curInstance.getIgnitionDelay())) { + boolean update = false; + for (MotorMount mount : mounts) { + for (FlightConfigurationId fcId : fcIds) { + MotorConfiguration config = mount.getMotorConfig(fcId); + IgnitionEvent initialIgnitionEvent = config.getIgnitionEvent(); + double initialIgnitionDelay = config.getIgnitionDelay(); + + config.useDefaultIgnition(); + + if (!initialIgnitionEvent.equals(config.getIgnitionEvent()) || (initialIgnitionDelay != config.getIgnitionDelay())) { + update = true; + } + } + } + + if (update) { fireTableDataChanged(ComponentChangeEvent.MOTOR_CHANGE); } } diff --git a/swing/src/net/sf/openrocket/gui/main/flightconfigpanel/RecoveryConfigurationPanel.java b/swing/src/net/sf/openrocket/gui/main/flightconfigpanel/RecoveryConfigurationPanel.java index 5cf62c634..d1e914c09 100644 --- a/swing/src/net/sf/openrocket/gui/main/flightconfigpanel/RecoveryConfigurationPanel.java +++ b/swing/src/net/sf/openrocket/gui/main/flightconfigpanel/RecoveryConfigurationPanel.java @@ -5,6 +5,7 @@ import java.awt.event.ActionListener; import java.awt.event.KeyEvent; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; +import java.util.List; import javax.swing.AbstractAction; import javax.swing.JButton; @@ -82,7 +83,7 @@ public class RecoveryConfigurationPanel extends FlightConfigurablePanel devices = getSelectedComponents(); + List fcIds = getSelectedConfigurationIds(); + if ((devices == null) || (fcIds == null) || (devices.size() == 0) || fcIds.size() == 0) { 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); - 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); } } private void resetDeployment() { - RecoveryDevice c = getSelectedComponent(); - FlightConfigurationId fcid = getSelectedConfigurationId(); - if ((c == null) || (fcid == null)) { + List devices = getSelectedComponents(); + List fcIds = getSelectedConfigurationIds(); + if ((devices == null) || (fcIds == null) || (devices.size() == 0) || fcIds.size() == 0) { return; } - DeploymentConfiguration initialConfig = c.getDeploymentConfigurations().get(fcid).copy(fcid); - FlightConfigurationId id = rocket.getSelectedConfiguration().getFlightConfigurationID(); - c.getDeploymentConfigurations().reset(id); - if (!initialConfig.equals(c.getDeploymentConfigurations().get(fcid))) { + + boolean update = false; + for (RecoveryDevice device : devices) { + 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); } } diff --git a/swing/src/net/sf/openrocket/gui/main/flightconfigpanel/SeparationConfigurationPanel.java b/swing/src/net/sf/openrocket/gui/main/flightconfigpanel/SeparationConfigurationPanel.java index 4114bb01d..6fea6265a 100644 --- a/swing/src/net/sf/openrocket/gui/main/flightconfigpanel/SeparationConfigurationPanel.java +++ b/swing/src/net/sf/openrocket/gui/main/flightconfigpanel/SeparationConfigurationPanel.java @@ -5,6 +5,7 @@ import java.awt.event.ActionListener; import java.awt.event.KeyEvent; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; +import java.util.List; import javax.swing.AbstractAction; 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.Rocket; import net.sf.openrocket.rocketcomponent.StageSeparationConfiguration; +import net.sf.openrocket.rocketcomponent.StageSeparationConfiguration.SeparationEvent; import net.sf.openrocket.startup.Application; import net.sf.openrocket.unit.UnitGroup; import net.sf.openrocket.gui.widgets.SelectColorButton; @@ -101,7 +103,7 @@ public class SeparationConfigurationPanel extends FlightConfigurablePanel stages = getSelectedComponents(); + List fcIds = getSelectedConfigurationIds(); + if ((stages == null) || (fcIds == null) || (stages.size() == 0) || (fcIds.size() == 0)) { 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); - 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); } } private void resetSeparation() { - AxialStage stage = getSelectedComponent(); - FlightConfigurationId fcid = getSelectedConfigurationId(); - if ((stage == null) || (fcid == null)) { + List stages = getSelectedComponents(); + List fcIds = getSelectedConfigurationIds(); + if ((stages == null) || (fcIds == null) || (stages.size() == 0) || (fcIds.size() == 0)) { return; } - StageSeparationConfiguration initialConfig = stage.getSeparationConfigurations().get(fcid).copy(fcid); - // why? - FlightConfigurationId id = rocket.getSelectedConfiguration().getFlightConfigurationID(); - stage.getSeparationConfigurations().reset(id); + boolean update = false; + for (AxialStage stage : stages) { + for (FlightConfigurationId fcId : fcIds) { + 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); } }