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        // disable edit load button if no cars selected
048        editLoadButton.setEnabled(false);
049        // show ignore checkboxes
050        ignoreStatusCheckBox.setVisible(true);
051        ignoreLocationCheckBox.setVisible(true);
052        ignoreDivisionCheckBox.setVisible(true);
053        ignoreRWECheckBox.setVisible(true);
054        ignoreRWLCheckBox.setVisible(true);
055        ignoreLoadCheckBox.setVisible(true);
056        ignoreKernelCheckBox.setVisible(true);
057        ignoreDestinationCheckBox.setVisible(true);
058        ignoreFinalDestinationCheckBox.setVisible(true);
059        ignoreTrainCheckBox.setVisible(true);
060        ignoreAllButton.setVisible(true);
061
062        // set the last state
063        ignoreStatusCheckBox.setSelected(ignoreStatusCheckBoxSelected);
064        ignoreLocationCheckBox.setSelected(ignoreLocationCheckBoxSelected);
065        ignoreDivisionCheckBox.setSelected(ignoreDivisionCheckBoxSelected);
066        ignoreRWECheckBox.setSelected(ignoreRWECheckBoxSelected);
067        ignoreRWLCheckBox.setSelected(ignoreRWLCheckBoxSelected);
068        ignoreLoadCheckBox.setSelected(ignoreLoadCheckBoxSelected);
069        ignoreKernelCheckBox.setSelected(ignoreKernelCheckBoxSelected);
070        ignoreDestinationCheckBox.setSelected(ignoreDestinationCheckBoxSelected);
071        ignoreFinalDestinationCheckBox.setSelected(ignoreFinalDestinationCheckBoxSelected);
072        ignoreTrainCheckBox.setSelected(ignoreTrainCheckBoxSelected);
073
074        // first car in the list becomes the master
075        int rows[] = _carsTable.getSelectedRows();
076        if (rows.length > 0) {
077            Car car = _carsTableModel.getCarAtIndex(_carsTable.convertRowIndexToModel(rows[0]));
078            super.load(car);
079        } else {
080            enableComponents(true);
081            showMessageDialogWarning();
082        }
083    }
084
085    @Override
086    public void buttonActionPerformed(java.awt.event.ActionEvent ae) {
087        super.buttonActionPerformed(ae);
088        if (ae.getSource() == ignoreAllButton) {
089            ignoreAll(toggle);
090        }
091    }
092
093    boolean toggle = false;
094
095    protected void ignoreAll(boolean b) {
096        ignoreStatusCheckBox.setSelected(!locationUnknownCheckBox.isSelected() & b);
097        ignoreLocationCheckBox.setSelected(b);
098        ignoreDivisionCheckBox.setSelected(b);
099        ignoreRWECheckBox.setSelected(b);
100        ignoreRWLCheckBox.setSelected(b);
101        ignoreLoadCheckBox.setSelected(b);
102        ignoreKernelCheckBox.setSelected(b);
103        ignoreDestinationCheckBox.setSelected(b);
104        ignoreFinalDestinationCheckBox.setSelected(b);
105        ignoreTrainCheckBox.setSelected(b);
106        enableComponents(!locationUnknownCheckBox.isSelected());
107        toggle = !b;
108    }
109
110    @Override
111    @SuppressFBWarnings(value = "ST_WRITE_TO_STATIC_FROM_INSTANCE_METHOD", justification = "GUI ease of use")
112    protected boolean save() {
113        // save ignore states
114        ignoreStatusCheckBoxSelected = ignoreStatusCheckBox.isSelected();
115        ignoreLocationCheckBoxSelected = ignoreLocationCheckBox.isSelected();
116        ignoreDivisionCheckBoxSelected = ignoreDivisionCheckBox.isSelected();
117        ignoreRWECheckBoxSelected = ignoreRWECheckBox.isSelected();
118        ignoreRWLCheckBoxSelected = ignoreRWLCheckBox.isSelected();
119        ignoreLoadCheckBoxSelected = ignoreLoadCheckBox.isSelected();
120        ignoreKernelCheckBoxSelected = ignoreKernelCheckBox.isSelected();
121        ignoreDestinationCheckBoxSelected = ignoreKernelCheckBox.isSelected();
122        ignoreFinalDestinationCheckBoxSelected = ignoreFinalDestinationCheckBox.isSelected();
123        ignoreTrainCheckBoxSelected = ignoreTrainCheckBox.isSelected();
124
125        // need to get selected cars before they are modified their location in the table can change
126        List<Car> cars = new ArrayList<Car>();
127        int rows[] = _carsTable.getSelectedRows();
128        for (int row : rows) {
129            Car car = _carsTableModel.getCarAtIndex(_carsTable.convertRowIndexToModel(row));
130            log.debug("Adding selected car {} to change list", car.toString());
131            cars.add(car);
132        }
133        if (rows.length == 0) {
134            showMessageDialogWarning();
135            return false;
136        } else if (cars.get(0) != _car) {
137            log.debug("Default car isn't the first one selected");
138            if (JmriJOptionPane.showConfirmDialog(this, Bundle
139                    .getMessage("doYouWantToChange", cars.get(0).toString()), Bundle
140                    .getMessage("changeDefaultCar"), JmriJOptionPane.YES_NO_OPTION) == JmriJOptionPane.YES_OPTION) {
141                super.load(cars.get(0)); // new default car
142                return false; // done, don't modify any of the cars selected
143            }
144        }
145
146        // don't ask for to change cars in a kernel when giving a selected group of cars a new kernel name
147        askKernelChange = false;
148        
149        // determine if all cars in every kernel are selected
150        for (Car car : cars) {
151            if (car.getKernel() != null) {
152                for (Car c : car.getKernel().getCars()) {
153                    if (!cars.contains(c)) {
154                        askKernelChange = true; // not all selected
155                        break;
156                    }
157                }
158            }
159        }
160
161        for (Car car : cars) {
162            if (!super.change(car)) {
163                return false;
164            } else if (car.getKernel() != null && !ignoreKernelCheckBox.isSelected()) {
165                askKernelChange = false; // changing kernel name
166            }
167        }
168        return false; // all good, but don't close window
169    }
170    
171    private void showMessageDialogWarning() {
172        JmriJOptionPane.showMessageDialog(this, Bundle.getMessage("selectCars"), Bundle
173                .getMessage("carNoneSelected"), JmriJOptionPane.WARNING_MESSAGE);
174    }
175
176    private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(CarsSetFrame.class);
177}