001package jmri.jmrit.beantable.routetable;
002
003import javax.swing.*;
004import java.awt.*;
005import java.awt.event.ActionEvent;
006import java.util.*;
007
008import jmri.InstanceManager;
009import jmri.Route;
010import jmri.RouteManager;
011import jmri.util.swing.JmriJOptionPane;
012
013/**
014 * Add frame for the Route Table.
015 *
016 * Split from {@link jmri.jmrit.beantable.RouteTableAction}
017 *
018 * @author Dave Duchamp Copyright (C) 2004
019 * @author Bob Jacobsen Copyright (C) 2007
020 * @author Simon Reader Copyright (C) 2008
021 * @author Pete Cressman Copyright (C) 2009
022 * @author Egbert Broerse Copyright (C) 2016
023 * @author Paul Bender Copyright (C) 2020
024 */
025public class RouteAddFrame extends AbstractRouteAddEditFrame {
026
027
028    public RouteAddFrame() {
029        this(Bundle.getMessage("TitleAddRoute"));
030    }
031
032    public RouteAddFrame(String name) {
033        this(name,false,true);
034    }
035
036    public RouteAddFrame(String name, boolean saveSize, boolean savePosition) {
037        super(name, saveSize, savePosition);
038        super.initComponents();
039    }
040
041    @Override
042    protected JPanel getButtonPanel() {
043        final JButton copyButton = new JButton(Bundle.getMessage("ButtonCopyRoute"));
044        final JButton createButton = new JButton(Bundle.getMessage("ButtonCreate"));
045        final JButton editButton = new JButton(Bundle.getMessage("ButtonEdit"));
046        final JButton cancelButton = new JButton(Bundle.getMessage("ButtonCancel"));
047        final JButton updateButton = new JButton(Bundle.getMessage("ButtonUpdate"));
048
049        // add Buttons panel
050        JPanel pb = new JPanel();
051        pb.setLayout(new BorderLayout());
052
053        // Copy button
054        JPanel left = new JPanel();
055        left.add(copyButton);
056        copyButton.addActionListener(this::copyPressed);
057
058        JPanel right = new JPanel();
059        right.setLayout(new FlowLayout(FlowLayout.TRAILING));
060
061        // Cancel (Add) button
062        right.add(cancelButton);
063        cancelButton.addActionListener(this::cancelAddPressed);
064
065        // Create button
066        right.add(createButton);
067        createButton.addActionListener(this::createPressed);
068        createButton.setToolTipText(Bundle.getMessage("TooltipCreateRoute"));
069
070        pb.add(left, BorderLayout.WEST);
071        pb.add(right, BorderLayout.EAST);
072
073        // Show the initial buttons, and hide the others
074        copyButton.setVisible(true);
075        cancelButton.setVisible(true);
076        updateButton.setVisible(false);
077        editButton.setVisible(false);
078        createButton.setVisible(true);
079        return pb;
080    }
081
082    /**
083     * Respond to the CancelAdd button.
084     *
085     * @param e the action event
086     */
087    private void cancelAddPressed(ActionEvent e) {
088        cancelAdd();
089    }
090
091    /**
092     * Cancel Add mode.
093     */
094    private void cancelAdd() {
095        if (routeDirty) {
096            showReminderMessage();
097        }
098        curRoute = null;
099        finishUpdate();
100        status1.setText(Bundle.getMessage("RouteAddStatusInitial1", Bundle.getMessage("ButtonCreate"))); // I18N to include original button name in help string
101        //status2.setText(Bundle.getMessage("RouteAddStatusInitial2", Bundle.getMessage("ButtonEdit")));
102        routeDirty = false;
103        // hide addFrame
104        setVisible(false);
105        _routeSensorModel.dispose();
106        _routeTurnoutModel.dispose();
107        closeFrame();
108    }
109
110    /**
111     * Respond to the Create button.
112     *
113     * @param e the action event
114     */
115    private void createPressed(ActionEvent e) {
116        if (!_autoSystemName.isSelected()) {
117            if (!checkNewNamesOK()) {
118                return;
119            }
120        }
121        updatePressed(true); // close pane after creating
122        //status2.setText(Bundle.getMessage("RouteAddStatusInitial2", Bundle.getMessage("ButtonEdit")));
123        pref.setSimplePreferenceState(systemNameAuto, _autoSystemName.isSelected());
124        // activate the route
125        if (curRoute != null) {
126            curRoute.activateRoute();
127        }
128        closeFrame();
129    }
130
131    /**
132     * Respond to the Copy button.
133     * Request a source route for the copy and load the page if possible.
134     *
135     * @param e the action event
136     */
137    private void copyPressed(ActionEvent e) {
138        var selectedRoute = selectSourceRoute();
139        if (selectedRoute != null) {
140            var route = InstanceManager.getDefault(RouteManager.class).getRoute(selectedRoute);
141            if (route != null) {
142                setPageContent(route);
143            }
144        }
145    }
146
147    /**
148     * Display an input dialog with a combo box of existing routes.
149     *
150     * @return the selected route name or null if none.
151     */
152    private String selectSourceRoute() {
153        var routes = InstanceManager.getDefault(RouteManager.class).getNamedBeanSet();
154        var routeList = new ArrayList<String>();
155        routes.forEach((r) -> {
156            routeList.add(r.getDisplayName());
157        });
158        Collections.sort(routeList);
159
160        var routeArray = new String[routeList.size()];
161        routeList.toArray(routeArray);
162
163        try {
164            var icon = new ImageIcon(jmri.util.FileUtil.getProgramPath() + jmri.Application.getLogo());
165            var choice = JmriJOptionPane.showInputDialog(
166                    this,
167                    Bundle.getMessage("LabelCopyRoute"),
168                    Bundle.getMessage("TitleCopyRoute"),
169                    JmriJOptionPane.QUESTION_MESSAGE,
170                    icon,
171                    routeArray,
172                    null);
173            return (String) choice;
174        } catch (HeadlessException ex) {
175            return null;
176        }
177    }
178
179    /**
180     * Check name for a new Route object using the _systemName field on the addFrame pane.
181     *
182     * @return whether name entered is allowed
183     */
184    private boolean checkNewNamesOK() {
185        // Get system name and user name from Add Route pane
186        String sName = _systemName.getText();
187        String uName = _userName.getText();
188        if (sName.length() == 0) {
189            status1.setText(Bundle.getMessage("AddBeanStatusEnter"));
190            status1.setForeground(Color.red);
191            return false;
192        }
193        Route g;
194        // check if a Route with the same user name exists
195        if (!uName.isEmpty()) {
196            g = routeManager.getByUserName(uName);
197            if (g != null) {
198                // Route already exists
199                status1.setText(Bundle.getMessage("LightError8"));
200                return false;
201            }
202        }
203        // check if a Route with this system name already exists
204        sName = routeManager.makeSystemName(sName);
205        g = routeManager.getBySystemName(sName);
206        if (g != null) {
207            // Route already exists
208            status1.setText(Bundle.getMessage("LightError1"));
209            return false;
210        }
211        return true;
212    }
213
214}