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