001package jmri.configurexml;
002
003import java.io.File;
004import java.util.Set;
005import java.awt.Component;
006import java.awt.event.ActionEvent;
007
008import javax.annotation.CheckForNull;
009import javax.annotation.Nonnull;
010import javax.swing.JFileChooser;
011
012import jmri.ConfigureManager;
013import jmri.InstanceManager;
014import jmri.PermissionManager;
015import jmri.jmrit.logixng.LogixNGPreferences;
016import jmri.JmriException;
017import jmri.jmrit.display.Editor;
018import jmri.jmrit.display.EditorManager;
019import jmri.jmrit.logixng.LogixNG_Manager;
020import jmri.util.swing.JmriJOptionPane;
021
022/**
023 * Load configuration information from an XML file.
024 * <p>
025 * The file context for this is the "config" file chooser.
026 * <p>
027 * This will load whatever information types are present in the file. See
028 * {@link jmri.ConfigureManager} for information on the various types of
029 * information stored in configuration files.
030 *
031 * @author Bob Jacobsen Copyright (C) 2002
032 * @see jmri.jmrit.XmlFile
033 */
034public class LoadXmlConfigAction extends LoadStoreBaseAction {
035
036    public LoadXmlConfigAction() {
037        this("Open Data File ...");  // NOI18N
038    }
039
040    public LoadXmlConfigAction(String s) {
041        super(s);
042    }
043
044    @Override
045    public void actionPerformed(ActionEvent e) {
046        if (! InstanceManager.getDefault(PermissionManager.class)
047                .checkPermission(LoadAndStorePermissionOwner.LOAD_XML_FILE_PERMISSION)) {
048            return;
049        }
050        loadFile(getConfigFileChooser(), JmriJOptionPane.findWindowForObject( e == null ? null : e.getSource()));
051    }
052
053    /**
054     * Load a File from a given JFileChooser.
055     * @param fileChooser {@link JFileChooser} to use for file selection
056     * @param component a Component which has called the File Chooser.
057     * @return true if successful
058     */
059    protected boolean loadFile(@Nonnull JFileChooser fileChooser, @CheckForNull Component component ) {
060        Set<Editor> editors = InstanceManager.getDefault(EditorManager.class).getAll();
061        if (!editors.isEmpty()) {
062            InstanceManager.getDefault(jmri.UserPreferencesManager.class).showWarningMessage(
063                    Bundle.getMessage("DuplicateLoadTitle"), Bundle.getMessage("DuplicateLoadMessage"),  // NOI18N
064                    "jmri.jmrit.display.EditorManager",  "skipDupLoadDialog", false, true);  //NOI18N
065            InstanceManager.getDefault(jmri.UserPreferencesManager.class).setPreferenceItemDetails(
066                    "jmri.jmrit.display.EditorManager", "skipDupLoadDialog", Bundle.getMessage("DuplicateLoadSkip"));  // NOI18N
067        }
068
069        boolean results = false;
070        File file = getFile(fileChooser, component);
071        if (file != null) {
072            log.info("Loading selected file: {}", file); // NOI18N
073            try {
074                ConfigureManager cm = InstanceManager.getNullableDefault(jmri.ConfigureManager.class);
075                if (cm == null) {
076                    log.error("Failed to get default configure manager");  // NOI18N
077                } else {
078                    results = cm.load(file);
079
080                    // If LogixNGs aren't setup, the actions and expressions will not
081                    // be stored if the user stores the tables and panels. So we need
082                    // to try to setup LogixNGs even if the loading failed.
083                    LogixNG_Manager logixNG_Manager = InstanceManager.getDefault(LogixNG_Manager.class);
084                    logixNG_Manager.setupAllLogixNGs();
085
086                    if (results) {
087                        // insure logix etc fire up
088                        InstanceManager.getDefault(jmri.LogixManager.class).activateAllLogixs();
089                        InstanceManager.getDefault(jmri.jmrit.display.layoutEditor.LayoutBlockManager.class).initializeLayoutBlockPaths();
090
091                        if (InstanceManager.getDefault(LogixNGPreferences.class).getStartLogixNGOnStartup()
092                                && logixNG_Manager.isStartLogixNGsOnLoad()) {
093                            logixNG_Manager.activateAllLogixNGs();
094                        }
095                    }
096                }
097            } catch (JmriException e) {
098                log.error("Unhandled problem in loadFile", e);  // NOI18N
099            }
100        } else {
101            results = true;   // We assume that as the file is null then the user has clicked cancel.
102        }
103        return results;
104    }
105
106    /**
107     * Get the File from a given JFileChooser.
108     * @return the selected File.
109     * @deprecated use {@link #getFile(JFileChooser fileChooser, Component component)}
110     * @param fileChooser the JFileChooser for the file.
111     */
112    @CheckForNull
113    @Deprecated (since="5.7.8",forRemoval=true)
114    public static File getFile(@Nonnull JFileChooser fileChooser) {
115        return getFile(fileChooser, null);
116    }
117
118    /**
119     * Get the File from an Open File JFileChooser.
120     * If a Component is provided, this helps the JFileChooser to not get stuck
121     * behind an Always On Top Window.
122     * @param fileChooser the FileChooser to get from.
123     * @param component a Component within a JFrame / Window / Popup Menu,
124     *                  or the JFrame or Window itself.
125     * @return the File, may be null if none selected.
126     */
127    @CheckForNull
128    public static File getFile(@Nonnull JFileChooser fileChooser, @CheckForNull Component component) {
129        fileChooser.setDialogType(javax.swing.JFileChooser.OPEN_DIALOG);
130        return getFileCustom(fileChooser, component);
131    }
132
133    /**
134     * @return the selected File.
135     * @deprecated use {@link #getFile(JFileChooser fileChooser, Component component)}
136     * @param fileChooser the FileChooser to get from.
137     */
138    @CheckForNull
139    @Deprecated (since="5.7.8",forRemoval=true)
140    public static File getFileCustom(@Nonnull JFileChooser fileChooser) {
141        return getFileCustom(fileChooser, null);
142    }
143
144    /**
145     * Get the File from a JFileChooser.
146     * If a Component is provided, this helps the JFileChooser to not get stuck
147     * behind an Always On Top Window.
148     * @param fileChooser the FileChooser to get from.
149     * @param component a Component within a JFrame / Window / Popup Menu,
150     *                  or the JFrame or Window itself.
151     * @return the File, may be null if none selected.
152     */
153    @CheckForNull
154    public static File getFileCustom(@Nonnull JFileChooser fileChooser, @CheckForNull Component component){
155        fileChooser.rescanCurrentDirectory();
156        int retVal = fileChooser.showDialog(component, Bundle.getMessage("MenuItemLoad"));  // NOI18N
157        if (retVal != JFileChooser.APPROVE_OPTION) {
158            return null;  // give up if no file selected
159        }
160        log.debug("Open file: {}", fileChooser.getSelectedFile().getPath());
161        return fileChooser.getSelectedFile();
162    }
163
164    private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(LoadXmlConfigAction.class);
165
166}