001package jmri.jmrit.display.layoutEditor.LayoutEditorDialogs;
002
003import java.awt.Container;
004import java.awt.FlowLayout;
005import java.awt.event.ActionEvent;
006
007import javax.annotation.Nonnull;
008import javax.swing.*;
009
010import jmri.*;
011import jmri.NamedBean.DisplayOptions;
012import jmri.jmrit.display.layoutEditor.*;
013import jmri.swing.NamedBeanComboBox;
014import jmri.util.JmriJFrame;
015
016/**
017 * MVC Editor component for LevelXing objects.
018 *
019 * Note there might not be anything for this class to do;
020 * LayoutTrackEditors has a comment saying that PositionablePoint
021 * doesn't have an editor.
022 *
023 * @author Bob Jacobsen  Copyright (c) 2020
024 * 
025 */
026public class LevelXingEditor extends LayoutTurntableEditor {
027
028    /**
029     * constructor method.
030     * @param layoutEditor main layout editor.
031     */
032    public LevelXingEditor(@Nonnull LayoutEditor layoutEditor) {
033        super(layoutEditor);
034    }
035
036    /*===============*\
037    | Edit Level Xing |
038    \*===============*/
039    // variables for Edit Track Segment pane
040    private LevelXingView levelXingView;
041    private LevelXing levelXing;
042
043    // variables for Edit Level Crossing pane
044    private JmriJFrame editLevelXingFrame = null;
045    private final JCheckBox editLevelXingHiddenCheckBox = new JCheckBox(Bundle.getMessage("HideCrossing"));  // NOI18N
046
047    private final NamedBeanComboBox<Block> editLevelXingBlock1NameComboBox = new NamedBeanComboBox<>(
048            InstanceManager.getDefault(BlockManager.class), null, DisplayOptions.DISPLAYNAME);
049    private final NamedBeanComboBox<Block> editLevelXingBlock2NameComboBox = new NamedBeanComboBox<>(
050            InstanceManager.getDefault(BlockManager.class), null, DisplayOptions.DISPLAYNAME);
051    private JButton editLevelXingBlock1Button;
052    private JButton editLevelXingBlock2Button;
053
054    private boolean editLevelXingOpen = false;
055    private boolean editLevelXingNeedsRedraw = false;
056    private boolean editLevelXingNeedsBlockUpdate = false;
057
058    /**
059     * Edit a Level Crossing.
060     * @param levelXingView the level crossing to edit.
061     */
062    public void editLayoutTrack(LevelXingView levelXingView) {
063    try {
064        sensorList.clear();
065
066        this.levelXingView = levelXingView;
067        this.levelXing = this.levelXingView.getLevelXing();
068        
069        if (editLevelXingOpen) {
070            editLevelXingFrame.setVisible(true);
071        } else // Initialize if needed
072        if (editLevelXingFrame == null) {
073            editLevelXingFrame = new JmriJFrame(Bundle.getMessage("EditXing"), false, true);  // NOI18N
074            editLevelXingFrame.addHelpMenu("package.jmri.jmrit.display.EditLevelXing", true);  // NOI18N
075            editLevelXingFrame.setLocation(50, 30);
076            Container contentPane = editLevelXingFrame.getContentPane();
077            contentPane.setLayout(new BoxLayout(contentPane, BoxLayout.Y_AXIS));
078
079            JPanel panel33 = new JPanel();
080            panel33.setLayout(new FlowLayout());
081            editLevelXingHiddenCheckBox.setToolTipText(Bundle.getMessage("HiddenToolTip"));  // NOI18N
082            panel33.add(editLevelXingHiddenCheckBox);
083            contentPane.add(panel33);
084
085            // setup block AC name
086            JPanel panel1 = new JPanel();
087            panel1.setLayout(new FlowLayout());
088            JLabel block1NameLabel = new JLabel(Bundle.getMessage("Block_ID", "AC"));  // NOI18N
089            panel1.add(block1NameLabel);
090            block1NameLabel.setLabelFor(editLevelXingBlock1NameComboBox);
091            panel1.add(editLevelXingBlock1NameComboBox);
092            editLevelXingBlock1NameComboBox.setName("Block AC");
093            LayoutEditor.setupComboBox(editLevelXingBlock1NameComboBox, false, true, true);
094            editLevelXingBlock1NameComboBox.setToolTipText(Bundle.getMessage("EditBlockNameHint"));  // NOI18N
095            contentPane.add(panel1);
096
097            // setup block BD name
098            JPanel panel2 = new JPanel();
099            panel2.setLayout(new FlowLayout());
100            JLabel block2NameLabel = new JLabel(Bundle.getMessage("Block_ID", "BD"));  // NOI18N
101            panel2.add(block2NameLabel);
102            block2NameLabel.setLabelFor(editLevelXingBlock2NameComboBox);
103            panel2.add(editLevelXingBlock2NameComboBox);
104            editLevelXingBlock2NameComboBox.setName("Block BD");
105            LayoutEditor.setupComboBox(editLevelXingBlock2NameComboBox, false, true, true);
106            editLevelXingBlock2NameComboBox.setToolTipText(Bundle.getMessage("EditBlockNameHint"));  // NOI18N
107            contentPane.add(panel2);
108
109            // set up Edit 1 Block and Edit 2 Block buttons
110            JPanel panel4 = new JPanel();
111            panel4.setLayout(new FlowLayout());
112            // Edit 1 Block
113            panel4.add(editLevelXingBlock1Button = new JButton(Bundle.getMessage("EditBlock", "AC")));  // NOI18N
114            editLevelXingBlock1Button.addActionListener(this::editLevelXingBlockACPressed);
115            editLevelXingBlock1Button.setToolTipText(Bundle.getMessage("EditBlockHint", "")); // empty value for block 1  // NOI18N
116            // Edit 2 Block
117            panel4.add(editLevelXingBlock2Button = new JButton(Bundle.getMessage("EditBlock", "BD")));  // NOI18N
118            editLevelXingBlock2Button.addActionListener(this::editLevelXingBlockBDPressed);
119            editLevelXingBlock2Button.setToolTipText(Bundle.getMessage("EditBlockHint", "")); // empty value for block 1  // NOI18N
120            contentPane.add(panel4);
121
122            // set up Done and Cancel buttons
123            JPanel panel5 = new JPanel();
124            panel5.setLayout(new FlowLayout());
125            addDoneCancelButtons(panel5, editLevelXingFrame.getRootPane(),
126                    this::editLevelXingDonePressed, this::editLevelXingCancelPressed);
127            contentPane.add(panel5);
128        }
129
130        editLevelXingHiddenCheckBox.setSelected(levelXingView.isHidden());
131
132        // Set up for Edit
133        BlockManager bm = InstanceManager.getDefault(BlockManager.class);
134        editLevelXingBlock1NameComboBox.getEditor().setItem(bm.getBlock(levelXing.getBlockNameAC()));
135        editLevelXingBlock2NameComboBox.getEditor().setItem(bm.getBlock(levelXing.getBlockNameBD()));
136        editLevelXingBlock1NameComboBox.setEnabled(!hasNxSensorPairs(levelXing.getLayoutBlockAC()));  // NOI18N
137        editLevelXingBlock2NameComboBox.setEnabled(!hasNxSensorPairs(levelXing.getLayoutBlockBD()));  // NOI18N
138        editLevelXingFrame.addWindowListener(new java.awt.event.WindowAdapter() {
139            @Override
140            public void windowClosing(java.awt.event.WindowEvent e) {
141                editLevelXingCancelPressed(null);
142            }
143        });
144        editLevelXingFrame.pack();
145        editLevelXingFrame.setVisible(true);
146        editLevelXingOpen = true;
147        editLevelXingNeedsBlockUpdate = false;
148
149        showSensorMessage();
150    } catch (Throwable t) {
151        log.error("temporary catch for test", t);
152    }
153    }
154
155    private void editLevelXingBlockACPressed(ActionEvent a) {
156        // check if a block name has been entered
157        String newName = editLevelXingBlock1NameComboBox.getSelectedItemDisplayName();
158        if (newName == null) {
159            newName = "";
160        }
161        if (!levelXing.getBlockNameAC().equals(newName)) {
162            // get new block, or null if block has been removed
163            levelXing.setLayoutBlockAC(layoutEditor.provideLayoutBlock(newName));
164            editLevelXingNeedsRedraw = true;
165            layoutEditor.getLEAuxTools().setBlockConnectivityChanged();
166            editLevelXingNeedsBlockUpdate = true;
167        }
168        // check if a block exists to edit
169        if (levelXing.getLayoutBlockAC() == null) {
170            JOptionPane.showMessageDialog(editLevelXingFrame,
171                    Bundle.getMessage("Error1"), // NOI18N
172                    Bundle.getMessage("ErrorTitle"), JOptionPane.ERROR_MESSAGE);  // NOI18N
173            return;
174        }
175        levelXing.getLayoutBlockAC().editLayoutBlock(editLevelXingFrame);
176        editLevelXingNeedsRedraw = true;
177    }
178
179    private void editLevelXingBlockBDPressed(ActionEvent a) {
180        // check if a block name has been entered
181        String newName = editLevelXingBlock2NameComboBox.getSelectedItemDisplayName();
182        if (newName == null) {
183            newName = "";
184        }
185        if (!levelXing.getBlockNameBD().equals(newName)) {
186            // get new block, or null if block has been removed
187            levelXing.setLayoutBlockBD(layoutEditor.provideLayoutBlock(newName));
188            editLevelXingNeedsRedraw = true;
189            layoutEditor.getLEAuxTools().setBlockConnectivityChanged();
190            editLevelXingNeedsBlockUpdate = true;
191        }
192        // check if a block exists to edit
193        if (levelXing.getLayoutBlockBD() == null) {
194            JOptionPane.showMessageDialog(editLevelXingFrame,
195                    Bundle.getMessage("Error1"), // NOI18N
196                    Bundle.getMessage("ErrorTitle"), JOptionPane.ERROR_MESSAGE);  // NOI18N
197            return;
198        }
199        levelXing.getLayoutBlockBD().editLayoutBlock(editLevelXingFrame);
200        editLevelXingNeedsRedraw = true;
201    }
202
203    private void editLevelXingDonePressed(ActionEvent a) {
204        // check if Blocks changed
205        String newName = editLevelXingBlock1NameComboBox.getSelectedItemDisplayName();
206        if (newName == null) {
207            newName = "";
208        }
209        if (!levelXing.getBlockNameAC().equals(newName)) {
210            // get new block, or null if block has been removed
211            levelXing.setLayoutBlockAC(layoutEditor.provideLayoutBlock(newName));
212            editLevelXingNeedsRedraw = true;
213            layoutEditor.getLEAuxTools().setBlockConnectivityChanged();
214            editLevelXingNeedsBlockUpdate = true;
215        }
216        newName = editLevelXingBlock2NameComboBox.getSelectedItemDisplayName();
217        if (newName == null) {
218            newName = "";
219        }
220        if (!levelXing.getBlockNameBD().equals(newName)) {
221            // get new block, or null if block has been removed
222            levelXing.setLayoutBlockBD(layoutEditor.provideLayoutBlock(newName));
223            editLevelXingNeedsRedraw = true;
224            layoutEditor.getLEAuxTools().setBlockConnectivityChanged();
225            editLevelXingNeedsBlockUpdate = true;
226        }
227
228        // set hidden
229        boolean oldHidden = levelXingView.isHidden();
230        levelXingView.setHidden(editLevelXingHiddenCheckBox.isSelected());
231        if (oldHidden != levelXingView.isHidden()) {
232            editLevelXingNeedsRedraw = true;
233        }
234
235        editLevelXingOpen = false;
236        editLevelXingFrame.setVisible(false);
237        editLevelXingFrame.dispose();
238        editLevelXingFrame = null;
239        if (editLevelXingNeedsBlockUpdate) {
240            levelXing.updateBlockInfo();
241        }
242        if (editLevelXingNeedsRedraw) {
243            layoutEditor.redrawPanel();
244            layoutEditor.setDirty();
245            editLevelXingNeedsRedraw = false;
246        }
247    }
248
249    private void editLevelXingCancelPressed(ActionEvent a) {
250        editLevelXingOpen = false;
251        editLevelXingFrame.setVisible(false);
252        editLevelXingFrame.dispose();
253        editLevelXingFrame = null;
254        if (editLevelXingNeedsBlockUpdate) {
255            levelXing.updateBlockInfo();
256        }
257        if (editLevelXingNeedsRedraw) {
258            layoutEditor.redrawPanel();
259            layoutEditor.setDirty();
260            editLevelXingNeedsRedraw = false;
261        }
262    }
263
264    
265
266    private final static org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(LevelXingEditor.class);
267}