001package jmri.jmrit.throttle;
002
003import java.awt.event.ActionEvent;
004import java.io.File;
005import java.util.List;
006import javax.swing.AbstractAction;
007import javax.swing.JFileChooser;
008import javax.swing.SwingUtilities;
009
010import jmri.InstanceManager;
011import jmri.jmrit.XmlFile;
012import jmri.util.swing.JmriJOptionPane;
013
014import org.jdom2.Element;
015
016/**
017 * Load throttles from XML
018 *
019 * @author Glen Oberhauser 2004
020 */
021public class LoadXmlThrottlesLayoutAction extends AbstractAction {
022
023    /**
024     * Constructor
025     *
026     * @param s Name for the action.
027     */
028    public LoadXmlThrottlesLayoutAction(String s) {
029        super(s);
030        // disable the ourselves if there is no throttle Manager
031        if (jmri.InstanceManager.getNullableDefault(jmri.ThrottleManager.class) == null) {
032            setEnabled(false);
033        }
034    }
035
036    public LoadXmlThrottlesLayoutAction() {
037        this("Open Throttle");
038    }
039
040    JFileChooser fileChooser;
041
042    /**
043     * The action is performed. Let the user choose the file to load from. Read
044     * XML for each ThrottleFrame.
045     *
046     * @param e The event causing the action.
047     */
048    @Override
049    public void actionPerformed(ActionEvent e) {
050        if (fileChooser == null) {
051            fileChooser = jmri.jmrit.XmlFile.userFileChooser(Bundle.getMessage("PromptXmlFileTypes"), "xml");
052            fileChooser.setDialogType(JFileChooser.OPEN_DIALOG);
053            fileChooser.setCurrentDirectory(new File(ThrottleFrame.getDefaultThrottleFolder()));
054        }
055        int retVal = fileChooser.showOpenDialog(null);
056        if (retVal != JFileChooser.APPROVE_OPTION) {
057            return;
058            // give up if no file selected
059        }
060
061        // if exising frames are open ask to destroy those or merge.
062        if (InstanceManager.getDefault(ThrottleFrameManager.class).getThrottleWindows().hasNext()) {
063            Object[] possibleValues = {Bundle.getMessage("LabelMerge"),
064                Bundle.getMessage("LabelReplace"),
065                Bundle.getMessage("ButtonCancel")};
066            int selectedValue = JmriJOptionPane.showOptionDialog(null,
067                    Bundle.getMessage("DialogMergeOrReplace"),
068                    Bundle.getMessage("OptionLoadingThrottles"),
069                    JmriJOptionPane.DEFAULT_OPTION,
070                    JmriJOptionPane.INFORMATION_MESSAGE, null, possibleValues,
071                    possibleValues[0]);
072            if (selectedValue == 2 || selectedValue == JmriJOptionPane.CLOSED_OPTION ) {
073                return; // array position 2 ButtonCancel or Dialog closed
074            }
075            if (selectedValue == 1 ) { // array position 1, LabelReplace
076                // replace chosen - close all then load
077                InstanceManager.getDefault(ThrottleFrameManager.class).requestAllThrottleWindowsDestroyed();
078            }
079        }
080        try {
081            loadThrottlesLayout(fileChooser.getSelectedFile());
082        } catch (java.io.IOException e1) {
083            log.warn("Exception while reading file", e1);
084        }
085    }
086
087    /**
088     * Parse the XML file and create ThrottleFrames.
089     * @return  true if throttle loaded successfully, else false.
090     * @param f The XML file containing throttles.
091     * @throws java.io.IOException on error.
092     */
093    public boolean loadThrottlesLayout(java.io.File f) throws java.io.IOException {
094        try {
095            ThrottlePrefs prefs = new ThrottlePrefs();
096            prefs.setValidate(XmlFile.Validate.CheckDtdThenSchema);
097            Element root = prefs.rootFromFile(f);
098            List<Element> throttles = root.getChildren("ThrottleFrame");
099            ThrottleFrameManager tfManager = InstanceManager.getDefault(ThrottleFrameManager.class);
100            if ((throttles != null) && (throttles.size() > 0)) { // OLD FORMAT
101                for (Element e : throttles) {
102                    SwingUtilities.invokeLater(() -> {
103                        ThrottleFrame tf = tfManager.createThrottleFrame();
104                        tf.setXml(e);
105                        tf.toFront();
106                    });
107                }
108            } else {
109                throttles = root.getChildren("ThrottleWindow");
110                for (Element e : throttles) {
111                    SwingUtilities.invokeLater(() -> {
112                        tfManager.createThrottleWindow(e).setVisible(true);
113                    });
114                }
115                Element tlp = root.getChild("ThrottlesListPanel");
116                if (tlp != null) {
117                    InstanceManager.getDefault(ThrottleFrameManager.class).getThrottlesListPanel().setXml(tlp);
118                }
119            }
120        } catch (org.jdom2.JDOMException ex) {
121            log.warn("Loading Throttles exception", ex);
122            jmri.configurexml.ConfigXmlManager.creationErrorEncountered(
123                    null, "parsing file " + f.getName(),
124                    "Parse error", null, null, ex);
125            return false;
126        }
127        return true;
128    }
129
130    /**
131     * An extension of the abstract XmlFile. No changes made to that class.
132     *
133     * @author glen
134     */
135    static class ThrottlePrefs extends XmlFile {
136    }
137
138    private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(LoadXmlThrottlesLayoutAction.class);
139
140}