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