forked from j62/ctbrec
1
0
Fork 0

Add confirmation dialog for shutdown

Show confirmation dialog when a shutdown is requested and there are
recordings in progress. The user now can decide to shutdown immediately,
shutdown gracefully or leave the app running
This commit is contained in:
0xb00bface 2020-08-19 12:45:47 +02:00
parent 17f1c3aec6
commit 7e2924d780
7 changed files with 90 additions and 52 deletions

View File

@ -5,6 +5,7 @@
* media player isn't working because of their authetication mechanism * media player isn't working because of their authetication mechanism
* Fixed bug in recorder servlet. Actions for unpin and notes were mixed up * Fixed bug in recorder servlet. Actions for unpin and notes were mixed up
* Recordings now start immediately for newly added models * Recordings now start immediately for newly added models
* Added confirmation dialog for "Pause All" and "Resume All"
3.8.6 3.8.6
======================== ========================

View File

@ -8,6 +8,8 @@ import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.InputStreamReader; import java.io.InputStreamReader;
import java.lang.reflect.Type; import java.lang.reflect.Type;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
@ -70,6 +72,7 @@ import javafx.beans.value.ChangeListener;
import javafx.geometry.Insets; import javafx.geometry.Insets;
import javafx.scene.Scene; import javafx.scene.Scene;
import javafx.scene.control.Alert; import javafx.scene.control.Alert;
import javafx.scene.control.ButtonType;
import javafx.scene.control.Label; import javafx.scene.control.Label;
import javafx.scene.control.Tab; import javafx.scene.control.Tab;
import javafx.scene.control.TabPane; import javafx.scene.control.TabPane;
@ -249,18 +252,34 @@ public class CamrecApplication extends Application {
} }
} }
// check for active recordings
boolean shutdownNow = false;
try {
if (!recorder.getCurrentlyRecording().isEmpty()) {
ButtonType result = Dialogs.showShutdownDialog(primaryStage.getScene());
if(result == ButtonType.NO) {
return;
} else if(result == ButtonType.YES) {
shutdownNow = true;
}
}
} catch (InvalidKeyException | NoSuchAlgorithmException | IOException ex) {
LOG.warn("Couldn't check, if recordings are running");
}
Alert shutdownInfo = new AutosizeAlert(Alert.AlertType.INFORMATION, primaryStage.getScene()); Alert shutdownInfo = new AutosizeAlert(Alert.AlertType.INFORMATION, primaryStage.getScene());
shutdownInfo.setTitle("Shutdown"); shutdownInfo.setTitle("Shutdown");
shutdownInfo.setContentText("Shutting down. Please wait while recordings are finished..."); shutdownInfo.setContentText("Shutting down. Please wait while recordings are finished...");
shutdownInfo.show(); shutdownInfo.show();
final boolean immediately = shutdownNow;
new Thread() { new Thread() {
@Override @Override
public void run() { public void run() {
modelsTab.saveState(); modelsTab.saveState();
recordingsTab.saveState(); recordingsTab.saveState();
onlineMonitor.shutdown(); onlineMonitor.shutdown();
recorder.shutdown(); recorder.shutdown(immediately);
for (Site site : sites) { for (Site site : sites) {
if(site.isEnabled()) { if(site.isEnabled()) {
site.shutdown(); site.shutdown();

View File

@ -11,6 +11,7 @@ import javafx.geometry.Insets;
import javafx.scene.Scene; import javafx.scene.Scene;
import javafx.scene.control.Alert; import javafx.scene.control.Alert;
import javafx.scene.control.Alert.AlertType; import javafx.scene.control.Alert.AlertType;
import javafx.scene.control.Button;
import javafx.scene.control.ButtonType; import javafx.scene.control.ButtonType;
import javafx.scene.control.Dialog; import javafx.scene.control.Dialog;
import javafx.scene.control.TextArea; import javafx.scene.control.TextArea;
@ -112,4 +113,19 @@ public class Dialogs {
confirm.showAndWait(); confirm.showAndWait();
return confirm.getResult() == ButtonType.YES; return confirm.getResult() == ButtonType.YES;
} }
public static ButtonType showShutdownDialog(Scene parent) {
String message = "There are recordings in progress";
AutosizeAlert confirm = new AutosizeAlert(AlertType.CONFIRMATION, "", parent, YES, FINISH, NO);
confirm.setTitle("Shutdown");
confirm.setHeaderText(message);
((Button) confirm.getDialogPane().lookupButton(ButtonType.YES)).setText("Shutdown Now");
((Button) confirm.getDialogPane().lookupButton(ButtonType.YES)).setDefaultButton(false);
((Button) confirm.getDialogPane().lookupButton(ButtonType.FINISH)).setText("Shutdown Gracefully");
((Button) confirm.getDialogPane().lookupButton(ButtonType.FINISH)).setDefaultButton(true);
((Button) confirm.getDialogPane().lookupButton(ButtonType.NO)).setText("Keep Running");
((Button) confirm.getDialogPane().lookupButton(ButtonType.NO)).setDefaultButton(false);
confirm.showAndWait();
return confirm.getResult();
}
} }

View File

@ -410,11 +410,12 @@ public class NextGenLocalRecorder implements Recorder {
} }
@Override @Override
public void shutdown() { public void shutdown(boolean immediately) {
// TODO add a config flag for waitign or stopping immediately // TODO add a config flag for waitign or stopping immediately
LOG.info("Shutting down"); LOG.info("Shutting down");
recording = false; recording = false;
if (!immediately) {
LOG.debug("Stopping all recording processes"); LOG.debug("Stopping all recording processes");
recorderLock.lock(); recorderLock.lock();
try { try {
@ -468,6 +469,7 @@ public class NextGenLocalRecorder implements Recorder {
LOG.error("Error while waiting for pools to finish", e); LOG.error("Error while waiting for pools to finish", e);
} }
} }
}
@Override @Override
public void suspendRecording(Model model) { public void suspendRecording(Model model) {

View File

@ -52,7 +52,7 @@ public interface Recorder {
*/ */
public void unpin(Recording recording) throws IOException, InvalidKeyException, NoSuchAlgorithmException; public void unpin(Recording recording) throws IOException, InvalidKeyException, NoSuchAlgorithmException;
public void shutdown(); public void shutdown(boolean immediately);
public void suspendRecording(Model model) throws IOException, InvalidKeyException, NoSuchAlgorithmException; public void suspendRecording(Model model) throws IOException, InvalidKeyException, NoSuchAlgorithmException;
public void resumeRecording(Model model) throws IOException, InvalidKeyException, NoSuchAlgorithmException; public void resumeRecording(Model model) throws IOException, InvalidKeyException, NoSuchAlgorithmException;
@ -66,7 +66,7 @@ public interface Recorder {
public List<Model> getOnlineModels(); public List<Model> getOnlineModels();
/** /**
* Returns only the models from getModels(), which are actually recorded right now * Returns only the models from getModels(), which are actually recorded right now (a recording process is currently running).
* @return * @return
* @throws IOException * @throws IOException
* @throws IllegalStateException * @throws IllegalStateException

View File

@ -175,7 +175,7 @@ public class RemoteRecorder implements Recorder {
} }
@Override @Override
public void shutdown() { public void shutdown(boolean immediately) {
syncThread.stopThread(); syncThread.stopThread();
} }

View File

@ -151,7 +151,7 @@ public class HttpServer {
onlineMonitor.shutdown(); onlineMonitor.shutdown();
} }
if (recorder != null) { if (recorder != null) {
recorder.shutdown(); recorder.shutdown(false);
} }
try { try {
server.stop(); server.stop();