001package jmri.jmrit.operations.setup;
002
003import java.awt.*;
004import java.awt.event.*;
005import java.io.IOException;
006import java.util.Date;
007
008import javax.swing.*;
009import javax.swing.border.EmptyBorder;
010import javax.swing.border.TitledBorder;
011
012import jmri.InstanceManager;
013import jmri.jmrit.operations.OperationsManager;
014import jmri.jmrit.operations.OperationsXml;
015import jmri.util.swing.*;
016
017public class RestoreDialog extends JDialog {
018
019    
020
021    private JPanel mainPanel;
022    private JPanel contentPanel;
023    private JRadioButton automaticBackupsRadioButton;
024    private JRadioButton defaultBackupsRadioButton;
025    private JComboBox<BackupSet> comboBox;
026    private JButton restoreButton;
027    //private JButton helpButton;
028
029    private BackupBase backup;
030    private String setName;
031    private JLabel newLabelLabel;
032
033    /**
034     * Create the dialog.
035     */
036    public RestoreDialog() {
037        initComponents();
038    }
039
040    private void initComponents() {
041        setModalityType(ModalityType.DOCUMENT_MODAL);
042        setModal(true);
043        setTitle(Bundle.getMessage("RestoreDialog.this.title"));
044        setBounds(100, 100, 378, 251);
045        mainPanel = new JPanel();
046        mainPanel.setLayout(new BorderLayout());
047        mainPanel.setBorder(null);
048        setContentPane(mainPanel);
049        {
050
051            contentPanel = new JPanel();
052            contentPanel.setBorder(new EmptyBorder(5, 5, 5, 5));
053            contentPanel.setLayout(new BoxLayout(contentPanel, BoxLayout.Y_AXIS));
054            mainPanel.add(contentPanel, BorderLayout.NORTH);
055
056            {
057                JPanel panel = new JPanel();
058                panel.setAlignmentX(Component.LEFT_ALIGNMENT);
059                panel.setLayout(new FlowLayout(FlowLayout.LEFT));
060                panel.setBorder(new TitledBorder(UIManager.getBorder("TitledBorder.border"), // NOI18N
061                Bundle.getMessage("RestoreDialog.label.text"), TitledBorder.LEADING, TitledBorder.TOP, null, new Color(0, 0, 0))); // NOI18N
062
063                contentPanel.add(panel);
064                ButtonGroup fromGroup = new ButtonGroup();
065
066                {
067                    automaticBackupsRadioButton = new JRadioButton(Bundle.getMessage("RestoreDialog.radioButton.autoBackup"));
068                    automaticBackupsRadioButton.addActionListener(new ActionListener() {
069                        @Override
070                        public void actionPerformed(ActionEvent e) {
071                            do_automaticBackupsRadioButton_actionPerformed(e);
072                        }
073                    });
074                    panel.add(automaticBackupsRadioButton);
075                    fromGroup.add(automaticBackupsRadioButton);
076                }
077                {
078                    defaultBackupsRadioButton = new JRadioButton(Bundle.getMessage("RestoreDialog.radioButton.defaultBackup"));
079                    defaultBackupsRadioButton.addActionListener(new ActionListener() {
080                        @Override
081                        public void actionPerformed(ActionEvent e) {
082                            do_defaultBackupsRadioButton_actionPerformed(e);
083                        }
084                    });
085                    panel.add(defaultBackupsRadioButton);
086                    fromGroup.add(defaultBackupsRadioButton);
087                }
088            }
089
090            {
091                newLabelLabel = new JLabel(Bundle.getMessage("RestoreDialog.label2.text"));
092                newLabelLabel.setBorder(new EmptyBorder(10, 0, 5, 0));
093                contentPanel.add(newLabelLabel);
094            }
095            {
096                comboBox = new JComboBox<>();
097                comboBox.addItemListener(new ItemListener() {
098                    @Override
099                    public void itemStateChanged(ItemEvent arg0) {
100                        do_comboBox_itemStateChanged(arg0);
101                    }
102                });
103                comboBox.setAlignmentX(Component.LEFT_ALIGNMENT);
104                contentPanel.add(comboBox);
105            }
106        }
107
108        {
109            JPanel buttonPane = new JPanel();
110            FlowLayout fl_buttonPane = new FlowLayout(FlowLayout.CENTER);
111            buttonPane.setLayout(fl_buttonPane);
112            mainPanel.add(buttonPane, BorderLayout.SOUTH);
113            {
114                restoreButton = new JButton(Bundle.getMessage("RestoreDialog.retoreButton.text"));
115                restoreButton.addActionListener(new ActionListener() {
116                    @Override
117                    public void actionPerformed(ActionEvent e) {
118                        do_restoreButton_actionPerformed(e);
119                    }
120                });
121                buttonPane.add(restoreButton);
122            }
123            {
124                JButton cancelButton = new JButton(Bundle.getMessage("ButtonCancel"));
125                cancelButton.addActionListener(new ActionListener() {
126                    @Override
127                    public void actionPerformed(ActionEvent arg0) {
128                        do_cancelButton_actionPerformed(arg0);
129                    }
130                });
131                buttonPane.add(cancelButton);
132            }
133        }
134
135        // Start out with Default backups
136        defaultBackupsRadioButton.doClick();
137//        pack();
138//        setLocationRelativeTo(null);
139//        setVisible(true);
140    }
141
142    // Event handlers
143    protected void do_automaticBackupsRadioButton_actionPerformed(ActionEvent e) {
144        backup = new AutoBackup();
145        loadComboBox();
146    }
147
148    protected void do_defaultBackupsRadioButton_actionPerformed(ActionEvent e) {
149        backup = new DefaultBackup();
150        loadComboBox();
151    }
152
153    protected void do_cancelButton_actionPerformed(ActionEvent arg0) {
154        dispose();
155    }
156
157    protected void do_comboBox_itemStateChanged(ItemEvent arg0) {
158        // If something has been selected, enable the Restore
159        // button.
160        // If we only have a deselect, then the button will remain disabled.
161        // When changing between items in the list, the item being left is
162        // deselected first, then the new item is selected.
163        //
164        // Not sure if there can be more than two states, so using the if
165        // statement to be safe.
166        int stateChange = arg0.getStateChange();
167
168        if (stateChange == ItemEvent.SELECTED) {
169            restoreButton.setEnabled(true);
170        } else if (stateChange == ItemEvent.DESELECTED) {
171            restoreButton.setEnabled(false);
172        }
173
174    }
175
176    protected void do_helpButton_actionPerformed(ActionEvent arg0) {
177        // Not implemented yet.
178    }
179
180    @edu.umd.cs.findbugs.annotations.SuppressFBWarnings(value = "SLF4J_FORMAT_SHOULD_BE_CONST",
181            justification = "I18N of Info Message")
182    protected void do_restoreButton_actionPerformed(ActionEvent e) {
183        log.debug("restore button activated");
184
185        // check to see if files are dirty
186        if (OperationsXml.areFilesDirty()) {
187            if (JmriJOptionPane.showConfirmDialog(this, Bundle.getMessage("OperationsFilesModified"),
188                    Bundle.getMessage("SaveOperationFiles"), JmriJOptionPane.YES_NO_OPTION) == JmriJOptionPane.YES_OPTION) {
189                OperationsXml.save();
190            }
191        }
192
193        // first backup the users data in case they forgot
194        try {
195            AutoBackup auto = new AutoBackup();
196            auto.autoBackup();
197
198            // now delete the current operations files in case the restore isn't a full set of files
199            backup.deleteOperationsFiles();
200
201            setName = ((BackupSet) comboBox.getSelectedItem()).getSetName();
202            Date date = ((BackupSet) comboBox.getSelectedItem()).getLastModifiedDate();
203            String sd = String.format("%s", date);
204
205            log.info(Bundle.getMessage("InfoRestoringSet", setName, sd));
206
207            // The restore method should probably be overloaded to accept a
208            // BackupSet instead of a simple string. Later.
209            backup.restoreFilesFromSetName(setName);
210
211            // now deregister shut down task
212            // If Trains window was opened, then task is active
213            // otherwise it is normal to not have the task running
214            InstanceManager.getDefault(OperationsManager.class).setShutDownTask(null);
215
216            JmriJOptionPane.showMessageDialog(this, Bundle.getMessage("YouMustRestartAfterRestore"),
217                    Bundle.getMessage("RestoreSuccessful"), JmriJOptionPane.INFORMATION_MESSAGE);
218            dispose();
219
220            try {
221                InstanceManager.getDefault(jmri.ShutDownManager.class).restart();
222            } catch (Exception er) {
223                log.error("Continuing after error in handleRestart", er);
224            }
225        } // These may need to be enhanced to show the backup store being used,
226          // auto or default.
227        catch (IOException ex) {
228            ExceptionContext context = new ExceptionContext(ex, Bundle.getMessage("RestoreDialog.restoring")
229                    + " " + setName, "Hint about checking valid names, etc."); // NOI18N
230            ExceptionDisplayFrame.displayExceptionDisplayFrame(this, context);
231
232        } catch (Exception ex) {
233            log.error("Doing restore from {}", setName, ex);
234
235            UnexpectedExceptionContext context = new UnexpectedExceptionContext(ex,
236                    Bundle.getMessage("RestoreDialog.restoring") + " " + setName);
237
238            ExceptionDisplayFrame.displayExceptionDisplayFrame(this, context);
239        }
240    }
241
242    /**
243     * Adds the names of the backup sets that are available in either the
244     * Automatic or the Default backup store.
245     */
246    private void loadComboBox() {
247        // Get the Backup Sets from the currently selected backup store.
248        // Called after the radio button selection has changed
249
250        // Disable the Restore button in case there is nothing loaded into the ComboBox
251        restoreButton.setEnabled(false);
252
253        comboBox.removeAllItems();
254
255        BackupSet[] sets = backup.getBackupSets();
256        ComboBoxModel<BackupSet> model = new DefaultComboBoxModel<>(sets);
257
258        // Clear any current selection so that the state change will fire when
259        // we set a selection.
260        model.setSelectedItem(null);
261
262        comboBox.setModel(model);
263
264        // Position at the last item, which is usually the most recent
265        // This is ugly code, but it works....
266        if (model.getSize() > 0) {
267            comboBox.setSelectedIndex(model.getSize() - 1);
268        }
269    }
270
271    private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(RestoreDialog.class);
272
273}