001package jmri.jmrix.openlcb.swing.lccpro; 002 003import java.awt.*; 004 005import java.beans.PropertyChangeEvent; 006import java.beans.PropertyChangeListener; 007import java.awt.event.WindowEvent; 008 009import java.io.File; 010import java.io.IOException; 011 012import javax.swing.*; 013 014import jmri.*; 015import jmri.jmrix.can.CanSystemConnectionMemo; 016import jmri.util.swing.JmriJOptionPane; 017 018import org.openlcb.*; 019import org.openlcb.cdi.impl.ConfigRepresentation; 020 021/** 022 * Do a backup of a specified node. 023 * 024 * Not truly an Action, though it might be some day 025 * @author Bob Jacobsen (c) 2026 026 */ 027 028 029class NodeBackupAction { 030 031 private ConfigRepresentation _cdi; 032 private String _name; 033 034 static JFileChooser directoryChooser = new JFileChooser(); 035 static final String PREFNAME = "backupDirectory"; 036 037 static { 038 directoryChooser.setFileSelectionMode(javax.swing.JFileChooser.DIRECTORIES_ONLY); 039 directoryChooser.setDialogTitle(Bundle.getMessage("ChooseADirectory")); 040 directoryChooser.setSelectedFile(new File(".")); 041 042 var prefsMgr = InstanceManager.getDefault(UserPreferencesManager.class); 043 var dirPref = prefsMgr.getProperty(NodeBackupAction.class.getName(), PREFNAME); 044 if (dirPref != null) { 045 directoryChooser.setSelectedFile(new File(dirPref.toString())); 046 } 047 048 } 049 050 public static void showOpenDialog(Component here) { 051 var response = directoryChooser.showOpenDialog(here); 052 053 if (response == JFileChooser.APPROVE_OPTION) { 054 String directory = directoryChooser.getSelectedFile().getAbsolutePath(); 055 var prefsMgr = InstanceManager.getDefault(UserPreferencesManager.class); 056 prefsMgr.setProperty(NodeBackupAction.class.getName(), PREFNAME, directory); 057 } 058 } 059 060 public void doBackup(MimicNodeStore.NodeMemo nodememo, CanSystemConnectionMemo memo, String name) { 061 var node = nodememo.getNodeID(); 062 _name = name; 063 log.info("Backup {} '{}' ", node.toString(), _name); 064 065 var iface = memo.get(OlcbInterface.class); 066 067 _cdi = iface.getConfigForNode(node); 068 069 // always show the status 070 JmriJOptionPane.showMessageDialogNonModal(null, 071 Bundle.getMessage("MessageCdiLoad", _name, node), 072 Bundle.getMessage("TitleCdiLoad", name), 073 JmriJOptionPane.INFORMATION_MESSAGE, 074 null); 075 076 if (_cdi.getRoot() != null) { 077 // configuration cache present, store and 078 // cancel window after short delay 079 storeCdiData(); 080 jmri.util.ThreadingUtil.runOnGUIDelayed(() -> { 081 closeStatusWindow(); 082 }, 1000); 083 084 } else { 085 // configuration cache present, wait for it 086 // to arrive 087 _cdi.addPropertyChangeListener(new CdiListener()); 088 } 089 } 090 091 // close the progress window and save the contents 092 // when the CDI has been completely read 093 private class CdiListener implements PropertyChangeListener { 094 @Override 095 public void propertyChange(PropertyChangeEvent e) { 096 String propertyName = e.getPropertyName(); 097 log.debug("CdiListener event = {}", propertyName); 098 099 if (propertyName.equals("UPDATE_CACHE_COMPLETE")) { 100 closeStatusWindow(); 101 storeCdiData(); 102 } 103 } 104 } 105 106 protected void closeStatusWindow() { 107 Window[] windows = Window.getWindows(); 108 for (Window window : windows) { 109 if (window instanceof JDialog) { 110 JDialog dialog = (JDialog) window; 111 if (Bundle.getMessage("TitleCdiLoad", _name).equals(dialog.getTitle())) { 112 dialog.dispatchEvent(new WindowEvent(dialog, WindowEvent.WINDOW_CLOSING)); 113 } 114 } 115 } 116 } 117 118 protected void storeCdiData() { 119 log.debug("Load complete"); 120 var filename = org.openlcb.cdi.swing.CdiPanel 121 .fileNameGenerator.generateFileName(_cdi, _name); 122 String directory = directoryChooser.getSelectedFile().getAbsolutePath(); 123 String storeName = directory+File.separator+filename; 124 log.info("Storing to file {}", storeName); 125 try { 126 org.openlcb.cdi.cmd.BackupConfig.writeConfigToFile(storeName, _cdi); 127 } catch (IOException e) { 128 log.error("Error writing file! ", e); 129 } 130 131 } 132 133 private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(NodeBackupAction.class); 134}