001package jmri.jmrit.operations.rollingstock.cars.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.cars.*;
010import jmri.util.swing.JmriJOptionPane;
011
012/**
013 * Frame for user to place a group of cars on the layout
014 *
015 * @author Dan Boudreau Copyright (C) 2011, 2013, 2023
016 */
017public class CarsSetFrame extends CarSetFrame {
018
019    CarsTableModel _carsTableModel;
020    JTable _carsTable;
021
022    public CarsSetFrame() {
023        super();
024    }
025
026    // Ignore checkbox states
027    private static boolean ignoreStatusCheckBoxSelected = true;
028    private static boolean ignoreLocationCheckBoxSelected = true;
029    private static boolean ignoreDivisionCheckBoxSelected = true;
030    private static boolean ignoreRWECheckBoxSelected = true;
031    private static boolean ignoreRWLCheckBoxSelected = true;
032    private static boolean ignoreLoadCheckBoxSelected = true;
033    private static boolean ignoreKernelCheckBoxSelected = true;
034    private static boolean ignoreDestinationCheckBoxSelected = true;
035    private static boolean ignoreFinalDestinationCheckBoxSelected = true;
036    private static boolean ignoreTrainCheckBoxSelected = true;
037
038    public void initComponents(JTable carsTable) {
039        _carsTable = carsTable;
040        _carsTableModel = (CarsTableModel) carsTable.getModel();
041
042        super.initComponents("package.jmri.jmrit.operations.Operations_SetCars");
043
044        setTitle(Bundle.getMessage("TitleSetCars"));
045        // modify Save button text to "Apply";
046        saveButton.setText(Bundle.getMessage("ButtonApply"));
047
048        // show ignore checkboxes
049        ignoreStatusCheckBox.setVisible(true);
050        ignoreLocationCheckBox.setVisible(true);
051        ignoreDivisionCheckBox.setVisible(true);
052        ignoreRWECheckBox.setVisible(true);
053        ignoreRWLCheckBox.setVisible(true);
054        ignoreLoadCheckBox.setVisible(true);
055        ignoreKernelCheckBox.setVisible(true);
056        ignoreDestinationCheckBox.setVisible(true);
057        ignoreFinalDestinationCheckBox.setVisible(true);
058        ignoreTrainCheckBox.setVisible(true);
059        ignoreAllButton.setVisible(true);
060
061        // set the last state
062        ignoreStatusCheckBox.setSelected(ignoreStatusCheckBoxSelected);
063        ignoreLocationCheckBox.setSelected(ignoreLocationCheckBoxSelected);
064        ignoreDivisionCheckBox.setSelected(ignoreDivisionCheckBoxSelected);
065        ignoreRWECheckBox.setSelected(ignoreRWECheckBoxSelected);
066        ignoreRWLCheckBox.setSelected(ignoreRWLCheckBoxSelected);
067        ignoreLoadCheckBox.setSelected(ignoreLoadCheckBoxSelected);
068        ignoreKernelCheckBox.setSelected(ignoreKernelCheckBoxSelected);
069        ignoreDestinationCheckBox.setSelected(ignoreDestinationCheckBoxSelected);
070        ignoreFinalDestinationCheckBox.setSelected(ignoreFinalDestinationCheckBoxSelected);
071        ignoreTrainCheckBox.setSelected(ignoreTrainCheckBoxSelected);
072
073        // first car in the list becomes the master
074        int rows[] = _carsTable.getSelectedRows();
075        if (rows.length > 0) {
076            Car car = _carsTableModel.getCarAtIndex(_carsTable.convertRowIndexToModel(rows[0]));
077            super.load(car);
078        } else {
079            enableComponents(true);
080            showMessageDialogWarning();
081        }
082    }
083
084    @Override
085    public void buttonActionPerformed(java.awt.event.ActionEvent ae) {
086        super.buttonActionPerformed(ae);
087        if (ae.getSource() == ignoreAllButton) {
088            ignoreAll(toggle);
089        }
090    }
091
092    boolean toggle = false;
093
094    protected void ignoreAll(boolean b) {
095        ignoreStatusCheckBox.setSelected(!locationUnknownCheckBox.isSelected() & b);
096        ignoreLocationCheckBox.setSelected(b);
097        ignoreDivisionCheckBox.setSelected(b);
098        ignoreRWECheckBox.setSelected(b);
099        ignoreRWLCheckBox.setSelected(b);
100        ignoreLoadCheckBox.setSelected(b);
101        ignoreKernelCheckBox.setSelected(b);
102        ignoreDestinationCheckBox.setSelected(b);
103        ignoreFinalDestinationCheckBox.setSelected(b);
104        ignoreTrainCheckBox.setSelected(b);
105        enableComponents(!locationUnknownCheckBox.isSelected());
106        toggle = !b;
107    }
108
109    @Override
110    @SuppressFBWarnings(value = "ST_WRITE_TO_STATIC_FROM_INSTANCE_METHOD", justification = "GUI ease of use")
111    protected boolean save() {
112        // save ignore states
113        ignoreStatusCheckBoxSelected = ignoreStatusCheckBox.isSelected();
114        ignoreLocationCheckBoxSelected = ignoreLocationCheckBox.isSelected();
115        ignoreDivisionCheckBoxSelected = ignoreDivisionCheckBox.isSelected();
116        ignoreRWECheckBoxSelected = ignoreRWECheckBox.isSelected();
117        ignoreRWLCheckBoxSelected = ignoreRWLCheckBox.isSelected();
118        ignoreLoadCheckBoxSelected = ignoreLoadCheckBox.isSelected();
119        ignoreKernelCheckBoxSelected = ignoreKernelCheckBox.isSelected();
120        ignoreDestinationCheckBoxSelected = ignoreKernelCheckBox.isSelected();
121        ignoreFinalDestinationCheckBoxSelected = ignoreFinalDestinationCheckBox.isSelected();
122        ignoreTrainCheckBoxSelected = ignoreTrainCheckBox.isSelected();
123
124        // need to get selected cars before they are modified their location in the table can change
125        List<Car> cars = new ArrayList<Car>();
126        int rows[] = _carsTable.getSelectedRows();
127        for (int row : rows) {
128            Car car = _carsTableModel.getCarAtIndex(_carsTable.convertRowIndexToModel(row));
129            log.debug("Adding selected car {} to change list", car.toString());
130            cars.add(car);
131        }
132        if (rows.length == 0) {
133            showMessageDialogWarning();
134            return false;
135        } else if (cars.get(0) != _car) {
136            log.debug("Default car isn't the first one selected");
137            if (JmriJOptionPane.showConfirmDialog(this, Bundle
138                    .getMessage("doYouWantToChange", cars.get(0).toString()), Bundle
139                    .getMessage("changeDefaultCar"), JmriJOptionPane.YES_NO_OPTION) == JmriJOptionPane.YES_OPTION) {
140                super.load(cars.get(0)); // new default car
141                return false; // done, don't modify any of the cars selected
142            }
143        }
144
145        // don't ask for to change cars in a kernel when giving a selected group of cars a new kernel name
146        askKernelChange = false;
147        
148        // determine if all cars in every kernel are selected
149        for (Car car : cars) {
150            if (car.getKernel() != null) {
151                for (Car c : car.getKernel().getCars()) {
152                    if (!cars.contains(c)) {
153                        askKernelChange = true; // not all selected
154                        break;
155                    }
156                }
157            }
158        }
159
160        for (Car car : cars) {
161            if (!super.change(car)) {
162                return false;
163            } else if (car.getKernel() != null && !ignoreKernelCheckBox.isSelected()) {
164                askKernelChange = false; // changing kernel name
165            }
166        }
167        return false; // all good, but don't close window
168    }
169    
170    private void showMessageDialogWarning() {
171        JmriJOptionPane.showMessageDialog(this, Bundle.getMessage("selectCars"), Bundle
172                .getMessage("carNoneSelected"), JmriJOptionPane.WARNING_MESSAGE);
173    }
174
175    private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(CarsSetFrame.class);
176}