001package jmri.jmrit.operations.rollingstock.engines.tools;
002
003import java.util.ArrayList;
004import java.util.List;
005
006import javax.swing.JTable;
007
008import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
009import jmri.jmrit.operations.rollingstock.engines.*;
010import jmri.util.swing.JmriJOptionPane;
011
012/**
013 * Frame for user to modify a group of engines on the layout
014 *
015 * @author Dan Boudreau Copyright (C) 2024
016 */
017public class EnginesSetFrame extends EngineSetFrame {
018
019    EnginesTableModel _enginesTableModel;
020    JTable _enginesTable;
021
022    public EnginesSetFrame() {
023        super();
024    }
025
026    // Ignore checkbox states
027    private static boolean ignoreStatusCheckBoxSelected = true;
028    private static boolean ignoreLocationCheckBoxSelected = true;
029    private static boolean ignoreConsistCheckBoxSelected = true;
030    private static boolean ignoreDestinationCheckBoxSelected = true;
031    private static boolean ignoreTrainCheckBoxSelected = true;
032
033    public void initComponents(JTable enginesTable) {
034        _enginesTable = enginesTable;
035        _enginesTableModel = (EnginesTableModel) enginesTable.getModel();
036
037        super.initComponents("package.jmri.jmrit.operations.Operations_SetEngines");
038
039        setTitle(Bundle.getMessage("TitleSetEngines"));
040        // modify Save button text to "Apply";
041        saveButton.setText(Bundle.getMessage("ButtonApply"));
042
043        // show ignore checkboxes
044        ignoreStatusCheckBox.setVisible(true);
045        ignoreLocationCheckBox.setVisible(true);
046        ignoreConsistCheckBox.setVisible(true);
047        ignoreDestinationCheckBox.setVisible(true);
048        ignoreTrainCheckBox.setVisible(true);
049        ignoreAllButton.setVisible(true);
050
051        // set the last state
052        ignoreStatusCheckBox.setSelected(ignoreStatusCheckBoxSelected);
053        ignoreLocationCheckBox.setSelected(ignoreLocationCheckBoxSelected);
054        ignoreConsistCheckBox.setSelected(ignoreConsistCheckBoxSelected);
055        ignoreDestinationCheckBox.setSelected(ignoreDestinationCheckBoxSelected);
056        ignoreTrainCheckBox.setSelected(ignoreTrainCheckBoxSelected);
057
058        // first engine in the list becomes the master
059        int rows[] = _enginesTable.getSelectedRows();
060        if (rows.length > 0) {
061            Engine engine = _enginesTableModel.getEngineAtIndex(_enginesTable.convertRowIndexToModel(rows[0]));
062            super.load(engine);
063        } else {
064            enableComponents(true);
065            showMessageDialogWarning();
066        }
067    }
068
069    @Override
070    public void buttonActionPerformed(java.awt.event.ActionEvent ae) {
071        super.buttonActionPerformed(ae);
072        if (ae.getSource() == ignoreAllButton) {
073            ignoreAll(toggle);
074        }
075    }
076
077    boolean toggle = false;
078
079    protected void ignoreAll(boolean b) {
080        ignoreStatusCheckBox.setSelected(!locationUnknownCheckBox.isSelected() & b);
081        ignoreLocationCheckBox.setSelected(b);
082        ignoreConsistCheckBox.setSelected(b);
083        ignoreDestinationCheckBox.setSelected(b);
084        ignoreTrainCheckBox.setSelected(b);
085        enableComponents(!locationUnknownCheckBox.isSelected());
086        toggle = !b;
087    }
088
089    @Override
090    @SuppressFBWarnings(value = "ST_WRITE_TO_STATIC_FROM_INSTANCE_METHOD", justification = "GUI ease of use")
091    protected boolean save() {
092        // save ignore states
093        ignoreStatusCheckBoxSelected = ignoreStatusCheckBox.isSelected();
094        ignoreLocationCheckBoxSelected = ignoreLocationCheckBox.isSelected();
095        ignoreConsistCheckBoxSelected = ignoreConsistCheckBox.isSelected();
096        ignoreDestinationCheckBoxSelected = ignoreConsistCheckBox.isSelected();
097        ignoreTrainCheckBoxSelected = ignoreTrainCheckBox.isSelected();
098
099        // need to get selected engines before they are modified their location in the table can change
100        List<Engine> engines = new ArrayList<Engine>();
101        int rows[] = _enginesTable.getSelectedRows();
102        for (int row : rows) {
103            Engine engine = _enginesTableModel.getEngineAtIndex(_enginesTable.convertRowIndexToModel(row));
104            log.debug("Adding selected engine {} to change list", engine.toString());
105            engines.add(engine);
106        }
107        if (rows.length == 0) {
108            showMessageDialogWarning();
109            return false;
110        } else if (engines.get(0) != _engine) {
111            log.debug("Default engine isn't the first one selected");
112            if (JmriJOptionPane.showConfirmDialog(this, Bundle
113                    .getMessage("doYouWantToChange", engines.get(0).toString()),
114                    Bundle
115                            .getMessage("changeDefaultEngine"),
116                    JmriJOptionPane.YES_NO_OPTION) == JmriJOptionPane.YES_OPTION) {
117                super.load(engines.get(0)); // new default engine
118                return false; // done, don't modify any of the engines selected
119            }
120        }
121
122        // don't ask for to change engines in a consist when giving a selected group of engines a new consist name
123        askConsistChange = false;
124        
125        // determine if all engines in every consist are selected
126        for (Engine engine : engines) {
127            if (engine.getConsist() != null) {
128                for (Engine c : engine.getConsist().getEngines()) {
129                    if (!engines.contains(c)) {
130                        askConsistChange = true; // not all selected
131                        break;
132                    }
133                }
134            }
135        }
136
137        for (Engine engine : engines) {
138            if (!super.change(engine)) {
139                return false;
140            } else if (engine.getConsist() != null && !ignoreConsistCheckBox.isSelected()) {
141                askConsistChange = false; // changing consist name
142            }
143        }
144        return false; // all good, but don't close window
145    }
146    
147    private void showMessageDialogWarning() {
148        JmriJOptionPane.showMessageDialog(this, Bundle.getMessage("selectEngines"), Bundle
149                .getMessage("engineNoneSelected"), JmriJOptionPane.WARNING_MESSAGE);
150    }
151
152    private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(EnginesSetFrame.class);
153}