/* * MediathekView * Copyright (C) 2008 W. Xaver * Copyright (C) 2014 Christian F. * W.Xaver[at]googlemail.com * http://zdfmediathk.sourceforge.net/ * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package mediathek.gui.dialog; import mediathek.config.Daten; import mediathek.config.Icons; import mediathek.config.MVConfig; import mediathek.daten.DatenDownload; import mediathek.file.GetFile; import mediathek.tool.EscBeenden; import org.jdesktop.swingx.JXBusyLabel; import javax.swing.*; import java.awt.*; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Calendar; import java.util.Date; @SuppressWarnings("serial") public class DialogBeendenZeit extends JDialog { private static final String WAIT_FOR_DOWNLOADS_AND_TERMINATE = "Auf Abschluß aller Downloads warten und danach Programm beenden"; private static final String WAIT_FOR_DOWNLOADS_AND_DONT_TERMINATE_PROGRAM = "Auf Abschluß aller Downloads warten, Programm danach NICHT beenden"; private static final String DONT_START = "Downloads nicht starten"; private final JFrame frameParent; private final Daten daten; private final ArrayList<DatenDownload> listeDownloadsStarten; /** * Indicates whether the application can terminate. */ private boolean applicationCanTerminate = false; /** * Indicate whether computer should be shut down. */ private boolean shutdown = false; /** * JPanel for displaying the glassPane with the busy indicator label. */ private JPanel glassPane = null; private final JXBusyLabel lblGlassPane = new JXBusyLabel(); /** * The download monitoring {@link javax.swing.SwingWorker}. */ private SwingWorker<Void, Void> downloadMonitorWorker = null; /** * Return whether the user still wants to terminate the application. * * @return true if the app should continue to terminate. */ public boolean applicationCanTerminate() { return applicationCanTerminate; } /** * Does the user want to shutdown the computer? * * @return true if shutdown is wanted. */ public boolean isShutdownRequested() { return shutdown; } public DialogBeendenZeit(JFrame pparent, final Daten daten_, final ArrayList<DatenDownload> listeDownloadsStarten_) { super(pparent, true); initComponents(); this.frameParent = pparent; daten = daten_; listeDownloadsStarten = listeDownloadsStarten_; this.setTitle("Zeitverzögerter Download-Start"); if (frameParent != null) { setLocationRelativeTo(frameParent); } new EscBeenden(this) { @Override public void beenden_() { escapeHandler(); } }; addWindowListener(new WindowAdapter() { @Override public void windowClosing(WindowEvent e) { escapeHandler(); } }); // set date format Calendar cal = Calendar.getInstance(); cal.add(Calendar.MINUTE, 1); Date startDate = cal.getTime(); cal.add(Calendar.MINUTE, 60); // würde sagen, das ist ein Bug, geht sonst nicht Date now = cal.getTime(); cal.add(Calendar.DATE, 2); Date endDate = cal.getTime(); SpinnerDateModel model = new SpinnerDateModel(now, startDate, endDate, Calendar.MINUTE); if (!MVConfig.get(MVConfig.Configs.SYSTEM_DIALOG_DOWNLOAD_STARTEN_ZEIT).isEmpty()) { try { String heute = new SimpleDateFormat("yyyyMMdd").format(new Date()); heute = heute + MVConfig.get(MVConfig.Configs.SYSTEM_DIALOG_DOWNLOAD_STARTEN_ZEIT); Date start = new SimpleDateFormat("yyyyMMddHH:mm").parse(heute); if (start.after(startDate)) { // nur wenn start nach "jetzt" kommt model = new SpinnerDateModel(start, startDate, endDate, Calendar.MINUTE); } else { // sonst 24h dazuzählen start = new Date(start.getTime() + 24 * 60 * 60 * 1000); model = new SpinnerDateModel(start, startDate, endDate, Calendar.MINUTE); } } catch (Exception ignored) { } } jSpinnerTime.setModel(model); JSpinner.DateEditor dEditor = new JSpinner.DateEditor(jSpinnerTime, "dd.MM.yyy HH:mm"); jSpinnerTime.setEditor(dEditor); comboActions.setModel(getComboBoxModel()); comboActions.addActionListener(e -> setCbShutdownCoputer()); jButtonHilfe.setIcon(Icons.ICON_BUTTON_HELP); jButtonHilfe.addActionListener(e -> new DialogHilfe(frameParent, true, new GetFile().getHilfeSuchen(GetFile.PFAD_HILFETEXT_BEENDEN)).setVisible(true)); setCbShutdownCoputer(); cbShutdownComputer.addActionListener(e -> shutdown = cbShutdownComputer.isSelected()); cbShutdownComputer.setSelected(Boolean.parseBoolean(MVConfig.get(MVConfig.Configs.SYSTEM_DIALOG_DOWNLOAD_SHUTDOWN))); btnContinue.addActionListener(e -> { final String strSelectedItem = comboActions.getSelectedItem().toString(); MVConfig.add(MVConfig.Configs.SYSTEM_DIALOG_DOWNLOAD_SHUTDOWN, String.valueOf(cbShutdownComputer.isSelected())); SimpleDateFormat format = ((JSpinner.DateEditor) jSpinnerTime.getEditor()).getFormat(); format.applyPattern("HH:mm"); Date sp = (Date) jSpinnerTime.getValue(); String strDate = format.format(sp); MVConfig.add(MVConfig.Configs.SYSTEM_DIALOG_DOWNLOAD_STARTEN_ZEIT, strDate); switch (strSelectedItem) { case WAIT_FOR_DOWNLOADS_AND_TERMINATE: applicationCanTerminate = true; waitUntilDownloadsHaveFinished(); break; case WAIT_FOR_DOWNLOADS_AND_DONT_TERMINATE_PROGRAM: applicationCanTerminate = false; waitUntilDownloadsHaveFinished(); break; case DONT_START: applicationCanTerminate = false; dispose(); break; } }); btnCancel.addActionListener(e -> escapeHandler()); pack(); getRootPane().setDefaultButton(btnContinue); } private void setCbShutdownCoputer() { final String strSelectedItem = (String) comboActions.getSelectedItem(); switch (strSelectedItem) { case WAIT_FOR_DOWNLOADS_AND_TERMINATE: cbShutdownComputer.setEnabled(true); break; default: //manually reset shutdown state cbShutdownComputer.setEnabled(false); cbShutdownComputer.setSelected(false); shutdown = false; break; } } /** * Create the ComboBoxModel for user selection. * * @return The model with all valid user actions. */ private DefaultComboBoxModel<String> getComboBoxModel() { return new DefaultComboBoxModel<>(new String[]{WAIT_FOR_DOWNLOADS_AND_TERMINATE, WAIT_FOR_DOWNLOADS_AND_DONT_TERMINATE_PROGRAM, DONT_START}); } /** * This will reset all necessary variables to default and cancel app termination. */ private void escapeHandler() { if (downloadMonitorWorker != null) { downloadMonitorWorker.cancel(true); } if (glassPane != null) { glassPane.setVisible(false); } applicationCanTerminate = false; dispose(); } /** * Create the glassPane which will be used as an overlay for the dialog while we are waiting for downloads. * * @return The {@link javax.swing.JPanel} for the glassPane. */ private JPanel createGlassPane() { String strMessage = "<html>Warte auf Abschluss der Downloads..."; if (isShutdownRequested()) { strMessage += "<br><b>Der Rechner wird danach heruntergefahren.</b>"; } strMessage += "<br>Sie können den Vorgang mit Escape abbrechen.</html>"; JPanel panel = new JPanel(); panel.setLayout(new BorderLayout(5, 5)); lblGlassPane.setText(strMessage); lblGlassPane.setBusy(true); lblGlassPane.setVerticalAlignment(SwingConstants.CENTER); lblGlassPane.setHorizontalAlignment(SwingConstants.CENTER); panel.add(lblGlassPane, BorderLayout.CENTER); return panel; } private void setTextWait() { SimpleDateFormat format = ((JSpinner.DateEditor) jSpinnerTime.getEditor()).getFormat(); format.applyPattern("dd.MM.yyy HH:mm"); Date sp = (Date) jSpinnerTime.getValue(); String strDate = format.format(sp); String strMessage = "<html>Downloads starten:<br><br><b>" + strDate + "</b><br>"; if (isShutdownRequested()) { strMessage += "<br><b>Der Rechner wird danach heruntergefahren.</b>"; } strMessage += "<br>Sie können den Vorgang mit Escape abbrechen.</html>"; lblGlassPane.setText(strMessage); } private void setTextDownload_() { String strMessage = "<html>Warte auf Abschluss der Downloads..."; if (isShutdownRequested()) { strMessage += "<br><b>Der Rechner wird danach heruntergefahren.</b>"; } strMessage += "<br>Sie können den Vorgang mit Escape abbrechen.</html>"; lblGlassPane.setText(strMessage); } private void setTextDownload() { try { if (SwingUtilities.isEventDispatchThread()) { setTextDownload_(); } else { SwingUtilities.invokeLater(this::setTextDownload_); } } catch (Exception ignored) { } } /** * Handler which will wait untill all downloads have finished. * Uses a {@link javax.swing.SwingWorker} to properly handle EDT stuff. */ private void waitUntilDownloadsHaveFinished() { glassPane = createGlassPane(); setGlassPane(glassPane); setTextWait(); glassPane.setVisible(true); downloadMonitorWorker = new SwingWorker<Void, Void>() { @Override protected Void doInBackground() throws Exception { while ((((Date) jSpinnerTime.getValue())).after(new Date())) { Thread.sleep(1000); } setTextDownload(); DatenDownload.startenDownloads(daten, listeDownloadsStarten); while ((Daten.getInstance().getListeDownloads().nochNichtFertigeDownloads() > 0) && !isCancelled()) { Thread.sleep(1000); } return null; } @Override protected void done() { glassPane.setVisible(false); dispose(); downloadMonitorWorker = null; } }; downloadMonitorWorker.execute(); } // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents private void initComponents() { javax.swing.JLabel jLabel1 = new javax.swing.JLabel(); comboActions = new javax.swing.JComboBox<>(); btnContinue = new javax.swing.JButton(); cbShutdownComputer = new javax.swing.JCheckBox(); btnCancel = new javax.swing.JButton(); jButtonHilfe = new javax.swing.JButton(); javax.swing.JLabel jLabel2 = new javax.swing.JLabel(); jSpinnerTime = new javax.swing.JSpinner(); javax.swing.JLabel jLabel3 = new javax.swing.JLabel(); setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); setResizable(false); jLabel1.setText("<html>Wie möchten Sie fortfahren<br>\nwenn alle Downloads fertig sind?</html>"); btnContinue.setText("Weiter"); cbShutdownComputer.setText("Rechner herunterfahren"); btnCancel.setText("Zurück"); jButtonHilfe.setIcon(new javax.swing.ImageIcon(getClass().getResource("/mediathek/res/muster/button-help.png"))); // NOI18N jButtonHilfe.setToolTipText("Hilfe anzeigen"); jLabel2.setText("alle Downloads starten um: "); jLabel3.setText("Uhr"); javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); getContentPane().setLayout(layout); layout.setHorizontalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() .addContainerGap() .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(jLabel1, javax.swing.GroupLayout.DEFAULT_SIZE, 551, Short.MAX_VALUE) .addComponent(comboActions, 0, 0, Short.MAX_VALUE) .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() .addGap(0, 0, Short.MAX_VALUE) .addComponent(jButtonHilfe) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(btnCancel) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(btnContinue)) .addGroup(layout.createSequentialGroup() .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(cbShutdownComputer) .addGroup(layout.createSequentialGroup() .addComponent(jLabel2) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(jSpinnerTime, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(jLabel3))) .addGap(0, 0, Short.MAX_VALUE))) .addContainerGap()) ); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() .addContainerGap() .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(jLabel2) .addComponent(jSpinnerTime, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(jLabel3)) .addGap(18, 18, Short.MAX_VALUE) .addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) .addComponent(comboActions, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) .addGroup(layout.createSequentialGroup() .addComponent(cbShutdownComputer) .addGap(18, 18, 18) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(btnContinue) .addComponent(btnCancel))) .addComponent(jButtonHilfe)) .addContainerGap()) ); pack(); }// </editor-fold>//GEN-END:initComponents // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.JButton btnCancel; private javax.swing.JButton btnContinue; private javax.swing.JCheckBox cbShutdownComputer; private javax.swing.JComboBox<String> comboActions; private javax.swing.JButton jButtonHilfe; private javax.swing.JSpinner jSpinnerTime; // End of variables declaration//GEN-END:variables }