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.jmrit.throttle.implementation.ThrottleUICore;
013import jmri.util.swing.JmriJOptionPane;
014
015import org.jdom2.Element;
016
017/**
018 * Load throttles from XML
019 * 
020 * <hr>
021 * This file is part of JMRI.
022 * <p>
023 * JMRI is free software; you can redistribute it and/or modify it under the
024 * terms of version 2 of the GNU General Public License as published by the Free
025 * Software Foundation. See the "COPYING" file for a copy of this license.
026 * <p>
027 * JMRI is distributed in the hope that it will be useful, but WITHOUT ANY
028 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
029 * A PARTICULAR PURPOSE. See the GNU General Public License for more details.
030 *
031 * @author Glen Oberhauser 2004
032 */
033public class LoadXmlThrottlesLayoutAction extends AbstractAction {
034
035    /**
036     * Constructor
037     *
038     * @param s Name for the action.
039     */
040    public LoadXmlThrottlesLayoutAction(String s) {
041        super(s);
042        // disable the ourselves if there is no throttle Manager
043        if (jmri.InstanceManager.getNullableDefault(jmri.ThrottleManager.class) == null) {
044            setEnabled(false);
045        }
046    }
047
048    public LoadXmlThrottlesLayoutAction() {
049        this("Open Throttle");
050    }
051
052    JFileChooser fileChooser;
053
054    /**
055     * The action is performed. Let the user choose the file to load from. Read
056     * XML for each ThrottleFrame.
057     *
058     * @param e The event causing the action.
059     */
060    @Override
061    public void actionPerformed(ActionEvent e) {
062        if (fileChooser == null) {
063            fileChooser = jmri.jmrit.XmlFile.userFileChooser(Bundle.getMessage("PromptXmlFileTypes"), "xml");
064            fileChooser.setDialogType(JFileChooser.OPEN_DIALOG);
065            fileChooser.setCurrentDirectory(new File(ThrottleUICore.getDefaultThrottleFolder()));
066        }
067        int retVal = fileChooser.showOpenDialog(null);
068        if (retVal != JFileChooser.APPROVE_OPTION) {
069            return;
070            // give up if no file selected
071        }
072
073        // if exising frames are open ask to destroy those or merge.
074        if (InstanceManager.getDefault(ThrottleFrameManager.class).iterator().hasNext()) {
075            Object[] possibleValues = {Bundle.getMessage("LabelMerge"),
076                Bundle.getMessage("LabelReplace"),
077                Bundle.getMessage("ButtonCancel")};
078            int selectedValue = JmriJOptionPane.showOptionDialog(null,
079                    Bundle.getMessage("DialogMergeOrReplace"),
080                    Bundle.getMessage("OptionLoadingThrottles"),
081                    JmriJOptionPane.DEFAULT_OPTION,
082                    JmriJOptionPane.INFORMATION_MESSAGE, null, possibleValues,
083                    possibleValues[0]);
084            if (selectedValue == 2 || selectedValue == JmriJOptionPane.CLOSED_OPTION ) {
085                return; // array position 2 ButtonCancel or Dialog closed
086            }
087            if (selectedValue == 1 ) { // array position 1, LabelReplace
088                // replace chosen - close all then load
089                InstanceManager.getDefault(ThrottleFrameManager.class).requestAllThrottleWindowsDestroyed();
090            }
091        }
092        try {
093            loadThrottlesLayout(fileChooser.getSelectedFile());
094        } catch (java.io.IOException e1) {
095            log.warn("Exception while reading file", e1);
096        }
097    }
098
099    /**
100     * Parse the XML file and create ThrottleFrames.
101     * @return  true if throttle loaded successfully, else false.
102     * @param f The XML file containing throttles.
103     * @throws java.io.IOException on error.
104     */
105    public boolean loadThrottlesLayout(java.io.File f) throws java.io.IOException {
106        try {
107            ThrottlePrefs prefs = new ThrottlePrefs();
108            prefs.setValidate(XmlFile.Validate.CheckDtdThenSchema);
109            Element root = prefs.rootFromFile(f);
110            List<Element> throttles = root.getChildren("ThrottleFrame");
111            ThrottleFrameManager tfManager = InstanceManager.getDefault(ThrottleFrameManager.class);
112            if ((throttles != null) && (throttles.size() > 0)) { // OLD FORMAT
113                for (Element e : throttles) {
114                    SwingUtilities.invokeLater(() -> {
115                        tfManager.createThrottleWindow(e).setVisible(true);                        
116                    });
117                }
118            } else {
119                throttles = root.getChildren("ThrottleWindow");
120                for (Element e : throttles) {
121                    SwingUtilities.invokeLater(() -> {
122                        tfManager.createThrottleWindow(e).setVisible(true);
123                    });
124                }
125                Element tlp = root.getChild("ThrottlesListPanel");
126                if (tlp != null) {
127                    InstanceManager.getDefault(ThrottleFrameManager.class).getThrottlesListPanel().setXml(tlp);
128                }
129            }
130        } catch (org.jdom2.JDOMException ex) {
131            log.warn("Loading Throttles exception", ex);
132            jmri.configurexml.ConfigXmlManager.creationErrorEncountered(
133                    null, "parsing file " + f.getName(),
134                    "Parse error", null, null, ex);
135            return false;
136        }
137        return true;
138    }
139
140    /**
141     * An extension of the abstract XmlFile. No changes made to that class.
142     *
143     * @author glen
144     */
145    public static class ThrottlePrefs extends XmlFile {
146    }
147
148    private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(LoadXmlThrottlesLayoutAction.class);
149
150}